资讯详情

基于大模型的智能客服对话代理系统搭建与调优实践

📅 2026/10/22 8:15:12 | 华诺云谱 👁 阅读
基于大模型的智能客服对话代理系统搭建与调优实践
智能客服这块过去半年我几乎把所有的业余时间都砸进去了。做的项目不是别的就是标题里写的这个基于大型语言模型的智能客服对话代理系统。背景是某零售平台的售后咨询场景用户进来会问物流、查订单、问退换货政策也会抱怨、吐槽、反复追问。团队最开始的想法很简单——“接个大模型API把问题扔进去不就行了”后来被现实教育得很彻底客服场景和通用聊天是完全不同的物种模型自由发挥的每一句话都可能变成售后成本。这篇内容把我从方案设计到落地调优的过程完整整理出来重点讲清楚意图识别、知识检索、工具调用、记忆管理这几大块是怎么串起来的以及上线后踩过的坑和处理思路希望能帮正在做同类系统的朋友少走几个月的弯路。1. 为什么不能只靠“套壳大模型”1.1 客服场景和通用聊天差在哪很多人低估了“客服”这两个字的重量。通用聊天模型可以天马行空用户问“什么是爱情”它怎么诗意都行。但客服系统一句话都不能乱说说错了退货流程用户多跑一趟快递说错了优惠叠加规则结算时对不上账投诉直接升级。我把客服对话的约束条件总结成四个准确性优先级高于流畅性。话术可以生硬但事实必须正确。答案必须可追溯。用户质疑“你们是不是乱说”的时候系统要能指出依据来自哪份文档、哪个条款。权限隔离。订单信息、会员信息属于具体用户模型绝对不能把A用户的数据回答给B用户。单次交互成本有红线。客服流量是海量的一次回复如果烧掉太多token整个项目在成本上就立不住。这四个约束决定了一件事大模型在系统里只能是“大脑的一部分”而不是“大脑本身”。业务规则、知识来源、操作权限这些必须放在模型外部的代码和流程里由系统来兜底和约束。1.2 把系统定位成“路由 组装 执行”的代理这个项目里的核心设计思路是把对话代理当作一个控制器而不是一个生成器。它要做的事情不是“想出一句话回复用户”而是“根据用户问题做出一系列决策”。我最后落地的系统结构大致分四层层级职责关键组件理解层识别意图、抽取实体、判断情绪大模型 提示词约束 结构化输出决策层决定走知识检索、工具调用还是直接回复路由策略 上下文记忆存储执行层调用订单接口、物流接口、检索知识库工具网关 向量检索服务生成层基于检索结果或工具执行结果组装最终话术大模型生成 引用校验模型处于理解层和生成层决策和执行则掌握在代码手里。这样设计的直接好处是问题可定位用户被乱回复了要么是理解层识别错了要么是检索层没召回要么是工具层数据没传对而不是一句“模型太笨”把所有责任都盖住。1.3 技术选型时我做的取舍基座模型是生成质量的基石。我们对比了商用大模型API和开源基座模型最后选了商用API扛生成环节原因很直白客服回复质量对中文表达和业务理解要求高商用API在复杂指令跟随上的表现稳定调试周期短。开源模型我们也试过微调和推理优化需要投入大量时间项目节奏不允许。知识库的向量检索用了开源向量库部署原因就两条数据不出一跳网络安全可控查询成本按自己的机器算不像第三方服务每调一次都要按量付费。会话状态用内存态KV存储TTL设成24小时用户当天进来能接着聊第二天重新开始。服务侧用异步网关做并发控制避免大模型推理接口被瞬时流量打满。选型的原则总结成一句话能先在代码里解决的不要指望模型自己懂能用缓存和规则挡住的流量不要全部堆给大模型。2. 意图识别与任务路由第一关是分清用户“要什么”2.1 意图体系设计宁粗不细分类别太碎开始设计意图体系的时候我把意图拆得很细物流咨询、订单状态、退换货政策、商品规格、优惠券使用、发票问题……结果上线测试直接翻车。用户说话的方式千奇百怪“东西怎么还没到”和“请问我的包裹在哪儿”表面上是两类问题实际都指向物流查询。细粒度分类导致大量误判因为模型在“这个意图和那个意图之间”反复横跳概率差距只有零点几。后来我把体系简化成五类反而准确率上去了知识咨询问规则、问政策、问商品信息。任务办理查订单、查物流、申请退款等需要调用系统的行为。闲聊互动情感表达、打招呼、无关内容。人工服务用户明确表示要转人工、投诉、表达强烈不满。其他/拒答无法识别或不属于客服服务范围的场景。这个设计背后有逻辑客服场景里模型其实不需要精确知道“优惠券叠加规则”和“满减活动细则”有什么区别只要识别出是“知识咨询”然后交给检索系统去处理就够了。真正的细粒度区分发生在检索阶段的文本匹配里而不是在模型分类里。意图层只负责方向不负责细节。2.2 让模型输出结构化指令而不是自然语言意图识别不能直接让模型“自由发挥”否则后面接的不是代码是噩梦。我在提示词里要求模型每次返回固定结构的JSON包含意图类别、关键实体、缺失信息、置信度。一个典型的结构化输出是这样{ intent: task, task_type: logistics_query, entities: { order_id: 20250630XXXXXX }, missing_params: [], confidence: 0.92 }如果用户只说“我的包裹还没到”系统可能提取不到订单号那么missing_params里就会列出order_id。这一步极其重要它是后面多人对话补参的起点。实体抽取能做对多少直接影响工具调用的质量。这里提醒一句一定要在提示词里把输出格式定义的足够精细最好直接给例子。模型对“尽量返回JSON”这种模糊要求的听话程度非常随机写成“必须返回以下结构的JSON对象不要输出多余内容”会稳定很多。解析端也要做容错处理偶尔模型可能多输出一个逗号、一个中文字符解析失败时宁可重试一次也不要直接抛异常给用户看到。2.3 会话记忆短期上下文和用户属性分开存多轮对话里记忆管理做得不好系统就会“精神分裂”。我踩过最典型的一个坑是用户先问“鸡蛋怎么保存”下一句又问“那能放多久”如果系统把上一轮的意图带过来会错误地认为用户还在问物流。所以记忆不能只是把聊天记录一股脑塞给模型。我的做法是把记忆拆成两层会话态记忆只保留当前任务相关的对话轮次通常取最近5轮并做摘要压缩。用户已经结束的话题不再出现在上下文里。用户态属性会员等级、默认收货地址、历史投诉标记、当前用户ID。这些单独存不混在对话历史里供工具调用和权限校验使用。会话态写内存KV存储按会话ID隔离。每轮对话结束后系统会把这一轮的结构化结果意图、实体、摘要写回存储而不是存原始聊天文本。这样下一轮模型看到的是紧凑的“信息卡”而不是一大段原始对话。2.4 路由决策任务优先知识其次闲聊垫底意图识别之后系统会走一条固定的决策逻辑如果意图是任务办理且参数齐全直接进入工具调用。如果意图是任务办理但参数缺失进入追问补参流程。如果意图是知识咨询进入检索增强流程。如果检索结果置信度不达标拒答并提示转人工。如果是闲聊简短回应不要长篇大论。如果用户明确表达不满判断是否需要升级人工座席。这条逻辑顺序不是随便排的。任务型问题直接涉及用户切身利益订单、退款、物流优先级最高要让用户快速得到结果。知识型问题需要查阅资料响应速度可以略慢但必须准确。闲聊类的处理原则是“不接话茬”避免模型在无关话题上消耗太多token和时间。有了清晰的意图识别和路由决策后面接RAG还是接工具调用就变成两个独立的子系统不需要搅在一起调试和上线灰度都能单独推进。3. 知识库构建与检索增强每一句回复都必须“有据可查”3.1 为什么客服知识必须走RAG而不是让模型死记硬背客服场景的知识有一个特点变化太快。售后政策一个月可能调整两次优惠活动每周都不同物流时效更是随天气和节假日变动。如果把这些塞进模型的训练数据更新成本高不说模型还可能用旧知识回答新问题。所以整个系统采用检索增强生成RAG的方式。思路可以理解为给模型配一本可以随时翻阅的电子手册用户每次提问时系统先从手册里找到相关段落再让模型基于这些段落组织答案。好处有两个内容更新只需要重建知识库索引几小时就能完成答案可以被精确追溯到原始文档一旦出错能立刻知道是哪份资料写的该改哪份文档。知识来源包括FAQ标准问法、售后政策、商品页参数、物流说明、优惠活动规则。来源越杂切分和检索环节越要小心。3.2 文档切分检索质量的命根子有很长一段时间我以为是向量检索拖了后腿后来发现是文档切分太粗暴。固定按512个字切一段的方式最省事但是把“优惠券仅限首页领取”和“优惠券不可叠加使用”切成两段检索时语义全断。切分策略直接影响最终回答质量这个环节值得投入时间。我最终用三种切分方式配合内容类型切分方式原因长文档、规则说明按标题层级和段落切每个二级标题下作为一个独立单元保留语义完整性避免跨段信息断裂FAQ问答对按“问题-答案”整对切不拆开检索时命中问题即可返回整个答案表格型参数保留表头上下文按行切分并附带表头信息避免“3天内发货”这种答案失去参照对象切分之后要给每条知识片段生成元信息来源文档ID、标题、更新时间、业务类型。这些元信息不参与向量检索但会在生成阶段用于引用校验。新版文档更新后旧片段要能快速定位下架这一步经常被忽略直到数据冲突的时候才发现问题。3.3 召回策略向量召回为主关键词兜底重排再压缩我第一次做检索只靠向量召回效果极不稳定。中文用户表达太随意经常出现“怎么还没发货”和“发货时效”这种说法差异很大的情况向量相似度能排上但不够靠前。后来加了关键词召回通道用BM25类的算法先拉回来一批包含关键字的文本再和向量召回结果合并去重统一进重排模型打分取Top5作为最终上下文。参数配置上向量召回取Top50关键词召回取Top30融合重排后只取Top5。相似度阈值设的是0.55低于这个值视为“没有可用知识”直接拒答。阈值不能拍脑袋定要用标注好的测试集反复校准调得太高大量能答的问题被拒答用户体验差调得太低无关文档混进来模型开始胡说。这里我还加了一个隐藏的“上下文裁量”逻辑如果检索到的Top5文档来自三个不同的业务子域取前两个域内得分最高的结果避免把互不相干的信息拼在一起。3.4 生成约束参考答案必须带引用ID检索做得再好生成环节没有约束也是白搭。我最开始让模型“根据资料回答”结果它自己发挥表面上通顺内容却不完全来自知识库。后来在生成提示词里强制要求答案必须列出所使用的资料ID并且关键事实不能脱离资料原文。输出端我加了一层“引用校验”模型返回的引用ID必须真实存在于本次检索的结果集里不存在就要求重新生成或者直接走拒答流程。这一步把“模型编依据”的问题直接挡在外面。引用校验的规则可以很轻量不需要复杂模型只要做一个集合包含判断即可性能开销非常低。另外一个细节拒答要设计成一种正常的输出而不是异常。我们特意准备了一句兜底话术“这个问题我暂时无法准确回答正在为你转接人工客服。” 用户感知到的是一次正常的服务转接而不是系统故障。至少要保证系统不会在不确定的领域硬编一个答案。4. 工具调用让客服真的能“办事”而不是只会“说话”4.1 把工具调用当成参数生成而不是让模型直连数据库很多初次做这个方向的人会想让模型直接生成SQL去查订单表不就行了我在项目里明确禁止这种方式。原因很简单权限没法控制SQL一旦写错影响的是整库数据审计也没法做无法知道每条数据是被谁调用、为什么调用。正确的做法是把每个业务动作变成“工具”用JSON Schema描述参数让模型只负责产出参数实际请求由统一网关执行。比如查物流的工具定义大概是{ name: query_logistics, description: 查询订单物流轨迹, parameters: { type: object, properties: { order_id: { type: string, description: 订单号必须是用户会话中出现的合法订单号 } }, required: [order_id] } }好处很明显网关负责鉴权、限流、日志记录工具出错可以独立修复不会影响对话主流程。4.2 参数补全多轮追问不能变成查户口工具调用最常翻车的不是调用本身而是参数收集。用户说“帮我把那个订单退了”订单号并没有出现在这句话里。如果系统直接猜测订单号百分之百要出事。我们的做法是在意图识别阶段就产出missing_params列表系统根据列表主动发起追问。追问的话术要自然比如用户提到“退货”但没给订单号系统会回复“您说的是哪个订单呢方便提供一下订单号或者告诉我大约什么时候下的单我帮您确认。”追问不是无限循环的。连续追问三次仍未获得必要参数系统自动生成为人工服务指令把上下文一并转给人工座席。这既保护了用户体验也避免了机器人“查户口”式的糟糕交互。这里有一个额外要注意的地方参数值如果没有在当前会话中显式出现即使模型自信地填了一个值也要触发追问确认。模型在上下文里看到用户上上周买过东西就可能把那个旧订单号拿来填充当前请求——这在技术上算“幻觉”在业务上就是重大错误。4.3 伪调用、越权和高风险操作的二次确认把工具调用跑通之后下一批问题来自“不该调的时候也调了”。用户只是问“退货的流程是什么”模型却把查询订单接口调了一遍白白浪费一个请求不说还可能因为接口返回异常导致整轮会话中断。我加了两道防线。第一道是路由前置校验只有意图明确是“任务办理”时才允许进入工具调用链路知识咨询、闲聊一律不进。第二道是结果校验工具返回的数据要与用户上下文做一致性检查比如返回的订单归属人不匹配当前用户立即中止输出并触发安全话术。对退款、修改地址这类高风险操作系统还增加了二次确认环节。工具调用先返回一个“待执行摘要”对话代理向用户展示“您要申请对订单xxxx退货退款对吗确认后将提交申请。”用户确认后才真正执行。这多了一次交互成本但避免了大量误操作带来的客诉。4.4 接口超时、失败重试和幂等保护工具调用依赖外部接口而外部接口一定会不稳定。我在统一网关里设置了两条铁律超时时间2秒超过即切换兜底话术业务操作失败时不把内部错误信息直接透传给用户。幂等保护也要提前想清楚查询类接口重复调用没有副作用可以自动重试一次申请退款、修改订单这类非幂等操作绝对不自动重试只触发人工确认流程。否则一次超时导致的重复提交可能让用户收到两笔退款原路退回的通知引发更大的麻烦。日志记录方面网关每次调用都会落一条结构化日志包含工具名、参数摘要、结果码、耗时。这个日志系统上线后成了我们定位客服答错问题的重要线索来源。5. 效果评估与上线调优指标好看不算数要能定位问题5.1 离线评测集没有标准的测试一切调优都是空谈系统上线前我们花了很大力气做了一套离线评测集。从历史客服会话里随机抽了500条真实用户问题每条标注四个字段期望意图、期望工具动作、期望知识来源、人工座席的标准回复要点。评测集规模不大但覆盖了高频场景和常见变体。评测指标分四块意图准确率、工具动作正确率、知识命中率、拒答合理率。每轮提示词改动后运行评测脚本对比这些指标的变化。一个典型的评测结果版本意图准确率工具动作正确率知识命中率拒答合理率v1初版84.6%79.2%68.3%71.5%v2加引用约束87.1%83.4%77.6%63.2%我记得v2版本是在加了“必须引用知识库ID”的约束之后知识命中率显著上升但拒答合理率反而下降了8个百分点。原因很典型模型遇到不算标准的表达时宁可拒答也不愿冒险回答。这个现象说明单纯靠提示词收紧会过度倾向保守策略需要用阈值和话术来平衡。5.2 灰度策略先放5%流量再放非敏感任务评测集只是纸上谈兵真正的问题只有真实流量能暴露。我们的灰度路径分了三步先放5%流量只开放知识咨询类问题观察是否出现检索错误和引用错误。稳定后放开任务办理中的查询类工具查订单、查物流观察参数提取和追问逻辑。最后才开放退款、改地址这类高风险操作且保持人工复核机制。核心观测指标不是“回答率”而是转人工率、用户重问率、平均对话长度。对话长度变长并不一定是好事可能是系统迟迟没能解决用户问题转人工率上升通常意味着某个环节出了问题。这些指标比单轮回答的流畅度更能反映系统真实健康度。5.3 日志驱动的问题定位三个真实典型的坑上线后我们养成了每天翻日志的习惯。几个典型问题值得单独记一笔第一个坑上下文串话题。用户上一轮问的是A下一轮其实转向B但意图识别时A的上下文还留在记忆里导致模型在B的问题上参考了A的语义。修复方式是每轮意图识别之前先把最近一轮的会话摘要和上一轮识别结果做一次相关性判断无关的上一轮内容直接裁剪掉不让它参与当前意图决策。第二个坑知识快照过期。客服文档某天更新了退换货政策但知识库索引还是旧版结果系统还在引用已经废弃的条款。修复方式是建立文档变更到索引重建的定时任务并每次重建后自动跑一遍关键政策的检索命中测试。关键词条要放到监督列表里一旦在新版索引下检索不到立刻告警。第三个坑参数幻觉。模型在订单号缺失时自己“猜”了一个值调用查单接口返回了空数据系统却说“该订单不存在”用户一脸懵。排查后发现模型并没有等用户提供订单号而是用“上一个会话里出现过的订单号”填了进去。修复逻辑前面说过关键参数必须在当前会话显式出现否则一律触发追问不管模型置信度多高。这三类问题的共性是只看整体指标很难发现必须把单轮对话的完整决策日志串起来一点一点看模型在哪一步做了错误决策。这也是我在整个项目里体会最深的一件事——评估体系没有捷径指标只能告诉你哪里坏了不能告诉你为什么坏原因一定藏在日志里。6. 成本控制与后续扩展把钱花在刀刃上6.1 token消耗的账要算清楚让我算一笔保守的账一个日咨询量1万次的项目每次用户咨询平均要跑3到5轮对话每轮主模型的输入输出合计约2000 token。按商用API的定价粗略估算单日成本就可能达到可观水平。如果所有对话都走全链路大模型推理项目根本没有可持续性。控制成本的思路不是不用大模型而是分级分流。我把流量分成三档简单闲聊、固定规则类问题用规则引擎或轻量模型直接挡掉。知识咨询走RAG链路检索命中后只用一次生成调用不做多余重试。只有任务办理和复杂追问才走全链路工具推理。另外一个有效的优化是缓存。对高频的、标准化的知识问题比如“发货时效是多久”向量检索命中的标准答案直接放入缓存下次相同或高度相似的问题直接返回不触发大模型生成。这个方案把相当一部分重复流量的成本降到几乎为零。6.2 后续可以继续扩展的方向这个系统的底座一旦稳定扩展方向就清晰了。我们目前在规划的方向有几个情绪识别在意图识别的结构化输出里增加情绪维度和强度分数对愤怒用户优先转人工避免机器人火上浇油多语言支持知识库和意图体系不变只在生成层切换多语言提示词从售后客服延伸到售前推荐在工具层增加商品咨询和优惠计算能力。这些方向有一个共同点都是在现有“理解层—决策层—执行层—生成层”的框架里加内容而不是推翻重来。底座的稳定性直接决定了扩展成本。这个项目做到后面我最大的体会有两个。第一别把大模型当成“答案生成器”把它当成一个“执行接口调用和资料组织的调度员”系统的稳定性和可控性会强很多。第二把“不知道”设计成一种正常输出比让模型硬着头皮回答更重要用户宁可听一句话转人工也不愿意听一段流畅的假话。整个系统的设计过程本质上就是在“模型能力”和“业务风险”之间不断找平衡这个平衡点只有靠数据和日志一点一点磨出来。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