LangChain4j 生态盘点:Java 开发者做 AI 的 5 个必备组件
引言
"AI 这波我们 Java 开发者能不能不学 Python 也跟上?"——这是过去一年团队里被问得最多的问题。确实,AI 生态的教程九成是 Python 的,LangChain、LlamaIndex、各种 Agent 框架,清一色 pip install。Java 开发者想做一个"接入大模型的客服助手",面对的是 Python 教程里 from langchain.chains import xxx 的陌生世界,而团队的技术栈、CI/CD、监控、服务治理全是 Java 的——为了一个 AI 接口引入 Python 技术栈,代价远大于收益。
LangChain4j 就是 Java 开发者对这个问题的回答:它把 LangChain 的核心能力(LLM 抽象、提示词模板、记忆、RAG、Agent/Tool Calling)用纯 Java API 重新实现,和 Spring Boot 无缝集成,不需要写一行 Python。这篇文章盘点 LangChain4j 生态里 Java 开发者做 AI 应用的 5 个必备组件,从核心抽象到向量存储到 Spring Boot 集成,每个组件给定位、核心代码、适用场景和避坑要点。
一、组件一:langchain4j-core——一切的起点
1.1 定位:LLM 调用的统一抽象层
你的业务代码
↓
ChatLanguageModel(接口) ← langchain4j-core 提供的抽象
↓
OpenAiChatModel / OllamaChatModel ← 具体实现(在各子模块里)
↓
HTTP API(OpenAI / 通义 / DeepSeek / 本地 Ollama)
langchain4j-core 定义了和 LLM 交互的核心接口:ChatLanguageModel(聊天)、StreamingChatLanguageModel(流式)、EmbeddingModel(向量化)、ImageModel(图像生成)。你的业务代码面向接口编程,底层换模型只改依赖和配置,不改业务代码——这是 LangChain4j 最核心的价值主张。
1.2 核心代码
// ① 最基础的调用:一问一答
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o")
.temperature(0.7)
.build();
String answer = model.generate("用一句话解释什么是 RAG");
// → "RAG 是检索增强生成,先从知识库检索相关文档再喂给大模型生成回答。"
// ② 带对话历史的调用:多轮对话
List<ChatMessage> messages = new ArrayList<>();
messages.add(UserMessage.from("帮我查一下最近的订单"));
messages.add(AiMessage.from("好的,您最近有 3 笔订单..."));
messages.add(UserMessage.from("第一笔的物流状态是什么?")); // 模型知道"第一笔"指什么
Response<AiMessage> response = model.generate(messages);
System.out.println(response.content().text());
// ③ 结构化输出:让模型返回 Java 对象
record OrderSummary(String orderId, String status, BigDecimal amount) {}
OrderSummary summary = model.generate(
UserMessage.from("提取订单信息:订单号 SO20250912001,已发货,金额 299.00"),
OrderSummary.class
);
// → OrderSummary[orderId=SO20250912001, status=已发货, amount=299.00]
1.3 三个核心设计
| 设计 | 说明 | 为什么重要 |
|---|---|---|
| ChatMessage 体系 | UserMessage/AiMessage/SystemMessage 三种角色 | 多轮对话的上下文管理——SystemMessage 设角色,UserMessage 用户输入,AiMessage 历史回复 |
| Response 包装 | 返回 Response,带 token 用量和 finishReason | token 用量是成本控制的基础数据——不看用量调 AI 等于不看账单刷信用卡 |
| 结构化输出 | model.generate(prompt, Class.class) | 直接反序列化成 Java record/POJO——免手写 JSON 解析,是 Function Calling 的底层支撑 |
1.4 避坑要点
| 坑 | 说明 | 对策 |
|---|---|---|
| Token 计费认知缺失 | GPT-4o 输入 $2.5/M token,一个长 prompt 10K token = $0.025 | 生产必须监控 token 用量,设日预算上限 |
| Temperature 乱设 | Temperature=0 确定性最强,=2 随机性最大 | 分类/抽取任务用 0~0.3;创意/对话用 0.7~1.0 |
| SystemMessage 位置 | 必须放在消息列表最前面 | 放后面会被模型忽略——角色设定在对话开始时就固定 |
二、组件二:langchain4j-open-ai——对接 OpenAI/通义/DeepSeek
2.1 定位:一个依赖,三个模型
langchain4j-open-ai 是 LangChain4j 里最常用的 LLM 对接模块。它的价值不只是对接 OpenAI 官方——通义千问、DeepSeek、Moonshot、智谱等国产大模型的 API 大多兼容 OpenAI 格式,只需要改 baseUrl 和 apiKey 就能切换:
// OpenAI 官方
ChatLanguageModel openai = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.baseUrl("https://api.openai.com/v1")
.modelName("gpt-4o")
.build();
// DeepSeek(OpenAI 兼容格式,改 baseUrl 和 modelName 即可)
ChatLanguageModel deepseek = OpenAiChatModel.builder()
.apiKey(System.getenv("DEEPSEEK_API_KEY"))
.baseUrl("https://api.deepseek.com/v1")
.modelName("deepseek-chat")
.build();
// 通义千问(DashScope 的 OpenAI 兼容端点)
ChatLanguageModel qwen = OpenAiChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.modelName("qwen-plus")
.build();
2.2 为什么"OpenAI 兼容"成了事实标准
2023年 OpenAI 的 /v1/chat/completions API 格式 → 行业事实标准
↓
国产模型纷纷提供 OpenAI 兼容端点
↓
LangChain4j 的 langchain4j-open-ai 模块 → 一套代码对接 10+ 家模型
↓
Java 开发者只需要改 baseUrl + apiKey + modelName
这是 Java 开发者的意外红利:不需要为每个国产模型装一个专门的 SDK——它们都兼容 OpenAI API 格式,一个 langchain4j-open-ai 依赖全搞定。选模型时优先选提供 OpenAI 兼容端点的,否则要引入专门的 SDK(如 langchain4j-dashscope),多一个依赖多一个维护点。
2.3 流式输出配置
StreamingChatLanguageModel streamingModel = OpenAiStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o")
.build();
// 流式回调:逐 token 返回(前端 SSE 推送)
streamingModel.generate("讲一个 Java 开发者的故事", new StreamingResponseHandler<AiMessage>() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.print(partialResponse); // 逐 token 打印
}
@Override
public void onCompleteResponse(Response<AiMessage> response) {
System.out.println("\n[完成] token=" + response.tokenUsage());
}
@Override
public void onError(Throwable error) {
log.error("[StreamError]", error);
}
});
流式输出是用户体验的关键:让用户等 10 秒一次性返回完整回答 vs 逐字输出 10 秒——体感差距巨大。SSE(Server-Sent Events)+ 流式模型是 ChatGPT 式体验的标配。
2.4 避坑要点
| 坑 | 说明 | 对策 |
|---|---|---|
| 坑 1:超时设太短 | 大模型响应慢(首 token 1~3s + 生成 5~15s),默认超时可能不够 | OpenAiChatModel.builder().timeout(Duration.ofSeconds(60)) |
| 坑 2:context window 超限 | gpt-4o-mini context 128K 但不同模型差异大,超限报错 | 用 Tokenizer 计数,超限时截断/摘要历史消息 |
| 坑 3:国产模型兼容性差异 | "OpenAI 兼容"不等于 100% 兼容——Function Calling/结构化输出支持度不同 | 上线前按目标模型跑一遍 Function Calling 测试用例 |
| 坑 4:API Key 泄露 | Key 写在代码里进了 git → 公网扫到 → 账单爆万刀 | Key 走环境变量/Nacos/Vault,绝不硬编码 |
三、组件三:langchain4j-spring-boot-starter——Spring Boot 一键集成
3.1 定位:AI 能力注入 Spring Bean
这是 Java 开发者最舒适的组件——像配一个 DataSource 一样配一个大模型:
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifact>
<version>0.36.2</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>0.36.2</version>
</dependency>
langchain4j:
open-ai:
chat-model:
api-key: ${OPENAI_API_KEY}
base-url: https://api.deepseek.com/v1 # 用 DeepSeek
model-name: deepseek-chat
temperature: 0.7
timeout: 60s
log-requests: true # 开发期打印请求日志
log-responses: false # 生产关掉(响应太长)
streaming-model:
api-key: ${OPENAI_API_KEY}
base-url: https://api.deepseek.com/v1
model-name: deepseek-chat
3.2 自动注入:直接用 Bean
@RestController
@RequiredArgsConstructor
public class ChatController {
private final ChatLanguageModel chatModel; // 自动注入
private final StreamingChatLanguageModel streamModel;
@PostMapping("/chat")
public String chat(@RequestBody String question) {
return chatModel.generate(question);
}
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> stream(@RequestParam String question) {
return Flux.create(sink -> {
streamModel.generate(question, new StreamingResponseHandler<>() {
@Override
public void onPartialResponse(String partial) {
sink.next(partial);
}
@Override
public void onCompleteResponse(Response<AiMessage> response) {
sink.complete();
}
@Override
public void onError(Throwable error) {
sink.error(error);
}
});
});
}
}
3.3 AI Service:声明式 AI 接口(最优雅的 API)
/**
* AI Service:像调 Feign 一样调大模型
* LangChain4j 用动态代理自动生成实现类——你只写接口
*/
@AiService
public interface CustomerServiceAssistant {
@SystemMessage("你是一个电商客服助手,回答用户的订单和售后问题")
@UserMessage("用户问题:{{question}}")
String answer(@V("question") String question);
}
// 使用:注入即用
@RestController
@RequiredArgsConstructor
public class AssistantController {
private final CustomerServiceAssistant assistant;
@PostMapping("/ask")
public String ask(@RequestBody String question) {
return assistant.answer(question);
}
}
@AiService 的哲学:像 Spring Data JPA 的 Repository 一样——你只定义接口,框架用动态代理生成实现。提示词模板用注解定义,参数用 @V 注入,底层自动拼装 ChatMessage、调模型、解析返回。这是 LangChain4j 区别于其他 Java AI 框架的核心设计——把"调大模型"这件事从命令式编程变成声明式编程。
3.4 避坑要点
| 坑 | 说明 | 对策 |
|---|---|---|
| 坑 1:版本不匹配 | langchain4j-core 和 spring-boot-starter 版本不一致 → 启动报错 | 统一用 BOM 管理版本(见 3.5) |
| 坑 2:log-requests 生产忘关 | 请求日志包含完整 prompt → 日志体积爆炸 + 敏感信息泄露 | 生产 log-requests: false, log-responses: false |
| 坑 3:AI Service 缺少 fallback | 模型不可用时 AI Service 调用直接抛异常 | 配合 try-catch + 降级返回(和 Feign Fallback 同理) |
3.5 版本统一管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-bom</artifactId>
<version>0.36.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 子依赖只写 groupId/artifactId,版本由 BOM 统一 -->
四、组件四:langchain4j-pgvector——向量存储
4.1 定位:RAG 的存储基座
RAG 流程:
文档 → 切片 → Embedding(向量化)→ 存入向量数据库 → 查询时语义检索 → 喂给 LLM
langchain4j-pgvector 就是"存入向量数据库"这一步的实现:
用 PostgreSQL + pgvector 插件作为向量存储
4.2 为什么选 PostgreSQL + pgvector
| 维度 | pgvector | Pinecone(SaaS) | Milvus(专用) |
|---|---|---|---|
| 部署成本 | 已有 PG 直接加插件 | SaaS 按量付费 | 独立集群 |
| 运维成本 | 低(PG 团队熟) | 零运维 | 高(专用向量 DB) |
| 事务一致性 | 与业务数据同库事务 | 跨系统 | 跨系统 |
| 规模 | 百万级向量 | 亿级 | 亿级+ |
| 过滤能力 | SQL WHERE 强大 | 元数据过滤有限 | 标量过滤 |
pgvector 的杀手锏:如果你的业务已经在用 PostgreSQL,加一个 CREATE EXTENSION vector 就有了向量存储能力——不需要引入新的有状态组件。文档元数据(标题/来源/时间)和向量在同一个 SQL 查询里过滤,这是专用向量数据库做不到的。
4.3 完整代码
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-pgvector</artifactId>
<version>0.36.2</version>
</dependency>
-- PostgreSQL 里先装插件
CREATE EXTENSION IF NOT EXISTS vector;
@Configuration
public class VectorStoreConfig {
@Bean
public EmbeddingStore<TextSegment> embeddingStore(EmbeddingModel embeddingModel) {
return PgVectorEmbeddingStore.builder()
.host("pg-host")
.port(5432)
.database("ai_db")
.user("ai_user")
.password(System.getenv("PG_PASSWORD"))
.table("knowledge_embeddings") // 存向量的表名
.dimension(1536) // 维度=embedding 模型输出维度
.createTable(true) // 首次自动建表
.build();
}
}
/**
* 知识库入库:文档 → 切片 → 向量化 → 存 PG
*/
@Service
@RequiredArgsConstructor
public class KnowledgeIngestService {
private final EmbeddingModel embeddingModel; // 组件五
private final EmbeddingStore<TextSegment> store; // pgvector
public void ingest(String documentText, String source) {
// ① 切片(按段落语义切,不只是固定字数)
DocumentSplitter splitter = DocumentSplitters.recursive(800, 100);
List<TextSegment> segments = splitter.split(
TextSegment.from(documentText)
.metadata("source", source)
.metadata("ingestedAt", Instant.now().toString())
);
// ② 批量向量化
Response<List<Embedding>> embeddings = embeddingModel.embedAll(segments);
// ③ 存入 pgvector
List<String> ids = store.addAll(embeddings.content(), segments);
log.info("[Ingest] source={}, segments={}, ids={}", source, ids.size(), ids);
}
/**
* 语义检索:用户问题 → 向量化 → pgvector 近邻搜索 → 返回最相关片段
*/
public List<TextSegment> search(String query, int maxResults) {
Response<Embedding> queryEmbedding = embeddingModel.embed(query);
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding.content())
.maxResults(maxResults)
.minScore(0.7) // 相似度阈值,低于 0.7 不返回
.build();
return store.search(request).matches().stream()
.map(EmbeddingMatch::embedded)
.toList();
}
}
4.4 避坑要点
| 坑 | 说明 | 对策 |
|---|---|---|
| 坑 1:维度不匹配 | OpenAI text-embedding-3-small=1536 维,换模型维度变 → 建表报错 | 维度是 embedding 模型的固有属性,换模型要重建向量表 |
| 坑 2:全表扫描慢 | pgvector 默认精确搜索(KNN),百万级向量查询秒级 | 加 HNSW 索引(CREATE INDEX ON table USING hnsw (embedding vector_cosine_ops)),百万级降到毫秒 |
| 坑 3:没有 minScore 过滤 | 不设相似度阈值 → 返回不相关结果 → RAG 答非所问 | minScore 0.6~0.7 起步,按评测集调优 |
| 坑 4:元数据没存 | 只存向量不存来源/时间 → 检索到片段但不知道出处 | TextSegment.metadata() 必须带 source,RAG 回答要引用来源 |
五、组件五:langchain4j-embeddings——文本向量化
5.1 定位:RAG 的"翻译器"
用户问题 "怎么退货" ──EmbeddingModel──→ [0.12, -0.34, 0.56, ...](1536维向量)
↓
知识库文档 "退换货政策" ──EmbeddingModel──→ [0.11, -0.32, 0.58, ...](1536维向量)
↓
向量余弦相似度 = 0.89(高度相似)→ 检索命中
EmbeddingModel 把文本变成向量——语义相近的文本,向量距离也近。这是语义检索(而不是关键词匹配)能工作的底层原因。
5.2 选用哪种 Embedding 模型
| 模型 | 维度 | 来源 | 适用 |
|---|---|---|---|
| text-embedding-3-small | 1536 | OpenAI | 通用,性价比高 |
| text-embedding-3-large | 3072 | OpenAI | 高精度场景 |
| bge-large-zh | 1024 | 智源(开源) | 中文效果最优,可本地部署 |
| nomic-embed-text | 768 | 开源 | 本地 Ollama 部署,零成本 |
中文场景的关键认知:OpenAI 的 embedding 对中文不如英文好——bge-large-zh 等中文优化的开源模型在中文语义检索上往往优于 OpenAI。建议做一次 A/B 评测:同一批中文文档 + 同一组查询,比较两个 embedding 模型的 recall@5,选数据说话的那个。
5.3 本地 Embedding(免 API 调用)
<!-- 用 ONNX Runtime 本地跑 embedding,零 API 调用费用 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embeddings-bge-small-zh-v15</artifactId>
<version>0.36.2</version>
</dependency>
@Bean
public EmbeddingModel embeddingModel() {
// 本地 ONNX 推理,模型权重随依赖打包,无需 API Key
return new BgeSmallZhV15EmbeddingModel();
// 维度 512,中文效果好,零 API 成本
// 代价:占 JVM 堆 ~200MB + 首次推理慢(模型加载)
}
5.4 避坑要点
| 坑 | 说明 | 对策 |
|---|---|---|
| 坑 1:混合使用不同 embedding 模型 | 入库用 OpenAI 1536 维,查询用 bge 512 维 → 维度不匹配,检索全废 | 入库和查询必须用同一个 embedding 模型,中途换模型=全量重建 |
| 坑 2:批量向量化不调 batch | 逐条调 embed() → API 调用次数 = 文档数 → 费用和延迟双高 | 用 embedAll() 批量向量化,一次请求处理多条 |
| 坑 3:向量入库不更新 | 文档更新后向量表没同步 → RAG 检索到旧内容 | 文档变更走 CDC/事件驱动重新 ingest,或定期全量重建 |
| 坑 4:忽略 embedding 成本 | 100 万文档 × 1536 维 × 每次更新都 embed → API 费用不可忽视 | 评估本地 embedding(bge/nomic),用 ONNX 免费跑 |
六、五组件组装:一个完整的 RAG 应用
@AiService
public interface KnowledgeAssistant {
@SystemMessage("""
你是一个知识库助手。根据以下检索到的上下文回答用户问题。
如果上下文中没有相关信息,回答"我不知道",不要编造。
回答时引用来源(source 字段)。
""")
@UserMessage("上下文:{{context}}\n\n问题:{{question}}")
String answer(@V("context") String context, @V("question") String question);
}
@RestController
@RequiredArgsConstructor
public class RagController {
private final KnowledgeIngestService ingestService;
private final KnowledgeAssistant assistant;
@PostMapping("/ask")
public String ask(@RequestBody String question) {
// ① 语义检索
List<TextSegment> hits = ingestService.search(question, 5);
String context = hits.stream()
.map(TextSegment::text)
.collect(Collectors.joining("\n---\n"));
// ② 拼装 prompt → 调 LLM → 返回回答
return assistant.answer(context, question);
}
}
组装链路:
langchain4j-embeddings(向量化)
↓
langchain4j-pgvector(向量存储+检索)
↓
langchain4j-open-ai(LLM 调用)
↓
langchain4j-spring-boot-starter(@AiService 自动代理)
↓
langchain4j-core(ChatMessage/Response 统一抽象)
五个组件各司其职:core 是抽象地基,open-ai 是模型对接,spring-boot-starter 是集成层,pgvector 是知识库存储,embeddings 是语义翻译器——拼在一起就是一个完整的 RAG 应用,全程零 Python。
七、常见问题
7.1 LangChain4j 和 Spring AI 有什么区别?选哪个?
Spring AI(Spring 官方出品)和 LangChain4j 定位高度重合,都是 Java 的 AI 应用框架。区别在生态哲学:Spring AI 深度绑定 Spring 生态(配置/自动装配/Actuator 全套),适合"纯 Spring Boot 技术栈、不想引入额外框架"的团队;LangChain4j 独立于 Spring(可用可不用),AI Service 和 @AiService 设计更优雅,适合"想要轻量 AI 抽象、不一定要全套 Spring 生态"的场景。2026 年两者的功能差距在快速缩小,选哪个看团队技术栈偏好——全 Spring 生态选 Spring AI,想要更多灵活性选 LangChain4j。两者都在快速迭代,建议每季度重新评估。
7.2 生产用 LangChain4j 的稳定性怎么样?
LangChain4j 在 0.x 版本阶段(当前 0.36),API 仍有 breaking change 风险——但核心接口(ChatLanguageModel/EmbeddingModel/EmbeddingStore)已经稳定,变动的是高级特性(Agent/Tool Calling/RAG 管线)。生产建议:① 锁版本(BOM),不追最新;② 在核心接口和 AI Service 之上包一层自己的 Service,底层框架变动不渗透到业务;③ 关注 release note 的 breaking change 标注,大版本升级前跑回归用例。
7.3 成本怎么控?
三层控制:① Token 监控——从 Response.tokenUsage() 取用量,打 Prometheus 指标 + 设日预算告警;② Prompt 优化——SystemMessage 精简、历史消息截断/摘要、few-shot 例子从 5 条减到 2 条;③ 模型分级——简单分类用 gpt-4o-mini($0.15/M),复杂推理才用 gpt-4o($2.5/M),路由层按任务复杂度选模型。一个真实账单案例:不加控制的 AI 接口日均 $50,加模型分级+Token 预算后日均 $8——控制和不控制差 6 倍。
7.4 向量数据库百万级以上怎么办?
pgvector 加 HNSW 索引能撑到百万级(实测 100 万 1536 维,查询 P99 < 50ms)。千万级以上考虑迁移:Milvus/Qdrant 等专用向量数据库在亿级规模上性能优势明显。但迁移代价是引入一个独立的有状态组件——运维、备份、监控全要新建。建议路径:pgvector 起步 → 百万级加 HNSW → 千万级再评估迁移,不要一上来就 Milvus(大多数应用的向量量到不了百万)。
7.5 AI Service 的 @SystemMessage 和 @UserMessage 怎么管理版本?
@SystemMessage 写在注解里 = 硬编码在代码里,改 prompt 要重新发版。生产建议:① 简单 prompt 写注解里(快速验证);② 复杂 prompt 外置到 Nacos 配置中心(和上一篇配置中心文章衔接),动态修改不重启;③ Prompt 变更走评测集验证(改一个字可能让效果翻车)。Prompt 是"代码"还是"配置"的判断标准:改动频率高 + 需要试错 → 配置;稳定不变 → 代码。
7.6 能不能不用 LangChain4j,直接调 OpenAI HTTP API?
能,但你会重新发明轮子。直接调 HTTP API 意味着:自己管 ChatMessage 拼装、自己写重试/超时、自己解析流式 SSE、自己实现 RAG 检索+prompt 拼装、自己写 Function Calling 的 JSON Schema 生成——这些全是 LangChain4j 已经做好的。直连 HTTP API 适合"就调一个 generate() 的极简场景",一旦涉及多轮对话、RAG、Tool Calling,框架的价值就远超学习成本。就像你可以用 JDBC 直连数据库,但不会因此就不用 MyBatis。
八、总结
五组件速查卡
┌──────────────────────────┬────────────────────────────────────────┐
│ 组件 │ 一句话 │
├──────────────────────────┼────────────────────────────────────────┤
│ langchain4j-core │ LLM 调用统一抽象,换模型不改业务代码 │
│ langchain4j-open-ai │ 一个依赖对接 OpenAI/DeepSeek/通义等 10+ │
│ langchain4j-spring-boot- │ 像 DataSource 一样配大模型,@AiService │
│ starter │ 声明式 AI 接口 │
│ langchain4j-pgvector │ PG 加插件即向量库,SQL 过滤+语义检索 │
│ langchain4j-embeddings │ 文本变向量,语义检索的翻译器 │
└──────────────────────────┴────────────────────────────────────────┘
组装链路:embeddings → pgvector → open-ai → spring-boot-starter → core
一句话
LangChain4j 让 Java 开发者做 AI 应用不用学 Python:core 是统一抽象地基(换模型不改代码),open-ai 一个依赖对接 10+ 家大模型(国产模型 OpenAI 兼容端点红利),spring-boot-starter 像 DataSource 一样配大模型且 @AiService 声明式 AI 接口比 Feign 还优雅,pgvector 在已有 PostgreSQL 上加插件即得向量库(不引入新组件),embeddings 把文本变向量让语义检索代替关键词匹配。五个组件拼在一起就是完整的 RAG 应用——全程零 Python,全程 Spring 生态。但核心纪律只有两条:embedding 模型入库和查询必须一致(中途换=全量重建),API Key 绝不进代码(走 Nacos/Vault 环境变量)。
给团队的建议
| 项 | 建议 |
|---|---|
| 起步 | 引入 langchain4j-spring-boot-starter + open-ai,先做一个 @AiService 验证链路 |
| RAG | pgvector 起步(已有 PG 零成本),中文用 bge 系列本地 embedding |
| 版本 | BOM 锁版本不追最新,业务层包 Service 隔离框架变动 |
| 成本 | Response.tokenUsage() 接 Prometheus + 日预算告警 + 模型分级路由 |
| 安全 | API Key 走环境变量/Nacos/Vault,log-requests 生产关掉 |
| 评测 | RAG 上线前建 100 条评测集(query + 期望命中文档),recall@5 量化验收 |
互动话题:你们在用 LangChain4j 还是 Spring AI?做 AI 应用时最痛的是什么?评论区聊聊。
参考资料
- LangChain4j 官方文档
- LangChain4j GitHub
- LangChain4j Spring Boot 集成指南
- pgvector 官方文档
- OpenAI API 兼容端点列表(国产模型)
- Spring AI 官方文档(对比参考)
- bge embedding 模型(智源开源)
标题:LangChain4j 生态盘点:Java 开发者做 AI 的 5 个必备组件
作者:jiangyi
地址:http://jiangyi.space/articles/2026/09/15/1789201786460.html
公众号:服务端技术精选
- 引言
- 一、组件一:langchain4j-core——一切的起点
- 1.1 定位:LLM 调用的统一抽象层
- 1.2 核心代码
- 1.3 三个核心设计
- 1.4 避坑要点
- 二、组件二:langchain4j-open-ai——对接 OpenAI/通义/DeepSeek
- 2.1 定位:一个依赖,三个模型
- 2.2 为什么"OpenAI 兼容"成了事实标准
- 2.3 流式输出配置
- 2.4 避坑要点
- 三、组件三:langchain4j-spring-boot-starter——Spring Boot 一键集成
- 3.1 定位:AI 能力注入 Spring Bean
- 3.2 自动注入:直接用 Bean
- 3.3 AI Service:声明式 AI 接口(最优雅的 API)
- 3.4 避坑要点
- 3.5 版本统一管理
- 四、组件四:langchain4j-pgvector——向量存储
- 4.1 定位:RAG 的存储基座
- 4.2 为什么选 PostgreSQL + pgvector
- 4.3 完整代码
- 4.4 避坑要点
- 五、组件五:langchain4j-embeddings——文本向量化
- 5.1 定位:RAG 的"翻译器"
- 5.2 选用哪种 Embedding 模型
- 5.3 本地 Embedding(免 API 调用)
- 5.4 避坑要点
- 六、五组件组装:一个完整的 RAG 应用
- 七、常见问题
- 7.1 LangChain4j 和 Spring AI 有什么区别?选哪个?
- 7.2 生产用 LangChain4j 的稳定性怎么样?
- 7.3 成本怎么控?
- 7.4 向量数据库百万级以上怎么办?
- 7.5 AI Service 的 @SystemMessage 和 @UserMessage 怎么管理版本?
- 7.6 能不能不用 LangChain4j,直接调 OpenAI HTTP API?
- 八、总结
- 五组件速查卡
- 一句话
- 给团队的建议
- 参考资料
评论