Skill Iter — 自迭代能力评审标准
评估一个 Skill 是否具备"自己让自己变好"的能力,输出结构化评分与可操作的改进建议。
核心理念
自迭代不是一个功能,而是三层递进的能力:
| 层级 | 名称 | 本质 | 最低要求 |
|---|---|---|---|
| L1 | 运行时自修复 | 边执行边修正过时步骤 | SKILL.md 中明确授权 Agent 就地修复 |
| L2 | 执行后经验沉淀 | 每次执行的教训自动积累 | 有 Local Lessons Learned 协议 + 本机 state 路径 + 合并策略 |
| L3 | 跨 Skill 知识联动 | 一个 skill 的经验惠及其他 skill | 经验可被外部 skill 引用或编排器聚合 |
评审维度(7 项)
D1: 反馈采集 — 是否有数据进来
| 等级 | 标准 |
|---|---|
| ❌ 缺失 | 无任何执行反馈机制 |
| ⚠️ 基础 | 仅记录成功/失败 |
| ✅ 达标 | 采集结果状态、轮数、错误次数、是否阻塞 |
| 🌟 优秀 | 额外采集对话轨迹摘要、耗时分布、工具调用统计 |
检测方法:检查 SKILL.md 是否有自检/回顾阶段,检查配套脚本/代码中是否有 collect_feedback 或等效逻辑。
D2: 触发判定 — 不是每次都分析,而是值得时才分析
| 等级 | 标准 |
|---|---|
| ❌ 缺失 | 无触发逻辑,从不分析 |
| ⚠️ 基础 | 仅失败时分析 |
| ✅ 达标 | 失败 + 阻塞 + "成功但低效"(轮数/耗时超阈值)均触发 |
| 🌟 优秀 | 支持自定义触发规则,可通过配置调整阈值 |
关键公式:
def should_improve(feedback) -> bool:
if feedback.has_error or feedback.blocked or feedback.failed:
return True
return feedback.turns_used > THRESHOLD # 成功但低效
D3: 分析能力 — 能从轨迹中提取可操作的改进
| 等级 | 标准 |
|---|---|
| ❌ 缺失 | 无分析环节 |
| ⚠️ 基础 | 人工回顾,无结构化输出 |
| ✅ 达标 | LLM 分析执行轨迹,输出结构化改进条目 |
| 🌟 优秀 | 区分"固化为工具调用" vs "记录为经验规避" vs "无需处理" |
mirror-release Phase 14 的三分法是达标标准:
- 固化为工具调用 → 确定性步骤,写入 SKILL.md Phase
- 记录为经验规避 → 条件性步骤,写入本机 Local Lessons Learned
- 无需处理 → 一次性问题,仅记录在报告中
D4: 经验持久化 — 分析结果写到哪里、怎么管理
| 等级 | 标准 |
|---|---|
| ❌ 缺失 | 经验仅存在于对话上下文,用完即消失 |
| ⚠️ 基础 | 手动维护"注意事项"章节 |
| ✅ 达标 | 自动写入本机 Local Lessons Learned,有去重 + FIFO 淘汰(上限 N 条) |
| 🌟 优秀 | 语义去重(embedding 相似度)+ LRU/引用频率淘汰 + 分类标签 |
当前最佳实践:
def _merge_lessons(existing, new_items, max_entries=10):
seen = {item.strip().lower() for item in existing}
merged = list(existing)
for item in new_items:
if item.strip().lower() not in seen:
merged.append(item)
return merged[-max_entries:] # FIFO 淘汰
默认持久化位置:${XDG_STATE_HOME:-~/.local/state}/openclaw-skills/<skill-name>/lessons-learned.md。
D5: 注入闭环 — 经验如何回到下次执行
| 等级 | 标准 |
|---|---|
| ❌ 缺失 | 经验写了但下次不读 |
| ⚠️ 基础 | 需要人工提醒 Agent 参考历史 |
| ✅ 达标 | 加载 SKILL.md 时自动读取本机 Local Lessons Learned |
| 🌟 优秀 | 按当前任务上下文动态筛选最相关的经验注入 |
核心验证:执行路径上是否存在 read SKILL.md → read local lessons → execute → write local lessons → next run reads updated lessons 的闭环。
D6: 安全门禁 — 防止自迭代引入破坏
| 等级 | 标准 |
|---|---|
| ❌ 缺失 | Agent 可任意修改 SKILL.md,无审核 |
| ⚠️ 基础 | 依赖 git 版本控制兜底 |
| ✅ 达标 | 改进先写入 .pending 文件,需人工确认后合入 |
| 🌟 优秀 | 高置信度自动合入 + 低置信度人工审核 + prompt 注入检测 |
prompt 注入检测(必须有):
THREAT_PATTERNS = [
r"ignore\s+(all\s+)?previous\s+instructions",
r"you\s+are\s+now\s+",
r"system\s+prompt\s*:",
r"<\s*/?system\s*>",
r"IMPORTANT:\s*NEW\s+INSTRUCTIONS",
r"\u200b|\u200c|\u200d|\u200e|\u200f", # 隐形 unicode
]
D7: 可观测性 — 能追溯迭代历史
| 等级 | 标准 |
|---|---|
| ❌ 缺失 | 无法知道 SKILL.md 何时被改、为什么改 |
| ⚠️ 基础 | 依赖 git log |
| ✅ 达标 | 每次改进附带触发原因 + 执行 session_id + 时间戳 |
| 🌟 优秀 | 维护 SKILL.md.versions.json 变更日志,支持按条目回滚 |
语义审计 — 应对模型进化
规则审计(Phase 1-2)依赖固定脚本名与关键词。模型越强,越倾向把能力内联进 SKILL.md 散文或非约定命名的脚本,导致 D1/D3/D5 等维度被误判为缺失/基础。语义审计层用 LLM 复核规则结论,仅在能引用 SKILL.md/脚本证据时改判。
skill-iter audit <skill_dir> --semantic # 规则审计 + LLM 语义复核
skill-iter audit <skill_dir> --semantic --json # 结构化输出
判定契约(semantic_auditor.py):
- 升级必须带证据:等级高于规则结论时,LLM 必须引用原文片段,否则回退规则等级(防幻觉拔高)。
- 允许下调:证据显示规则误报时(如把无关文档的 timestamp 当迭代日志)可下调,无需额外证据。
- 保守缺省:LLM 未给出某维度结论或等级非法时,保留规则等级。
- 改判 reason 带
[semantic]前缀,可追溯。 - 规则审计作为快速预筛与 CI 兜底(
--ci不依赖 LLM),语义审计按需触发以控制 token 成本。
评审流程
Phase 1: 结构扫描
读取目标 SKILL.md,检查以下结构要素:
| 检查项 | 扫描方式 | 判定 |
|---|---|---|
| Local Lessons Learned 协议 | 正则 `##.*(Local\s+)?Lessons?\s+Learned | ##.*经验 |
| 自检/回顾阶段 | 正则 `自检 | retrospective |
.pending 机制 |
检查 skill 目录下是否有 .pending 文件或代码中引用 .pending |
有/无 |
| references 目录 | 检查是否有 references/ 子目录存放补充文档 |
有/无 |
| 版本追踪 | 检查 .versions.json 或 git log 中的 skill 变更记录 |
有/无 |
Phase 2: 维度评分
逐一对照 D1-D7 评分,输出评分表:
📊 自迭代能力评审报告 — {skill_name}
| 维度 | 等级 | 说明 |
|------|------|------|
| D1 反馈采集 | ✅ | Phase 14 采集错误/耗时/阻塞 |
| D2 触发判定 | ⚠️ | 每次都执行,未区分"值得分析" |
| D3 分析能力 | ✅ | 三分法(固化/规避/忽略) |
| D4 经验持久化 | ⚠️ | 有 Local Lessons Learned 但无淘汰策略 |
| D5 注入闭环 | ✅ | Tier 2 加载自动包含 |
| D6 安全门禁 | ⚠️ | 依赖 git,无 .pending |
| D7 可观测性 | ⚠️ | 仅 git log |
总评:✅ 达标 3/7 | ⚠️ 基础 4/7 | ❌ 缺失 0/7
自迭代成熟度:L1(运行时自修复)已达标,L2(经验沉淀)部分达标
Phase 3: 生成改进建议
针对每个非 ✅/🌟 的维度,输出具体、可操作的改进建议:
🔧 改进建议
1. [D2] 添加触发判定逻辑
当前:Phase 14 每次都执行完整分析
建议:在 Phase 14 开头增加快速判定——如果 Phase 0-13 全程无错误且轮数 < 35,
输出"本次流程顺利"并跳过深度分析
收益:减少约 60% 的无效分析轮数
2. [D4] 引入本机 state + FIFO 淘汰策略
当前:Lessons Learned 写在 SKILL.md 或只增不减
建议:写入 `${XDG_STATE_HOME:-~/.local/state}/openclaw-skills/<skill-name>/lessons-learned.md`,超过 10 条时淘汰低价值旧条目
收益:保留多 agent 共享经验,同时避免私有经验进入 GitHub
配置
| 键 | 默认值 | 说明 |
|---|---|---|
| MAX_LESSONS_ENTRIES | 10 | Local Lessons Learned 最大条目数 |
| TURNS_THRESHOLD | 20 | "成功但低效"的轮数阈值 |
| AUTO_MERGE_CONFIDENCE | 0.9 | 高于此置信度可跳过人工确认 |
| THREAT_SCAN_ENABLED | true | 是否启用 prompt 注入检测 |
边界与排除
以下场景不应触发本 skill,请 do not use skill-iter:
- 创建新 skill — 应由 yao-meta-skill 处理
- 代码重构 / bug 修复 — 不属于 skill 评审
- 知识问答(如"D1 维度是什么")— 直接回答即可
- 工作流打包 — 应由 yao-meta-skill 处理
- 一次性脚本或迁移工具 — 不需要自迭代机制
触发词测试集见 evals/trigger_cases.json。
注意事项
- 评审结果是建议而非强制——不同 skill 的复杂度和执行频率不同,并非所有 skill 都需要 L3 能力
- 低频执行的 skill(如一次性迁移脚本)不需要经验沉淀机制
- 自迭代的核心价值是降低人工干预频率,而非追求零干预
- 改进建议必须考虑 token 成本——过度分析的 token 消耗可能超过收益
自检阶段 — Post-Execution Retrospective
每次评审执行完成后,Agent 必须执行以下自检流程:
快捷方式(推荐):调用 scripts/run_retrospective.py <skill_dir> --note "<备注>" --rating N --category <类别> 一键执行完整管线。
手动分步执行:
- 采集反馈:调用
scripts/collect_feedback.py记录本次执行的状态、轮数、错误情况 - 触发判定:调用
scripts/should_improve.py判断是否值得启动深度分析 - 轨迹分析:调用
scripts/analyze_trajectory.py对反馈执行三分法分类(固化/经验/忽略) - 安全扫描:如果产生了新的经验条目,调用
scripts/threat_scan.py扫描注入威胁 - 经验写入:把通过安全扫描的新经验写入本机 Local Lessons Learned state 文件
- 结构改动确认:只有需要固化流程/工具行为时,才生成 pending SKILL.md 改进并等待人工确认
注入闭环路径:Agent 读取 SKILL.md → 读取本机 Local Lessons Learned → 执行评审 → 采集反馈 → 分析改进 → 写入本机 lessons 或 pending 结构改动 → 下次执行自动读取
工具链 — scripts/
| 脚本 | 功能 | D 维度 |
|---|---|---|
collect_feedback.py |
采集执行反馈到 reports/feedback-log.json |
D1 |
should_improve.py |
判定是否需要触发改进分析 | D2 |
analyze_trajectory.py |
三分法分析(固化/经验/忽略),输出 reports/analysis-report.json |
D3 |
merge_lessons.py |
管理本机 Local Lessons Learned(去重 + 淘汰 + 写入) | D4, D6 |
threat_scan.py |
Prompt 注入检测 | D6 |
run_retrospective.py |
端到端编排管线(collect→judge→analyze→scan→merge),输出 reports/improvement-log.json |
D5, D7 |
Local Lessons Learned
Private runtime lessons are stored outside Git so multiple local agents can share them without uploading them to GitHub.
- Read before execution:
${XDG_STATE_HOME:-~/.local/state}/openclaw-skills/skill-iter/lessons-learned.md - If the file exists, treat it as part of this skill's local context.
- After real usage, update that file only when a new lesson changes future behavior.
- Keep at most 10 deduped lessons; evict stale or low-value entries first.
- When writing, acquire an atomic lock with
mkdir "${XDG_STATE_HOME:-$HOME/.local/state}/openclaw-skills/skill-iter/lessons-learned.lock"; remove it after the write. - Do not commit the local lessons file or copy private lessons back into this
SKILL.md.