2. LangChain Chat API 进阶

📅 发布时间:2026/8/31 5:12:11
2. LangChain Chat API 进阶
LangChain4j Chat API 进阶 - 手把手带你理解每个细节前言本文完全基于实际项目代码讲解从最简单的hello world到进阶配置每一步都解释为什么要这样写。即使你是第一次接触 Spring Boot 和 AI也能看懂学会。适合所有想快速上手的 Java 开发者。一、整体概览我们做了哪几件事通过两个小项目逐步掌握 LangChain4j 的 Chat API项目 1langchain4j-02-chatapi基础对话目标用两种方式调用大模型方式一直接调用 ChatModel底层 API方式二通过 ChatAssistant 接口高级代理模式项目 2langchain4j-03-chatapi-config进阶配置目标学习如何给 ChatModel 添加调试功能日志、监听器、超时控制等二、项目 1基础对话实现2.1 pom.xml —— 引入必要的依赖?xml version1.0 encodingUTF-8?projectxmlnshttp://maven.apache.org/POM/4.0.0modelVersion4.0.0/modelVersionparentgroupIdcom.study.ai/groupIdartifactIdstudy-ai/artifactIdversion1.0-SNAPSHOT/version/parentartifactIdlangchain4j-02-chatapi/artifactIdnamelangchain4j-02-chatapi/namedependencies!-- spring-boot-starterSpring 容器 IoC 容器负责管理 Bean --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependency!-- langchain4jLangChain4j 核心库提供基础能力 --dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j/artifactId/dependency!-- langchain4j-open-ai适配器用于连接 OpenAI 或兼容协议的 API如阿里云百炼 --dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j-open-ai/artifactId/dependency!-- spring-boot-starter-test用于写单元测试 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependencies/project为什么需要这些依赖依赖作用类比说明spring-boot-starter创建 Spring 容器管理所有对象Bean就像盖房子需要水泥钢筋这里是程序运行的大环境langchain4j核心框架提供对话管理、流程控制等能力相当于手机操作系统Android/iOSlangchain4j-open-ai适配器把不同大模型翻译成统一协议好比转接头让不同品牌的充电线都能充你的设备spring-boot-starter-test写测试代码的能力像质检员确保功能正常运行小贴士没有指定版本号时由父 POM 中的langchain4j-bom统一管理版本避免冲突。2.2 application.yml —— 告诉程序用什么大模型langchain4j:open-ai:chat-model:api-key:******# 【脱敏前】你的密钥model-name:qwen3.8-max# 选择通义千问大模型base-url:https://llm-k1s2eoitgcuz7t2g.cn-beijing.maas.aliyuncs.com/compatible-mode/v1# 阿里云百炼接口地址字段解释参数含义为什么需要它api-key身份验证码证明你是合法用户类似网站的登录密码model-name模型名称指定用哪个大脑Qwen3.8-Max / Qwen-Plus 等base-urlAPI 地址告诉程序去哪里找服务类似 QQ 账号登录服务器地址⚠️注意实际提交代码到 Git 时记得把api-key替换成******或使用环境变量2.3 Application.java —— 程序的入口packagecom.study.ai;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication// 标记这是一个 Spring Boot 启动类publicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);// 启动程序}}这行代码是干嘛的SpringBootApplication组合注解相当于声明“我是主程序从这里开始跑”SpringApplication.run()真正启动 Spring 容器加载配置文件创建 Bean类比就像按手机的开机键屏幕亮了才能操作其他功能。2.4 ChatConfig.java —— 自定义 Bean 工厂packagecom.study.ai.config;importcom.study.ai.service.ChatAssistant;importdev.langchain4j.model.chat.ChatModel;importdev.langchain4j.model.openai.OpenAiChatModel;importdev.langchain4j.service.AiServices;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * 配置 ChatModel */Configuration// 1. 标记这是一个配置类publicclassChatConfig{Value(${langchain4j.open-ai.chat-model.api-key})// 2. 从 yml 读取 api-keyprivateStringapiKey;Value(${langchain4j.open-ai.chat-model.model-name})// 3. 从 yml 读取模型名privateStringmodelName;Value(${langchain4j.open-ai.chat-model.base-url})// 4. 从 yml 读取接口地址privateStringbaseUrl;/** * 5. 创建 ChatModel Bean注册到 Spring 容器中 */BeanpublicChatModelchatModel(){returnOpenAiChatModel.builder().apiKey(apiKey)// 填入密钥.modelName(modelName)// 填入模型名.baseUrl(baseUrl)// 填入接口地址.build();// 构建并返回}/** * 6. 创建 ChatAssistant Bean使用 AiServices 代理模式 */BeanpublicChatAssistantchatAssistant(ChatModelchatModel){returnAiServices.create(ChatAssistant.class,chatModel);}}每段代码的作用①Configuration告诉 Spring“这是一个配置类里面有要创建的 Bean”没有这个注解后面的Bean不会被扫描到②Value注解读取 yml 配置Value(${...})从配置文件动态取值方便修改而不改代码比如你想换 API Key只需要改 yml不用重新编译③Bean方法创建对象方法返回值自动注册到 Spring 容器其他地方可以Autowired注入使用就像你创建一个玩具然后放到儿童乐园里其他小朋友都可以玩④OpenAiChatModel.builder()构建器模式先设置参数.apiKey().modelName()等最后.build()生成实例好处是可以链式调用一行代码写完复杂对象的创建过程⑤AiServices.create()创建 AI 助手代理把一个普通 Java 接口包装成能跟 AI 对话的对象以后调用chatAssistant.chat(你好)就像发微信消息一样简单2.5 ChatAssistant.java —— AI 助手的名片packagecom.study.ai.service;/** * AI 助手接口 */publicinterfaceChatAssistant{Stringchat(StringuserMessage);// 定义一个方法接收输入返回 AI 的回答}为什么是个空接口这是JDK 动态代理的特性只要有接口和实现逻辑Spring 会自动为你生成实现类chat()方法的参数String userMessage就是你要问 AI 的问题返回值String就是 AI 给你的回答不需要手写实现AiServices.create()已经帮你生成了✅类比就像点外卖 APP你点击下单按钮后系统自动处理接单、配送你不用管骑手是谁。2.6 ApplicationTests.java —— 写测试验证功能packagecom.study.ai;importcom.study.ai.service.ChatAssistant;importdev.langchain4j.model.chat.ChatModel;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;SpringBootTest// 1. 启动完整 Spring 上下文classApplicationTests{Autowired// 2. 自动注入 Spring 容器中的 BeanprivateChatModelchatModel;AutowiredprivateChatAssistantchatAssistant;/** * 3. 测试直接使用 ChatModel 的方式 */Testvoidchat(){StringchatchatModel.chat(我正在学习 AI这是我的第一个 LangChain API 程序);System.out.println(chat);}/** * 4. 测试通过 ChatAssistant 接口的方式 */TestvoidchatAssistant(){StringchatchatAssistant.chat(这是通过 AiServices 代理实现的对话);System.out.println(chat);}}这段代码在做什么SpringBootTest模拟真实运行环境加载全部配置Autowired从 Spring 容器中取出已经创建的 BeanchatModel底层 API手动调用chatAssistant高级代理更简洁TestJUnit 5 的测试注解表示这是一个测试方法两种方式的对比方式优点缺点适用场景chatModel.chat()更接近底层灵活度高每次都要调用.chat()需要精细控制时chatAssistant.chat()代码整洁类似调用本地方法封装程度高不易扩展日常开发首选2.7 运行结果预期在 IDEA 中右键运行测试你会看到控制台输出Hello! 我是 Qwen3.8-Max很高兴认识你 听到你在初学 AI还写了自己的第一个 LangChain API 程序真的太棒了 给你点个赞✨ 如果你有任何问题或者想要交流一下经验随时告诉我哦 祝你学习顺利加油冲鸭三、项目 2进阶配置详解3.1 pom.xml —— 增加了 Lombok 依赖!-- lombok自动生成 getter/setter/toString 等方法 --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdscopecompile/scope/dependencyLombok 是干什么的以前写 POJO 类要手敲 getter/setter/toString现在加上Data注解自动生成虽然本案例没用到但是推荐学习能减少大量重复代码3.2 application.yml —— 开启日志和错误监控langchain4j:open-ai:chat-model:api-key:******# 同上model-name:qwen3.8-maxbase-url:https://llm-k1s2eoitgcuz7t2g.cn-beijing.maas.aliyuncs.com/compatible-mode/v1logging:level:root:debug# 关键将日志级别设为 debug才能看到请求/响应内容为什么日志要设为debug默认是info级别只打印重要信息设置为debug后能看到详细的 HTTP 请求参数、API 响应结果必须配合日志框架一起看否则看不到效果3.3 ChatConfig.java —— 增强版配置packagecom.study.ai.config;importcom.study.ai.listener.MyChatModelListener;importcom.study.ai.service.ChatAssistant;importdev.langchain4j.model.chat.ChatModel;importdev.langchain4j.model.openai.OpenAiChatModel;importdev.langchain4j.service.AiServices;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.time.Duration;importjava.util.Collections;ConfigurationpublicclassChatConfig{Value(${langchain4j.open-ai.chat-model.api-key})privateStringapiKey;Value(${langchain4j.open-ai.chat-model.model-name})privateStringmodelName;Value(${langchain4j.open-ai.chat-model.base-url})privateStringbaseUrl;BeanpublicChatModelchatModel(){returnOpenAiChatModel.builder().apiKey(apiKey).modelName(modelName).baseUrl(baseUrl)// 新增配置项.logRequests(true)// 打印请求参数需要在 yml 中设置 logging.level.rootdebug.logResponses(true)// 打印响应结果.listeners(Collections.singletonList(newMyChatModelListener()))// 自定义监听器.maxRetries(1)// 最大重试次数 1 次默认重试 2 次总共请求 3 次.timeout(Duration.ofSeconds(10))// 超时时间 10 秒.build();}BeanpublicChatAssistantchatAssistant(ChatModelchatModel){returnAiServices.create(ChatAssistant.class,chatModel);}}每项参数的含义①.logRequests(true)和.logResponses(true)作用打印发送到 API 的参数和收到的回答原理借助 SLF4J 日志框架在 debug 级别下输出用途调试、排查问题、理解数据格式②.listeners(...)自定义监听器作用拦截请求/响应的全过程做额外处理如记录日志、统计耗时设计思想责任链模式多个监听器可以串联工作示例后面会详细讲解MyChatModelListener③.maxRetries(1)失败重试默认行为网络波动导致失败时自动重试 2 次共尝试 3 次改成 1只在第一次失败后重试 1 次共尝试 2 次为什么避免长时间卡住等待适合测试阶段④.timeout(Duration.ofSeconds(10))超时控制默认值60 秒如果 AI 处理太慢就取消改成 10 秒快速失败适合调试生产环境建议调大如 5 分钟RAG 场景因为要查向量数据库通常设置 5 分钟3.4 MyChatModelListener.java —— 监听器详解packagecom.study.ai.listener;importdev.langchain4j.model.chat.listener.ChatModelErrorContext;importdev.langchain4j.model.chat.listener.ChatModelListener;importdev.langchain4j.model.chat.listener.ChatModelRequestContext;importdev.langchain4j.model.chat.listener.ChatModelResponseContext;importlombok.extern.slf4j.Slf4j;Slf4j// 1. 自动生成 loggerpublicclassMyChatModelListenerimplementsChatModelListener{/** * 2. 请求前回调 */OverridepublicvoidonRequest(ChatModelRequestContextrequestContext){requestContext.attributes().put(tmp,临时变量);// 放入上下文数据log.info(请求内容{},requestContext.toString());// 打印请求详情}/** * 3. 响应后回调 */OverridepublicvoidonResponse(ChatModelResponseContextresponseContext){log.info(提取 tmp 内容{},responseContext.attributes().get(tmp));// 取出上下文数据log.info(响应内容{},responseContext.toString());// 打印响应详情}/** * 4. 异常时回调 */OverridepublicvoidonError(ChatModelErrorContexterrorContext){log.error(异常信息{},errorContext.toString());// 打印错误堆栈}}监听器的三大方法①onRequest()—— 请求发送前触发时机在向 API 发送数据之前能做什么修改请求参数不常用记录请求时间戳放入临时数据供后续使用如attributes.put(tmp, ...)②onResponse()—— 成功响应后触发时机收到 AI 的回答之后能做什么打印完整的响应 JSON提取响应中的 token 数量用于计费记录响应时长性能分析取出之前放入的临时数据③onError()—— 发生异常时触发时机网络中断、API 报错、超时等情况能做什么记录详细错误日志触发告警通知企业级应用收集错误上下文便于定位问题为什么需要监听器场景作用调试实时查看请求/响应的完整结构监控记录每次对话的耗时、token 消耗容错捕获异常并做友好提示而不是直接崩溃审计保存所有对话记录用于复盘或合规检查3.5 测试代码对比SpringBootTestclassApplicationTests{AutowiredprivateChatModelchatModel;AutowiredprivateChatAssistantchatAssistant;Testvoidchat(){StringchatchatModel.chat(我正在学习 AI这是我的第一个 LangChain API 程序);System.out.println(chat);}TestvoidchatAssistant(){StringchatchatAssistant.chat(这是通过 AiServices 代理实现的对话);System.out.println(chat);}}这两个项目使用的测试代码相同只是ChatConfig.java 的配置不同所以输出日志也不同。运行后会发现项目 1只有普通的输出项目 2多了大量 debug 日志包括请求参数、响应内容、异常信息等四、常见问题解答FAQQ1为什么需要写这么多类不能直接在 main() 里调用吗A可以但不好维护。使用 Spring 的好处是集中管理配置yml 文件改一处全局生效依赖注入不需要到处 new交给 Spring 管理可扩展性强随时替换 ChatModel 实现如从 OpenAI 换成 AnthropicQ2什么是 Bean我什么时候该用 BeanABean Spring 管理的对象。当你遇到下面情况时要用Bean第三方库的对象如这里 ChatModel没法直接改它的代码加注解需要根据配置文件动态创建对象想要控制 Bean 的初始化和销毁逻辑Q3为什么有的地方用Value有的直接传参给构造函数AValue读取简单配置字符串、数字构造函数注入适用于复杂对象或需要类型安全的场景Q4日志怎么才可以看到A满足两个条件application.yml中设置logging.level.rootdebugIDE 控制台显示 Logback 输出默认已开启Q5MaxRetries1 到底是什么意思A假设网络有问题AI 第一次调用失败默认maxRetries2→ 重试 2 次第 1 次 第 2 次 第 3 次 共 3 次尝试设置maxRetries1→ 只重试 1 次第 1 次 第 2 次 共 2 次尝试五、总结与下一步通过这篇博客你现在应该能够✅ 理解 LangChain4j Chat API 的核心组件✅ 知道为什么需要写这些类每个 Bean 的作用是什么✅ 掌握如何通过配置开启日志、重试、超时等功能✅ 学会写监听器来监控 AI 的请求和响应接下来你可以尝试流式输出让 AI 像打字机一样逐字输出答案多轮对话记住历史聊天内容实现智能客服RAG 知识库上传自己的文档让 AI 基于资料回答问题工具调用让 AI 自主调用订单查询、天气查询等外部接口六、参考资料LangChain4j 官方文档学习来源JavaAI pig4cloud 中文文档感谢大佬的学习资料大家一起进步我的项目源码本文档基于实际项目实战编写所有代码均已测试通过。作者8 年 Java 开发者自学转型 AI Agent不走 PythonLangGraph 路线专注 Java/Spring AI LangChain4j 技术栈。如有问题欢迎讨论交流