☰
AI Agent 稳定化:从评测闭环到成功率提升的完整实践
2026/10/14 10:38:39 网站建设 项目流程

从偶尔成功到稳定可用:AI Agent 的评测闭环

最近小半年我一直在跟 AI Agent 打交道,最深的感受可以用一句话概括:Agent 跑通一个 demo 不难,难的是把它从“偶尔成功”打磨成“稳定可用”。很多团队卡住的位置,其实不在模型选型、不在 Prompt 技巧,而是缺了一个真正在运转的评测闭环。没有闭环,Agent 的每一次改动都是一次赌博——这版 Prompt 上线后成功率是涨是跌,没人说得清。今天想系统聊聊我在这条路上踩过的坑和最终沉淀下来的方法,希望对你手头的 Agent 项目有点参考价值。

所谓评测闭环,简单说就是:有一套覆盖典型场景的测试集,能自动跑、自动判定结果,每次改动后拿同一把尺子去量,把失败样本捞回来做归因,再把修复后的 case 加回测试集防止回退。听起来很朴素,但真正做到位的团队并不多。多数情况是测了但没形成闭环,比如测试集是临时的、判定靠人肉看、失败样本看完就丢,结果回归问题反复发生。

  1. 为什么 Agent 会“偶尔成功”?先理解问题根源

1.1 Agent 和传统软件的不确定性差异

我们在排查 Agent 不稳定问题时,常说“不确定性来自三个层面”。第一层是 LLM 本身的非确定性:同样的输入,温度不为零时输出会有波动,即使设为 0,不同版本、不同部署环境下结果也可能有差异。第二层是环境状态的变化:Agent 要调工具、操作页面、读写数据,外部服务的状态、返回格式、网络延迟都会影响最终结果。第三层是多步执行中的错误累积:单步成功率如果是 95%,十步下来理论成功率只有 0.95^10 ≈ 60%,如果单步只有 90%,十步成功率连 35% 都不到。这就是为什么 Agent 看起来“大多数时候会做对”,但整条任务跑完经常挂掉。

传统软件的测试逻辑在 Agent 这里很难直接套用。对普通函数来说,输入确定,输出就能预期,断言写死了即可。但 Agent 面对同一个用户请求,可以用不同路径、不同工具组合完成任务,甚至最终答案的措辞都不一样。标准答案是“动态的”,必须有一套更贴近真实使用方式的评测体系,而不是简单地比对字符串。

1.2 我在早期踩过的“没闭环”的坑

最早的时候,我也经历过所谓的“感觉还行”阶段。demo 演示给团队看,跑几个精心挑的 case,效果确实不错。但一放到真实环境里,问题立刻暴露:有的用户问题换了个说法,Agent 就不理解了;某个第三方工具偶发超时,Agent 不会重试,整条链路直接断掉;最要命的是,我改了一版 Prompt,修复了之前的一个问题,结果另一类 case 的成功率掉了一大截,而当时完全没有手段发现这个回归。

后来想明白了:不是 Agent 本身不行,是我的工作方式不行。没有固定测试集,没有量化指标,没有自动化的回归对比,所有的“优化”都建立在拍脑袋上。一个人拍脑袋还能勉强撑住,团队一多就彻底乱套——A 改的 Prompt 破坏了 B 之前修好的行为,没人知道是谁、什么时候、改坏了什么。

1.3 评测闭环到底解决什么?

评测闭环解决的核心问题,是让 Agent 的稳定性从一个“感觉问题”变成一个“工程问题”。它给你三样东西:一是基线,告诉你当前这个版本的真实水平是多少分;二是方向,失败样本被归因后,你能知道瓶颈是在规划、工具调用还是结果输出;三是护栏,每次改动后只要跑一遍回归,有没有退化一目了然。

很多做 Agent 的人把精力大量花在 Prompt 调优上,但我的体会是,Prompt 调优的边际效益递减非常快。真正能让成功率稳步上升的,是后续那套“用评测数据驱动迭代”的机制。测试集就是你的方向盘,没有方向盘,油门踩得再猛也容易翻车。

  1. 搭一个评测体系,先解决“拿什么测”和“怎么算分”

