LangChain4j 实战指南:在 Java 应用中优雅集成大语言模型
概述
如果你是一名 Java 后端开发者,一定经历过这样的阶段:为了调用一次 ChatGPT,自己拼 HTTP 请求、解析 JSON、处理重试与超时;想做 RAG 问答,又要单独对接向量库、Embedding 模型和 Prompt 模板。代码越写越长,却越来越难维护。
LangChain4j 正是为解决这类问题而生的开源 Java 库。它对标 Python 生态中的 LangChain,为 JVM 世界提供统一的 LLM 接入 API,并内置 RAG、Tool Calling、对话记忆、Agent 等能力,与 Spring Boot、Quarkus 等企业级框架深度集成。
本文将带你从零理解 LangChain4j 的设计思路,并通过可运行的示例,掌握在 Spring Boot 3 项目中落地 AI 能力的正确姿势。
为什么选择 LangChain4j
| 对比维度 | 手写 HTTP 调用 | LangChain4j |
|---|---|---|
| 模型切换 | 每个厂商一套 SDK | 统一 ChatModel 接口,改配置即可 |
| Prompt 管理 | 字符串散落各处 | @SystemMessage / @UserMessage 声明式注解 |
| RAG | 自研检索 + 拼接逻辑 | ContentRetriever / RetrievalAugmentor 开箱即用 |
| 工具调用 | 手动解析 function call | @Tool 注解 + 自动注册 |
| Spring 集成 | 自行封装 Bean | @AiService 自动扫描与注入 |
LangChain4j 的核心价值不是「多包一层 HTTP」,而是把 LLM 应用中的重复模式抽象成可组合、可测试的组件,让业务代码只关注「做什么」,而不是「怎么调 API」。
核心概念
1. ChatModel 与 EmbeddingModel
LangChain4j 将大模型交互抽象为接口:
- ChatModel :同步对话,传入
UserMessage,返回AiMessage - StreamingChatModel:流式输出,适合 SSE 场景
- EmbeddingModel:文本向量化,RAG 的基础
官方与社区提供了 OpenAI、Anthropic、Ollama、Azure、DashScope(通义)等多种集成 Starter,通过 application.yml 即可完成配置。
2. AI Services(声明式 AI 接口)
AI Services 是 LangChain4j 最具特色的 API,类似 Spring Data JPA 的 Repository:你定义接口,框架生成实现。
java
@AiService
public interface Assistant {
@SystemMessage("你是一名专业的 Java 技术顾问,回答简洁准确。")
String chat(@UserMessage String userMessage);
}
启动 Spring Boot 应用后,langchain4j-spring-boot-starter 会扫描 @AiService 接口,自动注入 ChatModel、ChatMemory、ContentRetriever 等组件,并注册为 Spring Bean。
在 Controller 中直接注入即可:
java
@RestController
@RequestMapping("/api/assistant")
@RequiredArgsConstructor
public class AssistantController {
private final Assistant assistant;
@PostMapping("/chat")
public String chat(@RequestBody @Valid ChatRequest request) {
return assistant.chat(request.getMessage());
}
}
3. Chat Memory(对话记忆)
多轮对话需要上下文。LangChain4j 提供:
- MessageWindowChatMemory:保留最近 N 条消息
- ChatMemoryProvider :按用户 ID 隔离会话(配合
@MemoryId)
java
@AiService
public interface CustomerSupportAgent {
@SystemMessage("你是客服助手,请根据历史对话回答用户问题。")
String reply(@MemoryId String sessionId, @UserMessage String message);
}
4. Tools(工具调用)
当 LLM 需要查数据库、调接口、执行计算时,使用 @Tool 将 Java 方法暴露给模型:
java
@Component
public class OrderTools {
private final OrderService orderService;
public OrderTools(OrderService orderService) {
this.orderService = orderService;
}
@Tool("根据订单号查询订单状态")
public String getOrderStatus(@P("订单号") String orderNo) {
return orderService.getStatus(orderNo);
}
}
在 AI Service 中注册工具:
java
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(chatModel)
.tools(new OrderTools(orderService))
.build();
Spring Boot 场景下,将 OrderTools 注册为 Bean 后,Starter 会自动发现并注入。
5. RAG(检索增强生成)
RAG 解决「模型不知道你的私有知识」的问题,典型流程:
用户提问 → 向量化 → 检索相关文档片段 → 拼入 Prompt → LLM 生成回答
LangChain4j 提供 Naive RAG 与 Advanced RAG 两档能力:
| 模式 | 组件 | 适用场景 |
|---|---|---|
| 简单 RAG | EmbeddingStoreContentRetriever |
文档问答、知识库 |
| 高级 RAG | RetrievalAugmentor |
查询改写、重排序、多路检索 |
示例:使用内存向量库做文档问答
java
EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
// 1. 导入文档并切分
Document document = FileSystemDocumentLoader.loadDocument(Paths.get("docs/manual.pdf"));
DocumentSplitter splitter = DocumentSplitters.recursive(300, 30);
List<TextSegment> segments = splitter.split(document);
// 2. 向量化并入库
EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();
for (TextSegment segment : segments) {
Embedding embedding = embeddingModel.embed(segment).content();
embeddingStore.add(embedding, segment);
}
// 3. 构建 ContentRetriever
ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(3)
.minScore(0.75)
.build();
// 4. 注入 AI Service
Assistant ragAssistant = AiServices.builder(Assistant.class)
.chatModel(chatModel)
.contentRetriever(contentRetriever)
.build();
Spring Boot 快速集成
Maven 依赖
以 OpenAI 为例(Spring Boot 3):
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.0-beta3</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.0.0-beta3</version>
</dependency>
版本号请以 Maven Central 最新发布为准。
application.yml 配置
yaml
langchain4j:
open-ai:
chat-model:
api-key: ${OPENAI_API_KEY}
model-name: gpt-4o-mini
temperature: 0.7
timeout: 60s
log-requests: true
log-responses: true
定义 AI Service
java
@AiService
public interface CodeReviewer {
@SystemMessage("""
你是一名资深 Java Code Reviewer。
请从可读性、性能、空安全、并发安全四个维度给出建议。
输出 Markdown 格式。
""")
@UserMessage("""
请 Review 以下代码:
```java
{{code}}
```
""")
String review(@V("code") String code);
}
Controller 直接注入使用,无需手动 AiServices.builder(...)。
生产环境最佳实践
1. 分层清晰,Controller 不写 Prompt
- Controller:参数校验、鉴权、返回封装
- @AiService:Prompt 与 AI 逻辑
- @Tool / Service:业务数据访问
这与常规 Spring 分层一致,避免 Prompt 字符串污染 Web 层。
2. 明确事务边界
@Tool 方法可能触发数据库写操作。遵循 Spring 事务规范:Tool 内的 DB 操作走 Service 层,不要在 Tool 里直接发 HTTP 或 MQ;若 Tool 被 AI 多次调用,注意幂等与性能。
3. RAG 文档更新策略
向量库与源文档需保持一致:
- 文档变更 → 重新 Embedding 并 upsert
- 大规模场景使用 Milvus、PgVector、Elasticsearch 等外部
EmbeddingStore - 检索结果设置
minScore阈值,避免低相关片段污染回答
4. 可观测性
开启请求/响应日志(见上方 yml),并结合 TraceId 关联一次用户会话内的多次 LLM 调用。LangChain4j 支持监听 AiServiceRegisteredEvent,在启动时打印已注册的 AI Service 与 Tool 列表,便于排查。
5. 流式响应提升体验
长文生成场景,接口返回类型改为 TokenStream,配合 SSE 推送到前端:
java
@AiService
public interface StreamingWriter {
TokenStream write(@UserMessage String topic);
}
与 LangChain(Python)的对比
| 特性 | LangChain (Python) | LangChain4j (Java) |
|---|---|---|
| 生态成熟度 | 非常成熟 | 快速发展中 |
| 企业框架 | FastAPI 等 | Spring Boot / Quarkus 原生 |
| AI Services | 部分支持 | 核心设计,注解驱动 |
| MCP 支持 | 有 | 已支持 Tool / MCP 集成 |
| 适用团队 | AI 工程 / 数据 | Java 后端 / 企业 IT |
若团队技术栈以 Java 为主,LangChain4j 的学习与维护成本显著低于引入 Python 微服务。
FAQ
Q1:LangChain4j 需要什么 Java 版本?
A:官方要求 Java 17+,推荐 Java 21 LTS,与 Spring Boot 3.5+ 搭配。
Q2:能否使用本地 Ollama 模型?
A:可以。引入 langchain4j-ollama-spring-boot-starter,配置 base-url 为 http://localhost:11434,无需 API Key,适合开发与离线场景。
Q3:RAG 检索结果不准怎么办?
A:依次排查:文档切分粒度(chunk size)、Embedding 模型质量、maxResults / minScore 参数、是否需 Advanced RAG(查询扩展、重排序)。
Q4:AI Service 和直接调用 ChatModel 怎么选?
A:简单单次对话可直接用 ChatModel;涉及 Memory、Tools、RAG、结构化输出时,优先 AI Services,代码量通常减少 60% 以上。
Q5:如何防止 Prompt 注入?
A:对用户输入做长度限制与敏感词过滤;System Prompt 中明确「仅回答与业务相关的问题」;Tool 方法内校验参数合法性,禁止 LLM 间接执行危险操作。
总结
LangChain4j 让 Java 开发者可以用熟悉的方式构建 LLM 应用:
- 统一 API 屏蔽不同模型厂商差异
- AI Services 用接口 + 注解声明 Prompt 与能力
- Tools / RAG / Memory 以组件形式组合,而非堆砌 if-else
- Spring Boot Starter 实现零样板配置
从「调一次 OpenAI API」到「上线一个可维护的 AI 功能」,差距往往不在模型能力,而在工程化程度。LangChain4j 正是补齐 Java 生态这块短板的关键拼图。
建议下一步:用 @AiService + 本地 Ollama 跑通一个最小问答接口,再逐步叠加 RAG 与 Tool,比一上来追求复杂 Agent 更稳妥。
参考链接