ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

业务Agent评测平台建设实践:架构设计、评测集与踩坑全记录

业务Agent评测平台建设实践:架构设计、评测集与踩坑全记录

做业务 Agent 有些日子了。我们平台在同城货运这个赛道上跑了不少场景:用户咨询、司机调度、运营助手、订单异常处理……模型的能力肉眼可见地在进步,但真正让人头大的从来不是“模型能不能答”,而是“怎么证明它这次能答得更好,而且改了不会把别的地方弄坏”。这也是我们花了不少力气从零搭起一套业务 Agent 评测平台的原因。这篇文章把这些工程实践完整记录下来,包括架构怎么设计、评测集怎么建、执行器怎么做、结果怎么分析,以及一堆只有实际跑起来才会踩到的坑。如果你是做大模型应用、Agent 系统,或者日常要给 prompt 和工具调用做回归测试,那这部分经验应该能直接抄作业。

我先把结论放在前面:Agent 评测平台不是一个测试工具,它是一套基础设施,核心目标是让 Agent 的每一次迭代都“可度量、可追踪、可回归”。它不能完全替代人工评估,但可以把人工检查的范围从“每轮对话都盯”缩小到“只在关键变更时看报告”。下面我从为什么做到怎么做,再到踩过哪些坑,按工程落地的顺序展开。

1. 为什么需要一个专门的 Agent 评测平台

1.1 业务 Agent 落地前的真实困境

传统软件开发里,一个功能改完可以靠单元测试、接口测试来兜底,回归是件相对确定的事。但大模型应用完全不是这个玩法。同一个 prompt,上一版输出是好的,下一版可能就换了个语气,甚至同一版本同一输入在不同时间跑,结果也可能有细微差别。这种不确定性的叠加,导致你根本没法用传统测试的思维来管理 Agent 质量。

我们当时面对的是一堆散在各业务域的对话型 Agent。举个例子,用户在订单页发起退款咨询,Agent 需要先识别用户诉求是“仅退款”还是“退款+申诉”,然后决定是直接调用退款接口,还是先触发人工客服介入。这里面牵扯到意图识别、工具调用、话术生成三个环节,任何一个环节发生变化,都可能让整条链路的体验出现落差。可问题在于,prompt 里加一句话、工具描述改一个词,到底会不会影响其他场景,光靠看代码和拍脑袋是判断不出来的。

于是你只能依赖线上指标,比如转人工率、用户满意度、任务完成率。但线上指标的问题是噪声大、反馈慢,而且一个指标的波动往往有太多干扰因素,很难把它归因到某一次 Agent 变更上。更现实的是,很多业务 Agent 每天的调用量分散在大量低频场景里,等你在线上看出异常,影响面可能已经不小了。

1.2 评测平台要解决的三类核心问题

我们在设计评测平台时,把需求收敛成了三个场景,这三个场景基本上覆盖了 Agent 日常迭代的全部诉求。

第一是版本回归。这是最频繁的诉求。每次改 prompt、换工具参数映射、调对话策略,都需要拿同一批评测样本跑一遍新旧版本,看分数是升是降,看哪些 case 从好变坏。这个场景要求评测平台有严格的版本管理能力,样本不允许在对比过程中被改动。

第二是方案选型。同一个业务问题,可能有好几种 prompt 写法,也可以让 Agent 走不同的工具链。比方说同样处理“用户投诉司机迟到”,一个方案是让 Agent 先查订单再判断是否需要补偿,另一个方案是直接转人工客服。到底哪个方案更合理,空对空争论没有意义,拉出来在同样一批评测集上跑数据才是说服力的来源。

第三是模型替换评估。业务 Agent 的基座模型不可能永远不变,可能是换了更强的模型,也可能是为了降本换了小参数模型。模型替换最怕的是“平均指标没掉但某个高频场景崩了”,评测平台要能给出分场景、分维度的细化对比,而不是一个总分糊弄过去。

1.3 我们曾经用过的“土办法”及局限

在评测平台之前,我们确实靠土办法撑了一段时间。最早是维护一个共享表格,里面记录了几十条典型的用户问题,每期发版前人工拿这些问题去对话一遍,看看回答是不是正常。这个方法在 Agent 只有一个、场景只有几十条的时候勉强够用,但后期根本玩不转。

