关于 self-healing
self-healing 是供编码 Agent 在任务执行中处理故障的技能,要求先诊断、再修复,并重跑失败操作验证,最后记录结果供后续复用。
主要功能
- 01重试前诊断故障
- 02修复运行中的工具与环境问题
- 03记录修复前必须验证
- 04记录放弃或待验证的恢复
- 05按需保存可复用产物
适用场景
- 01恢复失败的构建或测试
- 02为缺失能力编写辅助工具
- 03处理环境或 API 变化
- 04为后续编码会话记录修复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pskoett/ pskoett-ai-skills --skill self-healing安装后在 Claude Code 中输入/self-healing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/benchmark-iteration-1.jsonbenchmark-iteration-1.mdevals.jsontrigger-evals.jsonevals/fixtures/abandoned-heal/recent-flake.logevals/fixtures/abandoned-heal/src/Card.test.tsxCard.tsxevals/fixtures/branch-rename/README.mdevals/fixtures/lockfile-mismatch/package.jsonpnpm-lock.yamlrecent-error.logevals/fixtures/recurring-heal/pyproject.tomlrecent-error.logevals/fixtures/recurring-heal/.learnings/HEALS.mdreferences/examples.mdhooks.mdinterop-with-self-improvement.mdpipeline-integration.mdscripts/detect-failure.shfind-similar-heals.shnew-heal.sh详细介绍
自愈
为编码 Agent 提供主动的运行时恢复能力。出现故障时,运行以下循环:诊断 → 修补 → 验证 → 归档。留下可复用且经过验证的成果,而不是把失败掩盖过去。
这一理念与 browser-use/browser-harness 如出一辙:测试框架每次运行都会自我改进。Agent 遇到缺口时不会就此失败,而是在执行过程中编写修复方案、验证其有效性,并归档持久化成果,供后续运行使用。编码任务也值得采用同样的循环。
这项技能的用途
当编码 Agent 在任务中途碰壁时,默认的失败处理方式有:
- 掩盖问题——“我换种方法试试”——然后丢失恢复方案
- 假装修复成功——却不重新运行出问题的操作
- 只修症状——跳过测试、吞掉错误,不断重试直到成功
这三种方式都会让一次性故障反复出现。下一个处理同一项目的 Agent 还会遇到同样的障碍。
这项技能要求遵循一项原则:先验证,再持久化。只有重新运行失败的操作并确认其成功,补丁才算真正生效。成功后,将经过验证的修复方案归档,让下次运行也能受益。
与自我改进的关系
这两项技能有意分开。两者都要运行——它们相互促进,但不会重叠。
| 方面 | self-healing(此技能) | self-improvement |
|---|---|---|
| 时机 | 执行期间,故障正在发生 | 事后,在自然的工作节点 |
| 动词 | 立即修复——恢复可用状态 | 留待日后参考——积累知识 |
| 结果 | 经过验证的补丁 +(可选)可复用成果 | 记录的经验、纠正建议、需求 |
| 验证 | 必须——没有证据就不能持久化 | 无需 |
| 文件 | .learnings/HEALS.md + .learnings/heals/<HEAL-ID>/(按需创建) | .learnings/ERRORS.md、LEARNINGS.md、FEATURE_REQUESTS.md |
| 触发条件 | 任务中途观察到故障 | 纠正建议、知识缺口、功能需求、反复出现的问题 |
**边界规则:**如果你要记录事实、纠正建议或愿望,那属于 self-improvement。如果你要针对正在发生的故障应用并验证修复方案,那属于 self-healing。
故障由技能导致时
向用户说明受影响的技能路径/指令、证据、依赖范围、拟议的具体修改以及验证限制,即使这是首次故障也一样。
在现有 HEAL 中记录 ### Skill Review Proposal,并设置 Approval: pending
和 Application: proposed;这与基于复发情况的升级处理是分开的。
未经明确批准,不得编辑、禁用、弃用或移除技能文件、配套资源、元数据或已安装/生成的副本。 展示具体提案并询问用户,同时说明此技能的审批规则。 对于相同范围,复用现有的明确批准;要求修复当前任务的一般性请求,不代表有权重写技能。即使无法使用 context-decay,或受审查的技能要求自我修复,也必须遵守此界限。
如有可能,继续安全且已获授权的任务本地恢复,并单独验证;恢复通过验证,并不表示技能提案已应用或已验证。如果恢复需要编辑技能,请暂停该步骤并等待批准。
记录 Status: pending-verify、Fix: none applied — awaiting approval 和待审批的提案;不得暗示补丁已运行或验证已成功。
如有 context-decay 的技能审查工作流,请使用;否则直接遵守此提案边界。在 HEAL 中保留验证证据。
修复循环
● failure observed
│
● 1. DIAGNOSE capture context — command, error, env, what was attempted
│ search HEALS.md for the same Pattern-Key first
│ (most heals are recurrences; don't reinvent)
│
● 2. PATCH write the fix — script, helper, env tweak, alt command
│ artifacts → .learnings/heals/<HEAL-ID>/ (only if needed)
│
● 3. VERIFY re-run the failing op — must succeed
│ ↻ if still failing: refine and retry, cap at 3 attempts
│ ✗ if uncrackable: file Status: abandoned with notes
│
● 4. FILE write HEAL-YYYYMMDD-XXX to .learnings/HEALS.md
│ with Pattern-Key, status, verification proof
│
✓ working state restored, heal persisted
(conditional) PROMOTE if Pattern-Key recurrence ≥ 3 across distinct tasks,
append a Handoff block → self-improvement promotes to memory
如果在循环中途放弃修复,不要假装修复成功。创建一条 HEAL- 记录,设置 Status: abandoned,并说明哪些尝试没有奏效。后续 Agent 也能从失败经验中吸取教训。
何时触发
自我修复仅在执行过程中发生实际故障时触发——Agent 刚刚发现某件事不起作用,需要修复它才能继续。分为五种情况:
1. 工具故障(命令/测试/构建/Lint)
任何调用以非零状态退出或产生错误输出。不要只确认问题后原样重试——应先诊断,再修补并验证。
示例: 存在 pnpm-lock.yaml 时,npm install 报错(切换工具);pytest 因 ModuleNotFoundError 失败(激活 venv);tsc 报告类型过时(重新生成客户端);eslint 报告配置错误(安装缺失的解析器)。
2. 缺少能力/工具缺口
Agent 需要某种尚不存在的东西——脚本、辅助工具、封装工具或胶合函数。立即编写。这与 browser-harness 的 agent_helpers.py 最为相似。
示例: 按自定义键对 CSV 去重(编写一个小型 Python 辅助工具);以相同方式引导 12 个微服务(编写 scripts/bootstrap-all.sh);批量重命名符合某种模式的分支(编写一个基于 gh 的 Shell 辅助工具)。
3. 环境问题
本地环境与项目预期不符。检测问题、修复并验证。
示例: 运行时版本不匹配(nvm use、pyenv local、rustup override);切换分支后依赖缓存过时;Git 工作区状态不干净,阻止了检出;缺少 .env(从 .env.example 复制并指出缺失项)。
4. 外部服务/API 变更
Agent 依赖的服务返回意外结果。寻找变通方案并记录下来。
示例: MCP 工具因架构变更返回 InputValidationError(调整调用参数结构);公共 API 触发速率限制(退避、切换端点或分批处理);上游库更改了默认值,导致脚本失效(固定版本)。
5. 即将重试相同的失败方案
Agent 发现自己即将重复执行失败的步骤。这种自我觉察意味着修复已在酝酿——应将替代方案记录为补丁。
需要留意的检测信号
- 非零退出码
- 工具输出中的堆栈跟踪
- 同一操作因相同错误连续失败两次
- “我试试另一种方法”——将其记录为修复
command not found/module not found/permission denied- 断言过时、快照不匹配、此前不存在的类型错误
- 暗示问题源于环境而非逻辑的“奇怪”输出
重试前先分类
每次重试前,根据观察到的证据对故障进行分类:
- 确定性故障 — 相同的输入或调用形式会产生相同的验证、解析器、架构或查询规划错误。不要原样重试。调整诊断或实质性地更改输入;条件允许时先在本地验证,然后最多再进行有界次数的尝试。
- 瞬时故障 — 限流、传输故障、服务暂时不可用,或有证据表明请求稍后可能成功的超时。采用有界退避并降低负载;不要并行扩散重试。
- 共享服务/批处理故障 — 不同项目 ID 出现相同的规范化故障。停止批处理,报告共同依赖项,并先运行一次经过更改的试点,再恢复处理。
规范化故障特征时,移除易变的时间戳、请求 ID 和项目 ID。即使发生在新会话中,重复的结构化输出验证失败仍属于确定性故障。一个有界查询反复超时,意味着需要采用不同的查询计划或缩小输入范围,而不是再次进行相同调用。报告 ID 不同,并不意味着相同的元数据服务故障彼此独立。
如果诊断无法支持上述任何一种分类,请停止并收集证据,不要猜测。切勿编造工具语法或看似成功的备用方案。
HEAL 条目格式
追加到 .learnings/HEALS.md(若文件不存在,则创建):
## [HEAL-YYYYMMDD-XXX] short_kebab_name
**Logged**: ISO-8601 timestamp
**Status**: verified | pending-verify | abandoned
**Trigger**: tool-failure | missing-capability | env-issue | external-change | <free-form>
**Active-Context**: (optional) — current skill, task phase, or workflow stage; omit if not applicable
**Area**: free-form tag — what part of the system (`build`, `tests`, `ci`, `auth`, `data-pipeline`, `mobile`, ...)
**Priority**: low | medium | high | critical
### Failure
What broke — concrete: the command, the error message, the action that was blocked. Include exit codes and verbatim error lines.
### Diagnosis
The root cause as understood after investigation. Why the obvious approach didn't work. Not a guess — what was actually verified during the heal.
### Fix
The patch that was applied. Verbatim commands, code snippets, or pointers to files under `.learnings/heals/<HEAL-ID>/`. Keep it minimal — just enough to reproduce.
### Verification
What was run after the fix and what it returned. Exit code, output snippet, test pass count. **This is the proof.** Without it, the entry is `pending-verify` or `abandoned`.
### Artifacts
(omit this section if no files were generated; otherwise list relative paths under `.learnings/heals/<HEAL-ID>/`)
### Metadata
- Related Files: path/to/file.ext
- See Also: HEAL-... | LRN-... | ERR-... (related entries)
- Pattern-Key: lower.snake.case key for recurrence detection (e.g. `env.lockfile_mismatch`)
- Recurrence-Count: 1
- First-Seen / Last-Seen: YYYY-MM-DD
---
字段说明
- Status —
verified= 验证步骤已通过。pending-verify= 恢复尚未得到证实;说明补丁已应用还是仅已提议,以及验证为何仍待完成(包括因审批受阻的技能编辑)。abandoned= 补丁无效或诊断有误 — 记录尝试过的内容。切勿将尚未应用的补丁描述为已应用。 - Trigger — 可自由填写。列出的值是常见形式;关键是充分描述故障形式,以便后续 Agent 能够据此识别。
- Active-Context — 可选。如果你的环境有意义明确的“我当时在做什么”标签(当前技能、当前任务阶段、构建阶段、Agent 角色),则使用此字段。不适用时可省略。浏览器测试框架中对应的做法是按域名限定范围的
domain-skills/<site>/。 - Area — 可自由填写。选择便于后续 Agent 查找的分类。
frontend、data-pipeline、ci、auth、terraform、mobile、embedded— 任何适合项目情况的值均可。 - Pattern-Key — 使用小写
snake_case,保持稳定,并可在多个项目中复用。键相同的两条 heal 记录表示问题再次发生。env.lockfile_mismatch是合适的示例;fixed_thing_tuesday则不合适。
ID 生成
格式:HEAL-YYYYMMDD-XXX。XXX 为连续递增的 3 位数字,或随机的 3 位字母数字字符。示例:HEAL-20260524-001、HEAL-20260524-A7B。
产物目录(按需创建)
只有当 heal 生成了值得保留的内容时,才创建 .learnings/heals/<HEAL-ID>/。单行修复无需创建文件夹;HEAL 条目文本已足够。未应用补丁的已放弃 heal 也无需创建文件夹。
.learnings/
├── HEALS.md
├── ERRORS.md / LEARNINGS.md / FEATURE_REQUESTS.md (self-improvement)
└── heals/
└── HEAL-20260524-001/
├── helper.sh
├── patch.diff
└── notes.md
**放在此处:**生成的脚本/辅助工具、补丁文件、补充说明、用于记录诊断过程的输出捕获文件。 **不要放在此处:**项目源代码更改(应放在项目树中,并通过 Related Files 引用)、机密信息、HEAL 文本中已记录的输出。
验证规则
验证是承重墙。自我修复与自我改进的根本区别在于,修复必须经过证实,而不是停留在推测层面。
什么算作验证依据
| 故障类型 | 验证方式 |
|---|---|
| 工具/命令/测试/构建/Lint | 重新运行原始调用;预期退出码为 0/通过 |
| 缺少功能 | 使用真实输入端到端调用辅助工具;预期结果符合意图 |
| 环境偏移 | 重新运行触发诊断的操作 |
| 外部服务的变通方案 | 应用补丁后重新运行失败的调用;预期得到可用响应 |
沙盒/离线/仅限 CI 的故障
如果确实无法运行验证步骤(没有网络、没有真实远程服务、Shell 受沙盒限制、仅能在 CI 中复现),请提交 Status: pending-verify,并包含:
- 用户/CI 应运行的确切命令
- 验收标准——什么样的结果才算作验证依据
- 如果可以构造,请提供模拟验证依据(例如,试运行模式、失败调用的桩实现、沙盒脚本)
pending-verify 是诚实的。伪称 verified,正是这项技能旨在防止的失败模式。
何时需要编写验证脚本
大多数修复无需单独的验证脚本——验证步骤只是重新运行失败的操作。出现以下情况时,请编写合适的验证脚本:
- 修复会生成可复用的辅助工具,需要在多种情况下进行测试
- 无法在实际环境中复现故障,但可在沙盒中复现(干净的 Git 仓库、模拟服务、伪造输入)
- 预计会在多个项目中重新应用该修复——此时验证脚本还可用作回归检查
如果验证失败
- 第一次——对故障进行分类,实质性地改进补丁或输入,然后重试。最初的诊断往往有误。
- 第二次——退一步,重新考虑诊断。对于重复出现的确定性特征,除非下一次尝试能改变诊断或输入,否则就此停止。对于共享服务特征,暂停批次并将控制权交还给协调器。
- 第三次——停止。提交
Status: abandoned,并附上尝试过的操作说明。告知用户。不要盲目尝试。
以下情况不算作验证
- “看起来没问题”/“我觉得这样应该可行”
- 重新运行与最初失败的命令不同的命令
- 抑制失败(
|| true、--ignore-errors)——这是在掩盖问题 - 跳过或删除失败的测试——这是回归
- 因修复前的缓存仍然有效而通过
可逆性
优先采用可逆补丁。如果修复修改了项目文件,请将差异保存到 patch.diff。如果修复具有破坏性(删除生成的文件、重写锁文件),请明确注明——未来读取 HEAL 的 Agent 需要知道被破坏了什么。
复发与晋升
大多数修复都属于复发情况。提交新的 HEAL 前,请先搜索:
grep -n "Pattern-Key: <your-pattern-key>" .learnings/HEALS.md
如果找到:
- 增加
Recurrence-Count - 更新
Last-Seen - 将当前情况添加为 See Also 链接
- 不要创建重复条目
晋升门槛
只有在全部符合以下条件时,才在现有条目中添加 Handoff 块:
Recurrence-Count >= 3- 在至少 2 个不同任务中出现
- 在 30 天内(符合
self-improvement和聚合器中的晋升规则) - 修复具有普适性(不是已记录在记忆文件中的项目专属修复)
### Handoff
- **Promoted To**: self-improvement at YYYY-MM-DD
- **Promotion Target**: CLAUDE.md | AGENTS.md | .github/copilot-instructions.md | new-skill
- **Distilled Rule**: One-line prevention guidance derived from the heal
随后由 self-improvement(或学习聚合器)接手:提炼规则,将其写入合适的上下文文件,或抽取为可复用技能。HEAL 会保留下来,以便追溯。
反模式
- 未经验证就记录。 在修复得到证实前提交 HEAL,会让这种自我改进变得更加嘈杂。如果 verify 尚未通过,该条目应标记为
pending-verify或abandoned。 - 只修复症状,不解决根因。 不能通过跳过失败的测试(
pytest.skip、it.skip、xit)来修复它。不能通过--retry来修复不稳定的 CI。找出根因;如果做不到,就如实放弃。 - 先生成新修复方案,却不尝试现有方案。 按 Pattern-Key 搜索
HEALS.md。大多数修复都是重复出现的问题。 - 项目已有辅助工具,却另行发明。 先查看
scripts/、Makefile、justfile、package.json、pyproject.toml。修复 = 补上缺失的内容,而不是重复已有的内容。 - 范围蔓延。 一项修复只针对一个故障。清理应放在质量检查阶段;重构属于功能开发。范围蔓延会让修复变得难以审查。
- 创建空的产物目录。 如果
.learnings/heals/<HEAL-ID>/中没有要放的内容,就不要创建它。
最佳实践
- 及时修复,始终记录。 即使放弃的修复,也能让下一个 Agent 知道哪些方法行不通。
- 持久化前先验证。 这条规则不可妥协。
- 补丁应尽量小且可逆。 3 行修复算修复;300 行重构属于功能开发。
- 保持 Pattern-Key 稳定。
env.node_version_mismatch可复用;fixed_the_thing_on_tuesday则不行。 - 引用而非重复。 通过 See Also 交叉链接相关的 HEAL/LRN/ERR。
- 将重复问题移交处理。 同一项修复出现 3 次,就值得纳入项目的长期记忆。
- 不要让修复产物阻塞主代码树。
.learnings/heals/下的文件是参考资料;如果某个脚本变成关键依赖,就将它移到scripts/。 - 试运行共享依赖的修复。 对于因同一个共享特征而失败的一批请求,在恢复处理前,先验证一个修改过的请求。
设置
mkdir -p .learnings # heals/ is lazy — created only when artifacts exist
touch .learnings/HEALS.md
Gitignore 的选择与 self-improvement 一致。可将修复保留在本地(在 .gitignore 中加入 .learnings/),也可将其作为团队知识共享(不要加入 gitignore——这样就能接受审查,成为持久的上下文)。
钩子集成
命令失败时自动触发是可选的,且因 Agent 而异。Claude Code / Codex 配置请参阅 references/hooks.md。
多 Agent 使用
此技能与 Agent 无关。.learnings/HEALS.md 采用纯 Markdown 格式——任何 Agent(Claude Code、Codex CLI、Copilot、Cursor、Aider 等)都可以读取和写入。不支持钩子的 Agent 可以通过其指令文件(例如 .github/copilot-instructions.md)获得提醒。示例请参阅 references/hooks.md。
流水线集成
如何将自我修复纳入更大的技能流水线(包括上游呈现过往修复、下游提升重复问题,以及机器验证关卡)记录在 references/pipeline-integration.md 中。使用此技能不需要这些内容——它可以独立使用。
另请参阅
references/examples.md— HEAL 条目的典型形式(命令失败、能力缺失、环境漂移、外部 API 变通方案、放弃的修复)references/interop-with-self-improvement.md— 两种技能之间的决策表和移交载荷references/pipeline-integration.md— 自我修复与更大流水线中的上游 / 下游技能之间的关系references/hooks.md— Claude Code / Codex 的自动触发设置