news 2026/3/30 6:05:50

Spring Boot 整合 LangChain4j 构建智能客服系统:从架构设计到生产实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot 整合 LangChain4j 构建智能客服系统:从架构设计到生产实践


背景与痛点:传统客服系统为什么“跑不动”

过去两年,我帮三家客户做过客服系统升级,总结下来最痛的点有三处:

  1. 响应慢:老系统把 FAQ 做成关键词匹配,用户一句话里只要多一个“的”,就匹配不到答案,平均响应 3-5 秒,高峰期直接 10 秒起步。
  2. 扩展难:规则库用 XML 维护,新增一条问答要重启整个服务;想做多渠道(微信、网页、App)就得复制三套代码。
  3. 无上下文:用户问完“怎么退货”,接着追问“邮费谁出”,系统却当成新问题,体验非常割裂。

要同时解决“语义理解 + 上下文 + 高并发”,继续堆规则已经不现实,引入 LLM 几乎是唯一选择。但 LLM 本身“不可控、不业务、不高性能”,于是 LangChain4j 成了最顺手的“胶水”——它把提示模板、记忆、工具调用、流式输出做成了 Java 工程师能看懂的 DSL,而 Spring Boot 生态又负责把这一切包装成可水平扩展的微服务。

技术选型:LangChain4j 为什么比“裸调”LLM 更香

先给出对比表,方便一眼看懂差异:

方案提示模板多轮记忆工具/插件流式输出Java 友好度学习成本
裸调 OpenAI HTTP自己拼自己存自己写自己解析
LangChain(Python)丰富极低(需 Python)
LangChain4j

结论:团队如果主力是 Java,Spring Boot + LangChain4j 可以把“提示管理、记忆、函数调用”三件事一次性解决,而且 jar 包直接启动,无需额外 Python 服务,运维复杂度直线下降。

核心实现:30 分钟跑通第一个问答接口

下面用 Spring Boot 3.2 + LangChain4j 0.28 做演示,OpenAI 作为 LLM 后端,最终暴露一个 REST 接口/chat,支持多轮会话。

1. 依赖与配置

pom.xml中引入 BOM,避免版本打架:

<dependencyManagement> <dependencies> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-bom</artifactId> <version>0.28.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

核心依赖只选两个:

<!-- LLM 后端 --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> </dependency> <!-- Spring Boot 集成 --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-spring-boot-starter</artifactId> </dependency>

application.yml里把 key 和超时配好:

langchain4j: open-ai: chat-model: api-key: ${OPENAI_API_KEY} model-name: gpt-3.5-turbo timeout: 15s max-tokens: 600

2. 领域 Prompt 模板

客服场景需要“角色 + 边界 + 输出格式”三件套,新建CustomerServicePromptTemplate.java

public class CustomerServicePromptTemplate { public static final String SYSTEM_PROMPT = """ 你是小助手,专门回答电商售后问题。 只能回答退货、退款、邮费、开发票四类问题,其余问题直接回复“抱歉,我帮不上忙”。 回答不超过 80 字,语气亲切。 上下文历史:{{history}} 用户问题:{{question}} """; }

LangChain4j 使用PromptTemplate.from(...)即可把{{}}占位符动态替换。

3. 会话记忆组件

LangChain4j 自带ChatMemory接口,我们用线程安全的MessageMemory实现,每用户一个实例,生命周期 30 分钟:

@Component public class InMemoryChatMemory implements ChatMemory { private final Cache<String, Deque<ChatMessage>> cache = Caffeine.newBuilder() .expireAfterAccess(30, TimeUnit.MINUTES) .build(); @Override public void add(String sessionId, ChatMessage message) { cache.get(sessionId, k -> new ArrayDeque<>()).add(message); } @Override public List<ChatMessage> getMessages(String sessionId) { return List.copyOf(cache.getIfPresent(sessionId)); } }

4. Service 层拼装

@Service public class ChatService { @Resource private OpenAiChatModel chatModel; @Resource private InMemoryChatMemory memory; private final PromptTemplate promptTemplate = PromptTemplate.from(CustomerServicePromptTemplate.SYSTEM_PROMPT); public String chat(String sessionId, String question) { // 1. 取历史 List<ChatMessage> history = memory.getMessages(sessionId); // 2. 渲染提示 Map<String, Object> vars = Map.of("history", history, "question", question); String prompt = promptTemplate.render(vars); // 3. 调 LLM String answer = chatModel.generate(prompt); // 4. 更新记忆 memory.add(sessionId, new UserMessage(question)); memory.add(sessionId, new AiAnswer(answer)); return answer; } }

5. REST 接口

@RestController @RequestMapping("/chat") public class ChatController { @Resource private ChatService chatService; @PostMapping public Map<String, String> chat(@RequestBody ChatRequest req) { String answer = chatService.chat(req.getSessionId(), req.getQuestion()); return Map.of("answer", answer); } }

启动后curl一把即可看到多轮效果:

curl -X POST localhost:8080/chat \ -H "Content-Type: application/json" \ -d '{"sessionId":"u123","question":"如何退货?"}'

性能优化:让 GPT 在 200 ms 内返回

LLM 本身延迟 800 ms 起步,但线上 SLA 要求 500 ms,必须把“能省的都省掉”。下面 4 步实测可把 P99 从 1.2 s 压到 220 ms:

