
做这个业务 Agent 评测平台之前我在货运平台这边已经吃了快一个月的“人工验收”的亏。业务同学提了一堆 Agent 需求客服机器人、调度助手、费用申诉助理每个听起来都能提效但每次要上线大家都不知道怎么验收。拉几个典型问题人工聊一轮凭感觉说“还行”可一旦放量各种边界情况全冒出来。后来我们决定把评测这件事工程化做一个统一的业务 Agent 评测平台。这篇文章就是这段时间的工程实践记录和复盘不聊概念只聊实际怎么设计、怎么落地、踩了哪些坑。适合正在做 Agent 应用尤其是业务侧 Agent 落地又对“怎么证明 Agent 变好了”这件事头疼的团队参考。1. 为什么货运业务的 Agent 不能继续“拍脑袋验收”1.1 业务 Agent 到底在解决什么问题货运平台里的 Agent跟传统意义上的“聊天机器人”差别很大。它不只是陪用户聊天而是要真正介入业务流程、调用系统能力、影响业务结果。我盘了一下平台里的 Agent 主要有这么几类用户侧服务助手用户问“货到哪了”“为什么司机还没接单”“运费怎么算”Agent 要查订单、查轨迹、查计价规则然后给出准确解释。司机侧费用申诉助手司机发起油费补贴、等待费、搬运费等申诉Agent 要按规则判断是否成立、该补多少钱或者决定要不要转人工审核。内部运营调度助手给调度运营提供改派建议、异常订单处理方案辅助决策。这些 Agent 的共同点是什么它们都会调用真实的接口、读取真实的订单数据甚至直接改动业务状态。一旦说错话、做错判断轻则用户投诉重则直接造成资金损失。所以问题从来不是“Agent 会不会聊天”而是“Agent 能不能在真实业务约束下把一件事办对、办稳、办得体面”。这句话直接决定了评测体系该怎么搭。1.2 没有统一评测时的三个真实痛点在评测平台做出来之前我们的验收状态基本是“裸奔”的核心痛点有三个第一个痛点验收靠抽查覆盖全靠运气。每次迭代业务同学会挑几条“平时最常遇到”的问题打开测试环境跟 Agent 聊一轮看看回复像不像人话。这本质上是在测“演示路径”不是在测系统能力。真实线上用户的问法千奇百怪有些地址写一半、有些话里有情绪、有些一句话里带三个诉求这些边界 case 在人工抽查里很难被覆盖到。第二个痛点口径不统一算法和业务对不上。算法同学说“这次任务完成率到了 92%”业务同学一听就炸“怎么可能 92%我随便试了几个都没解决。”两边吵了半天才发现算法定义的“完成”是“模型输出了结果”业务定义的“完成”是“用户诉求真真切切被处理好了”。中间差着一大截。第三个痛点回归成本太高改一句 Prompt 要半天没人敢发。有一次我们调了一版对话策略改动点很小但谁都不敢说“这版一定不会把老问题带出来”。于是只能手工把之前积累的几十条典型场景重新聊一遍一个同学聊了一下午第二天说“感觉差不多”。问题是“感觉差不多”完全不是一个可量化的上线依据。这三个痛点叠在一起结论就很清楚业务 Agent 需要一个能把“行还是不行”用统一标准量化出来的评测平台否则后面 Agent 数量越来越多一定失控。1.3 评测平台能承诺什么不能承诺什么这里要先划清边界。评测平台不是万能的它承诺的事情只有三件一致的指标所有人都用同一套评分规则看结果。可复现的测试同一份用例、同一个版本任何时候跑结果都一致。快速的反馈每次改动 Prompt 或模型几小时内得到完整回归报告。它不能承诺的是“评测分数高业务就一定成功”。分数代表的只是在预设条件下的表现线上真实流量、用户情绪、突发活动这些变量评测环境模拟不了。所以我把这个平台定位成“出厂质检线”不是“业务增长引擎”。想清楚这个边界后面很多设计决策就不会跑偏。2. 评测指标怎么定从任务完成率到过程合规度的取舍2.1 三个评测维度是怎么来的定评测指标的时候我们没有一上来就抄市面上常见的“准确率”“召回率”而是从头问了一个问题货运业务 Agent 做错事会错在哪几种方式答案归纳下来就三类事情没办成、办成了但过程违规、办成了但体验很差。所以评测维度就按这三类落地评测维度要回答的问题典型指标举例任务完成度用户诉求最终有没有被解决目标达成率、关键信息覆盖率查时效时有没有给出预计到达时间过程合规度每一步操作是否符合业务规则违规次数、越权操作数、错误承诺数有没有承诺规则外的赔偿金额体验友好度交互过程中用户是否感到顺畅重复话术率、转人工率、回复冗余度遇到不会的问题能不能坦诚说明这三个维度不是并列关系。任务完成度是底线过程合规度是红线体验友好度是加分项。2.2 指标怎么定义才算可执行很多团队把“指标”定义成“回答准确率”听起来很合理真正落地时完全没法判分。因为“准确”这个词太糊了。我们的做法是把每个用例拆成结构化、可判定的条件。一份用例至少包含四个部分预期目标会话结束时Agent 应该达成的状态。比如“给出预计到达时间并说明路况异常原因”。关键信息回复里必须覆盖哪些要素。比如“至少包含预计到达时间”“如果超时必须说明原因”。禁止行为绝对不能出现的话术或动作。比如“不得承诺 12:00 前一定送达”“不得自行修改订单金额”。可接受的失败方式有些问题 Agent 确实解决不了但必须给出合理的兜底。比如“承认暂时无法查询并引导用户联系人工”。这里我特别想强调一点判分条件要尽量做成“判断题”而不是“打分题”。“回复是否包含预计到达时间”是判断题“回复是否友好”是打分题。判断题机器能稳定判打分题哪怕是人工标也有分歧。所以我们把 80% 的判分条件都做成了判断题剩下必须打分的主观项留给 LLM 判分器处理。2.3 分数合成与阈值设定三个维度各自算完分之后要合成一个总分方便横向对比版本。我们初期用的公式很简单总分 0.6 × 任务完成度 0.25 × 过程合规度 0.15 × 体验友好度权重不是拍脑袋拍出来的是根据业务复盘结果反推的过去三个月线上客诉里60% 是因为事情没办好25% 是流程违规引发纠纷15% 是表达问题引发用户不满。如果后面数据分布变了权重也要跟着调这个公式只是起点。但有个例外一旦出现严重违规比如承诺了不存在的赔付、自行修改了订单金额总分直接清零不参与加权。这跟现实中“一票否决”的逻辑是一样的能力再强底线破了就是不行。阈值方面我们没有定一个死的“80 分及格”而是做“相对回归 绝对兜底”两条线。绝对兜底指的是严重违规 case 数量必须为 0相对回归指的是总分和关键子项不能比上一个版本下降超过 2%。这个设计防止了一个很常见的问题用单一分数卡版本容易让团队去“刷总分”而不是真正把薄弱环节做好。3. 测试数据从哪来真实会话重放与合成用例的双轨构造3.1 真实会话脱敏与重放评测这块最容易被低估的就是测试数据。刚开始我们以为写个几十条用例就够用了跑到第二周就发现用例太“正”了全是标准问法、标准场景Agent 答得很好一到线上就打回原形。后来我们把重心转回真实会话上。直接从线上日志里抽用户和 Agent 的真实对话记录做严格脱敏处理手机号、姓名、地址、订单号、车牌号全部替换成模拟数据。脱敏不是简单把字段打码还要保持语言风格和问题结构不变否则评测的就变成“另一个问题”了。重放的方式也踩过坑。最开始我们天真地以为“重放”就是把线上用户说的话原样发一遍给 Agent然后对比新的回答和线上回答像不像。后来发现这个思路不对因为 Agent 是多轮交互用户会根据 Agent 的回答继续追问。如果只重放第一句后面就断掉了。我们的做法是从真实会话里截取一段“Agent 独立服务”的片段把用户的每一轮输入按顺序存储评测时逐轮喂给被测 Agent。这本质上是把真实用户的对话路径当作预设脚本看新版 Agent 沿着这段路径走能不能走通。它对覆盖真实分布非常有效在我们平台里大约占了 60% 的用例来源。3.2 合成用例的构造方法真实会话覆盖的是“已知问题”但评测不能只有已知问题还得有“边界问题”和“未来可能遇到的问题”。这部分靠合成用例。合成用例我们主要靠两种方式生成规则模板 LLM 辅助扩写。先用业务同学把典型边界场景列出来比如“用户情绪激动反复追问”“地址信息不全导致无法计算时效”“司机和用户同时改约”这类然后人工写成结构化用例再用 LLM 基于这些模板扩写一批表达方式不同的变体。一份合成用例长这样我们用的是 YAML 结构方便版本管理case_id: SC_0412 场景: 时效查询_地址不完整 用户初始消息: 我的货到底几点到啊等了一天了 预期目标: 引导用户补充完整地址信息并提供大致时效范围 关键信息: - 需要向用户确认完整收货地址 - 需说明当前无法精确计算时效的原因 禁止行为: - 不得编造预计到达时间 - 不得承诺马上就到 难度标签: 边界情况_信息缺失生成合成用例有个特别要注意的地方不要让 Agent 察觉自己是在被测试。我们一开始在 Prompt 里带了明显的评测标记结果模型“演”得很乖所有规则都完美遵守一上真实环境就露馅。后来把所有评测相关标识从用户输入里去掉情况才好转。这算是一种“评测污染”后面细说。3.3 题库管理与版本对齐用例多了之后题库管理就成了新的工程问题。我们现在把用例当成代码一样管理进 Git 仓库每次修改都要走分支和评审。每条用例有唯一 ID、变更历史、适用场景标签、难度标签。评测报告里会记录“当前这批结果是用哪个版本的题库跑出来的”。这个看起来细枝末节实际救过大命。有一次一个版本跑分暴涨大家差点欢呼后来一查发现是题库里删掉了一批难用例不是 Agent 变强了。没有版本对齐机制这种乌龙根本查不出来。另外题库不是越多越好。我们每两周做一次用例体检淘汰三类用例已经被 Agent 完美解决很久的、跟现有业务流程已经不匹配的、线上线下表现差异特别大的。题库需要“流动”一旦僵住评测结果就会失真。4. 评测引擎的工程实现三个模块和一条流水线4.1 整体模块划分评测平台的代码结构没有做得很复杂核心就四个模块用例仓库管理所有评测用例包括真实会话重放脚本和合成用例支持按标签筛选和版本回溯。执行引擎负责把用例跑起来调用被测 Agent 的接口模拟用户输入收集每一轮对话以及 Agent 的每一次工具调用。判分服务拿到完整的会话轨迹先用规则判分器处理结构化条件再用 LLM 判分器兜底主观项。报告服务聚合所有用例的判分结果生成总分数、分维度分数、失败 case 列表和趋势报表。整体流水线就是一条直线从用例仓库取出用例集执行引擎跑出轨迹判分服务打分报告服务出报表。没有复杂的编排系统因为这条链路已经足够稳定引入重框架反而增加维护成本。4.2 执行引擎的关键取舍执行引擎是整个平台里最有技术含量的部分也是最容易被低估的。我们第一个取舍是用“模拟用户”的方式做端到端测试而不是把 Agent 的函数单独拆出来做单元测试。原因很简单Agent 的价值恰恰在多轮交互里。单测能发现“接口算错了”但发现不了“第一轮把用户带偏了第二轮怎么拉都拉不回来”。所以每条用例都走完整对话流程执行引擎负责按脚本发消息、等待响应、触发工具调用、继续下一轮。第二个取舍是对超时和异常做严格兜底。线上的一次 Agent 调用可能耗时几秒甚至更久评测时如果每轮都在那里傻等几百条用例跑下来没半天结束不了。我们给每轮交互设置了超时时间超时直接判失败并把卡住的轨迹存下来方便定位是模型问题还是环境问题。第三个取舍是全量记录轨迹。不只是记录用户说了什么、Agent 回了什么还包括中间每一次工具调用的入参、出参、耗时、走了哪个分支。这太重要了很多评测失败人工排查时需要看的是“Agent 在哪一步做了错误决定”而不是只看最后那句话。4.3 判分器规则优先LLM 兜底判分服务设计上我们坚持一个原则能用规则判的就不要用模型判。规则判分器处理的是结构化条件。比如“关键信息里要求包含预计到达时间”那就直接在回复文本里做信息抽取看有没有时间实体比如“禁止出现编造的赔付金额”那就先解析出所有金额实体再跟允许值列表比对。这些用正则、实体解析、字段比对就能搞定稳定、可解释、便宜。真正需要 LLM 判分的只剩那些没法用规则硬拆的主观项。比如“是否在无法解决问题时主动引导用户转人工”“回复语气是否得体”“解释是否足够清晰”。LLM 判分器我们自己写了一套提示词模板核心是强制它先给判断依据再给结论最后输出结构化 JSON你是业务对话质量评估员。 请根据以下评分标准判断这段客服回复是否合格。 先输出你的判断理由再输出结果 JSON。 评分标准 1. 当无法解决问题时是否明确告知用户并给出下一步建议。 2. 是否使用绝对化承诺如一定保证。 3. 语气是否礼貌、克制、不推卸责任。 回复文本 {对话轨迹} 输出格式 { reason: 判断理由, pass: true或false, violated_rules: [违反的规则列表] }这样设计有个额外的好处LLM 判分结果不是“是/否”一个值而是带理由的出问题后可以直接拿理由去追溯而不是对着一个分数猜。4.4 评测环境与线上一刀切最后说一个容易被忽略但很关键的工程点评测环境必须和线上完全隔离。我们刚开始直接连测试环境的接口跑着跑着发现评测数据会污染业务缓存也会被定时任务干扰。后来统一调整为专供评测的独立环境连接影子数据库和 mock 服务。被测 Agent 的所有工具调用都指向 mock不会真的发消息给用户、不会真的改订单状态。隔离这件事要做得非常彻底哪怕线上只是多了一个新的限流策略评测环境没同步结果也会失真。所以我们在每次发版前会同步一次环境配置并在评测报告里记录环境版本确保“这次结果和上次结果可比”。5. 上线半年踩过的坑判分不稳定、用例污染、环境隔离5.1 LLM 判分器为什么时好时坏第一个大坑就是 LLM 判分器的不稳定性。上线初期经常出现同一个 case 连续跑了两次一次显示合规一次显示违规毫无规律。排查了半天原因有两个。一是判分时的生成参数没固定。默认的 temperature 不是 0模型每次输出的概率分布都有波动同样的输入会产生不同的判断。解决办法很粗暴把判分模型的 temperature 固定为 0关闭随机性。二是判分标准太抽象。最初判分提示词里写的是“判断回复是否友好”这种词模型每次理解都不一样。后来我们把每个主观项都拆成更小的布尔问题比如“是否使用了威胁性语气”“是否出现连续重复内容”“是否拒绝回答但没有给出替代方案”。布尔问题的稳定性远高于“友好度打分”。但即便这样偶尔还是会出现模型误判。我们加了最后一层保险同一个 case 用两条不同路径的判分 Prompt 各判一次结果一致才通过不一致就转人工抽检。虽然成本高了但评测平台本身必须是可信的否则没人敢信它的结论。5.2 用例污染Agent 开始“背答案”第二个坑也是我们后知后觉发现的模型开始在评测用例上“过拟合”了。具体表现是日常回归分数稳定上涨但每次上新题分数都会明显掉一截。很长一段时间我们都以为只是“新题更难”后来才意识到研发同学在优化模型和 Prompt 的时候已经潜移默化地把固定评测用例里的题型信息带进去了。模型见过这些问题太多遍学会的不是“解决问题”而是“对这些问题输出标准答案”。这不是故意作弊而是整个评测机制天然会诱发的问题。我们做了三层改进引入私有留出集一批新题只在发版前跑不进日常回归研发平时看不到题面。题库定期轮换每次回归从大题库里随机抽一部分而不是全量固定跑减少模型“背题”的机会。强调效果而非答案在评测维度里增加对“推理过程”的检查让模型知道判分看的是过程合规和关键信息覆盖而不是某一句标准话术。5.3 并发评测时的状态互相污染第三个坑是典型的工程细节问题。平台上并发跑几百条用例经常出现“单独跑一条能过并发跑就挂掉”的诡异现象。查到最后发现是状态污染。Agent 的工具调用会读写一些共享缓存和会话状态并发场景下case A 的上下文串到了 case B 里导致 Agent 以为自己已经查过订单了实际上根本没有。解决办法是强制隔离一切可变状态隔离项风险处理方案会话状态Case 之间上下文串线每条用例独立 session按 case_id 隔离Mock 数据共享 mock 导致数据覆盖每条用例创建独立的 mock 数据副本缓存Agent 读取到其他用例写入的缓存评测环境禁用共享缓存或按 trace_id 隔离中间件状态限流、熔断误伤评测流量走独立队列不触发线上防护策略这个坑告诉我们评测平台自身的稳定性也是一项治标治本的工作。评测结果里的“失败”必须是 Agent 真实能力的失败而不能是基础设施串线造成的假失败。6. 关于 Agent 评测的几点后续思考6.1 评测平台守的是“下限”不是“上限”做了这么久我最大的体会是评测平台本质上是个“守下限的系统”它没办法帮你做出一个惊艳用户的 Agent但能防止你带着明显瑕疵上线。这就像工厂里的出厂质检线。质检不能保证产品一定大卖但能防止把一批次品发到客户手里。没有质检线产品偶尔超常发挥偶尔完全翻车业务没法稳定运转有了质检线也许产品不会每次惊艳但至少表现是稳定的、烂也是烂在明处团队知道改哪里。所以如果你想靠评测平台来回答“这个 Agent 到底能带来多少业务增量”大概率会失望。它更适合回答“这次改动有没有把老问题搞坏”“这个新场景能不能撑住底线”。6.2 评测得从“结果判断”走向“过程判断”当前评测体系里我们对“结果”的判断已经比较完善但对“过程”的判断还非常粗糙。而这个缺口正在变得越来越关键。很多线上问题并不是最终结果错了而是过程出了问题。比如 Agent 在合规底线边缘反复试探跟用户说“我可以试着申请但不保证成功”看起来没问题但话术里隐含了不该有的承诺再比如 Agent 绕了很多弯调用了一堆不必要的工具最终结果是对的但效率极低用户等得很不耐烦。后续我想把评测的重心从“最后那句话对不对”往“中间每一步该不该这么做”迁移。具体来说把会话轨迹拆成行为标签序列比如“查询订单”“解释原因”“主动承诺”“请求确认”再拿这个序列跟专家标注的“最优行为路径”做比较。这个方向工程量不小但我觉得是 Agent 评测绕不开的一站。6.3 评测平台自身也要有演进闭环最后一个思考是关于平台自身的。评测平台很容易做成一个一次性的工具但 Agent 在持续进化评测平台也必须跟着进化。我们现在已经在做的一是把线上用户的负面反馈自动回流到评测用例池里。线上出现一例投诉沉淀成一个新的评测用例下个版本重点盯。这样评测题库会跟着业务痛点一起长。二是判分器自身的纠错机制每次人工抽检发现的误判都会回到判分提示词或规则库里逐步减小判分盲区。如果让我重新做一次这个平台我会更早动手。业务 Agent 的评测这事永远没有“等数据攒够了再开始”的说法从第一条用例开始沉淀结果自然会慢慢长出来。