LangChain4j 实战指南

LangChain4j 实战指南:构建企业级 Java AI 应用

摘要

LangChain4j 是 LangChain 在 Java 生态系统中的官方实现,为 Java 开发者提供了构建 LLM 驱动应用的完整工具链。本文将深入探讨 LangChain4j 的核心特性、架构设计和实战应用,帮助开发者快速构建生产级 AI 应用。

目录

  1. LangChain4j 简介
  2. 核心架构与设计
  3. 快速开始
  4. 核心功能详解
  5. 高级特性
  6. 生产环境实践
  7. 与主流框架集成
  8. 实战案例
  9. 最佳实践与性能优化
  10. 总结

1. LangChain4j 简介

1.1 什么是 LangChain4j

LangChain4j 是专为 Java 和 Kotlin 开发者设计的 LLM 应用开发框架,提供了丰富的抽象层和工具,简化了 AI 应用的开发流程。

核心优势:

  • 🎯 原生 Java 支持,无需 Python 桥接
  • 🔌 支持 30+ 主流 LLM 模型(OpenAI、Claude、Gemini、Qwen 等)
  • 🛠️ 完整的工具链(RAG、Agent、Memory、Tools)
  • 🚀 Spring Boot 无缝集成
  • 📦 丰富的向量数据库支持
  • 🔄 流式响应和异步处理

1.2 应用场景矩阵

sql 复制代码
┌─────────────────────────────────────────────────────────────┐
│               LangChain4j 企业应用场景                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐  │
│  │  智能客服     │  │  知识问答     │  │  文档助手     │  │
│  │               │  │               │  │               │  │
│  │ • 多轮对话    │  │ • RAG 检索    │  │ • PDF 解析    │  │
│  │ • 意图识别    │  │ • 企业知识库  │  │ • 内容摘要    │  │
│  │ • 情感分析    │  │ • 语义搜索    │  │ • 信息提取    │  │
│  │ • 工单创建    │  │ • 上下文理解  │  │ • 多语言翻译  │  │
│  └───────────────┘  └───────────────┘  └───────────────┘  │
│                                                             │
│  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐  │
│  │  AI Agent     │  │  代码助手     │  │  数据分析     │  │
│  │               │  │               │  │               │  │
│  │ • 任务规划    │  │ • 代码生成    │  │ • SQL 生成    │  │
│  │ • 工具调用    │  │ • Bug 修复    │  │ • 报表生成    │  │
│  │ • 自主决策    │  │ • 代码审查    │  │ • 趋势预测    │  │
│  │ • 流程自动化  │  │ • 单元测试    │  │ • 异常检测    │  │
│  └───────────────┘  └───────────────┘  └───────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

1.3 与其他框架对比

特性 LangChain4j Spring AI Semantic Kernel
语言支持 Java/Kotlin Java C#/Java/Python
Spring 集成 ✅ 优秀 ✅ 原生 ⚠️ 一般
LLM 支持 30+ 10+ 15+
Agent 能力 ✅ 强大 ⚠️ 基础 ✅ 强大
RAG 支持 ✅ 完整 ✅ 完整 ✅ 完整
文档质量 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
社区活跃度

2. 核心架构与设计

2.1 整体架构图

scss 复制代码
┌──────────────────────────────────────────────────────────────┐
│                     Application Layer                         │
│                    (Your Business Logic)                      │
└───────────────────────────┬──────────────────────────────────┘
                            │
┌───────────────────────────▼──────────────────────────────────┐
│                    LangChain4j Framework                      │
├──────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              High-Level Components                   │    │
│  ├─────────────────────────────────────────────────────┤    │
│  │  • AI Services (Interface-based)                    │    │
│  │  • Chains (Sequential, Conditional)                 │    │
│  │  • Agents (ReAct, Plan-and-Execute)                 │    │
│  └─────────────────────────────────────────────────────┘    │
│                            │                                  │
│  ┌─────────────────────────▼───────────────────────────┐    │
│  │              Core Components                         │    │
│  ├─────────────────────────────────────────────────────┤    │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐          │    │
│  │  │ Chat     │  │ Embedding│  │ Moderation│         │    │
│  │  │ Language │  │  Model   │  │  Model   │          │    │
│  │  │  Model   │  └──────────┘  └──────────┘          │    │
│  │  └──────────┘                                       │    │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐          │    │
│  │  │  Memory  │  │  Tools   │  │ Document │          │    │
│  │  │ (ChatMem)│  │          │  │ Loaders  │          │    │
│  │  └──────────┘  └──────────┘  └──────────┘          │    │
│  └─────────────────────────────────────────────────────┘    │
│                            │                                  │
│  ┌─────────────────────────▼───────────────────────────┐    │
│  │           Integration Layer                          │    │
│  ├─────────────────────────────────────────────────────┤    │
│  │  • Model Providers (OpenAI, Azure, Anthropic...)   │    │
│  │  • Vector Stores (Pinecone, Chroma, Weaviate...)   │    │
│  │  • Document Parsers (PDF, DOCX, HTML...)           │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                               │
└──────────────────────────────────────────────────────────────┘

