AI Agent评测闭环实战:从偶尔成功到稳定可用 1. 为什么你的 Agent 总是“偶尔成功”1.1 从一次让人崩溃的演示说起上个月我帮一个朋友看他做的客服 Agent演示的时候一切正常用户问退货政策它准确调用了知识库检索回答得滴水不漏。结果第二天上线第一个真实用户问了个稍微绕一点的问题——“我上周买的东西包装拆了还能退吗”Agent 直接开始胡言乱语把退货政策编了一半还自信满满地给了个根本不存在的退货地址。这不是个例。我接触过十几个做 AI Agent 的团队几乎所有人都经历过这个阶段Demo 惊艳上线翻车。你调了十次成功七八次觉得“差不多了”但剩下那两三次失败在真实场景里就是灾难。因为用户不会给你十次机会一次错误就足以让他们关掉对话框。问题的根源在于大多数人做 Agent 的方式是“手工作坊式”的——改改提示词跑几个例子觉得行了就上。没有系统化的评测没有可重复的验证流程更没有从失败中自动学习的机制。Agent 的表现就像抛硬币你永远不知道下一次是正面还是反面。1.2 评测闭环到底在解决什么问题所谓“评测闭环”说白了就是给 Agent 装上一套自动化的体检系统。它要回答三个核心问题第一Agent 现在到底行不行第二不行的话是哪个环节出了问题第三改完之后是真的变好了还是只是碰巧这三个问题对应着评测闭环的三个关键能力可量化的评估指标、可定位的失败归因、可对比的迭代验证。没有这三样你的优化就是盲人摸象——今天觉得提示词加一句“请仔细思考”好像好点了明天又发现换个模型好像也行但到底哪个改动真正起了作用你根本说不清楚。我见过最离谱的案例是一个团队花了两个月调 Agent每次改完就找几个同事“感觉一下”觉得不错就上线。结果两个月后他们连自己最初版本的性能基线是多少都忘了。这种“凭感觉优化”的模式注定走不远。1.3 谁最需要这套东西如果你只是做个玩具项目跑几个例子乐呵乐呵那确实不需要。但只要你满足以下任意一条评测闭环就是刚需Agent 要面对真实用户用户不会容忍随机失败你需要知道成功率到底是多少。团队多人协作A 改了提示词B 换了工具调用逻辑没有统一评测根本不知道谁的改动是正向的。需要持续迭代今天加个新功能明天换个模型每次改动都可能引入回归问题。要向老板或客户汇报你需要拿出数据证明“这周比上周好了 15%”而不是“我感觉好多了”。我个人的经验是当你的 Agent 需要连续运行超过一周或者需要处理超过 20 种不同类型的用户输入时就必须上评测闭环了。再晚你欠下的技术债就会像滚雪球一样压得你喘不过气。2. 评测闭环的核心组件拆解2.1 测试用例集你的“考卷”决定了 Agent 的上限评测闭环的第一步是准备一套高质量的测试用例集。这东西就像给 Agent 出的考卷——考卷出得烂考出来的分数就没有意义。我见过很多团队的做法是随便找几十个问题跑一遍看正确率。这有两个致命问题第一问题分布不均匀可能 80% 都是简单问题Agent 随便答答就 90% 正确率但真实场景里用户问的全是那 20% 的难题。第二没有标准答案或者标准答案太死板Agent 换个说法就算错这也不合理。我的建议是测试用例集要满足三个条件覆盖真实分布从真实用户日志里采样或者至少模拟真实场景的问题分布。简单、中等、困难的问题比例要合理一般建议 3:5:2 或者 2:5:3。有明确的判定标准不是简单的字符串匹配而是要有语义级别的判定。比如用户问“退货要多久”Agent 回答“通常 3-5 个工作日”和“大概三到五天”都应该算对。持续更新每次发现新的失败案例就把它加进测试集。这样你的“考卷”会越来越贴近真实战场。我自己的习惯是维护一个“黄金测试集”大概 200-500 条覆盖核心场景和边界情况。每次改动后都跑一遍确保没有回归。另外还有一个“探索测试集”专门放那些新发现的、还没搞定的难题用来指导下一步优化方向。2.2 评估指标别只看“对”和“错”很多人评测 Agent 就只看一个指标准确率。这太粗糙了。一个 Agent 回答对了可能是因为它真的理解了也可能是因为它蒙对了。一个 Agent 回答错了可能是检索错了可能是推理错了也可能是格式错了。你只知道它错了但不知道错在哪就没法改。我通常会把评估拆成几个维度指标说明为什么重要任务完成率用户的问题是否被真正解决最核心的指标但粒度太粗工具调用准确率该调工具时调了没调的对不对Agent 的核心能力之一检索相关性检索到的内容是否真的有用决定回答质量的上限推理链正确性中间推理步骤是否合理影响可解释性和稳定性格式合规率输出是否符合预期格式影响下游系统对接响应延迟从输入到输出的时间影响用户体验这些指标不是孤立的。比如工具调用准确率低任务完成率肯定也高不了。但分开看你就能定位到具体是哪个环节拖了后腿。我一般会先看任务完成率如果低于预期再逐个维度排查找到瓶颈。2.3 自动化评测流水线让机器替你干活手工评测只能应付小规模一旦测试集超过 100 条手工跑一遍就要大半天根本不可持续。你需要一套自动化流水线。这套流水线的基本流程是加载测试集 → 逐条运行 Agent → 收集输出 → 自动判定 → 生成报告。听起来简单但有几个坑要注意判定逻辑要足够智能简单的字符串匹配肯定不行。我一般会用“规则判定 模型判定”的混合策略。规则判定处理那些有明确答案的比如“是否调用了搜索工具”模型判定处理那些开放性的比如“回答是否合理”。运行环境要隔离每次评测都要在干净的环境里跑避免缓存、状态残留影响结果。我习惯用容器化方案每次评测启动一个全新的实例。报告要可追溯不仅要看总体分数还要能下钻到每一条用例。哪条失败了失败原因是什么当时的输入输出是什么都要能查到。我自己的流水线大概长这样一个 Python 脚本读取 YAML 格式的测试集调用 Agent 的 API收集结果然后用一个判定模块打分最后输出一个 HTML 报告。整个流程跑一遍 200 条用例大概 10-15 分钟完全可以接受。2.4 失败归因从“错了”到“为什么错”自动化评测告诉你“错了 15 条”但不会告诉你“为什么错”。失败归因就是要把这 15 条失败案例归类到具体的失败模式上。常见的失败模式有检索失败知识库里明明有答案但没检索到或者检索到了不相关的内容。推理错误检索对了但推理过程中跑偏了比如把“退货”理解成了“换货”。工具调用错误该调工具时没调或者调错了工具或者参数传错了。格式错误内容对了但输出格式不符合要求比如该输出 JSON 却输出了纯文本。幻觉完全编造信息知识库里根本没有。我一般会先人工看一遍失败案例给它们打上标签然后统计各类失败模式的占比。如果检索失败占大头那就去优化检索策略如果推理错误多那就去调提示词或者换更强的模型。归因的粒度越细优化的方向就越明确。3. 从零搭建评测闭环的实操步骤3.1 第一步定义你的“成功标准”在写任何代码之前先想清楚什么样的 Agent 才算“好”这个问题听起来简单但很多人答不上来。我的做法是先跟业务方或者自己对齐三个问题核心任务是什么比如客服 Agent 的核心任务是“准确回答用户关于退换货、物流、支付的问题”。可接受的失败率是多少比如“核心任务完成率不低于 90%工具调用准确率不低于 95%”。哪些错误是绝对不能接受的比如“绝对不能编造退货地址”或者“绝对不能泄露用户隐私”。把这些写下来变成可量化的目标。这样你后续的评测才有方向优化才有终点。3.2 第二步构建测试集附具体方法测试集的来源主要有三个真实日志如果 Agent 已经上线直接从日志里采样。注意要脱敏去掉用户隐私信息。人工构造根据业务场景人工编写各种类型的问题。我一般会按照“正常问题、边界问题、对抗问题”三类来构造。失败案例回流每次发现新的失败案例就把它加进测试集。这是最宝贵的来源。构造测试集时每条用例至少包含以下字段- id: case_001 input: 我上周买的东西包装拆了还能退吗 expected_tools: [search_knowledge_base] expected_keywords: [拆封, 退货, 条件] category: 退货政策 difficulty: medium notes: 测试拆封后的退货政策注意区分拆封和使用这里的关键是expected_tools和expected_keywords。前者用来评测工具调用后者用来做初步的语义判定。当然更复杂的判定可以交给模型来做。我一般会先构造 50-100 条跑起来看看效果。然后根据失败情况有针对性地补充用例。测试集不是一次性的而是持续演进的。3.3 第三步搭建自动化评测脚本下面是一个简化版的评测脚本框架用 Python 写的你可以直接参考import yaml import json from agent_client import AgentClient from evaluator import Evaluator def load_test_cases(path): with open(path, r, encodingutf-8) as f: return yaml.safe_load(f) def run_evaluation(test_cases, agent, evaluator): results [] for case in test_cases: # 运行 Agent output agent.run(case[input]) # 评测 score evaluator.evaluate( outputoutput, expected_toolscase.get(expected_tools, []), expected_keywordscase.get(expected_keywords, []), input_textcase[input] ) results.append({ id: case[id], input: case[input], output: output, score: score, category: case.get(category, unknown) }) return results def generate_report(results): total len(results) passed sum(1 for r in results if r[score][overall] 0.8) print(f总用例数: {total}) print(f通过数: {passed}) print(f通过率: {passed/total*100:.1f}%) # 按类别统计 categories {} for r in results: cat r[category] if cat not in categories: categories[cat] {total: 0, passed: 0} categories[cat][total] 1 if r[score][overall] 0.8: categories[cat][passed] 1 print(\n分类通过率:) for cat, stats in categories.items(): rate stats[passed] / stats[total] * 100 print(f {cat}: {rate:.1f}% ({stats[passed]}/{stats[total]})) # 输出失败案例 print(\n失败案例:) for r in results: if r[score][overall] 0.8: print(f [{r[id]}] {r[input]}) print(f 输出: {r[output][:100]}...) print(f 得分: {r[score]}) if __name__ __main__: test_cases load_test_cases(test_cases.yaml) agent AgentClient() evaluator Evaluator() results run_evaluation(test_cases, agent, evaluator) generate_report(results) # 保存详细结果 with open(evaluation_results.json, w, encodingutf-8) as f: json.dump(results, f, ensure_asciiFalse, indent2)这个脚本的核心是Evaluator类它负责判定每条用例的得分。我一般会实现一个多维度打分的 Evaluator比如class Evaluator: def evaluate(self, output, expected_tools, expected_keywords, input_text): scores {} # 工具调用得分 actual_tools output.get(tools_called, []) if expected_tools: tool_score len(set(actual_tools) set(expected_tools)) / len(expected_tools) else: tool_score 1.0 if not actual_tools else 0.5 scores[tool] tool_score # 关键词得分 if expected_keywords: text output.get(text, ) keyword_hits sum(1 for kw in expected_keywords if kw in text) keyword_score keyword_hits / len(expected_keywords) else: keyword_score 1.0 scores[keyword] keyword_score # 模型判定得分可选 # 调用一个轻量级模型判断回答是否合理 # scores[model] self.model_judge(input_text, output.get(text, )) # 综合得分 scores[overall] (scores[tool] * 0.4 scores[keyword] * 0.6) return scores这个框架跑起来后你就能得到一个初步的评测报告。然后根据报告定位问题优化 Agent再跑一遍对比分数变化。这就是闭环。3.4 第四步建立迭代节奏评测闭环不是跑一次就完了而是要融入日常开发流程。我的习惯是每次改动后必跑不管是改提示词、换模型、还是调工具只要动了 Agent 的逻辑就跑一遍完整评测。每周一次全量评测即使没改动也跑一次确保没有环境变化导致的性能波动。每月一次测试集更新根据最近的失败案例和用户反馈补充新的测试用例。这样坚持下来你会有一个清晰的性能曲线知道每次改动到底带来了多少提升。数据不会骗人感觉会。4. 常见问题与排查技巧实录4.1 评测结果波动大今天 85% 明天 75%这是最常见的问题。原因通常有三个模型本身的随机性大模型输出有随机性同样的输入可能得到不同的输出。解决办法是固定随机种子如果 API 支持或者多次运行取平均。我一般会跑 3 次取平均分。测试集分布不均匀如果测试集里难题和简单题混在一起每次随机采样可能导致分布变化。解决办法是全量跑不要采样。环境不一致比如检索库更新了或者工具 API 版本变了。解决办法是锁定环境版本每次评测前检查依赖。我踩过最坑的一次是检索库的索引在后台自动重建导致评测时检索结果和之前不一样。后来我养成了习惯评测前先跑一个“环境检查”脚本确认所有依赖都是预期状态。4.2 模型判定太贵跑一次评测要花几百块用大模型做判定确实贵尤其是测试集大的时候。我的优化策略是规则优先能用规则判定的绝不用模型。比如工具调用、格式检查、关键词匹配这些都是确定性的。小模型判定对于需要语义理解的判定用一个小模型比如 7B 级别的就够了不需要用最大的模型。抽样判定如果测试集很大可以只对“规则判定不确定”的用例调用模型判定。比如规则判定得分在 0.5-0.8 之间的才需要模型介入。缓存结果同样的输入和输出判定结果可以缓存。我一般用 Redis 或者本地文件缓存避免重复调用。这样优化下来一次 200 条用例的评测成本可以控制在几块钱以内。4.3 Agent 在评测集上表现很好但上线后还是翻车这说明你的测试集没有覆盖真实场景。我见过太多团队测试集是自己人拍的脑袋想的跟真实用户问的完全不是一回事。解决办法只有一个从真实日志里采样。如果还没上线那就找一些真实用户来试用收集他们的输入。如果连真实用户都没有那就找几个不了解这个 Agent 的人让他们随便问你在旁边记录。你会发现他们问问题的方式跟你想象的完全不一样。另外对抗测试也很重要。专门构造一些“刁钻”的问题比如带错别字的、带歧义的、带多重意图的。这些在真实场景里很常见但人工构造测试集时很容易忽略。4.4 失败归因太耗时人工看不过来失败归因确实是个体力活尤其是失败案例多的时候。我的做法是半自动化自动聚类用文本聚类算法把相似的失败案例聚在一起。这样你只需要看每个簇的代表案例就能了解一类问题。自动打标训练一个简单的分类器根据失败案例的输入输出自动预测失败模式检索失败、推理错误、格式错误等。准确率不用太高70% 就行剩下的人工复核。优先级排序根据失败模式的影响面和修复难度排个优先级。先修那些“影响大、修复容易”的。我自己的经验是前 20% 的失败模式往往导致了 80% 的失败案例。所以不要试图一次性解决所有问题抓住主要矛盾就行。4.5 常见问题速查表问题现象可能原因排查方法解决方案评测分数波动大模型随机性、环境不一致固定种子、多次运行、环境检查锁定版本、取平均分评测成本太高模型判定调用过多统计模型判定占比规则优先、小模型、缓存评测好但上线差测试集不真实对比测试集和真实日志分布从真实日志采样、对抗测试归因耗时失败案例太多统计失败模式分布自动聚类、自动打标、优先级排序优化后分数没涨改动没生效或评测不准检查改动是否部署、评测逻辑是否正确确认部署、复核评测逻辑某些类别始终差该类问题本身难或测试集偏差分析该类失败案例针对性优化、补充训练数据5. 让闭环真正“闭”起来的关键细节5.1 评测集要“活”不能是死水我见过最可惜的情况是团队花大力气建了一个测试集然后就不管了。三个月后测试集还是那 100 条但 Agent 已经迭代了十几个版本真实用户的问题分布早就变了。这样的评测测出来的分数再高也没意义。测试集必须持续更新。我的做法是每次发现线上失败案例就把它脱敏后加进测试集。同时每个月 review 一次测试集把那些已经“太简单”的用例降权或者移除补充新的难题。这样测试集才能跟上 Agent 的成长。另外测试集要分版本管理。每次大改动前先冻结一个测试集版本改动后用同一个版本评测确保对比公平。我一般用 Git 管理测试集每次评测报告里都记录对应的测试集 commit hash。5.2 评测要“快”不能等半天评测速度直接影响迭代效率。如果跑一次评测要一个小时那你一天最多迭代两三次。如果跑一次只要五分钟那你一天可以迭代十几次。提速的关键在于并行化。测试用例之间是独立的完全可以并行跑。我一般用 Python 的concurrent.futures或者asyncio来并行调用 Agent。注意控制并发数别把 API 打挂了。一般 5-10 个并发就够了。另外增量评测也很重要。如果只改了检索模块那就只跑跟检索相关的用例不用全量跑。我一般会给测试用例打上标签比如retrieval、reasoning、format然后根据改动范围选择性地跑。5.3 评测报告要“可行动”评测报告不是给老板看的 PPT而是给你自己看的行动指南。所以报告里最重要的不是总分而是失败案例的详细信息。我自己的报告模板大概长这样评测时间: 2024-XX-XX 测试集版本: v1.2.3 Agent 版本: v0.8.1 总体通过率: 82.5% (165/200) 较上次: 3.5% 分类通过率: 退货政策: 90% (45/50) 物流查询: 85% (34/40) 支付问题: 75% (30/40) 其他: 80% (56/70) 失败案例 Top 5: 1. [case_023] 我买的东西还没发货能改地址吗 失败原因: 检索到了退货政策但没检索到改地址流程 建议: 补充改地址相关的知识库条目 2. [case_067] 退款到账要多久 失败原因: 工具调用正确但回答中编造了具体天数 建议: 在提示词中强调不确定的信息不要编造 ...这样的报告你一看就知道下一步该干什么。好的评测报告本身就是一份优化任务清单。5.4 把评测融入 CI/CD如果你的 Agent 是持续部署的那评测应该融入 CI/CD 流程。每次代码提交自动触发评测如果通过率低于阈值就阻止合并。我一般会在 CI 里配置两个阶段快速评测只跑核心的 50 条用例5 分钟内出结果。如果通过率低于基线直接 fail。全量评测跑完整的 200 条用例15 分钟内出结果。生成详细报告供人工 review。这样既能保证快速反馈又能保证全面覆盖。阈值怎么定我一般设成“不低于上次全量评测的 95%”。比如上次是 85%那这次快速评测至少要 80.75% 才通过。这样既能容忍正常波动又能及时发现严重退化。5.5 一个容易被忽略的细节评测数据的版本管理评测数据本身也需要版本管理。我见过团队因为测试集被误改导致评测结果不可比白白浪费了一周的优化。我的做法是测试集用 Git 管理每次修改都有 commit 记录可以追溯。评测结果存档每次评测的详细结果都保存下来跟测试集版本和 Agent 版本关联。基线管理维护一个“基线版本”每次大改动前先跑一遍基线确认当前性能。改动后再跑一遍对比差异。这样即使过了几个月你也能清楚地知道某个版本的 Agent 在某个版本的测试集上表现到底如何。可追溯性是工程化的基础。6. 从“偶尔成功”到“稳定可用”的实战心得6.1 先修“致命错误”再修“体验问题”评测报告里失败案例分两种一种是“致命错误”比如编造信息、泄露隐私、完全答非所问另一种是“体验问题”比如回答不够详细、语气不够友好、格式不够美观。我的原则是先修致命错误再修体验问题。因为致命错误会导致用户直接流失而体验问题只是让用户不爽。资源有限的情况下优先解决致命错误。怎么判断哪些是致命错误我一般会问自己如果这个错误发生在真实用户身上他会不会直接关掉对话框如果答案是“会”那就是致命错误。6.2 提示词优化要“小步快跑”很多人优化提示词喜欢一次性改一大段然后跑评测看分数涨没涨。涨了还好跌了根本不知道是哪句话改坏了。我的做法是每次只改一个点。比如这次只加一句“不确定的信息不要编造”跑评测看幻觉率有没有下降。下次只改检索的 top_k 参数看检索相关性有没有提升。这样每次改动的影响都是可归因的。另外保留每次改动的版本。我一般用 Git 管理提示词每次改动都有 commit message说明改了什么、为什么改、评测结果如何。这样即使改坏了也能快速回滚。6.3 不要迷信“更大更强的模型”我见过团队一遇到问题就想换模型觉得换个更大的模型就能解决。但实测下来很多问题不是模型能力不够而是提示词没写好、检索没做好、工具没调对。换模型确实能带来提升但成本也高。我的建议是先把提示词、检索、工具调用这些“免费”的优化做到极致再考虑换模型。很多时候你把检索的 top_k 从 3 调到 5或者把提示词里的示例从 2 个加到 5 个效果比换个贵十倍的模型还好。当然如果评测数据显示失败案例主要集中在“推理能力不足”上而且提示词优化已经到瓶颈了那该换模型就换。但一定要用数据说话不要凭感觉。6.4 建立“失败案例库”让每次失败都有价值每次失败都是宝贵的。我习惯把每个失败案例都记录下来包括输入、输出、失败原因、修复方案。时间长了这就成了一个“失败案例库”。这个库有三个用途第一作为测试集的补充来源第二作为新人的培训材料第三作为优化方向的参考。我经常翻这个库看看哪些失败模式反复出现哪些修复方案真正有效。失败不可怕可怕的是同样的失败反复发生。有了失败案例库你就能确保每次失败都让你离“稳定可用”更近一步。6.5 最后的体会做 Agent 评测闭环这件事最大的挑战不是技术而是耐心。它不像调提示词那样立竿见影也不像换模型那样简单粗暴。它需要你静下心来一条一条看失败案例一个一个定位问题一次一次验证改动。但只要你坚持下来你会发现Agent 的表现从“偶尔成功”变成了“稳定可用”。你不再需要祈祷这次演示别翻车因为你知道评测数据已经证明了它的可靠性。我自己的经验是从开始搭建评测闭环到 Agent 真正稳定可用大概需要 2-3 个月的持续迭代。这期间你会经历分数波动、优化瓶颈、甚至偶尔的倒退。但只要方向对了每一步都算数。最后分享一个小技巧每次评测后把失败案例的截图或者日志发到团队群里。不是为了追责而是为了让所有人都能看到 Agent 的真实表现。当整个团队都对失败案例有感知时优化就不再是你一个人的事而是所有人的共同目标。这种“全员评测”的文化比任何工具都管用。