手工测试有三个核心问题。第一,用例在表格里,执行靠人肉,每个人对“答得好不好”的标准不一样,有人说“够礼貌就行”,有人说“必须给出具体方案”,同一段输出在不同人手里可能得到完全相反的结论。第二,样本扩散严重,今天发现一个 bad case 就加一行到表格里,但没有人维护这些样本背后的场景分类和预期行为描述,半年之后表格里的样本已经变成了一个无人能解释的“黑盒”。第三,没有自动化的回归能力,表格里的样本就算再多,也只能证明你这次测试通过了,没法证明上一版没坏。

我后来一直跟同事讲,Agent 的评测不是“测一下看看行不行”,它本质上是给 Agent 建一个“考试系统”——出题、答卷、阅卷、报告、留档,每一步都需要工程化。这也是我们决定自己搭一套体系化评测平台的根本原因。

2. 评测平台的整体架构设计与评测类型拆解

2.1 总体架构:四个核心模块

评测平台的整体架构可以拆成数据层、执行层、评估层和结果层四块。每一层职责清晰,层与层之间通过标准数据格式对接,这样每个模块都可以独立演进。

数据层负责评测集的生命周期管理,包括样本的创建、版本标注、场景标签、数据集快照,以及评测集与 Agent 版本的绑定关系。执行层是评测平台的心脏,负责调度评测任务、初始化不同版本的 Agent、控制并发、采集运行时的完整 trace。评估层则通过多个评估器对输出进行打分,既包括硬性的规则判断,也包括大模型做裁判的语义评估。结果层负责汇总、比对、生成报告,以及把评测结果沉淀成历史记录,供后续做趋势分析和回归预警。

这四层看起来不复杂,但真正落地时每一层都有不少细节。比如执行层需要考虑 Agent 版本怎么在同一个环境里同时拉起,评估层需要考虑不同评估器之间的权重如何设定,结果层则需要解决“怎么判断这次得分提升是真提升还是噪声”这类统计问题。后面我会逐一展开。

2.2 评测类型的差异:不能一套逻辑走天下

Agent 评测和传统的 QA 评测差别很大,一个显著原因是 Agent 的交互形态非常多样。我们当时把评测类型分成了四类,每一类的断言方式和评估策略都不一样。

开放问答型是比较基础的,用户问一句,Agent 答一段,评测重点在答案的正确性、完整性和业务合规性上。多轮对话型则需要对多轮历史上下文建模,评测不仅要看最后一轮的输出,还要看 Agent 在对话过程中的信息收集是否完整、有没有提前承诺不能承诺的内容。工具调用型的核心是看 Agent 是否在正确时机调用了正确的工具,并传入了正确的参数,这需要依赖 Mock 系统提供可控的工具响应。流程型任务则更复杂,它涉及一整套业务动作,比如从识别用户意图开始,经过查询订单、计算金额、生成补偿方案,到最后执行操作,整个链路由多个工具和多次决策组成。

这四类评测在断言层面差异非常大。比如开放问答型你可以让大模型裁判按维度打分,但工具调用型必须做严格的结构化断言,调用错了工具就是错的,语义再流畅也不能给分。而流程型任务更关注整条链路的完整性,某个步骤缺失可能导致整个任务失败。评测平台在设计评估器时,必须能够区分这些类型,针对不同的任务形态挂载不同的评估策略,绝不能用一套通用评分逻辑包打天下。

2.3 从业务中拆解评测场景的方法

评测集的第一需求来源一定是业务本身。我们当时和业务团队开对齐会,把各业务域的 Top 用户问题、SOP 文档、异常处理流程都拉了出来,然后按“业务风险等级 × 触发频率”两个维度对场景做排列。

具体来说,我们用 P0/P1/P2 给场景分级。P0 场景是高频且风险高的,比如订单取消、退款金额计算、司机改派;P1 场景是低频但风险极高,比如重大客诉、安全事故处理;P2 场景是长尾的普通咨询。每个 P0 场景至少要有 20 条评测样本,P1 场景至少要有 10 条,P2 场景则可以适当减少。这样拆下来的好处是,评测集的构建不会变成“为凑数量而凑数量”,而是真正围绕业务风险去铺样本。

