LangChain4j 实战指南:构建企业级 Java AI 应用
摘要
LangChain4j 是 LangChain 在 Java 生态系统中的官方实现,为 Java 开发者提供了构建 LLM 驱动应用的完整工具链。本文将深入探讨 LangChain4j 的核心特性、架构设计和实战应用,帮助开发者快速构建生产级 AI 应用。
目录
- LangChain4j 简介
- 核心架构与设计
- 快速开始
- 核心功能详解
- 高级特性
- 生产环境实践
- 与主流框架集成
- 实战案例
- 最佳实践与性能优化
- 总结
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 参考资源
官方资源:
- 官方文档: docs.langchain4j.dev/
- GitHub: github.com/langchain4j...
- 示例项目: github.com/langchain4j...
社区资源:
- Discord 社区
- Stack Overflow 标签: langchain4j
- 中文技术博客和教程
推荐阅读:
- 《Prompt Engineering Guide》
- 《Building LLM Applications》
- 《RAG Systems Design》
结语
LangChain4j 为 Java 开发者打开了 AI 应用开发的大门。通过本文的学习,你应该能够:
✅ 理解 LangChain4j 的核心架构和设计理念 ✅ 掌握各种核心功能的使用方法 ✅ 构建生产级的 AI 应用 ✅ 应用最佳实践和优化策略