news 2026/4/16 14:48:59

基于LLM与SpringBoot的智能客服系统实战:架构设计与性能优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于LLM与SpringBoot的智能客服系统实战:架构设计与性能优化


背景痛点:规则引擎的“硬编码地狱”

去年双十一,公司老客服系统直接“罢工”。
那套基于正则+关键词的“古董”规则引擎,平时还能应付,一到大促就露馅:

  • 运营同学凌晨两点还在加规则,一条“满300减50”的文案要配十几条正则,一不小心就把“满300减0”也匹配进去。
  • 用户问“我买的鞋能换码吗?”和“鞋子码数不合适能换吗?”在系统眼里完全是两句话,得写两条几乎一样的规则。
  • 最惨的是,一旦并发飙到 200 TPS,后端 DSL 引擎就疯狂 GC,CPU 像火箭一样窜到 90%。

一句话:维护成本高、泛化能力差、性能瓶颈明显。于是,我们决定用 LLM 把“人工智障”升级成“人工智能”。

技术选型:为什么 SpringBoot + GPT-3.5 能打

先放对比表,直观感受:

模型意图识别 F1中文支持调用延迟成本/1000 次
GPT-3.5-turbo0.94原生600 ms0.14 $
Claude-30.92需 prompt 中英混写900 ms0.32 $
自研 6B0.86完全中文350 ms2 卡 A100

结论:GPT-3.5 在中文场景下 F1 最高,延迟可接受,成本也低。
框架侧,SpringBoot 3.x 已稳定支持虚拟线程(Project Loom),配合 WebFlux 能做到“异步非阻塞 + 注解式编程”两头甜,比 Vert.x 心智负担低,比 Django 生态更熟,Java 组直接上手。

核心实现:三步搭好骨架

1. 异步入口:Spring WebFlux

@RestController @RequestMapping("/bot") public class ChatController { private final ChatService chatService; public ChatController(ChatService chatService) { this.chatService = chatService; } @PostMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent<String>> chat(@RequestBody ChatRequest req) { return chatService.streamAnswer(req) .map(ans -> ServerSentEvent.builder(ans).build()); } }

全链路 Reactive,Tomcat 线程 0 阻塞,单机压测 TPS 直接翻倍。

2. 对话上下文 DTO

public class ChatContext { private String sessionId; // 会话标识 private Deque<Message> history; // 循环队列,长度=10 private Map<String, Object> slots; // 抽取的实体 private Instant expireAt; // TTL,默认 30 min }
  • 历史记录用ArrayDeque,超过 10 条自动丢最老 的,防止 token 爆炸。
  • 实体槽位存在用Map<String,Object>,后续可对接 NLU 插件。
  • 过期时间存 Redis,利用KeyspaceNotification做自动清理。

3. 带重试的 OpenAI 客户端

/** * 调用 OpenAI ChatCompletion,自带指数退避重试 * 最大重试 3 次,首次延迟 200 ms,最大延迟 2 s */ @Component public class OpenAiClient { private final WebClient webClient = WebClient.builder() .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + System.getenv("OPENAI_KEY")) .build(); public Mono<String> chat(ChatContext ctx) { return webClient .post() .uri("https://api.openai.com/v1/chat/completions") .bodyValue(buildRequest(ctx)) .retrieve() .bodyToMono(OpenAiResponse.class) .map(r -> r.getChoices().get(0).getMessage().getContent()) .retryWhen(Retry.backoff(3, Duration.ofMillis(200)) .maxBackoff(Duration.ofSeconds(2)) .filter(this::isRetryable)); } private boolean isRetryable(Throwable t) { return t instanceof WebClientResponseException && ((WebClientResponseException) t).getStatusCode().is5xxServerError(); } }

小提示:OpenAI 返回 429/500 时别急着重试,先退避,否则容易被限 IP。

性能优化:缓存 + 熔断双保险

1. Caffeine 本地缓存

高频“密码怎么重置?”这类标准 FAQ,命中率高达 68%,直接把 600 ms 的 LLM 调用省掉。

Cache<String, String> cache = Caffeine.newBuilder() .maximumSize(10_000) .expireAfterWrite(1, TimeUnit.HOURS) .build();

2. Hystrix 熔断

LLM 抖动时,fallback 返回静态文案“客服忙,请稍后再试”,保证核心链路不雪崩。

@HystrixCommand(fallbackMethod = "fallbackAnswer") public Mono<String> askLlm(ChatContext ctx) { return openAiClient.chat(ctx); } private Mono<String> fallbackAnswer(ChatContext ctx) { return Mono.just("客服忙,请稍后再试"); }

压测结果:线程池 20 核心,错误率>5% 时 5 s 内自动熔断,恢复时间 10 s。

避坑指南:token、敏感词与合规

1. token 长度限制

GPT-3.5 最大 4096 token,历史记录超长会直接报错。
解决思路:

  • 循环队列只保留最近 10 轮。
  • tiktoken库提前计算,超长就摘要:history.removeFirst()
  • 对返回也做截断,设置max_tokens=1000,留 500 token 给 prompt。