一个很深的体会是:评测场景的梳理不能只盯着“正常流程”看,更要把“异常分支”单独拎出来。比如 Agent 在处理退款时,遇到订单不存在怎么办?遇到用户已经申请过一次退款怎么办?遇到用户和司机各执一词怎么办?这些异常分支才是最消耗人工审核精力的地方,也是评测集价值密度最高的部分。

3. 评测数据集建设:从样本到规范的全流程

3.1 数据来源:线上会话与人工构造结合

评测集的样本来源,我们采用了线上真实会话抽取加上人工构造补充的双轨模式。

线上真实会话是最宝贵的种子数据。我们从日志系统里抽取了一段周期内各业务域的对话记录,然后按照意图标签和场景标签做聚类,把表达方式差异较大的用户问法都挑出来。比如同样是“查询订单到哪里了”,真实用户的表达可能是“我的东西现在到哪了”“都三天了怎么还没送到”“这个单子还有多久能到”,这三种问法在字面上差异极大,但意图完全一致。评测集如果把这类同意图不同表述的样本都覆盖到,才能真正检验 Agent 的泛化理解能力。

从线上抽样本时有两个关键步骤:一是脱敏,去掉用户的手机号、地址、订单号等敏感信息,这个环节必须流程化,不能靠人工肉眼检查;二是过滤,线上会话有很多是无效的,比如用户只发了一个表情、或者会话因为网络原因被中断,这些样本如果混进评测集,会显著增加评测结果的噪声。

人工构造的样本则主要用来覆盖线上尚未出现过或者频次极低的风险场景。比如某个新上线的业务规则,还没有真实用户问过,但我们知道它将来一定是高频场景,就需要手工编写对应的评测样本。这部分样本会由业务专家和产品经理共同审核,确保问法和预期行为的设置符合业务现实。

3.2 标注规范:多维标签与质检一致性

评测集里每个样本的标注质量,直接决定了评测结果的可信度。我们早期在这上面吃过亏——同一个评测样本,两个标注者对“预期行为”的理解不一致,导致评测执行完,同样的 Agent 输出在不同评测集版本下分数差距巨大。

后来我们把标注规范拆成了几个必填字段:意图标签、场景标签、对话类型、期望行为描述、必要工具调用链、禁止事项,以及可选的参考回复。期望行为描述这部分,我们要求标注者尽可能写清楚“Agent 应该获取什么信息、做出什么判断、输出什么结论”,而不是笼统地写“要能安抚用户情绪”。因为评测时我们希望的是,哪怕两个不同的 Agent 版本输出的话术完全不一样,在面对同一个业务问题时,它们的行为逻辑也应该指向同一套业务结果。

与标注规范配套的是质检流程。每个样本在创建后要经过一轮独立交叉审核,审核人不能是创样本的人。我们曾经统计过,交叉审核会发现大约 15% 左右的样本存在预期描述不清、意图标签错误、重复覆盖等问题。这个数字我很惊讶,也证明了交叉审核不是走过场,是真的能拦下问题样本。

3.3 评测集防污染:容易被忽视的坑

评测集污染是 Agent 评测里特别隐蔽的一个坑。一种情况是评测样本被混进了训练数据或 prompt 的 few-shot 示例里,导致模型记住了标准答案,评测分数虚高;另一种情况是评测集在不断迭代的过程中,样本被反复修改,旧版本和新版本用的根本不是同一套题,导致历史对比完全失真。

我们的做法是三条硬约束。第一,评测集管理的权限独立,生产环境使用的评测集不允许任何人直接编辑,所有修改必须通过评审流程并且生成新版本。第二,每次发布评测集新版本时,强制做差异报告,明确列出本次新增、删除和修改的样本,任何评测结论都必须标注它对应的评测集版本号。第三,定期从线上抽取新出现的用户问法加入评测集,防止评测集和线上真实分布脱节。做到这三点之后,评测结果的可信度和可追溯性有了明显提升。

