LangChain4j 使用技巧大全

LangChain4j 使用技巧大全
LangChain4j 使用技巧大全版本基于 1.x‑beta 系列Java / SpringBoot覆盖基础、AiServices、记忆、RAG、Tool 工具调用、Agent、性能调优、生产避坑、调试排错LangChain4...。一、依赖与版本最佳实践版本统一langchain4j 所有模块版本保持完全一致不要混用不同 beta 版本极易出现序列化、流式、Tool 调用 bug稀土掘金。SpringBoot 场景优先使用langchain4j‑spring‑boot‑starter非 Spring 使用原生 builder 模式。流式 Reactor 输出必须引入langchain4j‑reactor返回FluxString不要自己手动包装回调CSDN博...。国内大模型通义千问、DeepSeek、硅基流动优先使用 OpenAiChatModel 兼容模式修改base‑url即可无需专用集成包。生产禁止使用InMemoryEmbeddingStore仅用于 Demo生产选 Milvus / Chroma / RedisEmbeddingStore / PGVector稀土掘金。二、模型配置技巧核心参数调优OpenAiChatModel.builder() .baseUrl(xxx) .apiKey(xxx) .modelName(qwen‑plus) .temperature(0.1) // 知识库/RAG场景0‑0.3创意0.7‑1.0 .topP(0.9) .maxTokens(2048) .timeout(Duration.ofSeconds(45)) // 必须设置超时防止线程卡死 .logRequests(true) // 调试打开生产关闭 .logResponses(true) .build();temperatureRAG 问答、工具调用尽量调低减少幻觉创意场景调高。timeout生产强制配置避免大模型接口慢导致 Tomcat 线程耗尽CSDN。流式模型单独实例化OpenAiStreamingChatModel不要和普通 ChatModel 混用 Bean。多模型共存技巧Spring 中给不同模型指定不同 Bean 名称AiService(wiringMode EXPLICIT)指定 bean 名称防止注入混乱CSDN博...。AiService( wiringMode AiServiceWiringMode.EXPLICIT, chatModel chatModel, streamingChatModel streamingChatModel ) public interface Assistant { }三、AiServices 注解式开发最常用AiServices 是 langchain4j 最高层抽象尽量优先用少手写底层 ChatMessage。1. 系统提示词// 直接写 SystemMessage(你是企业客服只用知识库内容回答不知道就说不知道) // 从classpath文件加载便于维护长提示词 SystemMessage(fromResource prompt/customer‑system.txt) interface Assistant { String chat(String userMsg); }动态系统提示使用systemMessageProvider(chatMemoryId‑ {...})可根据用户身份动态变更 system promptLangChain4...。2. 结构化输出直接返回 Java POJOinterface OrderAi { UserMessage(解析用户订单{{text}}) Order parseOrder(String text); } // Order为普通Java Beanlangchain4j自动要求LLM输出JSON并反序列化坑部分模型对复杂嵌套对象支持差POJO 字段尽量简单加注释提升解析成功率稀土掘金。3. 流式输出interface Assistant { FluxString streamChat(String msg); } // 构建时同时传入 chatModel streamingChatModel必须依赖langchain4j‑reactorWebFlux 环境普通 SpringMVC 不支持 Flux 返回GitHub。四、ChatMemory 对话记忆重点技巧核心多用户场景绝对不能共用同一个 ChatMemory 实例内存记忆测试用重启丢失// 按消息条数窗口 MessageWindowChatMemory.withMaxMessages(8); // 按token窗口推荐更贴合模型上下文限制 TokenWindowChatMemory.withMaxTokens(1500, tokenCountEstimator);多用户隔离ChatMemoryProviderAiServices.builder(Assistant.class) .chatMemoryProvider(memoryId - MessageWindowChatMemory.withMaxMessages(10)) .build(); // 调用时传入memoryId区分不同会话 assistant.chat(hello, session‑001);持久化记忆生产实现ChatMemoryStore存入 Redis/Mysql框架自带 RedisChatMemoryStore。MessageWindowChatMemory 只存在 JVM 内存服务重启会话全部丢失禁止生产直接使用稀土掘金。高级记忆摘要记忆SummaryChatMemory历史过长自动摘要大幅降低 token 消耗长会话场景强烈推荐CSDN。⚠️坑ChatMemory 会自动裁剪历史不是完整日志业务如果需要完整对话记录要自己额外存储不要依赖 ChatMemory 拿全量历史。五、RAG 检索增强全套技巧三种 RAG 模式Easy‑RAG快速 POC零配置效果一般不适合生产langchain4j‑easy‑ragGitHub。Naive‑RAG基础 RAGEmbeddingStoreContentRetriever绝大多数业务够用。Advanced‑RAGRetrievalAugmentor支持查询改写、多路检索、重排序 rerank、路由企业级复杂知识库用LangChain4...。文档切片最佳实践// 递归分割最通用chunkSize, overlap重叠防止语义切断 DocumentSplitter splitter DocumentSplitters.recursive(450, 60);chunkSize中文一般 400‑600 字符overlap 取 chunkSize 10%‑15%。给 Document 带上 Metadata后续可以做元数据过滤检索按文档分类、时间、业务 ID 过滤非常实用CSDN博...。检索器调优EmbeddingStoreContentRetriever.builder() .embeddingStore(store) .maxResults(4) // 返回top‑N一般3‑5 .minScore(0.65) // 相似度阈值低于该分数丢弃 .build();minScore 需要根据你的 embedding 模型实测调参不要写死 0.5。Advanced‑RAG 增强DefaultRetrievalAugmentor.builder() .queryTransformer(rewriteQueryTransformer) // 查询改写把用户短问题扩写 .contentAggregator(...) .reranker(reranker) // 重排序提升召回精度 .build();RAG 避坑不要把超长检索片段全部塞进上下文会触发 token 超限。一定要在 SystemPrompt 约束只能使用检索到的上下文回答不知道就如实说禁止编造。批量导入文档用ingest.addAll()不要循环单条 add性能差距巨大GitHub。六、Tool / Function‑Calling 工具调用技巧Tool 注解包必须是dev.langchain4j.agent.tool.Tool不要导入其他包同名注解稀土掘金。Tool 注解描述非常关键清晰写清楚什么时候调用、参数含义描述模糊大模型就不会触发工具调用。public class MyTools { Tool(当用户需要查询订单信息时调用参数orderId是订单编号) public String queryOrder(String orderId){ // 业务逻辑 } }AiServices 绑定工具AiServices.builder(Assistant.class) .chatModel(model) .tools(new MyTools()) .build();坑工具返回结果不要过长会暴涨 token工具异常需要捕获返回友好文本给 LLM不要抛异常直接中断 Agent 流程。当 LLM 只返回工具调用无文本消息AiMessage.text()会 null代码要判空防止 NPE稀土掘金。七、Agent 智能体简单 Agent 直接用 AiServicesTools 即可80% 场景够用。复杂多步 Agentlangchain4j‑agentic属于实验模块API 会变动生产谨慎使用LangChain4...。Agent 一定要设置最大迭代轮次防止无限循环调用工具打爆 API 费用。八、性能与生产调优技巧HTTP 客户端自定义替换默认 OkHttpClient设置连接池、代理适合内网 / 代理环境。线程隔离AI 大模型调用是 IO 密集单独线程池不要占用 Web 容器线程池防止雪崩CSDN博...。Embedding 缓存高频重复查询用 Caffeine 缓存 Embedding 结果减少向量化 API 调用降成本提速度CSDN。向量库批量写入addAll()批量不要循环 add。Token 监控开启 token 计数统计输入输出 token做计费、限流。日志开发打开log‑requests/log‑responses生产关闭框架日志级别设置dev.langchain4j:INFO调试改为 DEBUGGitHub。虚拟线程Java21 环境Tool 执行使用虚拟线程提升 IO 密集并发。超时 重试自行封装重试针对 429 限流、5xx 错误框架本身没有内置重试。九、高频踩坑清单❌ 多会话共用同一个 ChatMemory 实例 → 会话错乱✅ 使用 ChatMemoryProvider memoryId。❌ 生产使用 InMemoryEmbeddingStore → 重启知识库丢失。❌ Tool 注解包导错 → 工具永远不触发。❌ 没设置 timeout → 接口慢导致服务线程耗尽。❌ memory 窗口设置过大不做裁剪 → token 超限、OOM、费用暴涨。❌ RAG 不设置 minScore 阈值 → 召回无关垃圾片段幻觉变多。❌ 版本混用不同 beta → 各种序列化、流式奇怪 bug。❌ 把 ChatMemory 当成完整业务对话日志存储 → 它会裁剪丢弃消息业务日志要自己存库。❌ 流式场景忘记引入 langchain4j‑reactor → Flux 报错。❌ Agent 不限制最大循环次数 → 无限 Tool 循环巨额 token 消耗。十、调试排错手段打开log‑requests:true log‑responses:true直接看到发给大模型完整 prompt 和返回内容定位幻觉、Tool 不调用、RAG 失效最快手段。打印 token 计数看是否上下文超限。先底层 ChatModel 测试通再上 AiServices出现问题降级到底层 API 复现区分是框架问题还是 prompt / 模型问题。Tool 不调用排查顺序检查注解包 → 看 log 里 tool‑spec 是否下发给 LLM → 修改 Tool 描述写得更直白。十一、选型小建议简单问答、RAG优先 AiServices ContentRetriever代码最少。需要精细控制消息流、自定义流程用底层 ChatModel、ChatMessage。多步复杂 Agent评估风险agentic 模块实验性质优先自己编排业务流程不要完全交给 Agent 自主循环。LangChain4j SpringBoot 完整 Demo功能包含AiServices、会话记忆、RAG 知识库、Tool 工具调用、流式输出、元数据过滤。环境SpringBoot3.xJDK17/21langchain4j 1.0.0‑beta20使用 OpenAI 兼容接口DeepSeek / 通义千问 / 硅基流动均可 依赖?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.4/version relativePath/ /parent groupIdcom.example/groupId artifactIdlangchain4j-demo/artifactId version0.0.1‑SNAPSHOT/version properties java.version21/java.version langchain4j.version1.0.0‑beta20/langchain4j.version /properties dependencies !-- springboot webflux 流式必须 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-webflux/artifactId /dependency dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-spring-boot-starter/artifactId version${langchain4j.version}/version /dependency !-- reactor 流式Flux支持 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-reactor/artifactId version${langchain4j.version}/artifactId /dependency !-- easy‑rag 文档加载、切片 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-easy-rag/artifactId version${langchain4j.version}/version /dependency !-- redis 持久化记忆生产使用测试可以不用 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-redis/artifactId version${langchain4j.version}/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis-reactive/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies /projectapplication.ymlspring: application: name: langchain4j-demo redis: host: 127.0.0.1 port: 6379 llm: base-url: https://api.deepseek.com/v1 api-key: sk‑xxx chat-model-name: deepseek-chat embedding-model-name: deepseek‑embedding timeout-seconds: 45配置类 LlmConfig.javapackage com.example.langchain4jdemo.config; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.memory.chat.ChatMemoryProvider; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.model.openai.OpenAiEmbeddingModel; import dev.langchain4j.model.openai.OpenAiStreamingChatModel; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; 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 LlmConfig { Value(${llm.base-url}) private String baseUrl; Value(${llm.api-key}) private String apiKey; Value(${llm.chat-model-name}) private String chatModelName; Value(${llm.embedding-model-name}) private String embeddingModelName; Value(${llm.timeout-seconds}) private int timeoutSeconds; /** 普通对话模型 */ Bean(chatModel) public OpenAiChatModel chatModel() { return OpenAiChatModel.builder() .baseUrl(baseUrl) .apiKey(apiKey) .modelName(chatModelName) .temperature(0.1) .maxTokens(2048) .timeout(Duration.ofSeconds(timeoutSeconds)) .logRequests(false) .logResponses(false) .build(); } /** 流式模型 */ Bean(streamingChatModel) public OpenAiStreamingChatModel streamingChatModel() { return OpenAiStreamingChatModel.builder() .baseUrl(baseUrl) .apiKey(apiKey) .modelName(chatModelName) .temperature(0.1) .maxTokens(2048) .timeout(Duration.ofSeconds(timeoutSeconds)) .logRequests(false) .logResponses(false) .build(); } /** 向量化模型 */ Bean public EmbeddingModel embeddingModel() { return OpenAiEmbeddingModel.builder() .baseUrl(baseUrl) .apiKey(apiKey) .modelName(embeddingModelName) .timeout(Duration.ofSeconds(timeoutSeconds)) .build(); } /** * 向量存储测试用InMemory生产替换为 Milvus/PGVector/RedisEmbeddingStore */ Bean public EmbeddingStoreTextSegment embeddingStore() { return new InMemoryEmbeddingStore(); } /** * 会话记忆提供者按sessionId隔离会话生产替换RedisChatMemoryStore持久化 */ Bean public ChatMemoryProvider chatMemoryProvider() { // 每个会话最多保留10条消息 return memoryId - MessageWindowChatMemory.withMaxMessages(10); } }Tool 工具类 DemoTools.javapackage com.example.langchain4jdemo.tool; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; Component public class DemoTools { /** * tool描述非常重要告诉大模型什么时候调用 */ Tool(用户需要查询订单价格时调用传入订单编号orderId返回订单价格没有订单编号不要调用) public String queryOrderPrice(String orderId) { // 模拟业务查询 if(ORD001.equals(orderId)){ return 订单ORD001价格299元; } return 未找到该订单; } }AiService 接口 AssistantAiService.javapackage com.example.langchain4jdemo.ai; import dev.langchain4j.service.AiServiceWiringMode; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import dev.langchain4j.service.spring.AiService; import reactor.core.publisher.Flux; AiService( wiringMode AiServiceWiringMode.EXPLICIT, chatModel chatModel, streamingChatModel streamingChatModel, chatMemoryProvider chatMemoryProvider, tools {demoTools}, contentRetriever ragContentRetriever ) SystemMessage( 你是企业知识库助手。 1.优先使用知识库检索内容回答用户问题如果知识库没有相关内容如实告知不知道不要编造。 2.需要查询订单的时候调用工具。 3.回答简洁。 ) public interface AssistantAiService { /** * 普通对话memoryId区分会话 */ String chat(UserMessage String userMessage, dev.langchain4j.service.MemoryId String memoryId); /** * 流式对话 */ FluxString streamChat(UserMessage String userMessage, dev.langchain4j.service.MemoryId String memoryId); }RAG 检索器配置 RagConfig.javapackage com.example.langchain4jdemo.config; import dev.langchain4j.data.document.Document; import dev.langchain4j.data.document.DocumentParser; import dev.langchain4j.data.document.DocumentSplitter; import dev.langchain4j.data.document.parser.TextDocumentParser; import dev.langchain4j.data.document.splitter.DocumentSplitters; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.EmbeddingStoreIngestor; import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; import dev.langchain4j.store.embedding.retriever.EmbeddingStoreContentRetriever; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; Configuration public class RagConfig { /** * RAG检索器 */ Bean(ragContentRetriever) public EmbeddingStoreContentRetriever ragContentRetriever( EmbeddingStoreTextSegment embeddingStore, EmbeddingModel embeddingModel ) { return EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) .maxResults(4) .minScore(0.65) .build(); } /** * 初始化加载测试知识库项目启动执行 */ Bean public EmbeddingStoreTextSegment initKnowledgeBase( EmbeddingStoreTextSegment embeddingStore, EmbeddingModel embeddingModel, ResourceLoader resourceLoader ) { // 测试文档resources下 kb.txt Resource resource resourceLoader.getResource(classpath:kb.txt); DocumentParser parser new TextDocumentParser(); Document document; try { document parser.parse(resource.getInputStream()); } catch (Exception e) { // demo模式无文件则构造内存文档 document Document.from( 公司上班时间周一至周五9点‑18点。 公司地址深圳市宝安区某某大厦。 报销规则打车费实报实销单次上限200元。 ); } // 切片中文chunk450重叠60 DocumentSplitter splitter DocumentSplitters.recursive(450,60); EmbeddingStoreIngestor ingestor EmbeddingStoreIngestor.builder() .documentSplitter(splitter) .embeddingModel(embeddingModel) .embeddingStore(embeddingStore) .build(); ingestor.ingest(document); return embeddingStore; } }resources/kb.txt公司上班时间周一至周五9点‑18点。 公司地址深圳市宝安区某某大厦。 报销规则打车费实报实销单次上限200元。 员工年假入职满一年5天年假。Controller AiController.javapackage com.example.langchain4jdemo.controller; import com.example.langchain4jdemo.ai.AssistantAiService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; RestController RequestMapping(/ai) RequiredArgsConstructor public class AiController { private final AssistantAiService assistantAiService; /** * 普通对话 * http://127.0.0.1:8080/ai/chat?msg公司几点上班sessionIds001 */ GetMapping(/chat) public String chat(RequestParam String msg, RequestParam String sessionId){ return assistantAiService.chat(msg, sessionId); } /** * 流式对话 SSE * http://127.0.0.1:8080/ai/stream?msg帮我查ORD001订单价格sessionIds001 */ GetMapping(value /stream, produces text/event-stream;charsetUTF‑8) public FluxString stream(RequestParam String msg, RequestParam String sessionId){ return assistantAiService.streamChat(msg, sessionId); } }启动类 Langchain4jDemoApplication.javapackage com.example.langchain4jdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication public class Langchain4jDemoApplication { public static void main(String[] args) { SpringApplication.run(Langchain4jDemoApplication.class, args); } }测试用例1.RAG 知识库http://127.0.0.1:8080/ai/chat?msg公司报销规则是什么sessionIds0012.Tool 工具调用http://127.0.0.1:8080/ai/chat?msg帮我查ORD001订单价格sessionIds0013. 会话记忆连续提问同一个 sessionId 会记住上下文 4. 流式 SSE 访问/ai/stream生产改造点清单InMemoryEmbeddingStore → 替换 Milvus / PGVector / RedisEmbeddingStoreMessageWindowChatMemory → RedisChatMemoryStore会话持久化logRequests/logResponses 生产关闭调试打开看完整请求报文增加重试机制处理 429 限流、5xx 异常框架无内置重试增加 token 统计做计费监控minScore 阈值根据 embedding 模型实测调整不要依赖 ChatMemory 存储业务对话业务侧额外保存完整对话记录Tool 内部捕获异常返回文本给 LLM不要抛出异常中断流程设置 http 连接池自定义 OkHttpClient如果你需要我可以给你补充Advanced‑RAG查询改写 Rerank 重排序示例代码POJO 结构化输出完整示例Redis 持久化 ChatMemory 完整替换代码大文件 PDF 加载入库代码

最新新闻

日新闻

周新闻

月新闻