2.2 核心组件说明

ChatLanguageModel: 对话模型抽象,支持同步和流式调用

EmbeddingModel: 文本向量化模型,用于语义搜索

ChatMemory: 对话历史管理(短期、长期、摘要)

Tools: 外部工具集成,让 AI 能够执行实际操作

DocumentLoader: 文档加载和解析

VectorStore: 向量数据库集成

AI Services: 声明式接口,自动处理对话、工具调用等


3. 快速开始

3.1 环境准备

前置条件:

  • JDK 11+ (推荐 JDK 17+)
  • Maven 3.6+ 或 Gradle 7.0+
  • 至少一个 LLM API Key (OpenAI, Qwen, Claude 等)

3.2 Maven 依赖配置

xml 复制代码
<dependencies>
    <!-- LangChain4j 核心库 -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j</artifactId>
        <version>0.34.0</version>
    </dependency>

    <!-- OpenAI 模型支持 -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-open-ai</artifactId>
        <version>0.34.0</version>
    </dependency>

    <!-- 阿里云通义千问支持 -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-dashscope</artifactId>
        <version>0.34.0</version>
    </dependency>

    <!-- Spring Boot Starter (可选) -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-spring-boot-starter</artifactId>
        <version>0.34.0</version>
    </dependency>

    <!-- Embedding Store (Chroma) -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId>
        <version>0.34.0</version>
    </dependency>

    <!-- 文档解析 -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-document-parser-apache-pdfbox</artifactId>
        <version>0.34.0</version>
    </dependency>
</dependencies>

3.3 第一个示例

简单对话:

java 复制代码
package com.example.langchain4j.quickstart;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;

public class HelloLangChain4j {

    public static void main(String[] args) {
        // 创建 ChatLanguageModel
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-3.5-turbo")
                .temperature(0.7)
                .build();

        // 发送消息
        String response = model.generate("介绍一下 Java 17 的新特性");
        System.out.println(response);
    }
}

使用通义千问:

java 复制代码
package com.example.langchain4j.quickstart;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.dashscope.QwenChatModel;

public class HelloQwen {

    public static void main(String[] args) {
        ChatLanguageModel model = QwenChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-turbo")
                .build();

        String response = model.generate("用一句话解释什么是微服务架构");
        System.out.println(response);
    }
}

4. 核心功能详解

4.1 对话管理

4.1.1 多轮对话
java 复制代码
package com.example.langchain4j.chat;

import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;

public class MultiTurnConversation {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        // 创建聊天记忆(保留最近 10 条消息)
        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        // 第一轮对话
        UserMessage userMessage1 = UserMessage.from("我想学习 Spring Boot");
        chatMemory.add(userMessage1);

        String response1 = model.generate(chatMemory.messages()).content().text();
        chatMemory.add(AiMessage.from(response1));
        System.out.println("AI: " + response1);

        // 第二轮对话(AI 会记住上下文)
        UserMessage userMessage2 = UserMessage.from("它的核心特性有哪些?");
        chatMemory.add(userMessage2);

        String response2 = model.generate(chatMemory.messages()).content().text();
        chatMemory.add(AiMessage.from(response2));
        System.out.println("AI: " + response2);

        // 第三轮对话
        UserMessage userMessage3 = UserMessage.from("给我一个实际的示例代码");
        chatMemory.add(userMessage3);

        String response3 = model.generate(chatMemory.messages()).content().text();
        chatMemory.add(AiMessage.from(response3));
        System.out.println("AI: " + response3);
    }
}
4.1.2 流式响应
java 复制代码
package com.example.langchain4j.chat;

import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.model.output.Response;

public class StreamingConversation {

    public static void main(String[] args) throws InterruptedException {
        StreamingChatLanguageModel model = OpenAiStreamingChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-3.5-turbo")
                .build();

        System.out.print("AI: ");

        // 流式生成,实时打印
        model.generate("写一个关于人工智能的短故事",
            new dev.langchain4j.model.output.StreamingResponseHandler<String>() {
                @Override
                public void onNext(String token) {
                    System.out.print(token);
                }

                @Override
                public void onComplete(Response<String> response) {
                    System.out.println("\n\n[完成]");
                }

                @Override
                public void onError(Throwable error) {
                    System.err.println("错误: " + error.getMessage());
                }
            }
        );

        // 等待流式输出完成
        Thread.sleep(10000);
    }
}