我特别想强调一点:评测集不是越多越好,而是越准越好。200 条相互重叠、语义含糊的样本,远不如 50 条边界清晰、各有侧重点的样本有价值。因为评测集最终的价值在于“每一次跑完,你能明确知道哪个环节有问题”,如果样本本身含糊,跑完的结果也只会是一团迷雾。

4. 评测执行引擎与关键设计

4.1 Runner 设计:并发控制与 Trace 采集

评测执行引擎本质上是一个“跑批系统”,但它比普通的跑批任务要复杂,因为它需要以可控的并发对我们的 Agent 发起大量模拟对话,同时把每轮对话的完整轨迹保存下来。

我们在 Runner 设计时首先解决的是并发控制问题。Agent 评测会调用底层的模型 API 和业务系统,如果不做限流,一批评测任务跑下去可能直接把下游服务打挂。我们在 Runner 层做了两级限流:一级是按 Agent 实例维度限制并发数,避免单个 Agent 承载过大的模拟流量;另一级是按下游服务维度限制 QPS,尤其是对业务系统接口,我们设置了一个保守的阈值,宁可评测跑得慢一点,也不能给线上环境带来风险。物理隔离虽然更安全,但维护成本太高,我们采用了“安全可控的共享环境 + 严格限流”的折中方案。

Trace 采集是 Runner 设计里另一个关键点。每跑完一个评测样本,我们需要保存完整的会话记录,包括用户每轮的输入、Agent 的中间推理结果(如果没有隐去的话)、工具调用请求与响应、最终回复,以及每步的时间消耗。这些 Trace 数据有两个用途:一是用于人工抽样核查评测结果是否准确,二是用于 bad case 分析,当某个样本评测得分低时,我们能够顺着 Trace 定位到具体是哪一步出了问题——是意图识别错了,还是工具调用的参数没映射对,还是最终话术生成阶段走了样。

4.2 评估器实现:规则、断言与 LLM-as-Judge 的组合

评估器是评测平台最核心的组件,我们的经验是“不要把所有判断都交给大模型”。在评测体系里,能够用规则判断的,就一定用规则判断。

客观规则评估器用来处理那些具有确定性答案的指标。比如调用某个工具时,参数里的订单号是否与用户描述一致;返回的状态码是否为成功;Agent 是否在某个禁止场景下仍发起了工具请求。这类指标没有任何歧义,只需要做结构化断言就能给出确定性的通过/失败结论。还有基于内容匹配的规则,例如 Agent 的回复中是否包含必须展示的“损失说明”或“联系客服入口”,这类硬性约束也应该规则化。

语义评估器则用 LLM-as-Judge 的方式处理那些需要主观判断的维度,比如回答是否有帮助、语气是否得体、安抚是否到位。这里我们踩过不少坑,最核心的教训是:裁判模型必须提供明确的评分标准(rubric),否则不同批次打分的稳定性会很差。我们的做法是把每个评分维度拆成 3-5 条具体的行为描述,裁判模型需要逐条对照打分,而不是给一个笼统的总分。比如“完整度”维度,我们要求裁判检查回复里是否包含用户问题的直接答案、是否提供了后续操作指引、是否遗漏了关键信息点,只有三条都满足才能给满分。

在我们实践中,客观规则和语义评估的比例大概在 4:6 到 5:5 之间。如果一个评测集里 90% 的指标都需要靠大模型裁判主观判断,那这个评测集的置信度是存疑的——因为这意味着评测标准和业务确定性之间没有建立起足够强的关联。

4.3 结果比对与置信判断

评测平台最后呈现的结果,不应该只是“新版 85 分、旧版 80 分”这种简单对比。因为 Agent 的输出有随机性,即便是同一个版本在同一个样本上多跑几次,结果也可能有波动。拿单次跑分做结论,很容易被随机误差误导。

我们采用了两层策略。第一层是固定随机种子,让 Agent 的生成过程在相同输入下尽可能可复现。虽然大模型本身有随机性,但固定温度、固定 seed 后,波动范围会显著缩小。第二层是在做版本对比时,对评测结果做重采样统计,比如用 bootstrap 方法计算新旧版本的分数置信区间,如果两个版本的置信区间有重叠,我们会判定为“没有显著差异”,而不是简单地认为新版更好或更差。