2.1 明确评测指标:不要只盯成功率

“成功率”当然是核心指标,但只盯成功率远远不够。我常用的指标分为四组,建议你根据业务形态取舍。

第一组是任务级别指标:任务成功率(Task Success Rate)、目标达成度(Goal Completion Rate)。定义要清晰——什么算成功?是 Agent 给了用户正确答案,还是用户问题背后的目标真正被完成了?我倾向于以“用户目标是否被满足”为准,超出用户预期的部分不作要求,但在标注时需要明确规则。

第二组是过程质量指标:工具调用准确率(Tool Call Accuracy)、关键路径合规率(Path Compliance Rate)、无效步骤数。Agent 最终结果对了,但过程非常绕,或者调用了不该调的工具,这在生产环境里往往意味着后续维护成本高、出错概率大。评测时我会同时看结果和过程。

第三组是效率成本指标:平均耗时、平均 Token 消耗、平均工具调用次数。Agent 不是越聪明越好,是“在保证成功率的前提下尽量少花钱、少绕路”。如果一版改动让成功率微增 1% 但成本暴涨 30%,那这笔交易通常是不划算的。

第四组是稳定性指标:同一 case 跑 N 次的成功率方差。Agent 的非确定性决定了同一个 case 不可能每次都成功,方差越大意味着越不可控。比如某类 case 跑五次,两次成功三次失败,这在线上就是用户时而满意时而不满意的原因。

2.2 测试集构建:从真实流量里来,再人为补边界

测试集太小没有统计意义,太大会让每次评测的成本不可接受。我的经验是:起步阶段 30~50 条精选 case 就能用,覆盖主要用户场景即可;随着产品迭代逐步扩充到 200~300 条,重点是维持场景覆盖度和边界 case 的比例。测试集来源主要有三个渠道。

第一个是从真实用户请求里采样。把自己产品的用户日志拉出来,按场景聚类,每个聚类选代表性问题。这一步最珍贵,因为它能暴露你“没想到”的情况。第二个是基于业务场景矩阵人工构造。把“用户类型 × 意图类型 × 操作对象难度”填满,比如简单查询、多条件筛选、跨模块操作、异常输入处理,每个格子写一两条 case。第三个是人为制造边界和陷阱:超长文本输入、包含歧义表述、需要 Agent 主动询问澄清、工具返回错误需要 Agent 判断重试等,这些 case 是提高鲁棒性的关键。

此外还要做难度分层。我习惯把 case 分成简单(单轮、单工具)、中等(多步、状态切换)、困难(长链路、多工具、容错要求高)三档。初期测试集可以中等难度为主,因为太难的全挂、太简单的没有区分度,都不利于迭代方向判断。

2.3 标注“标准答案”时容易忽略的事

测试集字段通常包含:输入(用户请求)、期望目标(用户真正想要的最终状态)、可接受路径(哪些工具调用顺序是允许的)、边界条件(哪些输入必须拒绝或澄清)、评判要点(结果里必须出现的关键信息)。我踩过的坑是只写期望结果,不写可接受路径。后来发现 Agent 用了一条我完全没想到但很优雅的路径完成了目标,结果被判失败,浪费了大量排查时间。现在我会在标注时写上“结果正确即可,路径不作强制要求”或“必须走某个特定流程”,把评判标准提前讲清楚。

另外,不要只保留“标准输入”,还要保留当时的环境快照。比如涉及查询天气、查快递这类依赖外部数据的 case,如果第三方 API 返回不同,Agent 的行为就会变。用 mock 固定住依赖的数据,评测结果才有可比性。

  1. 自动化评测执行:把“人肉看结果”变成“机器跑、机器判”

3.1 评测 runner 的基本架构

自动执行层,我用 Python 写过一个轻量 runner,核心思路很简单:逐条读取测试集 → 构造运行环境 → 运行 Agent → 采集轨迹 → 执行判定 → 输出结构化报告。Runner 本身不复杂,真正花心思的是“环境隔离”和“数据固定”。

