如何系统评估 Agent Skill,证明它没被改坏?
写好一个 Skill 只是开始,真正的挑战是:改了之后,怎么证明它没变坏?
靠体感迭代有根本性漏洞——一个版本感觉更快,另一个感觉更可靠,但你无法回答"这次改动是进步还是退步"。Skill 触发工具、生成文件,任何改动都可能让行为边界悄悄漂移。
这篇文章梳理 OpenAI Codex 给出的 Skill 系统性评估方法,说清楚四件事:怎么定义成功、哪里容易失控、怎么设计测试样本、怎么打分。
核心原则:把 Skill 当作 LLM prompt 来对待,用 Eval 量化行为,靠最小证据闭环替代体感维护。
四类成功指标
改 Skill 之前,先明确"成功"是什么。OpenAI 把它拆成四类:
| 类型 | 问题 | 示例 |
|---|---|---|
| 结果目标 | 任务完成了吗? | App 能跑吗? |
| 过程目标 | 步骤走对了吗? | Skill 被触发了?npm install 执行了? |
| 风格目标 | 输出符合约定吗? | 文件结构、代码风格 |
| 效率目标 | 有无浪费? | 无效循环、token 超支 |
结果正确不等于过程正确。 Skill 可能通过非预期路径完成任务,导致后续版本悄悄失效。过程目标不可省。
风格目标看起来不影响运行,但风格不一致会让下游系统或人员无法接手。效率目标单次测试不易察觉,但大量触发后浪费会被放大。
三类失控场景
Skill 在生产中失控,往往不是代码写错,而是隐藏假设被打破。
触发边界失控
- 该触发时没触发
- 相邻需求误触发——比如 "add tailwind styling" 意外触发了 "set up demo app"
- 边界越改越模糊,Skill 在不该出手时干扰现有内容
环境假设失控
- 默认空目录、默认有 npm、默认包管理器偏好一致
- 本地测试通过,换环境后前提失效
- 问题不在代码,在运行上下文
执行顺序失控
- 跳过 npm install、项目未建好先配 tailwind
- 每一步单看都对,顺序却错了,导致卡死或垃圾输出
四种回归样本
10–20 条 CSV 即可,四种 case 类型覆盖不同触发场景:
| 类型 | 目的 | 示例 |
|---|---|---|
| 显式调用 | 确认 Skill 可被直接点名触发 | "用 $setup-demo-app 创建项目" |
| 隐式调用 | 验证 name/description 足够强 | "搭建一个 React + Tailwind demo" |
| 上下文调用 | 真实噪声场景下仍能触发 | "为 Responses API 创建 demo app" |
| 负例控制 | 防止相邻场景误触发 | "给现有 React 项目加 Tailwind" |
负例控制不可省。 相邻请求(如"给现有项目加样式")可能意外触发"创建新项目"的 Skill,划定边界、验证 Skill 知道何时不该执行,和验证它能触发同样重要。
两层评分器架构
Layer 1:确定性检查
比喻:给 Skill 装了飞行记录仪——只能告诉你动作发生了没,不能告诉你做得对不对。
纯代码规则,无需大模型。通过解析运行轨迹(JSONL 事件流)核对基础动作:
npm install是否执行了?package.json是否存在?- 命令顺序是否符合预期?
两个关键特性:
- 确定性:相同行为判断结果一致,没有模糊地带
- 可调试:失败时能直接看到 Agent 在哪步走偏
Eval 失败时如何定位根因? 拿到 Trace 后,按三个方向依次排查:
| 根因 | 症状 | 排查方式 |
|---|---|---|
| Prompt 模糊 | Skill 触发了,但步骤走偏 | 对比 Trace 与预期步骤,看第一个分叉点 |
| 工具描述(Schema)误导 | 调用了错误工具或参数传错 | 检查 command_execution 事件的实际参数 |
| 上下文溢出 | 后半段行为突然退化或遗忘前置步骤 | 看 Trace 中 token 消耗曲线,定位溢出位置 |
三类根因对应三类修复方向,不用靠猜。
Layer 2:评分细则检查(Rubric)
确定性检查解决"做了吗",Rubric 解决"做得对吗"。
Skill 跑完后,单独跑一次只读检查(不修改文件,仅读取仓库),用 LLM 做裁判,按定义好的评分细则输出结构化打分结果。
评分细则的关键是把模糊质量标准拆解为具体可判断的维度,例如:
- 组件是否按功能分目录
- 是否有未使用的引用
- 样式类名是否遵循约定
- 配置项是否集中管理
必须锁死输出格式(如 overall_pass / score / checks[]),确保结果可跨版本比较、接入 CI 流水线。
两层互补,顺序不可反:先写确定性检查,规则覆盖不了的质量判断再交给模型。
成熟后的六类扩展检查
两层评分器解决"对不对",扩展检查解决"稳不稳、贵不贵、脏不脏"——按需叠加,不是必选项。
Skill 稳定后,按需叠加——先快速信号,再慢速重型检查:
| 检查类型 | 目的 | 说明 |
|---|---|---|
| 命令数检测 | 防行为退化 | 以前 6 步,现在 18 步,任务完成了但系统变差 |
| 消耗量追踪 | 防 Skill 越写越贵 | 记录 token 消耗,防止执行成本悄悄增加 |
| 构建检查 | 验证项目完整性 | 直接跑构建命令,成本低,应默认开启 |
| 冒烟检查 | 验证运行时行为 | 启动开发服务器并发送请求,按风险添加 |
| 仓库清洁度 | 防止系统被弄脏 | 任务做完了,不代表没留下无关文件 |
| 权限回归 | 防权限漂移 | 确认 Skill 在最小权限下工作,防止某次改动后悄悄依赖更高权限 |
分级测试策略:全量跑一遍成本不低,实际执行时按变更范围分级:
- 日常代码变更 → 只跑 Layer 1 确定性检查(秒级,零 token 成本)
- 重要版本发布前 → 跑 Layer 1 + Layer 2 全量 Rubric
- 生产异常排查 → 按需叠加扩展检查中的相关项
五条核心原则
- 量真正重要的东西:明确在意的指标,不为指标而指标
- 先写清可检查的定义:将验收标准转化为可执行的判断
- 把评估扎在真实行为上:记录完整运行轨迹,围绕实际动作写确定性检查
- 规则不够时再让模型补上:评分细则 + 锁死格式,顺序不可反
- 让真实失败驱动样本增长:将手动修复转化为测试用例,确保 Skill 持续做对
Bad Case 自动化转换:线上失败不应该只是修一次就算了。把失败日志脱敏后,按类型自动转化为测试样本——触发边界失败 → 补一条负例控制样本,上下文噪声导致的失败 → 补一条上下文调用样本。样本集随真实失败自然生长,覆盖的边界越来越准。
小结
Skill 接入生产后,成为需要持续验证的工作流资产。维护它需要明确三件事:
- 目标:想让它做成什么(四类成功指标)
- 失控点:会在哪些地方失控(三类失控场景)
- 样本:用哪些样本盯住失控点(四种回归样本 + 两层评分器)
从靠体感维护,转变为靠最小证据闭环维护。
本文内容整理自 OpenAI 官方博客 Testing Agent Skills Systematically with Evals 及慢学AI 视频,加入了个人理解和补充。