这一点在实际决策中非常重要。早期我们没有置信区间的概念,有次新版 prompt 在 100 条评测集上比旧版高了 2 分,我们以为是一次有效改进就匆匆上线,结果线上真实数据反而不如旧版。后来重新跑了 3 次评测,发现新旧版本的得分波动范围本来就有 ±3 分,那 2 分的差异纯粹是噪声。从那以后,所有关键结论都必须基于多轮评测的一致趋势,而不是单次跑分。

5. 实操案例:一次 Agent 升级的完整评测流程

5.1 场景背景与变更内容

拿一个具体的例子来说明整个流程是怎么走的。我们有一个订单调度咨询场景,用户会问“为什么我这个订单还没有司机接单”“能不能帮我催一下”“我想取消订单”等。原来的 Agent prompt 比较简单,它只能识别用户意图并返回一句安抚话术。这次变更的目标是让 Agent 能够主动查询订单状态,再根据状态给出分级的处理建议。

变更内容有两块:一是修改了 Agent 的系统 prompt,加入了“先查单再判断”的思路;二是修改了工具参数映射,新增了一个“查询订单详情”的工具调用。这个变更涉及工具调用能力从无到有,风险不小,必须经过完整评测才能考虑上线。

5.2 评测用例设计与预期行为标注

针对这个场景,我们在评测集里新建了一个场景标签“订单调度咨询”,并添加了 20 条用例。其中 12 条是常规咨询,比如订单已分配司机、订单等待接单、订单已被接单但尚未到达,每种状态分别有 2-3 条不同表达方式的问题。4 条是异常边界 case,比如订单号不存在、用户提供的是司机端订单号、会话中同时提到了两个不同订单。剩下 4 条是最有价值的部分——混淆场景,比如用户先问“这个订单怎么回事”,紧接着又说“算了我要取消”,此时 Agent 必须先处理查单需求还是先进入取消流程,不同的行为路径会导致完全不同的业务结果。

每条用例的预期行为里,我们标注了“必须先调用查单工具,再基于返回状态组织回复”、“禁止在未查单的情况下直接给出‘已经催单’类回复”、“如果订单不存在,必须引导用户核对订单号”等硬性断言。这些标注不是参考话术,而是可执行的行为检查项。

5.3 执行评测与结果定位

评测执行时,我们把旧版 Agent 和新版 Agent 在相同评测集上各跑了一遍,并行对比结果。评测报告显示新版在 20 条用例上的整体通过率确实比旧版高了一截,主要提升来自常规咨询这一类,旧版只会给安抚话术,新版能给出更具体的状态说明和处理建议。

但规则评估器抓到了一个隐蔽问题:在两条“不同订单混淆”的用例里,新版 Agent 虽然正确识别了第一个订单的查单需求,但同时把用户在后续消息里提到的第二个订单也打到了同一个上下文中,导致查单工具被调用了两次且参数全部指向第一个订单。这个 case 如果只看语义分,模型裁判可能还会给较高的分数,因为回复内容很流畅,工具链也看似完整。但客观的 trace 断言一下子就暴露了参数映射的错误。

这就是评测平台的价值所在——它在界面上直接展示了调用链的每个节点,我们顺着 trace 发现新版 prompt 对“多订单会话”的规则约束不够明确,于是又迭代了一版 prompt,增加了“一次只处理一个订单,如需切换必须主动确认”的约束。新版本再次跑完测评,这 4 条用例全部通过。

5.4 上线决策与持续回归

上线决策的依据不只是一次评测的通过,而是连续 3 次评测结果一致稳定地优于旧版,且 P0 用例全部通过、P1 用例没有新增失败。满足这些条件后,新版才被允许发布上线。

上线之后,这个场景的评测集被纳入每日自动跑批,每天凌晨跑一遍,如果当天评测分数低于设定阈值,平台会自动触发告警,相关开发同学上班后第一件事就是去查评测报告,结合 trace 定位问题。这套机制跑通之后,该场景再没有出现过“改了 A 场景结果把 B 场景弄坏了却没人发现”的回归事故。

6. 工程实践中踩过的坑与排查实录

6.1 LLM 裁判打分不稳定