2. 敏感词过滤

用 AOP 拦截入站消息:

@Aspect @Component public class SensitiveFilterAspect { @Around("@annotation(SensitiveCheck)") public Object filter(ProceedingJoinPoint pjp) throws Throwable { String text = (String) pjp.getArgs()[0]; if (SensitiveWordHolder.contains(text)) { throw new BusinessException("输入包含敏感词"); } return pjp.proceed(); } }

敏感词库每日离线更新,Hash 匹配 O(1)。

3. GDPR 合规日志

  • 对话内容写进chat_log表前,先 AES 加密,密钥放 KMS。
  • 提供“一键导出”与“删除”接口,满足用户数据可携带权。
  • 设置 30 天自动匿名化,把sessionId做 SHA-256 哈希,原 ID 丢弃。

验证指标:JMeter 压测一览

测试环境:4C8G Docker 容器,MySQL 8.0,Redis 6.2,并发 500 线程,持续 5 min。

指标平均值95 线99 线错误率
RT (ms)3205807200.3 %
TPS510

CPU 占用 55 %,内存 3.2 G,GC 停顿 < 30 ms。
对比老系统 RT 1100 ms、错误率 3 %,提升肉眼可见。

延伸思考:多模态的下一站

  1. 语音接入:集成阿里一句话识别,把 ASR 文本直接送进现有ChatContext,回答后用 TTS 回读,链路不变。
  2. 图像接入:用户拍商品吊牌,OCR 提取款号 → 查库存 → 返回“有货/缺货”。
  3. 视频客服:WebRTC 推流,LLM 实时生成字幕,辅助人工坐席快速回复。

想象一个场景:用户发语音“我买的这双鞋开胶了”,系统先语音转文字,再意图识别到“质量问题”,自动推送“退换货入口 + 附近门店地图”,全程 3 s 完成——这就是多模态的杀伤力。



写在最后的碎碎念

整套系统上线三个月,已接过 120 万次对话,把人工坐席从 60 人减到 15 人,运营成本降了 70 %。
LLM 不是银弹,但用对了场景,再配好 SpringBoot 的成熟“工具箱”,确实能让老系统“枯木逢春”。
下一步,我们打算把模型换成 GPT-4-turbo,再试试函数调用(Function Calling),让机器人直接帮用户改地址、发优惠券——如果踩到新坑,再来和大家分享。


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

为什么推荐用ms-swift微调Qwen2.5-7B?答案在这里

为什么推荐用ms-swift微调Qwen2.5-7B&#xff1f;答案在这里 1. 这不是又一个“跑通就行”的微调教程 你可能已经试过十几种微调方案&#xff1a;从Hugging Face Transformers原生训练&#xff0c;到PEFTLoRA组合&#xff0c;再到各种自研脚本。但每次打开终端&#xff0c;看…

作者头像 李华
网站建设 2026/4/16 12:57:58

从噪声中寻找信号:毫米波雷达2D-CFAR算法的艺术与科学

从噪声中寻找信号&#xff1a;毫米波雷达2D-CFAR算法的艺术与科学 雷达工程师们每天都在与噪声搏斗。当你驾驶着搭载毫米波雷达的汽车行驶在暴雨中&#xff0c;系统需要从雨滴、飞鸟和路牌反射的杂乱信号中&#xff0c;准确识别出前方突然出现的行人——这就像在重金属音乐会上…

作者头像 李华
网站建设 2026/4/14 21:44:04

亲测BSHM人像抠图镜像,效果惊艳的AI抠图体验分享

亲测BSHM人像抠图镜像&#xff0c;效果惊艳的AI抠图体验分享 1. 这不是绿幕&#xff0c;但比绿幕还省事的人像抠图体验 你有没有过这样的经历&#xff1a;想给一张人像照片换背景&#xff0c;打开PS调出“选择主体”&#xff0c;结果头发丝边缘毛毛躁躁、发丝和背景色混在一起…

作者头像 李华
网站建设 2026/4/16 12:59:21

YOLOv10官方镜像使用避坑指南,少走弯路

YOLOv10官方镜像使用避坑指南&#xff0c;少走弯路 你是不是刚拉取了 YOLOv10 官版镜像&#xff0c;满怀期待地执行 yolo predict&#xff0c;却卡在环境没激活、权重下不动、CUDA报错、TensorRT导出失败&#xff0c;或者——更常见的是&#xff0c;模型跑起来了&#xff0c;但…

作者头像 李华
网站建设 2026/4/16 12:21:11

Unity3D毕设实战:从零构建可扩展的2D游戏架构与性能优化方案

Unity3D毕设实战&#xff1a;从零构建可扩展的2D游戏架构与性能优化方案 适用对象&#xff1a;计算机相关专业、正在做 2D 毕设、想把“能跑”变成“能看又能改”的同学 阅读收益&#xff1a;带走一套可直接套用的 Clean Architecture 模板 性能自检清单&#xff0c;答辩时少被…

作者头像 李华