Skill Evolver — 自进化代理循环
一句话定位
给它一个任务描述(或现有 Skill),它会不断起草、运行、失败分析、改写,直到技能真正可用。
何时使用
| 场景 | 示例 |
|---|---|
| 为新任务从零生成 Skill | "帮我把批量下载港交所文件的方法做成一个技能" |
| 修复反复出错的 Skill | "这个 Skill 一直 timeout,帮我修好" |
| 对现有 Skill 做能力升级 | "让 browser-file-downloader 支持登录态" |
| 验证 Skill 在真实数据上是否可用 | "这个技能在测试数据上跑通了吗" |
核心循环(必须严格遵守)
INIT:
- 如果是"进化现有 Skill",先备份原文件:
将 SKILL.md 内容存入内存记为 BACKUP_v0(以及写临时文件 SKILL.md.bak)
- last_diagnosis = None(用于空转检测)
LOOP (轮次 n = 1 … MAX_ITER, 默认 5):
Step 1 — 起草 : 生成/更新 SKILL.md 草稿 + 配套测试用例
[! 起草前先在内存中保存本轮快照 snapshot_n,供回滚用]
Step 1.5 — 逻辑自检 : 在执行前对草稿做纯推理/静态分析检查(零算力)
[! 若自检未通过 → 回到 Step 1 修改,不计入 MAX_ITER 轮次]
[! 若自检通过 → 进入 Step 2 真实执行]
Step 2 — 执行 : 按测试用例实际运行技能(禁止纯推演替代,见执行规范)
Step 3 — 观察 : 捕获完整输出、报错、异常行为
Step 4 — 诊断 : 分析根因(见根因分类),输出修改计划
[! 空转检测:若本轮诊断结论与 last_diagnosis 完全相同 → 触发 STALE BREAK]
last_diagnosis = 本轮诊断结论
Step 5 — 判定 :
若通过验收 → 固化输出(见固化动作)→ BREAK
若未通过 → 回到 Step 1
逻辑自检失败修正(不消耗 MAX_ITER):
修正后回到 Step 1.5 重新自检,通过后再进入 Step 2。
逻辑自检最多连续失败 LOGIC_CHECK_MAX(默认 5)次后,视为无法突破,输出诊断报告 + 人工介入建议。
BREAK 条件(任一满足即停止):
① 所有验收项通过 → 输出产出报告
② 达到 MAX_ITER 轮次上限 → 输出诊断报告 + 人工介入建议
③ STALE BREAK:连续 2 轮诊断结论相同 → 说明 Agent 已无法自行突破,请求用户提供额外信息
④ LOGIC_CHECK MAX 连续自检失败 → 输出自检失败清单 + 人工介入建议
⑤ 用户明确说"停"/"中止" → 立即停止,还原备份(若有)
进化失败时(条件 ②③④⑤):
- 若有备份 SKILL.md.bak → 还原原文件,避免用户原本好用的技能被损坏
- 输出"哪里卡住了 + 需要用户提供什么"
Step 1:起草 Skill
接受的输入格式
A. 从零创建(任务描述)
任务: <用自然语言描述你要自动化的事情>
约束: <可选,如"只能用 Python 标准库""不需要登录">
验收标准: <可选;不提供时见"验收标准来源优先级">
MAX_ITER: <可选,默认 5>
B. 进化现有 Skill
skill_path: ~/.workbuddy/skills/<skill-name>/SKILL.md
问题描述: <当前哪里不对或要新增什么能力>
验收标准: <可选>
验收标准来源优先级
当用户未明确指定验收标准时,按以下优先级确定:
- 用户指定(最高优先级):直接使用
- Skill 已有的"快速测试"预期输出:从现有 SKILL.md 的快速测试节提取
- Agent 自行生成(最低优先级):生成时 必须 包含至少一条"内容正确性"验证(不得只验证"文件存在"或"命令无报错")
起草原则
- 先读再改:如果是进化现有 Skill,先完整读取原文件,保留已验证的部分。
- 最小差异:每轮只改上一轮诊断出的问题,不做无关重构。
- 内嵌验收标准:SKILL.md 末尾必须包含
## 验收清单小节(见格式模板)。 - 写测试用例:用
## 快速测试小节记录可直接运行的最小验证步骤。
SKILL.md 强制结构
---
name: <skill-name>
agent_created: true
description: <一句话触发描述>
---
# <技能名称>
## 适用场景
...
## 前置条件
(依赖库、环境变量、登录态、权限)
## 执行协议
(分步骤的操作指令,Agent 可以直接按步执行)
## 快速测试
(最小可运行示例 + 预期输出,必须包含内容正确性断言)
## 常见陷阱
(已验证的坑,每次循环后补充)
## 验收清单
- [ ] 验收项 1(含内容正确性验证)
- [ ] 验收项 2
Step 1.5:逻辑自检(执行前门)
定位
纯推理 / 静态分析检查,不运行任何代码,不消耗执行算力。目的是在真实执行前拦截明显有问题的版本。
自检清单(7 项,必须全部通过)
| # | 检查项 | 判断标准 | 不通过时怎么办 |
|---|---|---|---|
| 1 | 结构完整性 | SKILL.md 包含全部强制节(前置条件、执行协议、快速测试、验收清单) | 补充缺失节 |
| 2 | 快速测试可执行性 | 快速测试中的命令 / 操作是真实存在的工具或 API(不是凭空编造的函数名) | 换成实际可调用的命令 |
| 3 | 验收清单覆盖执行 | 验收清单的每一项都能在快速测试的预期输出中找到对应的验证点 | 补验收项或调测试 |
| 4 | 内容正确性断言存在 | 验收清单中至少有一条验证"输出值是否符合预期"(不只是"无报错""文件存在") | 加内容断言 |
| 5 | 前置条件已声明 | 快速测试依赖的库、环境变量、权限在前置条件节中列出 | 补充前置条件 |
| 6 | 无内部矛盾 | 快速测试的操作步骤与执行协议的指令不冲突(如:协议说用 curl,测试却写 wget) |
统一为一致的工具 |
| 7 | 路径 / 文件引用有效 | 快速测试中引用的文件路径和输出路径在 Skill 的上下文里是合理的(不需要真实存在,但不能是 C:\nonsense\fake 这种明显无效路径) |
修正路径 |
自检执行方式
自检是纯推理——Agent 对照清单逐项过,不需要启动子进程。
对每条检查项:
读取 SKILL.md 对应节 → 对照判断标准 → 通过 / 不通过
如果全部通过 → 进入 Step 2(真实执行)
如果有不通过 → 记录不通过项,回到 Step 1 修改,然后重新自检
自检失败计数
logic_check_failures = 0
每次自检不通过:
logic_check_failures += 1
if logic_check_failures >= LOGIC_CHECK_MAX (默认 5):
→ 触发 BREAK 条件 ④
→ 输出"逻辑自检连续失败 LOGIC_CHECK_MAX 次,无法自动修复:<列出未通过项>"
→ 停止循环
> 逻辑自检失败不消耗 MAX_ITER。只有进入 Step 2 真实执行后才计入轮次。这样设计的原因是:逻辑自检只做推理,成本极低;而真实执行才消耗算力。
Step 2:执行
执行方式(按优先级)
| 优先级 | 方式 | 适用 | 可作为验收证据? |
|---|---|---|---|
| 1 | 直接运行脚本(Bash / python) |
Skill 附带可执行代码 | ✅ 是 |
| 2 | 按 SKILL.md 的"快速测试"指令操作 | Skill 是操作性流程 | ✅ 是 |
| 3 | 模拟推演 + 静态分析 | 外部服务完全不可达时辅助分析用 | ❌ 不可 作为验收证据 |
> ⚠️ 方式 3(模拟推演)只能用于辅助分析,帮助制定修改方向。验收必须由方式 1 或方式 2 的实际执行结果证明。如果两者都无法运行,须向用户说明并暂停。
执行规范
- 完整捕获输出:stdout、stderr、退出码均记录。
- 记录实际行为:文件大小、内容摘要——有证据才能诊断。
- 不要跳过错误:即使部分成功,也要记录哪步失败了。
- 内容断言必做:不仅看"有没有报错",还要验证输出内容符合预期。
Step 3:诊断根因
每次失败后,必须对照以下分类定位问题,不允许写"原因不明":
根因分类表
| 类别 | 典型症状 | 修改方向 |
|---|---|---|
| 指令缺失 | Agent 执行时需要猜测、跳步 | 补充具体操作步骤 |
| 前提条件未声明 | 缺少依赖库、环境变量、登录态 | 在 Skill 顶部加"前置条件"章节 |
| 命令/参数错误 | 报 ModuleNotFoundError、AttributeError |
更新为正确的 API/命令 |
| 等待策略问题 | 超时、元素未找到 | 调整 timeout、换等待方式 |
| 编码/路径问题 | Windows GBK vs UTF-8、路径分隔符 | 参照用户内存中的 Windows 坑清单 |
| 网站/接口结构变化 | 选择器失效、接口返回格式变了 | 重新诊断页面,更新选择器 |
| 验收标准不合理 | 标准太严或太宽,与实际目标不符 | 和用户确认后修改验收标准 |
| 逻辑错误 | 数据处理结果不符合预期 | 加调试输出,逐步缩小范围 |
| 外部依赖不可用 | 服务宕机、权限拒绝、网络不通 | 人工介入,本技能无法自动修复 |
空转检测(STALE BREAK)
诊断完成后,与上一轮诊断进行对比:
if 本轮根因分类 == last_diagnosis.root_cause AND 本轮修改计划 == last_diagnosis.fix_plan:
→ STALE BREAK
→ 输出:"Agent 已连续 2 轮得出相同诊断,无法自行突破。需要您提供额外信息:[列出缺失项]"
→ 还原备份(若有)
→ 停止循环
诊断输出格式
## 第 N 轮诊断
**执行结果摘要**: <一句话,如"下载了3个文件,其中2个为空">
**失败步骤**: Step X — <具体操作>
**根因分类**: <从表中选一个>
**证据**: <报错原文 / 文件大小 / 内容摘要>
**修改计划**:
1. <具体要改哪一行/哪一节>
2. <改成什么>
**与上轮对比**: 相同 / 不同(若相同说明触发空转检测)
Step 4:判定与固化
验收通过条件(须全部满足)
- SKILL.md 末尾的"验收清单"所有项均打勾
[x]。 - 快速测试可以从头到尾无报错运行,且输出内容符合预期(有截图/摘要为证)。
- 至少有一条验收项验证了"内容正确性"(不只是"文件存在"或"无报错")。
固化动作(通过后执行)
- 清理 SKILL.md:去掉调试注释,保留
## 常见陷阱中本次发现的坑。 - 更新验收清单:所有项改为
[x],并标注验证日期。 - 写进化日志:在 SKILL.md 末尾追加
## 进化历史小节,记录本轮主要变更。 - 存档:将最终版写入正确路径(用户级
~/.workbuddy/skills/<name>/SKILL.md)。 - 清理备份:删除
SKILL.md.bak(如有)。 - 通知用户:输出一份简洁的"产出报告"(见格式)。
产出报告格式
## Skill Evolver 产出报告
- **技能名称**: <name>
- **总轮次**: N 轮
- **最终状态**: 通过 ✅ / 未通过 ❌(含原因)
- **路径**: ~/.workbuddy/skills/<name>/SKILL.md
- **主要变更**: <3条以内的要点>
- **已知限制**: <如有>
超出轮次上限 / 无法突破时的处理
若触发任意 BREAK 条件 ②③④:
- 输出最后一轮诊断报告。
- 明确列出仍未解决的问题和最可能的原因。
- 给出人工介入建议(如"需要你手动提供 Cookie"、"需要确认接口文档"、"外部服务当前不可用")。
- 还原备份(若本次是"进化现有 Skill"且有 SKILL.md.bak)。
- 不要强行声明成功。
与其他 Skill 的协作
本 Skill 可以调用以下技能辅助完成子任务:
| 子任务 | 可调用技能 |
|---|---|
| 浏览器自动化下载 | browser-file-downloader |
| 网页交互 / 截图 | agent-browser(如已安装) |
| 将成果写入 SKILL.md | SkillManage(内置工具) |
| 记录学习教训 | self-improvement |
快速测试(本技能自验证)
测试场景:给本技能一个最简单的子任务,验证它能完成一轮完整循环。
任务: 创建一个技能,能输出当前系统时间(Python 实现)
验收标准:
- SKILL.md 文件存在且格式正确(含 frontmatter、验收清单)
- 按快速测试步骤运行后,输出包含今天日期(格式 YYYY-MM-DD)
- 输出中日期与系统实际日期一致(内容正确性验证)
MAX_ITER: 3
预期:在 1~2 轮内完成,最终产出 system-time/SKILL.md。
✅ 已验证(2026-06-29,第 1 轮即通过)
常见陷阱
-
陷阱1:每轮都大幅重写 SKILL.md,导致已验证部分失效。
→ 每轮只改诊断出的问题,其余保持不变。 -
陷阱2:执行后只看"有没有报错",忽略输出内容是否正确。
→ 必须检查实际输出内容(文件大小、文本摘要),有内容断言才能通过验收。 -
陷阱3:把"模拟推演通过"当成"实际运行通过"。
→ 只要有可运行代码,必须真实执行,推演不作为验收证据。 -
陷阱4:Windows 环境下 Python 脚本 print 含 Unicode 崩溃。
→ 脚本顶部加sys.stdout.reconfigure(encoding="utf-8")。 -
陷阱5:SKILL.md 缺少验收清单,导致无法判定是否通过。
→ 第一轮起草时就必须写"验收清单",且至少一项是内容正确性验证。 -
陷阱6:进化现有 Skill 时没有备份,中途失败导致原来好用的技能被损坏。
→ 进化开始前先备份至SKILL.md.bak,失败则还原。 -
陷阱7:Agent 在无法突破的错误上反复绕圈(空转),浪费轮次。
→ 空转检测(连续 2 轮诊断结论相同)会强制暂停并请求人工介入。 -
陷阱8:自行生成的验收标准过松(只验证"文件存在"),实际内容错误却被判为通过。
→ 当 Agent 自行生成验收标准时,强制包含至少一条内容正确性验证。 -
陷阱9:没有逻辑自检,明显有问题的版本(缺少强制节、工具名拼错、验收项与测试不匹配)也去真实执行,白白消耗算力。
→ Step 1.5 逻辑自检是必过关卡,7 项全部通过才能进入真实执行。
验收清单
- [x] SKILL.md 包含完整的五步循环说明(含 Step 1.5 逻辑自检)
- [x] 每步都有可操作的具体指令(不是模糊描述)
- [x] 根因分类表覆盖常见失败模式(含"外部依赖不可用")
- [x] 有超出轮次上限的处理方案(含备份还原)
- [x] 有快速自验证测试场景(已实际运行通过)
- [x] 有空转检测机制(STALE BREAK)
- [x] 有版本备份/回滚保护(进化模式)
- [x] 验收标准来源优先级明确,Agent 自生成时有内容正确性强制要求
- [x] 执行方式表明确注明"模拟推演不可作为验收证据"
- [x] 逻辑自检门(Step 1.5):7 项检查清单,全部通过才能进入真实执行
- [x] 逻辑自检失败不消耗 MAX_ITER,仅消耗独立的 LOGIC_CHECK_MAX
进化历史
| 版本 | 日期 | 主要变更 |
|---|---|---|
| v1.0 | 2026-06-29 | 初始版本,从 browser-file-downloader 的进化实践中提炼 |
| v1.1 | 2026-06-29 | self-improving-agent 审查后强化:① 加入空转检测(STALE BREAK)② 加入备份/回滚保护 ③ 修复"模拟推演可当验收证据"漏洞 ④ 明确验收标准来源优先级 ⑤ 执行方式表增加"可否作为验收证据"列 ⑥ 补充外部依赖不可用根因类型 ⑦ 补充陷阱6/7/8 |
| v1.2 | 2026-06-29 | 加入 Step 1.5 逻辑自检门:7 项纯推理检查(结构完整性 / 测试可执行性 / 验收覆盖 / 内容断言 / 前置条件 / 无内部矛盾 / 路径有效),全部通过才进入真实执行;自检失败不消耗 MAX_ITER;新增 BREAK 条件 ④ (LOGIC_CHECK_MAX);补充陷阱9 |