  1. 流式输出 + 前端打字机效果
    generate()换成generateStream(),Spring WebFlux 返回Flux<String>,前端边读边渲染,用户感知延迟降低 50%。
  2. 连接池与 Keep-Alive
    默认OpenAiChatModel每次新建 HTTP 连接,在application.yml里把max-connections调到 200,并开启connection-pool: true,可减少 80 ms TLS 握手。
  3. Prompt 缓存
    对高频问题做本地缓存,Key 用“问题 32 位 MD5”,Value 放“最佳答案”,命中率 38%,直接省掉一次 LLM 调用。
  4. 垂直扩容 → 水平扩容
    单容器 2 vCPU 时,并发 50 QPS CPU 就打满;无状态后直接上 3 副本,K8s HPA 根据 CPU 60% 阈值自动弹到 10 副本,轻松扛 500 QPS。

生产环境避坑指南:我们踩过的 5 个坑

  1. Token 超限
    GPT-3.5 最大 4096 token,对话一长就抛InvalidRequestException。解决:记忆队列长度按 token 计数而非条数,超过 3000 自动摘要旧消息。
  2. 敏感词泄露
    LLM 可能返回“激活码”“内部价”等违规内容。上线前必须加一层“输出过滤器”,用 DFA + 正则双保险,命中直接替换成“***”。
  3. 会话内存泄漏
    早期用ConcurrentHashMap存记忆,30 分钟过期靠ScheduledExecutor,结果大促期间 20 万在线用户把 Map 打满 Old Gen。切到 Caffeine 带权重的expireAfterAccess后,FullGC 次数降到 0。
  4. API Key 轮换
    OpenAI 对并发 QPS 有限流,单 Key 超过 3 次 429 就会封 1 分钟。生产环境用 Vault 存 5 组 Key,客户端侧轮询,保证 429 自动重试下一组。
  5. 多环境混淆
    测试同学曾把压测流量打到生产,导致真用户 503。后来给 LLM 调用加一层EnvironmentHeaderInterceptor,非 prod 环境 header 带x-env=test,网关直接拒掉。

总结与展望:下一步还能怎么玩

把客服机器人跑通只是第一步,LangChain4j 的“函数调用”能力还没完全用上。接下来我们准备做三件事:

  1. 工具链:让 LLM 直接调用内部订单接口,用户说“帮我退掉昨天那单”,机器人自动查到 orderId 并发起退款流。
  2. 多模型:GPT-4 负责“复杂推理”,本地部署的 ChatGLM3-6B 负责“高频简单问答”,用路由层按问题长度 + 意图分流,成本可再降 45%。
  3. 插件市场:把“开发票”“价查询”做成独立插件,运营通过 YAML 上架,系统动态加载,做到“零代码”扩展新业务。

如果你也在用 Java 栈,LangChain4j 基本能让你“不写 Python 也能玩 LLM”。先把问答链路跑通,再逐步加记忆、加工具、加并发,路线很清晰。希望这篇笔记能帮你少踩几个坑,早点下班。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/23 12:24:17

当lsblk遇见容器化:云原生时代的磁盘信息采集新范式

当lsblk遇见容器化&#xff1a;云原生时代的磁盘信息采集新范式 在云原生技术席卷全球的今天&#xff0c;传统基础设施正经历着前所未有的变革。Kubernetes和Docker等容器技术的普及&#xff0c;让"不可变基础设施"从理论走向实践&#xff0c;同时也对底层资源监控提…

作者头像 李华
网站建设 2026/3/25 17:41:13

Google学术搜索实验室:AI驱动的跨学科文献探索新范式

1. Google学术搜索实验室的AI革命 第一次用Google学术搜索实验室时&#xff0c;我正为嵌入式系统课程设计发愁。以往查文献要反复调整关键词&#xff0c;这次我直接输入"find papers from the past 2 years about llm used in embedded system"&#xff0c;结果让我惊…

作者头像 李华
网站建设 2026/3/19 6:40:07

Dify工作流响应延迟骤降70%:揭秘YAML编排+缓存预热双引擎优化方案

第一章&#xff1a;Dify工作流响应延迟骤降70%&#xff1a;揭秘YAML编排缓存预热双引擎优化方案在高并发场景下&#xff0c;Dify平台默认工作流执行常因重复解析、动态加载和冷启动导致平均响应延迟达1.8s。我们通过深度剖析其执行链路&#xff0c;定位到两个关键瓶颈&#xff…

作者头像 李华
网站建设 2026/3/27 17:29:01

SpringBoot+Vue校园社团管理平台:从零搭建到功能实现

1. 项目背景与技术选型 校园社团管理一直是高校学生工作中的重要环节&#xff0c;但传统的手工管理方式效率低下、信息不透明。我去年帮本地一所大学开发社团管理系统时&#xff0c;亲眼见过他们还在用Excel表格登记社团成员&#xff0c;活动通知要靠微信群转发&#xff0c;经常…

作者头像 李华