4.2 AI Services - 声明式接口

AI Services 是 LangChain4j 的杀手级特性,允许通过接口定义来自动处理复杂的 AI 交互。

4.2.1 基础 AI Service
java 复制代码
package com.example.langchain4j.service;

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;

public interface CodeReviewAssistant {

    @SystemMessage("你是一位资深的 Java 代码审查专家,擅长发现代码中的问题并提供改进建议。")
    String reviewCode(@UserMessage String code);
}

使用 AI Service:

java 复制代码
package com.example.langchain4j.service;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

public class CodeReviewExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        // 创建 AI Service 实例
        CodeReviewAssistant assistant = AiServices.create(CodeReviewAssistant.class, model);

        String code = """
                public void processUser(String userId) {
                    User user = userRepository.findById(userId);
                    if (user != null) {
                        user.setLastLogin(new Date());
                        userRepository.save(user);
                    }
                }
                """;

        String review = assistant.reviewCode(code);
        System.out.println(review);
    }
}
4.2.2 带记忆的 AI Service
java 复制代码
package com.example.langchain4j.service;

import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;

/**
 * 智能客服助手
 */
public interface CustomerServiceAssistant {

    String chat(@MemoryId String conversationId, @UserMessage String message);
}

实现示例:

java 复制代码
package com.example.langchain4j.service;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;

public class CustomerServiceExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        // 创建聊天记忆存储
        ChatMemoryStore chatMemoryStore = new InMemoryChatMemoryStore();

        // 创建带记忆的 AI Service
        CustomerServiceAssistant assistant = AiServices.builder(CustomerServiceAssistant.class)
                .chatLanguageModel(model)
                .chatMemoryProvider(memoryId -> MessageWindowChatMemory.builder()
                        .id(memoryId)
                        .maxMessages(20)
                        .chatMemoryStore(chatMemoryStore)
                        .build())
                .build();

        // 用户 A 的对话
        String conversationA = "user-123";
        System.out.println("User A: 我的订单号是 ORD-001,想查询物流信息");
        System.out.println("AI: " + assistant.chat(conversationA, "我的订单号是 ORD-001,想查询物流信息"));

        System.out.println("\nUser A: 大概什么时候能送达?");
        System.out.println("AI: " + assistant.chat(conversationA, "大概什么时候能送达?"));

        // 用户 B 的独立对话
        String conversationB = "user-456";
        System.out.println("\n\nUser B: 如何申请退款?");
        System.out.println("AI: " + assistant.chat(conversationB, "如何申请退款?"));
    }
}

4.3 工具调用 (Tools)

工具调用让 AI 能够执行实际操作,如查询数据库、调用 API 等。

4.3.1 定义工具
java 复制代码
package com.example.langchain4j.tools;

import dev.langchain4j.agent.tool.Tool;

public class WeatherTools {

    @Tool("获取指定城市的当前天气信息")
    public String getCurrentWeather(String city) {
        // 实际应用中应该调用真实的天气 API
        return String.format("城市: %s, 温度: 22°C, 天气: 晴天, 湿度: 65%%", city);
    }

    @Tool("获取指定城市的未来天气预报")
    public String getWeatherForecast(String city, int days) {
        return String.format("城市: %s, 未来%d天天气预报: 多云转晴,温度范围 18-28°C", city, days);
    }
}
4.3.2 使用工具的 AI Service
java 复制代码
package com.example.langchain4j.service;

import dev.langchain4j.service.UserMessage;

public interface WeatherAssistant {

    String chat(@UserMessage String message);
}

集成工具:

java 复制代码
package com.example.langchain4j.tools;

import com.example.langchain4j.service.WeatherAssistant;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

public class WeatherToolExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        WeatherTools weatherTools = new WeatherTools();

        WeatherAssistant assistant = AiServices.builder(WeatherAssistant.class)
                .chatLanguageModel(model)
                .tools(weatherTools)
                .build();

        // AI 会自动调用合适的工具
        String response1 = assistant.chat("北京现在天气怎么样?");
        System.out.println(response1);

        String response2 = assistant.chat("上海未来3天的天气如何?");
        System.out.println(response2);
    }
}
4.3.3 复杂工具示例 - 数据库操作
java 复制代码
package com.example.langchain4j.tools;

import dev.langchain4j.agent.tool.Tool;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
public class DatabaseTools {

    private final JdbcTemplate jdbcTemplate;

