不是「装一个叫 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 是可选外挂:它帮你提改法,考试规则仍是你们自己的棘轮。