AI Agent Skill 工程化 09:让 Skill 自己变好——走向自进化流水线

AI Agent Skill 工程化 09:让 Skill 自己变好——走向自进化流水线

不是「装一个叫 Darwin 的工具,Skill 就会自己变好」。 而是:真实问题 → 写成可测的东西 → 一次只改一处 → 考不过就回滚。

前言

一句话:让 Skill 走向自动化,需要有要求和约束。

开场:改完 Skill,你怎么知道没改坏?

2026 年 6 月 22 日,我用frontend-dev-prompt-craft跑了一轮真实任务:订单继承与合并功能,任务本身做完了。

复盘时却发现一堆刺:PRD 里的接口 path 是/api/resition/...,项目里真正请求的是leave/...。Skill 生成的提示词经常只写一边,下游 Loop 一接就漂飞走了。

这类问题以前怎么处理?记在脑子里,改天改两句SKILL.md,凭感觉说「应该好了」。

但是现在,我把问题写进skill-issues.jsonl,排了优先级,锁了一个假设,改了校验脚本,再跑 fixture 回归——eval-007 PASS,旧用例没挂,才 KEEP

这篇文章讲的就是这条线。

不是「装一个叫 Darwin 的工具,Skill 就会自己变好」。 而是:真实问题 → 写成可测的东西 → 一次只改一处 → 考不过就回滚。

配套仓库:

•脚手架:plugins/frontend-team-toolkit/skill-engineering

•案例 Skill:skills/frontend-dev-prompt-craft

08 讲原则,09 讲怎么跑

08篇把道理说清楚了:单一修改面、固定验证标准、人类设边界、KEEP/REVERT。

09 只做一件事——把这些原则落到你们仓库里已经有的脚本上:

真实使用 → skill-issues.jsonl → triage_issues.py → convert_issue_to_eval.py(或手工补 eval) → grade_evals.py(改前基线) → 写 evolution-hypothesis.json,只改一个维度 → grade_evals.py + check_regression.py → KEEP 就发版;挂了就回滚

口诀还是那句:问题可观测、Eval 可锚定、变异可单假设、回归可棘轮。

先用人话讲一遍

把 Skill 当成一段会跑偏的程序,就好懂了:

你熟悉的

自进化里对应什么

Bug 单

skill-issues.jsonl

里的一行

排期 / 优先级

triage_issues.py

单元测试

evals/evals.json

+ fixture

改代码前先跑测试

grade_evals.py

打基线

一次只修一个 bug

evolution-hypothesis.json

锁一个维度

CI 红了不许合

check_regression.py

,high 挂就 REVERT

「自进化」听起来很玄。落地后,它就是:别凭感觉改 Skill,改完要考试。

前置条件:没有这些,别谈自动变好

跑通这条线,Skill 目录至少要有:

SKILL.md

evals/evals.json(建议 ≥ 3 条)

skill-issues.jsonl

results.tsv

.skill-meta.json

用脚手架自检:

python3 plugins/frontend-team-toolkit/skill-engineering/bin/validate-skill.py \ plugins/frontend-team-toolkit/skills/frontend-dev-prompt-craft

还有一条硬条件:想做确定性回归,就要有 fixture。

没有 fixture 时,你只能靠run_evals.py调 Agent 实测——慢、贵、不稳定。frontend-dev-prompt-craft后来把 eval-001~007 全补上 fixture,才做到grade_evals.py7/7 PASS。这不是锦上添花,是门禁能自动化的前提。

七步流水线(对照真实试跑)

下面每一步,都对应 2026-06-22 那次frontend-dev-prompt-craft试跑。完整记录在 Skill 目录的evolution-practice-log.md

1)任务结束,先记一行问题

不要等「攒够十个再写」。下一单结束就追加:

{"date":"2026-06-22","skill":"frontend-dev-prompt-craft","task_type":"API","symptom":"PRD 接口 path 与项目 request path 不一致,提示词易只写其一","expected":"output-contract 要求 PRD path 与项目 path 双轨记录","severity":"high","source":"session_retro","converted_to_eval":false,"eval_id":null,"status":"open"}

那次特殊单任务,session_retro 一口气记了 8 条。其中 path 双轨、枚举映射是 high。

2)Triage:先打哪只蚊子

./plugins/frontend-team-toolkit/skill-engineering/bin/run-evolution-cycle.sh \ --skill frontend-dev-prompt-craft \ --phase triage

或直接:

python3 plugins/frontend-team-toolkit/skill-engineering/scripts/triage_issues.py \ --skills-base plugins/frontend-team-toolkit/skills \ --status open

试跑结果:15 条 open;L10/L11(path 双轨、术语→枚举)优先级最高。每周只啃 top 1 的 high,比一次改五处靠谱。

3)把问题变成 Eval

有两种做法:

•半自动:convert_issue_to_eval.py --dry-run预览,确认后--apply

•手工:像我们当时那样,eval-007(craft+loop 串联)已经在 v0.1.1 建好,本轮直接拿来当锚点

关键不是「谁写的 eval」,而是:改 Skill 之前,先有一条能复现失败的测试。

4)改之前先打基线

有 fixture 时,本地零 Token:

python3 plugins/frontend-team-toolkit/skill-engineering/scripts/grade_evals.py \ --skill frontend-dev-prompt-craft \ --skills-base plugins/frontend-team-toolkit/skills \ --mode all \ --append-results

没有 fixture、必须看真实 Agent 行为时,再用run_evals.py。日常迭代优先 fixture。

5)写假设,一次只改一个维度

先写evolution-hypothesis.json,再动手。我们那轮是这样的:

{ "skill":"frontend-dev-prompt-craft", "target_eval":"frontend-dev-prompt-craft-007", "problem":"PRD 接口 path 与项目 request path 未双轨记录", "proposed_change":"validate-output.sh --chain 增加 PRD path / 项目 path / userType 检查", "dimension":"output-contract", "rollback_condition":"eval-001~006 regression fail", "status":"verified" }

脚手架约定的可改维度(每次只选一个):

维度

改什么

trigger

description / When to Activate

workflow

Workflow 步骤

output-contract

references/output-contract.md

template

references/prompt-templates.md

anti-pattern

Anti-patterns 表

那一轮实际改的是validate-output.sh --chain,让 eval-007 能卡住「双 path + userType」。 假设写清楚,回滚才有依据——不是「感觉不对再 git 找」,而是「旧 regression 挂了就 REVERT」。

6)考试:过了才 KEEP

python3 plugins/frontend-team-toolkit/skill-engineering/scripts/grade_evals.py \ --skill frontend-dev-prompt-craft \ --skills-base plugins/frontend-team-toolkit/skills \ --eval-id frontend-dev-prompt-craft-007 \ --append-results --version 0.1.2

随后用棘轮门禁看 high risk:

python3 plugins/frontend-team-toolkit/skill-engineering/scripts/check_regression.py \ --results plugins/frontend-team-toolkit/skills/frontend-dev-prompt-craft/results.tsv \ --risk high --block true

试跑裁决:

轮次

做了什么

结果

v0.1.2

--chain校验,修 path 双轨

eval-007 PASS →KEEP

v0.1.3

给 001~006 全补 fixture

7/7 PASS

,maturity → beta

挂了怎么办?回滚本轮改动,把失败原因写回 hypothesis / practice log,下一轮换假设。棘轮的意义不是让你永远成功,而是让失败变得便宜、可复盘。

7)发版,并把 issue 关掉

KEEP 之后才做这些:

1.更新CHANGELOG.md.skill-meta.json

2.相关 issue 标fixed(可用mark_issue_resolved.py

3.需要的话写两句LEARNINGS.md

4.看趋势:

python3 plugins/frontend-team-toolkit/skill-engineering/scripts/evolution_report.py \ --results plugins/frontend-team-toolkit/skills/frontend-dev-prompt-craft/results.tsv

哪些能自动试,哪些必须人点头

这条流水线再熟,也有边界。

适合小步试的:

•触发词措辞

•Workflow 步骤顺序 / 检查点表述

•output-contract 里可被脚本校验的字段

•模板补充、反面例子

不要交给「自动改完就合」的:

•Safety / 权限边界

•对外承诺、合规条款

evals/evals.json本身(测试基线被人偷偷改,棘轮就废了)

•大范围重构(一次改五十行以上,先拆轮次)

一句话:流水线负责提方案和考试;人负责划红线。

Darwin 是什么?要不要装?

读到这里,你可能才想起来标题里曾经出现过的 Darwin。

Darwin(darwin-skill)是可选外挂,不是本篇主角。

用人话讲:

Darwin 像一个会改SKILL.md的实习生:它按评分标准提修改、跑几轮试、分数涨了就留、跌了就回滚。 你们仓库里的grade_evals.py/check_regression.py,才是带教老师和期末考试。

脚手架 README 也把它放在「与外部工具配合(可选)」里,和 skill-creator、skill-audit 并列。核心观点:L5 = 外挂 darwin-skill,仍须过 L4 棘轮。实践复盘里,Darwin 封装还标在 P2——意思是:

七步流水线已经能跑;Darwin 是加速「提假设」的插件,不是地基。

什么时候值得接 Darwin?

•你已经有完整 fixture + 回归门禁

•你厌倦了自己想「下一句 description 怎么改」

•你接受:Darwin 的产出,照样要过check_regression.py

什么时候先别装?

•还没有 eval / fixture

•连skill-issues.jsonl都懒得写

•指望「装上就全自动变好」

没有 Darwin,按本文七步手改,一样是正经的自进化。有 Darwin,也只是多了一个提案来源——考试规则不变。

我们试跑时踩过的坑(诚实版)

这些不是教学故事,是脚手架evolution-practice-retro.md里记过的:

后来怎么处理

无 fixture 的 eval 没法进确定性 CI

补齐 001~007 fixture,再谈全量回归

grade_evals.py

子进程路径不对

cwd 指到 Skill 目录

convert_issue_to_eval.py

的 dry-run 逻辑绕

改成只有--apply才写入

想一次修很多 issue

强制单假设;其余进evolution-backlog.md

所以如果你照着本文做,卡在「命令跑不通」——优先查脚手架脚本和 Skill 目录结构,而不是怀疑方法论本身。

方法论已经在一个真实 Skill 上跑通过;脚本细节会继续迭代。

读完你可以立刻做的三件事

1.给正在用的那个 Skill,建或打开skill-issues.jsonl,把最近一次翻车写成一行

2.跑一次triage_issues.py,只选 top 1 high

3.写一份evolution-hypothesis.json,改一个维度,跑grade_evals.py——过了再谈发版

不要一上来研究 Darwin。先让「改完能考试」变成肌肉记忆。

总结

本篇只记住三件事:

1.自进化的主角是脚手架流水线,不是 Darwin 这个skill。

是一套自动流水线:issue → triage → eval → 单假设 →grade_evals→ KEEP/REVERT,这条链在frontend-dev-prompt-craft上已经跑通过。

2.没有 fixture,就没有便宜的确定性回归;没有回归,就谈不上放心自动改。

3.Darwin 是可选外挂:它帮你提改法,考试规则仍是你们自己的棘轮。