    public DatabaseTools(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Tool("查询用户信息")
    public String findUserById(Long userId) {
        try {
            Map<String, Object> user = jdbcTemplate.queryForMap(
                    "SELECT id, name, email, created_at FROM users WHERE id = ?",
                    userId
            );
            return String.format("用户信息: ID=%s, 姓名=%s, 邮箱=%s, 创建时间=%s",
                    user.get("id"), user.get("name"), user.get("email"), user.get("created_at"));
        } catch (Exception e) {
            return "未找到该用户";
        }
    }

    @Tool("查询订单列表")
    public String findOrdersByUserId(Long userId, int limit) {
        try {
            List<Map<String, Object>> orders = jdbcTemplate.queryForList(
                    "SELECT order_id, amount, status, created_at FROM orders WHERE user_id = ? ORDER BY created_at DESC LIMIT ?",
                    userId, limit
            );

            if (orders.isEmpty()) {
                return "该用户没有订单";
            }

            StringBuilder result = new StringBuilder("订单列表:\n");
            for (Map<String, Object> order : orders) {
                result.append(String.format("- 订单号: %s, 金额: %s, 状态: %s, 时间: %s\n",
                        order.get("order_id"), order.get("amount"),
                        order.get("status"), order.get("created_at")));
            }
            return result.toString();
        } catch (Exception e) {
            return "查询订单失败: " + e.getMessage();
        }
    }

    @Tool("统计订单数量")
    public String countOrdersByStatus(String status) {
        try {
            Integer count = jdbcTemplate.queryForObject(
                    "SELECT COUNT(*) FROM orders WHERE status = ?",
                    Integer.class,
                    status
            );
            return String.format("状态为 '%s' 的订单共有 %d 个", status, count);
        } catch (Exception e) {
            return "统计失败: " + e.getMessage();
        }
    }
}

4.4 RAG (检索增强生成)

RAG 是构建知识库问答系统的核心技术。

4.4.1 文档加载和分割
java 复制代码
package com.example.langchain4j.rag;

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentSplitter;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.apache.pdfbox.ApachePdfBoxDocumentParser;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;

import java.nio.file.Path;
import java.util.List;

public class DocumentProcessor {

    public static List<TextSegment> loadAndSplitDocument(String filePath) {
        // 1. 加载文档
        Document document = FileSystemDocumentLoader.loadDocument(
                Path.of(filePath),
                new ApachePdfBoxDocumentParser()
        );

        // 2. 分割文档
        DocumentSplitter splitter = DocumentSplitters.recursive(
                300,  // 每个分块最大字符数
                30    // 分块之间的重叠字符数
        );

        return splitter.split(document);
    }
}
4.4.2 向量存储
java 复制代码
package com.example.langchain4j.rag;

import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

import java.util.List;

public class VectorStoreExample {

    public static void main(String[] args) {
        // 1. 创建 Embedding 模型
        EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();

        // 2. 创建向量存储
        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

        // 3. 准备文档
        List<TextSegment> segments = List.of(
                TextSegment.from("Spring Boot 是一个用于简化 Spring 应用开发的框架。"),
                TextSegment.from("Spring Boot 提供了自动配置功能,减少了样板代码。"),
                TextSegment.from("Spring Cloud 用于构建微服务架构。"),
                TextSegment.from("Spring Data 简化了数据访问层的开发。")
        );

        // 4. 向量化并存储
        for (TextSegment segment : segments) {
            Embedding embedding = embeddingModel.embed(segment).content();
            embeddingStore.add(embedding, segment);
        }

        // 5. 语义搜索
        String query = "如何简化 Spring 开发?";
        Embedding queryEmbedding = embeddingModel.embed(query).content();

        List<EmbeddingMatch<TextSegment>> matches = embeddingStore.findRelevant(
                queryEmbedding,
                3,    // 返回前 3 个最相关的结果
                0.7   // 相似度阈值
        );

        // 6. 打印结果
        System.out.println("查询: " + query);
        System.out.println("\n最相关的文档:");
        for (EmbeddingMatch<TextSegment> match : matches) {
            System.out.printf("相似度: %.2f, 内容: %s\n",
                    match.score(),
                    match.embedded().text());
        }
    }
}
4.4.3 完整的 RAG 系统
java 复制代码
package com.example.langchain4j.rag;

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

import java.nio.file.Path;
import java.util.List;

/**
 * RAG 知识库问答助手
 */
public class RagAssistant {

    interface KnowledgeBaseAssistant {
        String answer(String question);
    }

