ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

客服Agent渡劫48关:Tool、RAG、MCP、Eval实战避坑指南

客服Agent渡劫48关:Tool、RAG、MCP、Eval实战避坑指南 1. 从标题拆解客服 Agent 的真实战场“客服 Agent 渡劫 48 关”这个标题第一次看到的时候我笑了很久因为它太真实了。做过客服 Agent 的人都知道这东西不是搭一个对话机器人那么简单它更像是在一条充满陷阱的流水线上反复调试每过一关就掉一层皮。标题里提到的 Tool、RAG、MCP、Eval 四个关键词恰好对应了客服 Agent 从“能说话”到“能干活”再到“干得靠谱”的四个阶段。我打算围绕这四个阶段把我在实际项目里踩过的坑、总结的方法、以及那些文档里不会写的经验完整地摊开来讲。先说清楚这个内容适合谁看。如果你正在做客服方向的 AI Agent或者你手上有一个 Agent 项目正在从 Demo 往生产环境推进那这篇内容基本就是给你写的。如果你只是好奇 Agent 是什么、能干什么也能看懂因为我会尽量用生活化的类比来解释。但核心受众还是那些已经在写代码、调 Prompt、跑评测的从业者因为我要讲的东西偏实操偏工程细节偏“怎么让它在真实业务里不翻车”。客服 Agent 和通用聊天机器人的最大区别在于它必须“办事”。用户说“我要退这个订单”Agent 不能只回复“好的我帮您处理”它得真的去调退款接口、查订单状态、确认退款金额、处理异常情况。这就引出了 Tool 的必要性。但光有 Tool 还不够用户的问题千变万化Agent 需要知道“什么时候该调哪个 Tool”这就需要 RAG 来补充知识。再往后Tool 越来越多、系统越来越复杂就需要 MCP 这样的协议来统一管理。最后你怎么知道你的 Agent 到底行不行这就需要 Eval 来量化评估。这四块内容环环相扣缺一个都不行。我见过太多团队在客服 Agent 上翻车的案例总结下来无非几种Tool 定义得太粗Agent 不知道该调哪个RAG 检索出来的内容驴唇不对马嘴Agent 拿着错误信息一本正经地胡说MCP 没做好权限隔离Agent 调了一个不该调的接口Eval 只测了 happy path上线之后各种边界情况全炸了。这些问题我都会在后面的章节里逐一展开给出我自己的解决方案和排查思路。2. Tool 层客服 Agent 的手和脚2.1 为什么 Tool 定义决定了 Agent 的上限Tool 就是 Agent 能调用的外部能力相当于给它装上了手和脚。没有 Tool 的 Agent 只能动嘴皮子有了 Tool 它才能真的去查订单、改地址、退款、发优惠券。但 Tool 的定义方式直接决定了 Agent 能不能用对、用准。我见过最粗糙的 Tool 定义是这样的一个叫handle_order的接口参数只有一个action字符串Agent 需要自己填refund、query、modify这些值。这种设计看起来灵活实际上是把所有复杂度都推给了模型模型很容易填错而且一旦填错排查起来非常痛苦。我的做法是每个 Tool 只做一件事参数尽量结构化枚举值尽量少。比如退款就单独做一个refund_order参数是order_id和reason其中reason是一个枚举只有几个合法值。这样模型在调用的时候选择空间小出错概率就低。有人可能会担心 Tool 太多会导致模型选择困难但实测下来只要 Tool 的命名和描述足够清晰模型在 20 个以内的 Tool 中选择的准确率是可以接受的。超过 20 个之后就需要考虑分组或者用 MCP 来管理了。还有一个容易被忽略的点Tool 的返回值格式。很多开发者只关注 Tool 的输入不关注输出结果模型拿到一堆嵌套 JSON 之后完全不知道怎么用。我的经验是Tool 的返回值要尽量扁平化关键信息放在最外层并且用自然语言补充一句摘要。比如退款接口返回{status: success, refund_amount: 59.9, estimated_arrival: 3-5个工作日}同时再给一个summary字段写着“退款成功金额 59.9 元预计 3-5 个工作日到账”。这样模型在生成回复的时候可以直接引用 summary减少理解成本。2.2 Tool 调用中的参数校验与兜底策略Tool 调用最怕的是什么是模型传了一个不存在的订单号或者传了一个格式不对的手机号然后接口直接报错Agent 拿到错误信息之后不知道怎么办要么胡编一个回复要么直接卡死。我在项目里加了两层防护第一层是参数预校验在 Tool 真正执行之前先用一个轻量的校验函数检查参数格式格式不对就直接返回一个友好的错误提示给模型让它重新问用户要正确的参数。第二层是异常兜底如果 Tool 执行过程中抛了异常不要直接把原始异常信息丢给模型而是包装成一个结构化的错误对象包含错误类型和给用户的建议话术。举个例子用户说“帮我退一下昨天那个订单”Agent 需要先查订单。如果用户没有提供订单号Agent 应该调用query_recent_orders来获取最近的订单列表然后让用户确认是哪一个。但如果用户提供了订单号而订单号格式不对refund_order的预校验就会拦截返回“订单号格式不正确请提供 12 位数字订单号”。模型拿到这个信息之后就会重新向用户询问。这个流程看起来简单但如果没有预校验模型可能会反复调用同一个接口陷入死循环。注意Tool 的预校验逻辑不要写得太复杂否则会增加响应延迟。我的做法是只校验格式和必填项业务逻辑的校验放在真正的接口里。还有一个实操心得给每个 Tool 设置调用频率上限。有些模型在遇到不确定的情况时会反复调用同一个 Tool 试图获取更多信息。如果不加限制可能会导致接口被刷爆。我在项目里给每个 Tool 设置了每分钟最多调用 10 次的限制超过之后直接返回“操作过于频繁请稍后再试”同时记录日志方便后续排查。2.3 Tool 编排从单步调用到多步规划客服场景里很多任务不是一步就能完成的。比如“我要把昨天买的那个鞋退了然后重新买一双大一号的”这涉及到查订单、退款、查库存、下单、支付等多个步骤。早期的做法是让模型自己规划但模型经常规划得乱七八糟要么漏步骤要么顺序搞反。后来我改用工作流编排的方式把常见的多步任务拆成预定义的流程每个流程由多个 Tool 调用组成模型只需要判断用户意图然后触发对应的流程。具体实现上我用了一个简单的状态机。每个流程有多个状态每个状态对应一个 Tool 调用或者一个用户交互节点。模型在每个状态下的任务被简化成“判断当前状态是否完成如果完成则进入下一个状态”。这样做的好处是可控性强每一步都有明确的输入输出出了问题容易定位。坏处是灵活性差遇到流程之外的请求就处理不了。所以我的策略是高频场景用工作流长尾场景用模型自由规划。高频场景比如退款、改地址、查物流这些占了客服请求的 80% 以上用工作流保证稳定性。长尾场景比如用户问了一个很奇怪的问题就让模型自由发挥但加一个兜底话术实在处理不了就转人工。3. RAG 层让 Agent 有知识可查3.1 客服 RAG 和通用 RAG 的区别RAG 这个词现在很火但客服场景的 RAG 和通用问答的 RAG 有本质区别。通用 RAG 通常是“用户问一个问题我从知识库里找一段相关内容然后生成回答”。客服 RAG 更复杂因为客服的知识是分层的有产品知识这个商品有什么颜色、尺寸、有政策知识退货规则是什么、运费谁承担、有操作知识怎么修改收货地址、怎么申请价保。不同层的知识检索策略和更新频率都不一样。我刚开始做的时候把所有知识都塞进一个向量库结果检索出来的内容经常是“张冠李戴”。用户问退货政策检索出来的是某个商品的尺寸说明。后来我把知识库拆成了三个独立的集合产品库、政策库、操作库。每个库有自己的 embedding 模型和检索参数。产品库更新频繁用较小的 chunk 和较高的检索精度政策库相对稳定用较大的 chunk 保证上下文完整操作库需要步骤清晰所以每个 chunk 对应一个完整的操作流程。提示知识库拆分之后需要在 Agent 的 Prompt 里明确告诉它“先判断问题类型再去对应的库检索”。这个判断逻辑可以用一个轻量的分类模型来做也可以用规则匹配看你的场景复杂度。3.2 Chunk 策略与检索优化Chunk 的大小和切分方式对检索效果影响巨大。我试过固定长度切分、按段落切分、按语义切分最后发现按语义切分 重叠窗口的效果最好。具体来说先用一个句子分割模型把文档拆成句子然后根据语义相似度把相邻句子合并成 chunk每个 chunk 控制在 200-400 字之间相邻 chunk 之间保留 50 字的重叠。这样既能保证每个 chunk 的语义完整又能避免信息在边界处丢失。检索方面我用了混合检索向量检索 关键词检索。向量检索擅长语义匹配但有时候会漏掉一些关键实体关键词检索擅长精确匹配但对同义词无能为力。两者结合之后召回率明显提升。具体做法是先用向量检索召回 top 20再用关键词检索召回 top 20然后合并去重用一个重排序模型reranker对合并后的结果重新打分取 top 5 送给模型。这个流程听起来复杂但实测下来延迟增加不到 200ms效果提升非常明显。还有一个细节检索结果的格式化。不要把检索到的原始文本直接丢给模型而是包装成一个结构化的对象包含来源、置信度、摘要。比如{source: 退货政策 v2.3, confidence: 0.92, content: ...}。这样模型在生成回答的时候可以引用来源增加可信度。如果置信度低于某个阈值模型应该主动说“我不太确定建议您联系人工客服”而不是硬答。3.3 RAG 的瓶颈与应对RAG 最大的瓶颈是什么是检索不到。用户的问题和知识库里的表述方式可能完全不同。用户说“我买的东西坏了想换一个”知识库里写的是“商品质量问题退换货流程”。向量检索在这种情况下经常失效。我的应对策略是Query 改写 多路召回。先用一个小模型把用户的问题改写成多个不同表述的查询比如“商品损坏如何换货”、“质量问题退换流程”、“坏了怎么换”然后用这些查询分别去检索最后合并结果。这个做法能把召回率提升 20% 以上。另一个瓶颈是知识更新滞后。客服政策经常变今天退货包运费明天可能就不包了。如果知识库更新不及时Agent 就会给出过时的信息。我的做法是给每个知识 chunk 加一个有效期字段检索的时候过滤掉过期的内容。同时建一个定时任务每天检查即将过期的知识提醒运营人员更新。这个机制看起来简单但能避免很多客诉。4. MCP 层让 Agent 的工具管理规范化4.1 MCP 解决了什么问题MCP 全称是 Model Context Protocol直译过来就是模型上下文协议。它的核心作用是标准化 Agent 和外部工具之间的通信方式。在没有 MCP 之前每个 Tool 的接入方式都不一样有的用 REST API有的用 gRPC有的直接读数据库。Agent 要调用这些 Tool需要为每个 Tool 写适配代码维护成本很高。MCP 出现之后所有 Tool 都按照统一的协议暴露自己的能力Agent 只需要按照协议去发现和调用就行了。我用一个生活化的类比来解释MCP 就像是 USB 接口。以前每个设备都有自己的充电口诺基亚的、摩托罗拉的、索尼的都不一样出门要带一堆线。后来有了 USB-C所有设备都用同一个接口一根线走天下。MCP 就是 Agent 世界的 USB-C。它定义了工具怎么描述自己、怎么被调用、怎么返回结果Agent 不需要关心底层实现只需要按照协议来就行。在客服场景里MCP 的价值尤其明显。客服 Agent 需要调用的工具非常多订单系统、物流系统、支付系统、优惠券系统、用户画像系统每个系统可能由不同的团队维护接口风格各异。如果没有 MCP每接一个新工具就要改一次 Agent 的代码。有了 MCP新工具只需要实现 MCP ServerAgent 就能自动发现并调用。4.2 MCP Server 的设计要点写一个 MCP Server 不难但写好一个 MCP Server 需要注意几个点。首先是工具描述的清晰度。MCP 协议要求每个工具提供名称、描述、参数 schema。这个描述是给模型看的所以要用自然语言写清楚这个工具是干什么的、什么时候该用、参数是什么意思。我见过很多 MCP Server 的描述写得像 API 文档全是技术术语模型根本看不懂。正确的写法应该是“查询用户的订单列表。当用户询问订单状态、物流信息、退款进度时使用。参数 user_id 是用户的唯一标识可以从上下文获取。”其次是权限控制。MCP Server 不应该把所有工具都暴露给所有 Agent。有些工具是敏感的比如修改用户手机号、删除订单这些应该只对特定的 Agent 开放或者需要额外的鉴权。我的做法是在 MCP Server 层面加一个权限层根据 Agent 的身份和当前会话的上下文动态决定哪些工具可见。这样即使 Agent 被恶意引导也无法调用它不该调用的工具。注意MCP Server 的日志要记录完整包括谁在什么时候调用了什么工具、传了什么参数、返回了什么结果。这些日志在排查问题的时候非常有用。还有一个实操经验MCP Server 要做好限流和熔断。客服场景的流量波动很大大促期间可能是平时的几十倍。如果某个下游系统扛不住MCP Server 要能快速失败返回一个友好的错误而不是让整个 Agent 卡死。我用了一个简单的令牌桶算法做限流每个工具每秒最多处理 N 个请求超过就排队或者拒绝。同时配置了熔断器如果某个工具的失败率超过阈值自动断开一段时间避免雪崩。4.3 MCP 与多 Agent 协作MCP 还有一个高级用法多 Agent 协作。在复杂的客服场景里一个 Agent 可能搞不定所有事情。比如售后 Agent 负责退换货物流 Agent 负责查快递技术 Agent 负责处理产品使用问题。这些 Agent 各自有自己的工具集通过 MCP 协议互相调用。用户的问题先由一个路由 Agent 判断类型然后分发给对应的专业 Agent。这种架构的好处是每个 Agent 的职责清晰Prompt 可以写得更专注工具集也更小模型选择准确率更高。坏处是链路变长延迟增加而且需要处理 Agent 之间的上下文传递。我的做法是用一个共享的上下文对象所有 Agent 都能读写但每个 Agent 只能修改自己负责的字段。这样既能共享信息又能避免冲突。5. Eval 层怎么知道 Agent 到底行不行5.1 客服 Agent 的评测维度Eval 是客服 Agent 最容易被忽视的环节。很多团队做完 Agent 之后随便找几个人聊几句觉得“还行”就上线了。结果上线之后各种问题暴露出来用户投诉不断。我的经验是客服 Agent 的评测必须系统化、自动化、持续化。评测维度至少包括以下几个维度说明评测方法意图识别准确率Agent 是否正确理解用户意图标注数据集计算分类准确率工具调用准确率Agent 是否调用了正确的工具、传了正确的参数模拟用户请求检查调用日志回答准确性Agent 的回答是否与知识库一致人工抽检 自动比对任务完成率用户的问题是否被真正解决端到端测试检查最终状态响应延迟从用户发消息到收到回复的时间埋点统计 P50、P95、P99安全合规Agent 是否泄露敏感信息、是否被诱导对抗测试红队演练这些维度里任务完成率是最重要的也是最难测的。因为很多任务不是一轮对话就能完成的需要多轮交互。我的做法是构造一批端到端的测试用例每个用例模拟一个完整的用户旅程从用户发起请求到任务完成全程自动化执行最后检查业务状态是否正确。比如退款场景测试用例会模拟用户发起退款、Agent 确认订单、Agent 调用退款接口、检查退款状态最后验证订单状态是否变成了“已退款”。5.2 自动化评测流水线的搭建自动化评测流水线的核心是可重复、可对比。每次修改 Prompt 或者调整工具之后都要跑一遍完整的评测集看看各项指标是涨了还是跌了。我用的工具组合是pytest 自定义断言 报告生成。每个测试用例是一个 pytest 函数里面模拟用户输入调用 Agent然后断言输出是否符合预期。跑完之后生成一个 HTML 报告展示每个用例的通过情况和各项指标的变化趋势。这里有个坑评测集的质量决定了评测的价值。如果评测集里全是简单问题那跑出来的分数再高也没用。我的评测集里至少包含 30% 的边界情况比如用户输入乱码、用户中途改变主意、用户同时问多个问题、用户情绪激动。这些情况在真实场景里很常见但在开发阶段容易被忽略。提示评测集要持续更新。每次线上发现新的 bad case就把它加到评测集里确保下次不会再犯。还有一个实操心得用 LLM 做自动评分。有些指标很难用规则判断比如“回答是否友好”、“语气是否合适”。这时候可以用一个评分模型给它一个评分标准让它对 Agent 的回答打分。虽然不如人工准确但胜在速度快、成本低适合做大规模筛查。人工只需要复核低分样本就行了。5.3 线上监控与持续迭代Eval 不只是上线前的事情上线后的监控同样重要。我在生产环境里埋了几个关键指标用户满意度对话结束后让用户打分、转人工率Agent 搞不定转给人工的比例、重复提问率用户同一个问题问了两遍以上、异常退出率用户中途关闭对话。这些指标能实时反映 Agent 的健康状况。如果转人工率突然升高说明 Agent 在某些场景下出了问题需要赶紧排查。如果重复提问率升高说明 Agent 的回答没有解决用户的问题。我会把这些指标做成看板每天定时检查。同时设置告警指标超过阈值就发通知。持续迭代的节奏也很重要。我的做法是每周一次小迭代每月一次大迭代。小迭代主要是修 bad case、调 Prompt、加 Tool。大迭代会重新跑一遍完整的评测集对比各项指标决定是否上线。每次迭代都要有明确的假设和验证方法不能凭感觉改。6. 渡劫 48 关那些让我掉头发的瞬间6.1 Tool 调用死循环有一次上线之后发现 Agent 在某个场景下会无限循环调用同一个工具。用户问“我的退款到哪了”Agent 调用query_refund_status返回“处理中”Agent 又调用一次还是“处理中”如此反复。原因是 Prompt 里写了一句“如果退款状态不是成功就继续查询”模型理解成了“一直查到成功为止”。后来我加了一个限制同一个工具在同一个会话里最多调用 3 次超过就强制返回一个兜底话术。这个问题才解决。6.2 RAG 检索到过期政策还有一次用户问“退货包运费吗”Agent 回答“包运费”但实际上政策已经改了不再包运费。排查发现知识库里有两个版本的退货政策旧版本没有删除检索的时候旧版本排在前面。后来我加了有效期字段并且每次更新知识的时候旧版本自动标记为过期检索时过滤掉。这个问题提醒我知识库的版本管理非常重要不能只加不删。6.3 MCP 权限泄露最惊险的一次是 MCP 权限没做好Agent 被用户诱导调用了修改用户手机号的接口。幸好那个接口有二次验证没有造成实际损失。后来我在 MCP Server 层面加了严格的权限控制敏感工具需要额外的 token 才能调用而且 token 和会话绑定不能跨会话使用。同时加了一个敏感操作确认机制Agent 在调用敏感工具之前必须先向用户确认。6.4 Eval 覆盖不全导致上线翻车有一次评测集里全是正常问题跑出来分数很高就上线了。结果上线第一天就收到大量投诉因为用户输入里有很多错别字和口语化表达Agent 完全理解不了。后来我在评测集里加了大量噪声数据包括错别字、拼音、方言、表情符号重新训练了意图识别模型问题才解决。这件事让我明白评测集必须尽可能接近真实分布不能只测理想情况。7. 一些零散但重要的经验7.1 Prompt 的版本管理Prompt 是客服 Agent 的灵魂但很多团队不把 Prompt 当代码管理改了就改了没有版本记录。我吃过这个亏有一次改了一版 Prompt效果变差了想回滚却发现找不到旧版本。后来我把 Prompt 也纳入 Git 管理每次修改都提交写清楚改了什么、为什么改。同时给每个 Prompt 版本打标签方便对比不同版本的效果。7.2 上下文窗口的管理客服对话可能很长尤其是多轮交互的场景。如果把所有历史消息都塞进上下文很快就会超出模型的窗口限制。我的做法是滑动窗口 摘要保留最近 N 轮对话的完整内容更早的对话用一个摘要代替。摘要由模型生成包含关键信息比如用户 ID、订单号、已确认的事项。这样既能保留重要上下文又能控制 token 消耗。7.3 兜底话术的设计不管 Agent 做得多好总会有搞不定的情况。这时候兜底话术就很重要。我的兜底话术分三级第一级是“我不太确定让我再查一下”然后重新检索第二级是“这个问题比较复杂建议您联系人工客服”然后转人工第三级是“抱歉我暂时无法处理请稍后再试”然后结束对话。每一级都有明确的触发条件避免 Agent 在搞不定的时候胡言乱语。7.4 多语言和方言的处理如果客服 Agent 要服务全国用户方言和口语化表达是绕不开的。我的做法是在意图识别之前加一个归一化层把方言和口语化的表达转换成标准表达。比如“咋整”转成“怎么办”“搞不定”转成“无法处理”。这个归一化层可以用规则 模型结合的方式实现规则处理高频词模型处理长尾。7.5 成本控制客服 Agent 的成本主要来自模型调用和向量检索。模型调用方面我用了分级策略简单的意图识别用一个小模型复杂的生成用大模型。向量检索方面我用了缓存相同或相似的问题直接返回缓存结果不重复检索。这两个策略加起来能把成本降低 40% 左右。8. 最后的个人体会做客服 Agent 这两年我最大的体会是这东西没有银弹只有不断迭代。Tool、RAG、MCP、Eval 每一层都有坑每一层都需要根据业务场景去调。别人的方案可以参考但不能照搬。我见过很多团队直接抄了一个开源方案结果上线之后发现完全不适用自己的业务又推倒重来。另一个体会是评测比开发更重要。开发一个 Agent 可能只需要两周但建立一套完整的评测体系可能需要两个月。但这两个月是值得的因为没有评测就没有方向你不知道改了什么、效果是好了还是坏了。我现在做任何改动之前都会先跑一遍评测集确认基线然后再改改完再跑一遍对比指标。这个习惯让我避免了很多“感觉变好了但实际上变差了”的情况。最后分享一个小技巧让 Agent 自己解释它的决策。在 Prompt 里加一句“在调用工具之前先用一句话说明你为什么调用这个工具”。这样在排查问题的时候你能看到 Agent 的思考过程快速定位是意图识别错了、还是工具选择错了、还是参数传错了。这个技巧看起来简单但能省下大量排查时间。
返回列表