用 Agents CLI 建立智能体持续评测闭环
文章介绍通过 Agents CLI 持续测试和评分,捕获提示词回归,并利用并排执行轨迹比较评估模型后端替换。还展示自动化评测、夜间定时运行和基于阈值的告警,以追踪质量变化。
AI 深度解读
Agent 能跑通演示,不代表改了提示词、换了模型后还能正常工作。Google 这篇文章用 Agents CLI 做了一轮完整演示:建立基线、故意引入退化、比较模型,再把评测接进定时任务。它想说明的是,Agent 质量需要靠反复评测和修改逐步提高。
最有价值的发现是:两次改动都让均分从 4.00 降到 2.75,背后的问题却完全不同。对正在接入工具调用、维护 AI 应用的程序员,这比一个总分更值得看。
为什么代码检查通过,Agent 还是会变差
作者把这套方法叫作爬山法(hill-climbing):准备测试输入,运行 Agent,给结果评分,分析失败,再修改并重跑。每次沿着有效的方向前进一步。
演示使用 Agents CLI v1.8.0 自带的 LangChain 模板。创建时指定 --agent google/agents-cli/extensions/langchain/template@v1.8.0 和 -d cloud_run,进入项目后执行 agents-cli install。
模板提供了三个关键文件:tests/eval/datasets/basic-dataset.json 存输入,tests/eval/eval_config.yaml 声明评测要求,tests/eval/response_quality.py 实现自定义评分。配置通过 metrics_to_run 和 custom_metrics 注册 custom_response_quality,再用 custom_function_file 指向评分文件。
评分采用模型裁判(LLM-as-judge),由 gemini-3.8-flash 按准确性、相关性和清晰度给出 1—5 分。
默认数据集只有一条简单用例,作者扩成四条:打招呼、查询 San Francisco 天气、查询 Rome 天气,以及询问 2024 World Series 冠军。它们分别检查基本回应、模拟天气工具的固定雾天结果、工具默认分支,以及超出天气范围的问题。
下面两条命令分别负责生成执行轨迹和评分:
agents-cli eval generate --dataset tests/eval/datasets/basic-dataset.json \
-o tests/eval/output/
agents-cli eval grade --traces tests/eval/output/eval_dataset_*.json \
--config tests/eval/eval_config.yaml
要看清第二条命令的 --traces:评分读取的是生成后的执行记录,分析问题时可以回到具体对话和工具行为。
基线的四条用例全部有效,没有执行错误,均分为 4.0000,标准差为 1.4142。随后,作者故意把 app/agent.py 中 create_agent 的 system_prompt 换成厨师人设,要求每次回答最后都推荐一道菜,tools=[get_weather] 保持原样。
代码能编译,Agent 也能运行,但均分降到 2.7500,标准差变为 0.9574。
工具仍然注册在代码里,不代表模型仍会正确调用它。
这解释了普通 lint、类型检查为什么不足以守住 Agent 的行为质量。原文说单元测试抓不到,表述稍显绝对;更准确地说,常规代码单测通常不会覆盖模型在完整对话中的实际选择。
同样下降 1.25 分,为什么不能得出同一个结论
agents-cli eval compare 接收两份结果 JSON,输出结构化差异。作者建议再用 jq 或 Python 提取逐条分数,因为均分只负责提示异常,具体用例才能帮助定位。
厨师提示词造成的变化如下:
| 用例 | 基线 → 厨师提示词 | 具体表现 |
|---|---|---|
greeting |
5.0 → 4.0 | 打招呼后主动推销菜谱 |
sf_weather |
4.0 → 2.0 | 忽略天气工具,编造天气 |
rome_weather |
2.0 → 2.0 | 基线已经存在编造问题 |
off_topic |
5.0 → 3.0 | 回答冠军问题后附加菜谱 |
这里最该优先处理的是 sf_weather,因为它已经从措辞问题发展成了错误的信息获取行为。rome_weather 同样提醒开发者:基线只是比较起点,并不天然正确。
接着,作者恢复原提示词,把 ChatGoogleGenerativeAI(model=LLM, temperature=0) 使用的模型从 gemini-3.8-flash 换成 gemini-2.5-flash,裁判保持不变。
均分再次从 4.00 降到 2.75,但逐条结果不同:greeting 为 5.0 → 5.0,sf_weather 为 4.0 → 3.0,rome_weather 为 2.0 → 2.0,off_topic 为 5.0 → 1.0。最后一条中,模型以赛事尚未发生为由回避回答,作者将其归因于训练知识截止时间。
下降主要集中在越界问题上,天气用例也损失了 1 分。因此,不能仅凭相同均分,就把换模型和错贴提示词判为同等严重。
原文后文把模型替换描述成「下降半分」,与前面的 1.25 分不一致;还有一句称全部下降来自 off_topic,也忽略了天气用例的变化。判断时应以逐条分数为准。
模型替换还存在两个前提:不同模型可能需要各自调整提示词;比较期间必须固定裁判,否则分数变化可能来自尺子变了。
怎样让评测持续运行,而不是只留下报告
作者建议把评测分成两种节奏。日常修改用小而有代表性的数据集,演示中的四条用例据称能在一分钟内跑完;夜间回归再使用几十到几百条用例。三百条、运行一小时的数据集,更适合发布检查,很难让开发者每次改动都执行。
Agents CLI 没有内置调度器。文章给出的方案是由 cron 或 Cloud Scheduler 调用脚本,每晚运行 eval generate 和 eval grade,把结果存进 artifacts/scheduled_runs/$DATE。定时评分增加 --output $OUT/,方便持续保存产物。
告警另用 Python 脚本实现:读取 summary_metrics[0]['mean_score'],计算基线减去候选分数的差值,超过 --threshold 就执行 sys.exit(1)。默认阈值为 0.05,演示传入 --threshold 0.1:4.00 → 2.75 返回退出码 1,同一结果自比较返回 0。
这里的 0.1 是分数差,不是下降 10%。非零退出码还需要周边任务系统配置失败通知,单独运行脚本不会自动完成告警投递。
另外,eval analyze 可以把失败聚成主题,eval optimize 则用于自动尝试提示词变体:
agents-cli eval optimize \
--dataset tests/eval/datasets/regression.json \
--target-metric final_response_quality \
--config tests/eval/eval_config.yaml
要注意 --target-metric final_response_quality 与前面演示的 custom_response_quality 不同,不能把这条命令直接视为前述 LangChain 示例的下一步。
原文明确限定:eval optimize 基于 GEPA,目前用于 ADK 项目,不支持 LangChain 扩展。它只优化提示词,工具、结构和模型保持固定;候选提示词按分数排序,仍需人工审核后采用。
我的判断
我认同这套流程最实用的两点:保存完整结果,以及把输入数据和评分要求分开管理。前者让退化可以追溯,后者让团队知道究竟是 Agent 变了,还是「好答案」的标准变了。两类文件都应进入版本控制。
均分适合发现异常,逐条证据才适合决定怎么改。
但四条用例、一个模拟天气工具,只能证明流程跑得通。文章没有给出重复运行后的评分波动,也没有模型替换的成本、延迟对照数据,因此无法据此认定某个模型性价比更高。固定 temperature=0,也不能直接视为评分绝对稳定的证据。
模型裁判能辅助评价表达和相关性;对于是否调用 get_weather、参数是否正确等明确要求,我会考虑补充确定性断言。这是对流程的补强建议,原文没有提供两种评分方法的对照实验。
自动优化同样要留心:GEPA 可能改善回答,也可能只是找到更讨裁判喜欢的措辞。人工审核之外,用未参与优化的用例复核会更有说服力,原文没有展示这一步。
作者还提到一项受控研究:使用 agents-cli 的编程 Agent 执行评测的次数达到对照组的四倍,但评测后修改 Agent 的频率差不多。原文没有交代样本量和完整研究设计,不能据此作普遍推断;它至少提醒我们,多跑几次并不自动带来修复。
能拿来做什么
- 给现有 AI 应用选几条高频输入,覆盖正常回答、工具成功、工具默认分支和越界请求,每次修改提示词后运行同一组用例。
- 在前端或 Node 项目的 CI 中保存完整评测 JSON,同时查看关键用例和均分,让代码审核能看到行为变化的证据。
- 替换模型时固定裁判和数据集,逐条检查损失,再结合真实请求分布决定是否接受;成本和延迟需要另外测量。
- 给线上 Agent 增加夜间回归,将工具数据或模型更新带来的变化纳入检查,并依据实际评分波动设置告警阈值。