    public static void main(String[] args) {
        // 1. 创建 Embedding 模型
        EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();

        // 2. 创建向量存储
        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

        // 3. 加载和处理文档
        List<Document> documents = FileSystemDocumentLoader.loadDocuments(
                Path.of("docs"),
                path -> path.toString().endsWith(".txt")
        );

        // 4. 文档摄取(分割、向量化、存储)
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .documentSplitter(DocumentSplitters.recursive(300, 30))
                .embeddingModel(embeddingModel)
                .embeddingStore(embeddingStore)
                .build();

        ingestor.ingest(documents);

        // 5. 创建内容检索器
        EmbeddingStoreContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .maxResults(3)
                .minScore(0.7)
                .build();

        // 6. 创建 Chat 模型
        ChatLanguageModel chatModel = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        // 7. 创建 RAG AI Service
        KnowledgeBaseAssistant assistant = AiServices.builder(KnowledgeBaseAssistant.class)
                .chatLanguageModel(chatModel)
                .contentRetriever(contentRetriever)
                .build();

        // 8. 使用助手回答问题
        String question = "Spring Boot 的主要优势是什么?";
        String answer = assistant.answer(question);

        System.out.println("问题: " + question);
        System.out.println("回答: " + answer);
    }
}

5. 高级特性

5.1 AI Agent

Agent 是能够自主决策和执行任务的 AI 系统。

5.1.1 ReAct Agent
java 复制代码
package com.example.langchain4j.agent;

import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

/**
 * 搜索工具
 */
class SearchTools {

    @Tool("在互联网上搜索信息")
    public String search(String query) {
        // 模拟搜索结果
        return String.format("搜索结果: '%s' 的相关信息...", query);
    }

    @Tool("获取网页内容")
    public String getWebPageContent(String url) {
        return String.format("网页 %s 的内容...", url);
    }
}

/**
 * 计算工具
 */
class CalculatorTools {

    @Tool("执行数学计算")
    public double calculate(String expression) {
        // 简化示例,实际应使用表达式解析器
        return 42.0;
    }

    @Tool("获取当前日期时间")
    public String getCurrentDateTime() {
        return java.time.LocalDateTime.now().toString();
    }
}

/**
 * ReAct Agent 接口
 */
interface ReactAgent {
    String execute(String task);
}

public class ReactAgentExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .temperature(0.0)
                .build();

        ReactAgent agent = AiServices.builder(ReactAgent.class)
                .chatLanguageModel(model)
                .tools(new SearchTools(), new CalculatorTools())
                .build();

        // Agent 会自主决定使用哪些工具
        String result = agent.execute(
                "搜索 Spring Boot 3.0 的新特性,并总结成3点"
        );

        System.out.println(result);
    }
}

5.2 Prompt 模板

java 复制代码
package com.example.langchain4j.prompt;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.openai.OpenAiChatModel;

import java.util.HashMap;
import java.util.Map;

public class PromptTemplateExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        // 定义 Prompt 模板
        PromptTemplate template = PromptTemplate.from("""
                你是一位专业的 {{profession}}。

                请对以下代码进行审查:

                编程语言: {{language}}
                代码:
                ```{{language}}
                {{code}}
                ```

                请从以下角度进行分析:
                {{#each aspects}}
                - {{this}}
                {{/each}}

                输出格式: Markdown
                """);

        // 准备变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("profession", "Java 架构师");
        variables.put("language", "Java");
        variables.put("code", """
                public class UserService {
                    private UserRepository repo;

                    public void saveUser(User user) {
                        repo.save(user);
                    }
                }
                """);
        variables.put("aspects", List.of(
                "代码质量",
                "设计模式",
                "潜在问题",
                "改进建议"
        ));

        // 渲染并执行
        Prompt prompt = template.apply(variables);
        String response = model.generate(prompt.text());

        System.out.println(response);
    }
}

5.3 输出解析

java 复制代码
package com.example.langchain4j.output;

import com.fasterxml.jackson.annotation.JsonProperty;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.UserMessage;

/**
 * 结构化输出
 */
class CodeReview {
    @JsonProperty("quality_score")
    public int qualityScore;

    @JsonProperty("issues")
    public List<String> issues;

    @JsonProperty("suggestions")
    public List<String> suggestions;

    @JsonProperty("summary")
    public String summary;
}

interface CodeAnalyzer {
    @UserMessage("请分析以下代码:\n{{code}}")
    CodeReview analyze(String code);
}

public class OutputParsingExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .responseFormat("json_object")
                .build();

        CodeAnalyzer analyzer = AiServices.create(CodeAnalyzer.class, model);

        String code = """
                public void process(List<String> items) {
                    for(int i=0; i<items.size(); i++) {
                        System.out.println(items.get(i));
                    }
                }
                """;

        CodeReview review = analyzer.analyze(code);

        System.out.println("质量评分: " + review.qualityScore);
        System.out.println("问题: " + review.issues);
        System.out.println("建议: " + review.suggestions);
        System.out.println("总结: " + review.summary);
    }
}

6. 生产环境实践

6.1 Spring Boot 集成

application.yml 配置:

yaml 复制代码
langchain4j:
  open-ai:
    chat-model:
      api-key: ${OPENAI_API_KEY}
      model-name: gpt-3.5-turbo
      temperature: 0.7
      max-tokens: 2000
      timeout: 60s

  embedding-model:
    api-key: ${OPENAI_API_KEY}
    model-name: text-embedding-ada-002

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/vectordb
    username: user
    password: pass

