从 LangChain 到 LangChain4j:Java 开发者的 AI 应用实战指南
2026/4/27 22:25:48 网站建设 项目流程

如果你已经熟悉 Python 版的 LangChain,那 LangChain4j 的核心概念你基本都能对上号。但 Java 生态有它自己的玩法,尤其在 Spring Boot 整合、声明式 API 和工具调用方面,LangChain4j 的设计更贴合 Java 开发者的习惯。

一、为什么是 LangChain4j?

Java 调用大模型的主流框架有两个:LangChain4jSpring AI。如果你是 Spring 生态的重度用户,两者都可以选。LangChain4j 的优势在于:

  • 与 LangChain(Python)概念高度对应,迁移成本低
  • Spring Boot 起步依赖,配置即用
  • 声明式@AiService注解,代码极简
  • 内置 RAG、Tools、会话记忆等高阶能力

官网:https://docs.langchain4j.dev

二、快速入门:5 分钟跑通第一个对话

2.1 引入依赖

<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>1.0.1</version></dependency>

LangChain4j 使用 OpenAI 兼容协议,所以阿里云百炼、DeepSeek 等平台只需换baseUrl即可。

2.2 构建模型 & 发起对话

OpenAiChatModel model = OpenAiChatModel.builder() .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1") .apiKey(System.getenv("API-KEY"))// 推荐:从环境变量读取.modelName("qwen-plus") .logRequests(true)// 开发阶段开启日志.logResponses(true) .build(); String result = model.chat("你好,介绍一下自己"); System.out.println(result);

对比 LangChain(Python):

操作LangChain (Python)LangChain4j (Java)
构建模型ChatOpenAI(model=..., api_key=...)OpenAiChatModel.builder()...build()
发起对话model.invoke("...")model.chat("...")
日志调试需手动配置 logging.logRequests(true).logResponses(true)

核心差异:LangChain4j 用Builder 模式替代 Python 的关键字参数,日志开关是内建的。

三、Spring Boot 整合:配置驱动

纯 Java 方式能用,但实际项目必然要和 Spring 结合。LangChain4j 提供了起步依赖,做到配置即注入。

3.1 引入起步依赖

<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai-spring-boot-starter</artifactId><version>1.0.1-beta6</version></dependency>

3.2 application.yml 配置

langchain4j:open-ai:chat-model:base-url: https://dashscope.aliyuncs.com/compatible-mode/v1api-key: ${API-KEY}model-name: qwen-pluslog-requests: truelog-responses: truelogging:level:dev.langchain4j: debug

配置完成后,IOC 容器自动注入OpenAiChatModel对象,直接@Autowired使用。

3.3 接口开发

@RestControllerpublicclassChatController{ @AutowiredprivateOpenAiChatModel model; @RequestMapping("/chat")publicString chat(String message) {returnmodel.chat(message); } }

到这里,一个可用的 AI 对话接口就完成了。但直接用model.chat()做高阶功能(会话记忆、RAG、Tools)会很麻烦——所以 LangChain4j 提供了AiServices

四、AiServices:LangChain4j 的灵魂(原理:动态代理)

LangChain4j 中,AiServices是对 LangChain(Python)中Chain的替代方案。它把模型、记忆、检索、工具等能力封装到一个接口的动态代理中,用起来像调用普通方法一样简单。

4.1 编程式使用

// 1. 声明接口publicinterfaceConsultantService{ String chat(String message); }// 2. 用 AiServices 创建代理对象@ConfigurationpublicclassCommonConfig{ @AutowiredprivateOpenAiChatModel model; @BeanpublicConsultantService consultantService() {returnAiServices.builder(ConsultantService.class) .chatModel(model) .build(); } }

4.2 声明式使用(推荐)

更简洁的方式——直接在接口上加@AiService注解,LangChain4j 自动扫描创建代理:

@AiService( wiringMode = AiServiceWiringMode.EXPLICIT,// 手动装配chatModel = "openAiChatModel" )publicinterfaceConsultantService{ String chat(String message); }

不需要写@Configuration,不需要手动构建 Bean,一个注解搞定。

对比 LangChain(Python):

概念LangChain (Python)LangChain4j (Java)
链式调用chain = LLMChain | prompt | memory@AiService注解 + 属性配置
装配方式代码串联声明式注解,Spring 自动注入
扩展能力传参给 Chain 构造函数@AiService的属性指定 Bean 名

LangChain4j 的声明式风格对 Java 开发者更友好——不需要记住 Chain 的嵌套顺序,在注解里指明用哪个组件就行。

五、流式调用:从阻塞到实时

阻塞式调用一次性返回完整结果,用户体验差。流式调用逐 Token 推送,类似打字机效果。

5.1 配置流式模型

langchain4j:open-ai:streaming-chat-model:# 流式模型配置base-url: https://dashscope.aliyuncs.com/compatible-mode/v1api-key: ${API-KEY}model-name: qwen-plus

5.2 引入 WebFlux 依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-reactor</artifactId><version>1.0.1-beta6</version></dependency>

5.3 接口返回 Flux

@AiService( wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "openAiChatModel", streamingChatModel = "openAiStreamingChatModel" )publicinterfaceConsultantService{ Flux<String> chat(@MemoryId String memoryId, @UserMessage String message); }

Controller 返回Flux<String>,前端通过 SSE 接收实时推送。

六、消息注解:SystemMessage 与 UserMessage

大模型的行为由消息类型决定。SystemMessage设定 AI 角色和规则,UserMessage携带用户输入。

6.1 SystemMessage:设定 AI 人设

// 方式一:直接写在注解里@SystemMessage("你是志愿填报顾问,只回答高考志愿相关问题") Flux<String> chat(@MemoryId String memoryId, @UserMessage String message);// 方式二:从外部文件加载(推荐,方便管理长提示词)@SystemMessage(fromResource = "system.txt") Flux<String> chat(@MemoryId String memoryId, @UserMessage String message);

6.2 UserMessage:模板化用户消息

可以在用户消息前后拼接预设内容,通过{{it}}@V注解引用参数:

// 使用默认占位符 {{it}}@UserMessage("你是AI助手。{{it}}") Flux<String> chat(String message);// 自定义占位符名称@UserMessage("你是AI助手。{{msg}}") Flux<String> chat(@V("msg") String message);

七、会话记忆:从无状态到有上下文

大模型本身没有记忆,每次对话都是独立的。会话记忆的原理是把历史消息一起发给模型,让它"看到"之前的对话。

7.1 基本实现

@BeanpublicChatMemory chatMemory() {returnMessageWindowChatMemory.builder() .maxMessages(20)// 最多保留 20 条,超出淘汰最早的.build(); }
@AiService( wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "openAiChatModel", chatMemory = "chatMemory"// 注入会话记忆)

为什么要限制条数?两个原因:大模型上下文有上限(约 10 万 Token);消息越多,Token 消耗越大,费用越高。

7.2 会话隔离

不同用户不能共享同一个记忆对象。通过ChatMemoryProvider+@MemoryId实现:

@BeanpublicChatMemoryProvider chatMemoryProvider() {returnmemoryId -> MessageWindowChatMemory.builder() .id(memoryId) .maxMessages(20) .build(); }
@AiService( wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "openAiChatModel", chatMemoryProvider = "chatMemoryProvider" )publicinterfaceConsultantService{ @SystemMessage(fromResource = "system.txt") Flux<String> chat(@MemoryId String memoryId, @UserMessage String message); }

LangChain4j 根据memoryId查找或创建对应的ChatMemory对象,实现用户间记忆隔离。

对比 LangChain(Python):

操作LangChain (Python)LangChain4j (Java)
记忆管理ConversationBufferMemoryMessageWindowChatMemory
消息窗口ConversationBufferWindowMemory(k=20).maxMessages(20)
会话隔离手动管理 session_idChatMemoryProvider+@MemoryId

7.3 持久化:记忆存到 Redis

默认的MessageWindowChatMemory使用内存存储,重启即丢失。实现ChatMemoryStore接口即可持久化:

@RepositorypublicclassRedisChatMemoryStoreimplementsChatMemoryStore { @AutowiredprivateStringRedisTemplate redisTemplate; @OverridepublicList<ChatMessage> getMessages(Object memoryId) { String json = redisTemplate.opsForValue().get(memoryId);returnChatMessageDeserializer.messagesFromJson(json); } @Overridepublicvoid updateMessages(Object memoryId, List<ChatMessage> list) { String json = ChatMessageSerializer.messagesToJson(list); redisTemplate.opsForValue().set(memoryId.toString(), json, Duration.ofDays(1)); } @Overridepublicvoid deleteMessages(Object memoryId) { redisTemplate.delete(memoryId.toString()); } }

然后在ChatMemoryProvider中指定使用:

@BeanpublicChatMemoryProvider chatMemoryProvider() {returnmemoryId -> MessageWindowChatMemory.builder() .id(memoryId) .maxMessages(20) .chatMemoryStore(redisChatMemoryStore)// 使用 Redis 存储.build(); }

八、RAG 知识库:让 AI 拥有专属知识

RAG(Retrieval Augmented Generation)的本质:先检索相关知识,再让模型结合知识生成答案

8.1 RAG 工作原理

用户提问 → 向量化 → 在向量数据库中检索相似片段 → 把「问题 + 检索到的片段」一起发给大模型 → 生成答案

核心概念:
-向量:文本的数学表示,多维坐标中的一个点
-余弦相似度:衡量两个向量的方向接近程度,值越大越相似(0~1)
-向量数据库:专门存储和检索向量的数据库(Milvus、Chroma、RedisSearch 等)

8.2 快速入门:内存版 RAG

<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-easy-rag</artifactId><version>1.0.1-beta6</version></dependency>
@BeanpublicEmbeddingStore store() {// 1. 加载文档List<Document> documents = ClassPathDocumentLoader.loadDocuments("content");// 2. 构建内存向量数据库InMemoryEmbeddingStore store =newInMemoryEmbeddingStore();// 3. 分割 + 向量化 + 存储(一步搞定)EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder() .embeddingStore(store) .build(); ingestor.ingest(documents);returnstore; } @BeanpublicContentRetriever contentRetriever(EmbeddingStore store) {returnEmbeddingStoreContentRetriever.builder() .embeddingStore(store) .minScore(0.5)// 最低相似度阈值.maxResults(3)// 最多返回 3 个片段.build(); }
@AiService( wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "openAiChatModel", chatMemoryProvider = "chatMemoryProvider", contentRetriever = "contentRetriever"// 配置检索器)

三步搞定:存文档 → 建检索器 → 配到@AiService

8.3 核心组件详解

RAG 涉及五个核心 API,LangChain4j 把大部分细节封装到了EmbeddingStoreIngestor中:

① 文档加载器

加载器用途
ClassPathDocumentLoader从 classpath 加载
FileSystemDocumentLoader从本地磁盘加载
UrlDocumentLoader从 URL 加载

② 文档解析器

解析器支持格式
ApacheTikaDocumentParser(默认)几乎所有格式
ApachePdfBoxDocumentParserPDF
ApachePoiDocumentParserOffice 文件
TextDocumentParser纯文本

③ 文档分割器

分割器策略
DocumentByParagraphSplitter按段落
DocumentByLineSplitter按行
DocumentBySentenceSplitter按句子
DocumentSplitters.recursive()(默认)段落 → 行 → 句子 → 词,逐级递归

递归分割器最实用,还支持配置片段重叠保持语义连贯:

DocumentSplitter ds = DocumentSplitters.recursive(500, 100);// 500 = 每个片段最大字符数// 100 = 相邻片段重叠字符数(防止语义断裂)

④ 向量模型

内存版向量模型功能有限,生产环境建议替换为百炼的text-embedding-v3

langchain4j:open-ai:embedding-model:base-url: https://dashscope.aliyuncs.com/compatible-mode/v1api-key: ${API-KEY}model-name: text-embedding-v3

注入后交给EmbeddingStoreIngestorEmbeddingStoreContentRetriever

@AutowiredprivateEmbeddingModel embeddingModel;// 存储时用EmbeddingStoreIngestor.builder() .embeddingStore(store) .embeddingModel(embeddingModel) .build();// 检索时也用EmbeddingStoreContentRetriever.builder() .embeddingStore(store) .embeddingModel(embeddingModel) .build();

⑤ 向量数据库

内存版InMemoryEmbeddingStore重启即丢,生产环境用 RedisSearch:

<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-redis-spring-boot-starter</artifactId><version>1.0.1-beta6</version></dependency>
langchain4j:community:redis:host: localhostport: 6379

配置后自动注入RedisEmbeddingStore,替换InMemoryEmbeddingStore即可。

8.4 LangChain vs LangChain4j RAG 对比

环节LangChain (Python)LangChain4j (Java)
文档加载PyPDFLoader/DirectoryLoaderClassPathDocumentLoader/FileSystemDocumentLoader
文本分割RecursiveCharacterTextSplitterDocumentSplitters.recursive()
向量模型OpenAIEmbeddings()EmbeddingModel(yml 配置注入)
向量数据库FAISS/Chroma/PineconeInMemoryEmbeddingStore/RedisEmbeddingStore
检索器retriever = vectorstore.as_retriever()EmbeddingStoreContentRetriever
整合方式RetrievalQA.from_chain_type()@AiService(contentRetriever=...)

关键差异:LangChain4j 用@AiService注解的contentRetriever属性挂载检索器,比 Python 的 Chain 组装更简洁。

九、Tools 工具:让 AI 调用你的代码

Tools(原 Function Calling)让大模型能调用你定义的 Java 方法。典型场景:AI 在对话中识别用户意图,自动调用预约接口写入数据库。

9.1 工作原理

用户提问 → 大模型判断是否需要调用工具 → 返回工具名称 + 参数 → AI 应用执行工具方法 → 把执行结果发回大模型 → 大模型生成最终回答

大模型不直接执行你的代码,它只是告诉你"该调用哪个方法、传什么参数",由你的程序执行后把结果回传。

9.2 定义工具方法

@Tool描述方法作用,用@P描述参数含义:

@ComponentpublicclassReservationTool{ @AutowiredprivateReservationService reservationService; @Tool("预约志愿填报服务")publicvoid addReservation( @P("考生姓名") String name, @P("考生性别") String gender, @P("考生手机号") String phone, @P("预约沟通时间,格式:yyyy-MM-dd'T'HH:mm") String communicationTime, @P("考生所在省份") String province, @P("考生预估分数") Integer estimatedScore ) { Reservation reservation =newReservation(null, name, gender, phone, LocalDateTime.parse(communicationTime), province, estimatedScore); reservationService.insert(reservation); } @Tool("根据考生手机号查询预约单")publicReservation findReservation(@P("考生手机号") String phone) {returnreservationService.findByPhone(phone); } }

9.3 配置工具

@AiService( wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "openAiChatModel", streamingChatModel = "openAiStreamingChatModel", chatMemoryProvider = "chatMemoryProvider", contentRetriever = "contentRetriever", tools = "reservationTool"// 挂载工具)

用户说"我想预约,我叫张三,电话13800000001",大模型会自动解析出参数并调用addReservation方法。

对比 LangChain(Python):

操作LangChain (Python)LangChain4j (Java)
工具定义@tool装饰器 或StructuredTool@Tool+@P注解
工具挂载agent = Agent(tools=[...])@AiService(tools="beanName")
参数描述Pydantic BaseModel 的 Field@P("描述")
自动执行Agent 自动调用LangChain4j 自动调用

十、全能力配置:最终形态

把所有能力整合到一个@AiService接口上:

@AiService( wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "openAiChatModel",// 对话模型streamingChatModel = "openAiStreamingChatModel",// 流式模型chatMemoryProvider = "chatMemoryProvider",// 会话记忆(Redis 持久化)contentRetriever = "contentRetriever",// RAG 知识库检索tools = "reservationTool"// Tools 工具)publicinterfaceConsultantService{ @SystemMessage(fromResource = "system.txt")// 系统人设Flux<String> chat(@MemoryId String memoryId, @UserMessage String message); }

一个接口,五个注解属性,覆盖了 AI 应用开发的核心能力。

十一、总结:LangChain vs LangChain4j 核心映射

能力LangChain (Python)LangChain4j (Java)
模型调用ChatOpenAI()OpenAiChatModel.builder()或 yml 配置
链式编排LLMChain \| SequentialChain@AiService声明式注解
会话记忆ConversationBufferMemoryMessageWindowChatMemory+ChatMemoryProvider
消息模板ChatPromptTemplate@SystemMessage/@UserMessage注解
RAGRetrievalQA+ 各种 LoaderEmbeddingStoreIngestor+ContentRetriever
工具调用@tool+Agent@Tool+@P+tools="beanName"
流式输出astream()Flux<String>+ WebFlux
Spring 整合不适用起步依赖 + yml 配置即注入

LangChain4j 的核心设计哲学:用声明式注解替代编程式组装,用 Spring 生态替代手动管理。如果你已经理解了 LangChain 的概念,迁移到 LangChain4j 只需要换一套 API 风格——底层原理完全一致。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询