LLM-as-Judge 是我们最早踩也是最深的坑。最开始我们用 ChatGPT 风格的通用裁判提示词,结果发现同一个 Agent 输出,同一批样本,前一天跑和后一天跑,分数能差出 5-8 分。这个波动范围完全没法支撑上线决策。

排查下来是三个原因叠加。一是裁判模型没有固定的判定标准,它只能给一个“看起来还不错”的印象分;二是模型版本本身在更新,第二天底层模型的分布已经变了;三是评测结果的打分没有聚合策略,单次采样就被当成最终值。

解决方法是三管齐下:先把裁判模型的版本固定,不随线上模型自动升级;再给每个评分维度编写详细打分规则,要求模型逐条对照,减少主观波动;最后对每个样本做多次独立评估,取中位数或平均值作为最终分数。用了这些方法之后,LLM 打分的稳定性明显提升,同一个 case 在相同条件下的重复跑分基本能控制在 1-2 分以内的波动。

6.2 并发评测把下游服务打爆

评测平台刚上线时,我们设置了一个比较激进的并发数,目的是尽快跑完一批评测。结果某个深夜跑批时,Agent 在大量评测用例里密集触发了“查单”工具,下游订单查询接口直接被突如其来的流量打满,监控台一片飘红,只能紧急熔断。

这个问题给我们的教训很深:评测流量跟线上流量一样需要敬畏。我们后来把并发数调低了两个量级,并加了下游服务的流量控制,同时在评测任务启动前做一次“预检查”,大致估算这批用例会触发多少外部调用,超过预设阈值就拒绝启动。这里也给个建议:如果下游服务有独立的测试环境,优先用测试环境;必须在共享环境跑时,一定要控制 QPS 并且时刻盯着监控。

6.3 评测结果噪声大导致误判

这跟前面置信区间的问题是一脉相承的。有一次我们对比两个模型版本,跑了 120 条用例,新版总分高了 2.3 分,所有人都觉得可以上。但我顺手看了一眼分场景的得分,发现问题很微妙——新版在“投诉处理”场景里实际上比旧版低了 6 分,只是因为它在“普通咨询”场景里高出了很多,把总分拉了上来。

如果只看总分,这个版本绝对会被误判为“全面优秀”。拆分维度看问题之后,我们把这个版本打回,针对投诉场景做了专项优化。这件事让平台在产品层面强制要求:所有评测报告必须展示分场景、分维度的得分矩阵,不允许只放一个总分。改动之后,评测结论的可解释性大幅提高,决策质量也上来了。

6.4 评测集长期维护的成本与应对

评测集不是建完就能一劳永逸的。线上用户表达在演化、业务规则在调整、Agent 的能力边界在扩张,如果评测集不跟着更新,它迟早会变得陈旧,评测结果也会慢慢失去参考意义。

但我们也不能无节制地往评测集里加样本,因为每个样本都需要维护预期行为描述,样本一多,标注一致性就难以维持。我们采用的办法是“定期做样本淘汰”,每季度审视一遍现有评测集,删除那些已经被业务淘汰的用例、合并高度重复的用例,再加入新的线上真实样本。这个机制让评测集保持在一个比较精干的状态,也更利于维护。

从成本角度看,评测平台真正的投入大头不是代码开发,而是样本的梳理和业务对齐。开发一个 Runner 可能两周就完成,但把一个场景的评测样本打磨到经得起推敲,往往要一个月以上。这中间的差距,就是“能做出来”和“能放心用”之间的距离。

我个人在实际操作中的体会是:Agent 评测平台最大的价值不是帮你找到一个完美的 Agent,而是让你在每一次改动时都能快速回答“这次到底有没有变好、好在哪里、坏在哪里”。这种确定性,在大模型应用的工程化管理里非常重要。另外还有一个小技巧值得分享——评测集讲究“价值密度”胜过“数量规模”。20 条真正覆盖业务边界和异常分支的用例,远比 200 条泛泛而谈的普通问答更有用,因为它每一次跑完都能告诉你系统的真实短板在哪里。后续如果要做更深入的落地,可以考虑把评测结果和 trace 数据喂回给自动化分析模块,让平台不仅能“打分”还能“定位问题”,那会是另一个很有价值的方向。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进