Spring Bean 配置:

java 复制代码
package com.example.langchain4j.config;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

@Configuration
public class LangChain4jConfig {

    @Value("${langchain4j.open-ai.chat-model.api-key}")
    private String apiKey;

    @Bean
    public ChatLanguageModel chatLanguageModel() {
        return OpenAiChatModel.builder()
                .apiKey(apiKey)
                .modelName("gpt-3.5-turbo")
                .temperature(0.7)
                .timeout(Duration.ofSeconds(60))
                .logRequests(true)
                .logResponses(true)
                .build();
    }

    @Bean
    public EmbeddingModel embeddingModel() {
        return OpenAiEmbeddingModel.builder()
                .apiKey(apiKey)
                .modelName("text-embedding-ada-002")
                .build();
    }
}

6.2 错误处理和重试

java 复制代码
package com.example.langchain4j.resilience;

import dev.langchain4j.model.chat.ChatLanguageModel;
import io.github.resilience4j.retry.Retry;
import io.github.resilience4j.retry.RetryConfig;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.function.Supplier;

@Service
public class ResilientChatService {

    private final ChatLanguageModel chatModel;
    private final Retry retry;

    public ResilientChatService(ChatLanguageModel chatModel) {
        this.chatModel = chatModel;

        RetryConfig config = RetryConfig.custom()
                .maxAttempts(3)
                .waitDuration(Duration.ofSeconds(2))
                .retryExceptions(Exception.class)
                .build();

        this.retry = Retry.of("chatService", config);
    }

    public String chatWithRetry(String message) {
        Supplier<String> supplier = Retry.decorateSupplier(
                retry,
                () -> chatModel.generate(message)
        );

        return supplier.get();
    }
}

6.3 异步处理

java 复制代码
package com.example.langchain4j.async;

import dev.langchain4j.model.chat.ChatLanguageModel;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

@Service
public class AsyncChatService {

    private final ChatLanguageModel chatModel;

    public AsyncChatService(ChatLanguageModel chatModel) {
        this.chatModel = chatModel;
    }

    @Async
    public CompletableFuture<String> generateAsync(String message) {
        return CompletableFuture.supplyAsync(() -> chatModel.generate(message));
    }

    public CompletableFuture<String> batchProcess(List<String> messages) {
        List<CompletableFuture<String>> futures = messages.stream()
                .map(this::generateAsync)
                .toList();

        return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                .thenApply(v -> futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.joining("\n\n")));
    }
}

6.4 监控和日志

java 复制代码
package com.example.langchain4j.monitoring;

import dev.langchain4j.model.chat.ChatLanguageModel;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MonitoredChatService {

    private static final Logger logger = LoggerFactory.getLogger(MonitoredChatService.class);

    private final ChatLanguageModel chatModel;
    private final Counter requestCounter;
    private final Counter errorCounter;
    private final Timer responseTimer;

    public MonitoredChatService(ChatLanguageModel chatModel, MeterRegistry meterRegistry) {
        this.chatModel = chatModel;
        this.requestCounter = meterRegistry.counter("langchain4j.requests.total");
        this.errorCounter = meterRegistry.counter("langchain4j.errors.total");
        this.responseTimer = meterRegistry.timer("langchain4j.response.time");
    }

    public String chat(String message) {
        requestCounter.increment();
        logger.info("处理请求: {}", message.substring(0, Math.min(50, message.length())));

        return responseTimer.record(() -> {
            try {
                String response = chatModel.generate(message);
                logger.info("请求成功,响应长度: {}", response.length());
                return response;
            } catch (Exception e) {
                errorCounter.increment();
                logger.error("请求失败", e);
                throw e;
            }
        });
    }
}

7. 实战案例

7.1 智能文档问答系统

java 复制代码
package com.example.langchain4j.cases;

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.apache.pdfbox.ApachePdfBoxDocumentParser;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.springframework.stereotype.Service;

import java.nio.file.Path;
import java.util.List;

/**
 * 智能文档问答系统
 */
@Service
public class DocumentQASystem {

    interface DocumentAssistant {
        String answer(String question);
    }

    private final DocumentAssistant assistant;

    public DocumentQASystem() {
        // 初始化模型
        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        ChatLanguageModel chatModel = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .build();

        // 创建向量存储
        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

        // 加载和处理文档
        loadDocuments(embeddingStore, embeddingModel);

        // 创建内容检索器
        EmbeddingStoreContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .maxResults(5)
                .minScore(0.6)
                .build();

        // 创建助手
        this.assistant = AiServices.builder(DocumentAssistant.class)
                .chatLanguageModel(chatModel)
                .contentRetriever(retriever)
                .build();
    }

