新闻详情

新闻详情

首页 / 资讯中心 / 详情

【AI全栈后端12-03】Spring Boot 用多模型路由把智能客服成本降下来

发布时间:2026/9/30 9:43:32来源:尧图网络
【AI全栈后端12-03】Spring Boot 用多模型路由把智能客服成本降下来
本文是「Spring Boot AI 全栈后端」系列第 03 篇。第 02 篇跑通了 AI 对话接口这一篇解决上线后最现实的问题账单。示例基于 Spring AI 2.0 / Boot 4.1。让财务皱眉的场景真是巧了给做客服系统的团队做方案评审几乎每家都踩过同一个坑接口接上了查物流、问营业时间、退换货政策本以为省了人力月底账单却傻了眼——占比 80% 以上的「几点下班」「快递到哪了」这类简单问题和真正的投诉、理赔走的是同一张账单因为代码里写死了一个最贵的旗舰模型。它按 token 计费、单价是轻量档好几倍简单问题「高射炮打蚊子」钱就这么悄悄烧没了。问题很具体不是模型不行是没分档——问题全喂给最贵的。解决思路就一条Spring AI 把模型抽象成ChatModel一套接口挂多个实例便宜轻量 强旗舰再写路由策略挑档。业务只认抽象简单问题走轻量档、复杂风险才上旗舰成本立降。V哥 的建议是这一步别等账单爆了才做接口一上线就把路由留出来。先算一笔账看看能省多少别凭感觉先拿数字说话。假设日均 1 万条客服问答八成是简单问题单条输入输出合计约 800 token旗舰档单价约为轻量档的 6 倍各家的公开单价不一样你按自己的签约价代入即可方案旗舰调用轻量调用相对成本全部走旗舰10 000 条0 条100%全部走轻量0 条10 000 条约 17%按复杂度路由2 000 条8 000 条约 33%结论很清楚路由方案用两成的旗舰调用拿到了接近全轻量的成本还保住了复杂问题的回答质量。全切轻量倒是便宜但客户来投诉理赔的时候给它一个敷衍的答案省下的钱还不够赔一次客诉。这张表还有个隐藏价值它是你和领导谈预算时的抓手——省钱要能被算出来方案才立得住。第一步把分档抽象成策略别把if (question.contains(退款))散落在业务代码里。先抽象出档位和策略两个概念publicenumModelTier{LITE,FLAGSHIP}publicinterfaceRoutingStrategy{ModelTierroute(Stringquestion);}最朴素的关键词命中高风险词走旗舰其余轻量ComponentpublicclassKeywordRoutingStrategyimplementsRoutingStrategy{privatestaticfinalSetStringCOMPLEX_MARKERSSet.of(退款,投诉,纠纷,赔偿,违约金,起诉,仲裁);OverridepublicModelTierroute(Stringquestion){if(questionnull||question.isBlank()){returnModelTier.LITE;}for(Stringmarker:COMPLEX_MARKERS){if(question.contains(marker)){returnModelTier.FLAGSHIP;}}returnModelTier.LITE;}}三种路由策略怎么选关键词只是起点。V哥 把常见做法列成一张表你按团队阶段挑策略怎么判断优点代价适合阶段关键词/规则命中高风险词、超长文本、带附件就上旗舰零成本、可解释、出问题能立刻定位覆盖不全新词得人工补刚上线先把八成的钱省下来规则 打分关键词、长度、用户等级各占权重过阈值上旗舰比纯规则平滑误判少阈值要调得有人盯数据跑了一两个月有历史数据小模型分类器先让轻量模型判断这个问题难不难再决定档位覆盖率高能识别没见过的问题多一次调用多一份延迟和成本量大、且前两种已榨干收益无论选哪种RoutingStrategy这个接口都不用改——换策略是换实现类不是改业务代码。这就是为什么第一步要先抽象今天用关键词明天换分类器CustomerRouterService一个字都不用动。第二步按档选模型顺手把降级和计数做了服务用Qualifier注入两档ChatModel先选档再调用。这里多了两件上线必备的事——降级和计数ServicepublicclassCustomerRouterService{privatefinalChatModelflagship;privatefinalChatModellite;privatefinalRoutingStrategystrategy;/** 分档调用计数最小可观测实现生产里换成 Micrometer 埋点或落库报表。 */privatefinalMapModelTier,AtomicLongusagenewEnumMap(ModelTier.class);publicCustomerRouterService(Qualifier(flagship)ChatModelflagship,Qualifier(lite)ChatModellite,RoutingStrategystrategy){this.flagshipflagship;this.litelite;this.strategystrategy;}publicCsReplyanswer(Stringquestion){ModelTiertierstrategy.route(question);booleandegradedfalse;Stringtext;try{textcall(tierModelTier.FLAGSHIP?flagship:lite,question);}catch(RuntimeExceptionex){if(tier!ModelTier.FLAGSHIP){// 轻量档都挂了说明模型服务整体不可用交给全局异常返回 503throwex;}tierModelTier.LITE;degradedtrue;textcall(lite,question);}usage.computeIfAbsent(tier,k-newAtomicLong()).incrementAndGet();returnnewCsReply(question,text,tier.name(),degraded);}/** 某个档位累计被调用了多少次省没省钱得有数才算数。 */publiclongusageOf(ModelTiertier){AtomicLongcounterusage.get(tier);returncounternull?0L:counter.get();}privateStringcall(ChatModelmodel,Stringquestion){returnmodel.call(newPrompt(newUserMessage(question))).getResult().getOutput().getText();}}为什么要降级路由之后有个新问题旗舰档比轻量档慢、也更容易被限流。一个来投诉的用户本来就憋着火再让他等三十秒最后弹个 503这单客诉基本就定了。上面的catch干的事很朴素——旗舰档失败就退到轻量档宁可答得简单点也别让用户干等。同时把degraded标成true带回响应方便你单独统计和告警降级次数突然涨了说明旗舰档或它的上游出问题了这是要人盯的信号不是可以默默吞掉的异常。注意那个if (tier ! ModelTier.FLAGSHIP) throw ex;轻量档自己都挂了说明是模型服务整体不可用这时降级没有意义直接抛出去让全局异常处理返回 503 才是正解。为什么要计数tier和usageOf()加起来就是成本可观测的最小闭环。有了它你能回答三个此前答不上来的问题这个月旗舰档被调用了多少次占比多少昨天调了关键词表之后旗舰占比降了没有降级发生了几次集中在哪个时段V哥 见过太多团队上了路由就以为省钱了问省了多少答不上来。没有埋点的优化等于没优化——因为你既证明不了收益也发现不了回退。第三步接上接口控制器只收请求做校验RestControllerRequestMapping(/api/cs)publicclassCsController{privatefinalCustomerRouterServicerouterService;publicCsController(CustomerRouterServicerouterService){this.routerServicerouterService;}PostMappingpublicCsReplyask(RequestBodyValidCsAskRequestrequest){returnrouterService.answer(request.question());}}publicrecordCsAskRequest(NotBlank(message问题不能为空)Stringquestion){}publicrecordCsReply(Stringquestion,Stringanswer,Stringtier,booleandegraded){}CsReply里的两个字段各有分工tier告诉前端这次是轻量档答的前端可选择性标注degraded是给运维看的告警信号。V哥 建议这两个字段不要藏着直接进日志和监控——它们是这套路由系统唯一的自我证明。第四步配置里挂两档模型真正的「分档」在配置用同一 OpenAI 客户端包出两档ChatModel靠app.chat.provideropenai开关测试默认不加载ConfigurationConditionalOnProperty(nameapp.chat.provider,havingValueopenai)publicclassChatModelsConfig{BeanQualifier(flagship)publicChatModelflagshipModel(OpenAIClientopenAIClient){OpenAiChatOptionsoptionsOpenAiChatOptions.builder().model(gpt-4o).build();returnOpenAiChatModel.builder().openAiClient(openAIClient).options(options).build();}BeanQualifier(lite)publicChatModelliteModel(OpenAIClientopenAIClient){OpenAiChatOptionsoptionsOpenAiChatOptions.builder().model(gpt-4o-mini).build();returnOpenAiChatModel.builder().openAiClient(openAIClient).options(options).build();}}配置与代码分离正是「配置切换不动业务」轻量档明天换国产模型只改这个类。你的CustomerRouterService、CsController、RoutingStrategy全都不知情也不需要知情。怎么验证路由逻辑不需要真去调模型用两个桩模型轻量/旗舰回复里带不同标记就能验证问「几点下班」→ 命中tier LITE问带退款、投诉、赔偿的问题 → 命中tier FLAGSHIP问题为空 → 400 校验拦截。再给旗舰桩加一点脾气——让它在遇到特定问题时抛异常就能验证降级链路原本该走旗舰的投诉问题在旗舰失败后应该返回tier LITE、degraded true且答案来自轻量档。最后连问几次简单问题断言usageOf(LITE)正好递增了对应次数。整个过程不需要真实密钥也不依赖网络。落地要点策略可替换关键词只是入门线上用小模型做复杂度分类或按意图、长度加权即可接口不变。默认便宜档拿不准就默认LITE别让每句话都烧旗舰的钱。降级要留痕degraded进日志、进监控别让降级悄悄发生。成本要出报表usageOf()的计数定期落到报表里不然省了多少永远是一句口头承诺。关键词表外置把COMPLEX_MARKERS挪到配置中心运营同学发现新类型的客诉时能自己加词不用走一次发版。V哥 的提醒别一上来就搞「智能路由」先用关键词把八成的省钱拿到手再用数据决定要不要上分类器——省钱这件事见效快的方案先落地。最后一句别再让每句「在吗」都烧旗舰模型的钱——接上多模型路由简单问题交给便宜档复杂问题留给旗舰失败还能自动降级成本这道坎几行配置就跨过去。下一篇04V哥 带你解决另一种「看得见却用不了」的尴尬让模型按你定义的字段输出把简历解析结果直接落库。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

旋转电磁铁控场系统|动态旋转磁场实验解决方案 2026/9/30 11:04:59

旋转电磁铁控场系统|动态旋转磁场实验解决方案

在磁性材料各向异性测试、动态旋转磁场模拟、磁器件角度性能标定、磁场姿态仿真等科研场景中,固定磁场设备已无法满足多角度、动态旋转、连续可调的实验需求。高精度旋转电磁铁控场系统集成卧式磁场发生单元、精密电动旋转平台、高稳直流励磁电源与高精度磁场采集模…

阅读更多 →
ScrapeGraphAI 的 models_tokens 模块全解析:跨 Provider 模型 Token 上限字典与分片机制 2026/9/30 11:04:59

ScrapeGraphAI 的 models_tokens 模块全解析:跨 Provider 模型 Token 上限字典与分片机制

网页爬虫人工智能AI 应用 【免费下载链接】Scrapegraph-ai Python scraper based on AI 项目地址: https://gitcode.com/GitHub_Trending/sc/Scrapegraph-ai 点击查看 免费下载 导读 ScrapeGraphAI 是面向 AI 的 Python 抓取框架,其核心能力之一是根据…

阅读更多 →
Docker Compose 一键部署 Redis + Redis-Commander 可视化管理工具 2026/9/30 11:04:59

Docker Compose 一键部署 Redis + Redis-Commander 可视化管理工具

Docker Compose 部署 Redis6.2 Redis‑Commander 可视化管理【redis有密码】-CSDN博客 一、方案简介 本文提供一套完整 docker-compose-redis.yml 编排文件,可一次性启动 Redis 6.2 服务与 Redis Commander 可视化管理面板,具备容器自重启、健康检查、…

阅读更多 →
Switch 上的 wiliwili 安装与上手指南:15 分钟看番刷 B 站 2026/9/30 11:04:59

Switch 上的 wiliwili 安装与上手指南:15 分钟看番刷 B 站

Switch 上的 wiliwili 安装与上手指南:15 分钟看番刷 B 站 【免费下载链接】wiliwili 第三方B站客户端,目前可以运行在PC全平台、PSVita、PS4 、Xbox 和 Nintendo Switch上 项目地址: https://gitcode.com/GitHub_Trending/wi/wiliwili 周五晚上 …

阅读更多 →
Word中文文档批量去多余空格:从查找到VBA宏的完整解决方案 2026/9/30 11:04:59

Word中文文档批量去多余空格:从查找到VBA宏的完整解决方案

做文档处理这些年,我遇到最多的一个问题就是:别人发来的 Word 中文文档,里面总有一堆莫名其妙的多余空格。这些空格有的在段首、有的在段尾、有的夹在汉字之间,看起来像一个个小洞,删起来极其烦人。尤其是几十页标书、…

阅读更多 →
Handy 0.9.7 快捷键行为升级:Auto(Hold or Toggle)模式完整解析 2026/9/30 11:04:52

Handy 0.9.7 快捷键行为升级:Auto(Hold or Toggle)模式完整解析

桌面应用语音音频AI 应用本地部署 【免费下载链接】Handy A free, open source, and extensible speech-to-text application that works completely offline. 项目地址: https://gitcode.com/GitHub_Trending/handy11/Handy 点击查看 免费下载 Handy 0.9.7 为转录…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