环境隔离指的是 Agent 运行时依赖的外部服务全部用 mock 或者沙箱替身。比如 Agent 要调支付接口、要读写某个数据库、要操作一个页面,在评测环境里全部换成可控的假服务。假服务返回什么数据,测试集里写死,这样 Agent 的行为就只跟它的决策逻辑相关,跟外部波动无关。有人担心“mock 和真实环境不一致”,这个担心是合理的,但评测闭环的定位是“快速回归防线”,不是“全链路压测”。真实环境的稳定性,留给专门的线上监控来做即可。

3.2 判定方式:规则优先,模型评判兜底

自动判定是评测闭环里争议最多的一环。我的原则是三层结合:能用规则判定的绝不用大模型,能用药水判定的不轻易上主观分。

第一层是严格规则判定。对结果有明确结构化约束的场景,比如 Agent 需要输出一个 JSON、调用某个工具并传参正确,直接用断言判断。字段缺失、类型错误、参数越界,这些用代码写死即可,速度快,零成本,完全确定。

第二层是宽松规则判定。结果是非结构化文本,但有关键要素,比如“回答里必须包含订单号”“不能出现某些误导性表述”,用关键词、正则表达式检查。注意这种情况容易误伤——Agent 语义上正确但表述完全不同,关键词匹配容易产生漏判。

第三层是大模型评判(LLM-as-a-judge)。拿一个独立的、性能较强的模型当裁判,给定用户请求、Agent 的完整轨迹、标准答案,输出“成功/失败”以及原因说明。实战中我总结出的要点是:裁判模型的判定提示词必须结合评分标准一起给,比如“用户的核心目标是否被满足”“是否存在未完成的关键步骤”“是否产生了误导性信息”,逐条打分后再汇总。同时要控制裁判模型的随机性,温度调成 0,并且最好跑两次取多数结论,因为法官模型自己也会抖动,单次判定不够稳。

3.3 把评测接入版本迭代流程

评测体系要发挥最大作用,必须嵌到开发流程里,而不是等到上线前临时跑一次。我的建议是搭一套自动化任务,每次代码或 Prompt 变更时自动触发回归。触发机制可以是提交代码后、合并请求时或者发布前,结合自己的工程习惯来。

回归策略我一般设置两级。第一级“冒烟测试”:从全集里抽 15~20 条最容易失败的、最核心的 case,5 分钟内跑完,做成合并请求的门禁,挂了就拦住,不让劣化版本进去。第二级“全量评测”:所有 case 全部跑一遍,可能耗时较长,放在后台跑,跑完出报告,作为版本发布的参考依据。报告里最关键的是“对比上一版基线”的差异列表——哪些 case 从成功变失败(回归)、哪些从失败变成功(进步)、哪些一直失败(未解决)。只看这个差异列表,就能快速定位改动造成的真实影响。

3.4 基线管理:没有基线的评测等于没有评测

第一次建立自动化评测后,我犯过一个错误:跑完发现成功率 67%,团队觉得低,但不知道是低了还是正常水平,更不知道应该往哪个方向优化。后来才意识到,评测结果必须挂在某个“版本基线”上才有意义。

我的做法是:每发布一个正式版本,就把这次全量评测的结果固化成基线。后续的每一次实验改动,都跟最近一次基线做对比。基线的保存内容包括:每个 case 的成功/失败标签、Agent 的输出轨迹、耗时和成本数据。这样当你回溯“到底哪个版本开始某类 case 开始挂”的时候,可以翻历史数据而不是靠回忆。基线更新的时机也很重要:如果当前版本相对上个正式版有明显改进,且稳定运行了一段时间,就可以把它设为新基线。

  1. 失败归因:从“有 case 挂了”到“知道为什么挂、改哪里”

4.1 记录足够完整的轨迹是归因的前提

评测系统不仅要记录“成功还是失败”,还必须记录完整的决策轨迹,包括:Agent 每一步的思考内容、每次工具调用的输入与输出、每一步的耗时、最终答案、以及各环节的 Token 消耗。没有轨迹数据的评测报告,就只是考试分数,对优化毫无帮助。

