Skill Eval
Overview
本技能提供一套评估驱动迭代(eval-driven iteration)的方法论与配套脚本,用于衡量并改进 Agent Skill 的输出质量。核心思想:不靠感觉判断一个 Skill 好不好,而是用真实测试用例 + 自动/人工评分 + 多轮迭代把它量化出来。关键动作是对比——同一个用例分别跑「用技能(with_skill)」与「不用技能 / 旧版本(without_skill)」,看 delta(差值)来权衡质量提升与成本。
适用对象:任何已写好或正在改进的 Agent Skill(含本技能自身)。
When to use
- 用户问「测试这个 skill」「评估我的 skill 有没有用」「这个 skill 输出质量怎么样」。
- 用户要为某个 skill 搭建 evals(测试用例、断言、评分)。
- 用户要做基准测试 / 对比 skill 的新旧版本。
- 用户要根据评分与反馈迭代改进某个 skill。
- 用户想量化一次改动到底有没有让 skill 变好。
不适用:单纯检查 SKILL.md 格式是否合法(用 package_skill.py 的校验即可);与技能输出质量无关的通用测试。
工作区约定
评估产物与技能本体分离,避免污染技能目录:
<skill-under-test>/ # 被测技能(SKILL.md 在此)
└── evals/evals.json # 测试用例(由 init_eval.py 生成)
<workspace>/ # 评估工作区(任意干净目录)
└── iteration-1/
├── benchmark.json # 聚合结果(由 aggregate.py 生成)
└── eval-<id>/
├── with_skill/ # 用技能跑的输出
│ ├── outputs/ # 技能产出文件
│ ├── timing.json # total_tokens + duration_ms
│ └── grading.json # 评分记录(由 grade.py 生成)
└── without_skill/ # 基线(不加载技能 / 旧版本)
├── outputs/
├── timing.json
└── grading.json
每次运行使用干净上下文(子代理或独立会话),保证 with_skill 与 without_skill 互不污染。
评估循环(8 步)
1. 设计测试用例
在 evals/evals.json 中定义用例,每个用例含三要素:
- prompt:真实用户消息(变换措辞 / 细节度 / 正式度)。
- expected:成功标准的可读描述(首轮先不写具体 pass/fail)。
- input_files(可选):技能所需输入文件。
先用 2–3 个用例起步,覆盖边界情况(畸形输入、歧义指令),使用真实上下文(真实路径、列名)。运行 scripts/init_eval.py 生成该文件骨架。
2. 运行评估
每个用例跑两次:
- with_skill:加载被测技能后执行 prompt。
- without_skill:不加载技能(或加载旧版本)执行同一 prompt。
每次运行记录 timing.json(total_tokens、duration_ms),用于后续成本权衡。输出写入对应 outputs/。
3. 编写断言
看完首轮输出后,为每个用例补充断言到 grading.json。好断言的特征:可程序验证、具体可观察、可计数(如「输出为合法 JSON」「包含字段 X」)。避免太模糊("输出好")或太脆弱(精确匹配某句话)。只断言客观可检项;风格 / 视觉等留给人工复核。
4. 评分输出
对每条断言记录 PASS/FAIL + 具体证据(引用输出原文片段)。机械检查(JSON 合法性、字段存在、行数等)用 scripts/grade.py 跑脚本化断言;需语义判断的用 LLM 评,两版本整体质量对比可做盲测。PASS 必须有确凿证据,不酌情给分。
5. 聚合结果
运行 scripts/aggregate.py,汇总所有用例的 grading.json 产出 benchmark.json:含 with_skill / without_skill 的通过率、时间、token 的均值与标准差,以及 delta。早期样本少时关注原始通过数与 delta,而非统计显著性。
6. 分析模式
- 两配置都过的断言 → 删掉 / 替换(无区分度)。
- 两配置都挂 → 断言写错或用例太难,排查。
- 有技能过、无技能挂 → 技能的真正价值点,重点保留。
- 结果抖动(stddev 高)→ 收紧指令。
- 检查时间 / token 离群值,读执行日志找瓶颈。
7. 人工复核
捕捉断言未覆盖的问题,写可执行的反馈到 feedback.json(如「缺失轴标签」「第三步解释含糊」),而不是「看起来差」这类主观评价。
8. 迭代技能
信号来源:失败断言、人工反馈、执行 transcript。改进原则:
- 从反馈泛化,不打特定补丁。
- 保持技能精简,删冗余指令。
- 解释「为什么」,用推理型指令。
- 重复的脚本归入 scripts/。
回到第 2 步,新开 iteration-N+1/ 重跑。停止条件:结果满意 / 反馈为空 / delta 无显著提升。
Quick Start(推荐路径)
- 生成脚手架:
python scripts/init_eval.py <被测技能目录> <评估工作区目录> - 编辑生成的
evals/evals.json,填入 2–3 个真实用例。 - 按第 2 步跑
with_skill与without_skill,落盘outputs/与timing.json。 - 看输出后补断言,跑
python scripts/grade.py <eval-目录>生成各grading.json。 - 跑
python scripts/aggregate.py <iteration-目录>生成benchmark.json。 - 人工写
feedback.json,据第 6–8 步改进 SKILL.md,进入下一轮迭代。
Resources
scripts/
init_eval.py:脚手架。在<被测技能目录>/evals/生成evals.json模板,并在<评估工作区目录>/iteration-1/下为每个用例生成with_skill/without_skill目录骨架(含outputs/、timing.json、grading.json占位)。grade.py:对单个eval-<id>目录,读outputs/与grading.json中定义的脚本化断言,逐条执行并写回 PASS/FAIL + 证据。仅覆盖客观可程序验证项;语义项留待 LLM / 人工。aggregate.py:读iteration-<N>下所有eval-<id>的grading.json与timing.json,聚合产出benchmark.json(通过率、时间、token 均值/标准差、delta)。
references/
methodology.md:完整方法论细节——测试用例设计清单、断言写法正反例、评分原则、模式分析决策树、迭代循环与停止条件、benchmark.json字段说明。需要深入细节时加载。
assets/
evals.template.json/grading.template.json/benchmark.template.json/feedback.template.json:各阶段 JSON 模板,供脚本与手动填写参考。