    private void loadDocuments(EmbeddingStore<TextSegment> store, EmbeddingModel model) {
        // 加载 PDF 文档
        List<Document> documents = FileSystemDocumentLoader.loadDocuments(
                Path.of("documents"),
                new ApachePdfBoxDocumentParser()
        );

        // 文档摄取
        EmbeddingStoreIngestor.builder()
                .documentSplitter(DocumentSplitters.recursive(500, 50))
                .embeddingModel(model)
                .embeddingStore(store)
                .build()
                .ingest(documents);
    }

    public String askQuestion(String question) {
        return assistant.answer(question);
    }
}

7.2 多功能客服机器人

java 复制代码
package com.example.langchain4j.cases;

import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.springframework.stereotype.Service;

/**
 * 客服工具
 */
class CustomerServiceTools {

    @Tool("查询订单状态")
    public String queryOrderStatus(String orderId) {
        // 模拟数据库查询
        return String.format("订单 %s 状态: 运输中,预计3天后送达", orderId);
    }

    @Tool("申请退款")
    public String requestRefund(String orderId, String reason) {
        // 模拟退款流程
        return String.format("已为订单 %s 发起退款申请,原因: %s。预计3-5个工作日处理完成", orderId, reason);
    }

    @Tool("查询用户积分")
    public String queryPoints(String userId) {
        return String.format("用户 %s 当前积分: 1250分", userId);
    }

    @Tool("创建工单")
    public String createTicket(String userId, String issue, String category) {
        String ticketId = "TKT-" + System.currentTimeMillis();
        return String.format("已创建工单 %s,类别: %s,问题: %s。客服将在24小时内处理",
                ticketId, category, issue);
    }
}

/**
 * 客服机器人接口
 */
interface CustomerServiceBot {
    String chat(@MemoryId String conversationId, @UserMessage String message);
}

/**
 * 多功能客服机器人
 */
@Service
public class CustomerServiceBotSystem {

    private final CustomerServiceBot bot;

    public CustomerServiceBotSystem(
            ChatLanguageModel chatModel,
            ChatMemoryStore chatMemoryStore) {

        CustomerServiceTools tools = new CustomerServiceTools();

        this.bot = AiServices.builder(CustomerServiceBot.class)
                .chatLanguageModel(chatModel)
                .chatMemoryProvider(memoryId -> MessageWindowChatMemory.builder()
                        .id(memoryId)
                        .maxMessages(50)
                        .chatMemoryStore(chatMemoryStore)
                        .build())
                .tools(tools)
                .build();
    }

    public String handleCustomerMessage(String userId, String message) {
        return bot.chat(userId, message);
    }
}

8. 最佳实践与性能优化

8.1 Prompt 优化技巧

arduino 复制代码
┌─────────────────────────────────────────────────────────┐
│               Prompt 工程最佳实践                         │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  1. 明确角色定义                                         │
│     ✓ "你是一位资深的 Java 架构师"                       │
│     ✗ "帮我看看这段代码"                                 │
│                                                         │
│  2. 提供上下文                                           │
│     ✓ 包含相关背景信息和约束条件                         │
│     ✗ 只给出简单问题                                     │
│                                                         │
│  3. 明确输出格式                                         │
│     ✓ "以 JSON 格式输出结果"                            │
│     ✗ 没有格式要求                                       │
│                                                         │
│  4. 使用示例                                             │
│     ✓ 提供输入输出示例(Few-shot Learning)              │
│     ✗ 依赖模型自行理解                                   │
│                                                         │
│  5. 分步骤思考                                           │
│     ✓ "让我们一步一步思考"(Chain of Thought)           │
│     ✗ 期待直接给出答案                                   │
│                                                         │
└─────────────────────────────────────────────────────────┘

8.2 性能优化策略

java 复制代码
package com.example.langchain4j.optimization;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import dev.langchain4j.model.chat.ChatLanguageModel;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class OptimizedChatService {

    private final ChatLanguageModel chatModel;
    private final Cache<String, String> responseCache;
    private final ExecutorService executorService;

    public OptimizedChatService(ChatLanguageModel chatModel) {
        this.chatModel = chatModel;

        // 1. 响应缓存
        this.responseCache = Caffeine.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(Duration.ofHours(1))
                .build();

        // 2. 线程池
        this.executorService = Executors.newFixedThreadPool(10);
    }

    /**
     * 带缓存的请求
     */
    public String chatWithCache(String message) {
        return responseCache.get(message, key -> chatModel.generate(key));
    }

    /**
     * 批量并行处理
     */
    public List<String> batchProcess(List<String> messages) {
        List<CompletableFuture<String>> futures = messages.stream()
                .map(msg -> CompletableFuture.supplyAsync(
                        () -> chatWithCache(msg),
                        executorService
                ))
                .toList();

        return futures.stream()
                .map(CompletableFuture::join)
                .toList();
    }

    /**
     * 流式响应(更好的用户体验)
     */
    public void streamResponse(String message, Consumer<String> onToken) {
        // 使用流式模型
        // 实时发送 token,减少等待时间
    }
}