这里有一个容易被低估的点:轨迹数据的存储结构要提前设计好。不要事后从日志里翻,成本太高。我现在的做法是让 Agent 在运行时把所有决策步骤和工具调用结构化输出,统一入库,评测报告直接关联这些结构化数据。这既方便自动化的失败聚类,也方便人工快速定位问题环节。

4.2 把失败样本做聚类,找到共性病灶

当全量评测跑完,可能有二三十条失败 case。逐条去查太耗时,而且容易陷进个案细节里。更好的办法是把失败 case 按“失败模式”聚类。

我常用的聚类维度有三个。按失败阶段分:是规划环节就错了(Agent 选择的工具或路径根本不对)、还是执行环节出错(工具调用参数传错、接口报错没处理)、还是最终结果有误(答案内容没满足用户要求)。按失败类型分:幻觉编造、信息缺失、指令遵循失败、上下文混乱、工具交互错误。按触发场景分:是不是特定格式的输入必挂?是不是某个特定工具必挂?聚类出来后,往往能发现“80% 的失败集中在 2~3 个共因”上,这时修复方向就非常清晰了。

举个例子:一次评测中某类 case 大面积失败,逐条看发现它们都涉及同一个外部服务 mock 的返回值变化——一个字段从字符串改成了对象,Agent 解析失败,直接崩溃。聚类后一天就定位到原因,修好解析逻辑后这批 case 全过了。如果当时逐条处理,可能还在跟 Prompt 较劲,方向完全跑偏。

4.3 归因时要区分“模型问题”和“工程问题”

失败归因时最怕一种情况:不管什么问题都归结为“模型能力不够”,然后盲目调 Prompt 或换模型。实际上很多失败根因不在模型,而在工程设计。比如工具描述不清晰导致 Agent 理解错了用法,这是工具层问题;状态管理不当导致超时后没有重试机制,这是代码层问题;外部服务返回了非预期格式没有兜底,这也是代码层问题。

我的经验是准备一份归因检查清单:先确认输入是否正确;再确认工具定义与返回格式是否符合预期;然后看 context 是否足够、是否有遗忘或截断;最后才考虑是 Prompt 指令不清还是模型本身能力边界。按这个顺序排查,能把相当一部分“模型问题”降级为“工程问题”,而工程问题的修复是确定性的,改完就有效。

  1. 从评测到迭代:让闭环真正转起来

5.1 每一次改动都是一个小型实验

评测闭环运转起来后,Agent 的迭代模式会发生质变。以前是“改一版 Prompt,感觉应该更好”,现在是“改一版 Prompt,用同一批 case 跑一遍对比”。我把每次实验当作一次小型 A/B 测试来处理:控制变量只改一个维度,比如只改 Prompt 或只改工具描述;用同一测试集;跑多轮取平均,因为单次评测受随机性影响太大,短期抖动可能被误判为成功或失败。

具体操作上,我会在改动前后各跑三轮全量评测,对比三轮的中位数和波动范围。如果改动后的成功率均值提升超过两个 case,且没有新增严重回归,才算一次有效改进。如果成功率没变,但 Token 消耗显著下降,也算有效改进,因为成本也是稳定性的一部分。

5.2 失败的 case 是下一次迭代的起点

一个能持续推进的闭环,必须把“失败的 case”转化为“新的测试用例”。每次全量评测发现的失败样本,人工确认后如果属于合理的、应该支持的真实场景,就保留在测试集里成为一个新的 case。下一次改动后,它会被自动跑一遍。如果修复好了,就保持;如果没修复,继续留在失败列表里。这套机制保证了测试集永远不会被“刷熟”——因为每次评测都会用真实业务场景不断注入新样本。

还有一个反直觉的经验:不要让测试集无限膨胀。case 太多了,评测成本高、失败样本聚焦困难,反而降低迭代速度。我会定期做一次“测试集评审”:把过去一个月全部跑通的、没有产生过失败的大批 case 降权或移入低频池子,保持核心测试集在 200~300 条的规模,确保每次迭代的反馈信号足够清晰。

