LangChain4J:Java 开发者的 AI 应用框架
引言:为什么 Java 开发者需要 LangChain4J?
想象一下,你要在 Java 应用中集成 AI 功能:
传统方式(直接调用 API)
Java 应用:
↓
手动调用 OpenAI API
↓
处理 JSON 响应
↓
手动调用 Google API
↓
处理不同的响应格式
↓
手动调用其他 LLM API
↓
代码复杂、难以维护
问题:
- 每个 API 都要单独处理
- 代码重复
- 难以切换提供商
- 缺少高级功能(RAG、Agent 等)
使用 LangChain4J(统一框架)
Java 应用:
↓
LangChain4J 统一 API
├── OpenAI
├── Google Vertex AI
├── Anthropic Claude
└── 其他 15+ 提供商
↓
统一的接口和响应
↓
高级功能(RAG、Agent、Memory)
↓
代码简洁、易于维护
优势:
- 统一 API,易于使用
- 轻松切换提供商
- 内置高级功能
- 与 Spring Boot 无缝集成
LangChain4J 就是 Java 开发者的"AI 应用构建框架":它让 Java 开发者能够轻松构建由大语言模型驱动的应用程序,无需深入了解每个 LLM 提供商的 API 细节。
第一部分:什么是 LangChain4J?
核心比喻:LangChain4J 就像"Java 世界的 LangChain"
想象 LangChain4J 就像Java 版本的 LangChain:
-
统一接口 = 适配器模式
- 统一的 API 接口
- 支持多个 LLM 提供商
- 轻松切换,无需重写代码
-
模块化设计 = 乐高积木
- 核心模块
- 集成模块(OpenAI、Google 等)
- 按需选择和使用
-
高级功能 = 现成的工具
- RAG(检索增强生成)
- Agent(智能代理)
- Memory(记忆管理)
- 工具调用
技术定义
LangChain4J 是一个专为 Java 开发者设计的开源库,旨在简化将大型语言模型(LLM)集成到 Java 应用程序中的过程。
核心特点:
- 统一 API:支持 15+ 个主流 LLM 提供商
- 向量数据库:支持 20+ 个向量数据库
- 模块化设计:按需选择模块
- Spring Boot 集成:无缝集成 Spring 生态
- 类型安全:Java 的类型系统优势
支持的 LLM 提供商:
- OpenAI(GPT-3.5、GPT-4)
- Google Vertex AI(Gemini)
- Anthropic(Claude)
- Azure OpenAI
- Ollama(本地模型)
- 等等...
第二部分:核心概念
概念 1:Chat Model(聊天模型)
比喻:Chat Model 就像"对话接口"
传统 API:
需要手动构建请求
需要手动解析响应
需要处理错误
Chat Model:
统一的接口
自动处理请求/响应
类型安全的响应
基础使用
import dev.langchain4j.model.openai.OpenAiChatModel;
// 创建聊天模型
OpenAiChatModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.temperature(0.7)
.build();
// 简单对话
String response = chatModel.generate("你好,LangChain4J!");
System.out.println(response);
// 流式响应
chatModel.generate("讲一个故事", new StreamingResponseHandler<AiMessage>() {
@Override
public void onNext(String token) {
System.out.print(token);
}
@Override
public void onComplete(Response<AiMessage> response) {
System.out.println("\n完成");
}
@Override
public void onError(Throwable error) {
System.err.println("错误:" + error.getMessage());
}
});
概念 2:Embedding Model(嵌入模型)
比喻:Embedding Model 就像"文本转换器"
文本 → 向量
"猫" → [0.1, 0.5, 0.3, ...]
"狗" → [0.2, 0.4, 0.3, ...]
相似的文本 → 相似的向量
使用示例
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
// 创建嵌入模型
EmbeddingModel embeddingModel = new OpenAiEmbeddingModel("your-api-key");
// 生成嵌入向量
String text = "LangChain4J 是一个 Java AI 框架";
Embedding embedding = embeddingModel.embed(text).content();
// 计算相似度
String text1 = "Java AI 框架";
String text2 = "Python AI 框架";
Embedding embedding1 = embeddingModel.embed(text1).content();
Embedding embedding2 = embeddingModel.embed(text2).content();
double similarity = CosineSimilarity.between(embedding1, embedding2);
System.out.println("相似度:" + similarity);
概念 3:Memory(记忆)
比喻:Memory 就像"对话历史记录"
没有记忆:
用户:"我叫张三"
系统:"好的"
用户:"我叫什么?"
系统:"我不知道" ❌
有记忆:
用户:"我叫张三"
系统:"好的,记住了"
用户:"我叫什么?"
系统:"你叫张三" ✅
记忆类型
1. MessageWindowMemory(窗口记忆)
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
// 创建记忆(记住最近 10 条消息)
ChatMemory memory = MessageWindowChatMemory.withMaxMessages(10);
// 添加消息
memory.add(UserMessage.userMessage("我叫张三"));
memory.add(AiMessage.aiMessage("你好,张三!"));
// 获取历史
List<ChatMessage> messages = memory.messages();
2. TokenWindowMemory(Token 窗口记忆)
// 记住最近 1000 个 Token
ChatMemory memory = TokenWindowChatMemory.withMaxTokens(1000);
概念 4:Prompt Template(提示模板)
比喻:提示模板就像"邮件模板"
没有模板:
每次都要写完整的提示
容易出错
难以维护
有模板:
定义一次,多次使用
统一格式
易于修改
使用示例
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
// 创建提示模板
PromptTemplate promptTemplate = PromptTemplate.from(
"你是一位专业的产品经理。\n" +
"请为以下产品写一个产品描述:\n" +
"产品名称:{{productName}}\n" +
"产品类型:{{productType}}\n" +
"目标用户:{{targetAudience}}\n" +
"\n产品描述:"
);
// 填充模板
Prompt prompt = promptTemplate.apply(
Map.of(
"productName", "智能手表",
"productType", "可穿戴设备",
"targetAudience", "年轻专业人士"
)
);
// 使用
String response = chatModel.generate(prompt.text());
概念 5:Tools(工具)
比喻:工具就像"函数调用"
LLM 可以调用 Java 函数:
用户:"计算 123 + 456"
LLM:调用计算器工具
返回:579
工具定义和使用
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.agent.tool.ToolSpecification;
// 定义工具
public class CalculatorTools {
@Tool("计算两个数的和")
public double add(double a, double b) {
return a + b;
}
@Tool("计算两个数的差")
public double subtract(double a, double b) {
return a - b;
}
@Tool("计算两个数的乘积")
public double multiply(double a, double b) {
return a * b;
}
@Tool("计算两个数的商")
public double divide(double a, double b) {
if (b == 0) {
throw new IllegalArgumentException("除数不能为0");
}
return a / b;
}
}
// 使用工具
CalculatorTools tools = new CalculatorTools();
String response = chatModel.generate(
"计算 123 + 456,然后乘以 2"
);
// LLM 会自动调用相应的工具
第三部分:RAG(检索增强生成)
什么是 RAG?
比喻:RAG 就像"带参考资料的考试"
传统 LLM(闭卷考试):
只能基于训练数据回答
可能产生幻觉
无法访问最新信息
RAG(开卷考试):
可以查阅文档
基于真实信息回答
减少幻觉
RAG 工作流程
1. 文档加载
↓
2. 文档分割
↓
3. 向量化
↓
4. 存储到向量数据库
↓
5. 用户提问
↓
6. 检索相关文档
↓
7. 将文档作为上下文
↓
8. LLM 生成答案
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.splitter.DocumentSplitters;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
// 1. 加载文档
Document document = FileSystemDocumentLoader.loadDocument(
Paths.get("knowledge_base.txt")
);
// 2. 分割文档
DocumentSplitter splitter = DocumentSplitters.recursive(300, 0);
List<TextSegment> segments = splitter.split(document);
// 3. 创建嵌入模型
EmbeddingModel embeddingModel = new OpenAiEmbeddingModel("your-api-key");
// 4. 生成嵌入并存储
EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
for (TextSegment segment : segments) {
Embedding embedding = embeddingModel.embed(segment).content();
embeddingStore.add(embedding, segment);
}
// 5. 创建检索器
EmbeddingStoreContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(3)
.minScore(0.6)
.build();
// 6. 创建 RAG 链
ChatLanguageModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.build();
String question = "文档中主要讲了什么?";
List<Content> relevantContents = retriever.retrieve(question);
// 7. 构建上下文
String context = relevantContents.stream()
.map(Content::textSegment)
.map(TextSegment::text)
.collect(Collectors.joining("\n\n"));
String prompt = String.format(
"基于以下上下文回答问题:\n\n%s\n\n问题:%s",
context,
question
);
// 8. 生成答案
String answer = chatModel.generate(prompt);
System.out.println("答案:" + answer);
第四部分:Agent(智能代理)
什么是 Agent?
比喻:Agent 就像"智能助手"
传统方式(固定流程):
你:问问题
LLM:回答(只能基于训练数据)
Agent 方式(自主决策):
你:问问题
Agent:分析问题
├── 需要搜索?→ 使用搜索工具
├── 需要计算?→ 使用计算器
├── 需要查数据库?→ 查询数据库
└── 需要总结?→ 调用 LLM
Agent:组合结果
你:得到完整答案
Agent 示例
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
// 定义工具
public class SearchTools {
@Tool("搜索网络信息")
public String searchWeb(String query) {
// 实际实现搜索逻辑
return "搜索结果:" + query;
}
@Tool("获取当前天气")
public String getWeather(String city) {
// 实际实现天气查询
return city + "的天气:晴天,25°C";
}
}
// 创建 Agent
ChatLanguageModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.build();
SearchTools tools = new SearchTools();
// Agent 会自动选择和使用工具
String response = chatModel.generate(
"北京今天的天气怎么样?然后搜索一下 LangChain4J 的信息"
);
第五部分:与 Spring Boot 集成
为什么需要 Spring Boot 集成?
比喻:Spring Boot 集成就像"现成的配置"
手动配置:
需要手动创建 Bean
需要手动管理依赖
配置复杂
Spring Boot 集成:
自动配置
依赖注入
配置简单
集成步骤
1. 添加依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.3.0</version>
</dependency>
2. 配置文件
# application.properties
langchain4j.openai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.openai.chat-model.temperature=0.7
langchain4j.openai.chat-model.model-name=gpt-3.5-turbo
# 可选:流式响应
langchain4j.openai.chat-model.log-streaming=true
3. 创建服务
import dev.langchain4j.model.chat.ChatLanguageModel;
import org.springframework.stereotype.Service;
@Service
public class ChatService {
private final ChatLanguageModel chatModel;
public ChatService(ChatLanguageModel chatModel) {
this.chatModel = chatModel;
}
public String chat(String message) {
return chatModel.generate(message);
}
public void chatStream(String message,
StreamingResponseHandler<AiMessage> handler) {
chatModel.generate(message, handler);
}
}
4. 创建控制器
import org.springframework.web.bind.annotation.*;
import org.springframework.http.MediaType;
import reactor.core.publisher.Flux;
@RestController
@RequestMapping("/api/chat")
public class ChatController {
private final ChatService chatService;
public ChatController(ChatService chatService) {
this.chatService = chatService;
}
@PostMapping
public String chat(@RequestBody String message) {
return chatService.chat(message);
}
@PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> chatStream(@RequestBody String message) {
return Flux.create(sink -> {
chatService.chatStream(message, new StreamingResponseHandler<AiMessage>() {
@Override
public void onNext(String token) {
sink.next(token);
}
@Override
public void onComplete(Response<AiMessage> response) {
sink.complete();
}
@Override
public void onError(Throwable error) {
sink.error(error);
}
});
});
}
}
高级配置
@Configuration
public class LangChain4jConfig {
@Bean
public ChatMemory chatMemory() {
return MessageWindowChatMemory.withMaxMessages(10);
}
@Bean
public EmbeddingModel embeddingModel() {
return new OpenAiEmbeddingModel("your-api-key");
}
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return new InMemoryEmbeddingStore<>();
}
}
第六部分:实际应用示例
应用 1:智能客服系统
@Service
public class CustomerService {
private final ChatLanguageModel chatModel;
private final ChatMemory chatMemory;
public CustomerService(ChatLanguageModel chatModel,
ChatMemory chatMemory) {
this.chatModel = chatModel;
this.chatMemory = chatMemory;
}
public String handleCustomerQuery(String customerId, String query) {
// 添加上下文
String context = String.format(
"你是客服助手。客户ID:%s\n客户问题:%s",
customerId,
query
);
// 添加用户消息
chatMemory.add(UserMessage.userMessage(context));
// 生成回复
String response = chatModel.generate(chatMemory.messages());
// 添加 AI 回复
chatMemory.add(AiMessage.aiMessage(response));
return response;
}
}
应用 2:文档问答系统
@Service
public class DocumentQAService {
private final ChatLanguageModel chatModel;
private final EmbeddingModel embeddingModel;
private final EmbeddingStore<TextSegment> embeddingStore;
public DocumentQAService(ChatLanguageModel chatModel,
EmbeddingModel embeddingModel,
EmbeddingStore<TextSegment> embeddingStore) {
this.chatModel = chatModel;
this.embeddingModel = embeddingModel;
this.embeddingStore = embeddingStore;
}
public void loadDocument(Path documentPath) {
// 加载文档
Document document = FileSystemDocumentLoader.loadDocument(documentPath);
// 分割文档
DocumentSplitter splitter = DocumentSplitters.recursive(300, 0);
List<TextSegment> segments = splitter.split(document);
// 生成嵌入并存储
for (TextSegment segment : segments) {
Embedding embedding = embeddingModel.embed(segment).content();
embeddingStore.add(embedding, segment);
}
}
public String answerQuestion(String question) {
// 检索相关文档
Embedding questionEmbedding = embeddingModel.embed(question).content();
List<EmbeddingMatch<TextSegment>> matches = embeddingStore.findRelevant(
questionEmbedding,
3,
0.6
);
// 构建上下文
String context = matches.stream()
.map(match -> match.embedded().text())
.collect(Collectors.joining("\n\n"));
// 生成答案
String prompt = String.format(
"基于以下上下文回答问题:\n\n%s\n\n问题:%s\n答案:",
context,
question
);
return chatModel.generate(prompt);
}
}
应用 3:代码分析工具
@Service
public class CodeAnalysisService {
private final ChatLanguageModel chatModel;
public CodeAnalysisService(ChatLanguageModel chatModel) {
this.chatModel = chatModel;
}
public String analyzeCode(String code, String language) {
String prompt = String.format(
"你是一位代码审查专家。\n" +
"请分析以下 %s 代码:\n\n" +
"```%s\n%s\n```\n\n" +
"请提供:\n" +
"1. 代码功能说明\n" +
"2. 潜在问题\n" +
"3. 改进建议",
language,
language,
code
);
return chatModel.generate(prompt);
}
public String generateCode(String description, String language) {
String prompt = String.format(
"请用 %s 语言实现以下功能:\n%s",
language,
description
);
return chatModel.generate(prompt);
}
}
第七部分:向量数据库集成
支持的向量数据库
LangChain4J 支持 20+ 个向量数据库:
- InMemoryEmbeddingStore:内存存储(开发测试)
- Pinecone:云向量数据库
- Milvus:开源向量数据库
- Elasticsearch:搜索引擎
- Chroma:轻量级向量数据库
- 等等...
使用示例
InMemoryEmbeddingStore(内存)
EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
Pinecone(云服务)
import dev.langchain4j.store.embedding.pinecone.PineconeEmbeddingStore;
PineconeEmbeddingStore embeddingStore = PineconeEmbeddingStore.builder()
.apiKey("your-pinecone-api-key")
.environment("us-west1-gcp")
.indexName("my-index")
.build();
Milvus(本地部署)
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;
MilvusEmbeddingStore embeddingStore = MilvusEmbeddingStore.builder()
.host("localhost")
.port(19530)
.collectionName("my-collection")
.dimension(1536) // OpenAI 嵌入维度
.build();
第八部分:最佳实践
实践 1:错误处理
@Service
public class RobustChatService {
private final ChatLanguageModel chatModel;
public String safeChat(String message) {
try {
return chatModel.generate(message);
} catch (Exception e) {
log.error("Chat error", e);
return "抱歉,处理您的请求时出现错误。请稍后重试。";
}
}
}
实践 2:超时控制
ChatLanguageModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.timeout(Duration.ofSeconds(30))
.build();
实践 3:成本控制
// 使用更便宜的模型
ChatLanguageModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.modelName("gpt-3.5-turbo") // 而不是 gpt-4
.maxTokens(100) // 限制 Token 数
.build();
实践 4:缓存
import dev.langchain4j.model.cache.Cache;
import dev.langchain4j.model.cache.CaffeineCache;
// 创建缓存
Cache<Object> cache = CaffeineCache.builder()
.maximumSize(1000)
.expireAfterWrite(Duration.ofHours(1))
.build();
// 使用缓存
ChatLanguageModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.cache(cache)
.build();
实践 5:流式响应
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String message) {
return Flux.create(sink -> {
chatModel.generate(message, new StreamingResponseHandler<AiMessage>() {
@Override
public void onNext(String token) {
sink.next(token);
}
@Override
public void onComplete(Response<AiMessage> response) {
sink.complete();
}
@Override
public void onError(Throwable error) {
sink.error(error);
}
});
});
}
第九部分:常见问题与解决方案
问题 1:如何切换 LLM 提供商?
解决方案:使用统一的接口
// 使用接口而不是具体实现
@Autowired
private ChatLanguageModel chatModel; // 接口
// 配置文件中切换
// langchain4j.openai.chat-model.api-key=...
// 或
// langchain4j.anthropic.chat-model.api-key=...
问题 2:如何处理长文本?
解决方案:使用文档分割和 RAG
DocumentSplitter splitter = DocumentSplitters.recursive(
1000, // chunk 大小
200 // 重叠大小
);
List<TextSegment> segments = splitter.split(document);
问题 3:如何提高响应速度?
解决方案:
// 1. 使用流式响应
chatModel.generate(message, handler);
// 2. 使用缓存
chatModel.withCache(cache);
// 3. 异步处理
CompletableFuture<String> future = CompletableFuture.supplyAsync(() ->
chatModel.generate(message)
);
问题 4:如何监控和调试?
解决方案:使用日志和监控
// 启用详细日志
ChatLanguageModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.logRequests(true)
.logResponses(true)
.build();
第十部分:学习路径
入门阶段(1 周)
-
安装和配置
<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>1.3.0</version> </dependency> -
学习基础概念
- Chat Model
- Embedding Model
- Memory
-
完成第一个项目
- 简单的聊天应用
进阶阶段(2-3 周)
-
深入学习
- RAG
- Agent
- Tools
-
Spring Boot 集成
- 自动配置
- 依赖注入
- REST API
-
完成复杂项目
- 文档问答系统
- 智能客服系统
高级阶段(持续学习)
-
掌握高级特性
- 自定义工具
- 向量数据库集成
- 性能优化
-
生产部署
- 监控和日志
- 错误处理
- 成本控制
第十一部分:总结
LangChain4J 的核心价值
- 统一 API:支持多个 LLM 提供商,轻松切换
- Java 原生:充分利用 Java 的类型系统和生态
- Spring 集成:与 Spring Boot 无缝集成
- 高级功能:RAG、Agent 等开箱即用
- 模块化设计:按需选择模块
适用场景
- 企业级 AI 应用
- 文档问答系统
- 智能客服机器人
- 代码分析工具
- 内容生成应用
与其他框架对比
| 特性 | LangChain4J | LangChain (Python) | 直接调用 API |
|---|---|---|---|
| 语言 | Java | Python | 任意 |
| 统一 API | ✅ | ✅ | ❌ |
| Spring 集成 | ✅ | ❌ | ❌ |
| 类型安全 | ✅ | ❌ | 部分 |
| RAG 支持 | ✅ | ✅ | ❌ |
| Agent 支持 | ✅ | ✅ | ❌ |
学习建议
- 从简单开始:先理解基础概念
- 多做项目:通过实践学习
- 阅读文档:官方文档很详细
- 参与社区:GitHub、Discord 等
结语
LangChain4J 为 Java 开发者提供了一个强大而优雅的 AI 应用开发框架。它让 Java 开发者能够轻松构建由大语言模型驱动的应用程序,无需深入了解每个 LLM 提供商的 API 细节。
无论你是要构建智能客服系统、文档问答系统,还是其他 AI 应用,LangChain4J 都能为你提供所需的工具和功能。
开始你的 LangChain4J 之旅吧!