8.3 成本控制

java 复制代码
package com.example.langchain4j.optimization;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.output.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class CostControlService {

    private static final Logger logger = LoggerFactory.getLogger(CostControlService.class);
    private final ChatLanguageModel chatModel;

    public CostControlService(ChatLanguageModel chatModel) {
        this.chatModel = chatModel;
    }

    /**
     * 跟踪 Token 使用
     */
    public String chatWithTokenTracking(String message) {
        long startTime = System.currentTimeMillis();
        Response<String> response = (Response<String>) chatModel.generate(message);
        long duration = System.currentTimeMillis() - startTime;

        // 记录使用情况
        logger.info("Token 使用 - 输入: {}, 输出: {}, 总计: {}, 耗时: {}ms",
                response.tokenUsage().inputTokenCount(),
                response.tokenUsage().outputTokenCount(),
                response.tokenUsage().totalTokenCount(),
                duration);

        return response.content();
    }

    /**
     * 限制输出长度以控制成本
     */
    public String chatWithLimitedOutput(String message, int maxTokens) {
        // 配置 maxTokens 参数
        return chatModel.generate(message);
    }
}

9. 总结

9.1 核心优势回顾

复制代码
┌─────────────────────────────────────────────────────────┐
│            LangChain4j 核心价值                          │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ✅ Java 原生支持                                        │
│     • 无需 Python,纯 Java 开发                         │
│     • 类型安全,IDE 友好                                │
│                                                         │
│  ✅ 丰富的生态                                           │
│     • 30+ LLM 模型支持                                  │
│     • 多种向量数据库集成                                 │
│                                                         │
│  ✅ 开发效率高                                           │
│     • 声明式 AI Services                                │
│     • 自动化工具调用                                     │
│                                                         │
│  ✅ 生产就绪                                             │
│     • Spring Boot 集成                                  │
│     • 完善的错误处理                                     │
│                                                         │
│  ✅ 功能强大                                             │
│     • RAG 支持                                          │
│     • Agent 能力                                        │
│     • 记忆管理                                           │
│                                                         │
└─────────────────────────────────────────────────────────┘

9.2 学习路径建议

makefile 复制代码
第一阶段: 基础入门 (1-2周)
├── 理解核心概念
├── 完成快速开始示例
├── 掌握基本对话功能
└── 学习 AI Services

第二阶段: 进阶学习 (2-3周)
├── 实现工具调用
├── 构建 RAG 系统
├── 学习 Agent 开发
└── 掌握 Prompt 工程

第三阶段: 生产实践 (4-6周)
├── Spring Boot 集成
├── 性能优化
├── 监控和日志
└── 实际项目开发

9.3 参考资源

官方资源:

社区资源:

  • Discord 社区
  • Stack Overflow 标签: langchain4j
  • 中文技术博客和教程

推荐阅读:

  • 《Prompt Engineering Guide》
  • 《Building LLM Applications》
  • 《RAG Systems Design》

结语

LangChain4j 为 Java 开发者打开了 AI 应用开发的大门。通过本文的学习,你应该能够:

✅ 理解 LangChain4j 的核心架构和设计理念 ✅ 掌握各种核心功能的使用方法 ✅ 构建生产级的 AI 应用 ✅ 应用最佳实践和优化策略

相关推荐
okseekw1 小时前
Java 中的方法:从定义到重载的完整指南
java
雨中飘荡的记忆1 小时前
深入理解设计模式之适配器模式
java·设计模式
用户84913717547161 小时前
生产级故障排查实战:从制造 OOM 到 IDEA Profiler 深度破案
java·jvm
雨中飘荡的记忆1 小时前
深入理解设计模式之装饰者模式
java·设计模式
雨中飘荡的记忆1 小时前
秒杀系统设计与实现
java·redis·lua
小坏讲微服务2 小时前
Spring Cloud Alibaba 整合 Scala 教程完整使用
java·开发语言·分布式·spring cloud·sentinel·scala·后端开发
老鼠只爱大米2 小时前
Java设计模式之外观模式(Facade)详解
java·设计模式·外观模式·facade·java设计模式
vx_dmxq2112 小时前
【微信小程序学习交流平台】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·spring boot·python·mysql·微信小程序·小程序·idea
9号达人2 小时前
优惠系统演进:从"实时结算"到"所见即所得",前端传参真的鸡肋吗?
java·后端·面试