5.3 防过拟合:测试集也会骗人

当某一类失败被反复修复后,Agent 可能渐渐“背下”了测试集的答案,而不是真正学会了泛化。一个典型的信号是:测试集成功率接近 100%,但线上真实用户满意度没有明显改善。这时候就要做防过拟合处理。

我的做法有几个:定期引入新采样用例,让测试集跟得上真实分布变化;在测试集里加入同义改写、句式变换、上下文微调的变体,增加覆盖度;保留部分“真实冷启动式”的开放 case,这些 case 无法靠记忆套路完成,必须依赖 Agent 的真实推理能力。另外,如果发现某些 Prompt 规则到了“为过测试集而写”的程度,就要警惕了,可能是优化方向出了问题。

  1. 常见问题与排查经验实录

6.1 一张实用的评测问题速查表

现象可能原因处理建议
同一版本跑三次成功率差异大LLM 非确定性、未固定随机种子/温度温度设为 0,多次运行取中位数,检查环境依赖
新版相比旧版成功率不升反降改动影响了其他场景看回归差异列表,定位具体 case,把改动回滚或缩窄边界
单个 case 单独跑成功,全量跑失败上下文清理不彻底、资源竞争、状态残留检查 Agent 运行隔离性,每条 case 独立实例
Mock 返回正常,真实环境表现差Mock 数据跟真实数据分布不一致定期从真实日志里抽样,更新 mock 数据模板
大模型裁判误判明显评判标准不清晰、模型自身偏好细化评判标准、明确路径合规规则、跑两次取多数
测试集成功率高,线上反馈差测试集过拟合或覆盖不足引入新采样用例,增加开放式场景,减少“背题”可能

6.2 踩过坑之后我才学到的几个真经验

第一个经验是:优先做确定性高的断言。哪怕一开始能自动化判定的 case 比例不高,也先把那部分做扎实,再逐步扩展到大模型评判。纯模型裁判的评测系统看起来很省事,但裁判自身的不可靠会让整个评测结果的可信度下降,团队对数字的信任一旦崩塌,闭环就废了。

第二个经验是:评测用例的可维护性,跟写好的代码一样重要。每条测试用例的标注者、标注时间、标注理由都要留下来。初期的 case 可能过半年之后发现标准过时了,没有标注信息时根本不知道当初为什么这么定,也没法判断该不该改。

第三个经验是:不要追求一度评测结果好看,要追求“对比之后趋势向上”。如果每次评测都在波动,只需要确保“这周的平均水平高于上周的平均水平”,而不是“每一次都绝对进步”。Agent 优化本来就是一个涨涨跌跌、总体向上的过程,认清这一点能省下很多不必要的焦虑。

第四个经验是关于团队协作的:评测结果谁都可以看,但测试集变更必须有权限管理。如果人人都能往测试集里加 case,很快测试集就会变成“谁的嗓门大谁的需求占比高”,失去客观性。统一由一个人或一个小团队负责测试集的维护和评审,其他成员可以提交新 case 建议,但合并需要经过审查。

最近我在做一个面向业务场景的 Agent 重构时,明显感觉到评测闭环的价值已经不是锦上添花,而是整个项目的“地基”。没有这套地基,上面的每一层优化都是悬空的。我把自己的评测流程不断简化,现在核心操作就三步:跑全量回归、对比基线、捞失败样本做归因。有时候一个下午就能完成一个完整的“发现问题、修复、验证、回归”循环,这在做闭环之前是完全不敢想象的。

如果你也在做 Agent 类的项目,我真心建议不管项目多早期,都先把最小可用版本的评测闭环搭起来。不需要一开始就搞大平台、复杂指标,先有 20 条能跑的 case、一个能判定的脚本、一份能对比的基线,就足够让你的每一步优化都走得有底气了。后面你可以不断往里加 case、加指标、加自动化,但第一步的关键是让“评测”这件事真正开始运转起来。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询