Verboo Code 的 Hook Chains:任务失败时自动恢复
返回博客
文章dev toolshow toverboo codetutorialautomação

Verboo Code 的 Hook Chains:任务失败时自动恢复

Mafra2026年9月11日阅读约 4 分钟

深夜里一个任务失败了,没有人盯着终端:目前在 Verboo Code 中,它就会一直停在失败状态,直到有人回来手动重新运行。Hook Chains 正是为了解决这个问题。它是一个事件驱动的恢复层:当失败 hook 触发时,评估声明式规则并执行一个动作,比如用新代理恢复任务,或者通知团队。这是一个真实存在的功能,默认关闭。本文展示开启它的确切命令和完整的配置文件,全部直接在 verbeux-ai/code 源码中核实过(src/utils/hookChains.tsdocs/hook-chains.md)。

什么会触发一次 hook chain?

目前是两种事件。PostToolUseFailure,当一个 tool 在执行过程中失败时;以及 outcome"failed"TaskCompleted,当一个任务未成功结束时。每条规则声明它响应哪个事件和哪个结果;结果可以用 outcome 填一个单值,或用 outcomes 填一个列表(两者不能同时使用,schema 本身会拒绝)。

我要怎么在 Verboo Code 里开启 hook chains?

需要两步。第一步,开启整个功能的环境变量,因为即使存在配置文件,它默认也是关闭的:

export CLAUDE_CODE_ENABLE_HOOK_CHAINS=1
# 也接受: true, yes, on

第二步,规则文件。默认路径是项目根目录下的 .verboo/hook-chains.json。要使用其他路径:

export CLAUDE_CODE_HOOK_CHAINS_CONFIG_PATH=/path/to/hook-chains.json

没有这个激活变量,Verboo Code 甚至不会去读取文件:enabled 的检查发生在任何从磁盘加载配置的尝试之前。

配置文件的格式是什么样的?

一个对象,包含四个通用控制字段和一个规则列表。它可以直接放在 JSON 根部,也可以包在一个 hookChains 键里,两种写法都可以。

字段类型默认值
version数字1
enabled布尔值true
maxChainDepth整数,1 到 102
defaultCooldownMs整数30000
defaultDedupWindowMs整数30000
rules列表[]

一个最简示例,用新代理恢复一个失败的任务:

{
  "version": 1,
  "enabled": true,
  "maxChainDepth": 2,
  "defaultCooldownMs": 30000,
  "defaultDedupWindowMs": 30000,
  "rules": [
    {
      "id": "retry-task-via-fallback",
      "trigger": { "event": "TaskCompleted", "outcome": "failed" },
      "cooldownMs": 60000,
      "actions": [
        {
          "type": "spawn_fallback_agent",
          "id": "spawn-retry-agent",
          "description": "Retry failed task with fallback agent",
          "promptTemplate": "A task failed. Recover it safely.\nTask=${TASK_SUBJECT}\nError=${ERROR}",
          "agentType": "general-purpose",
          "model": "sonnet"
        }
      ]
    }
  ]
}

我要怎么让规则只针对特定错误?

在规则内部使用 condition 块。它是可选的,但如果不写,规则会对所声明的事件和结果的任何一次出现都作出反应。

字段作用
toolNames规则接受的 tool 名称列表(匹配事件里的 tool_name/toolName
taskStatuses接受的任务状态列表
errorIncludes对错误信息做不区分大小写的子串匹配
eventFieldEquals按字段路径做精确相等匹配,例如 "meta.source": "scheduler"
"condition": {
  "toolNames": ["Edit", "Write", "Bash"],
  "errorIncludes": ["timeout", "permission denied"]
}

可以只通知团队,不运行任何代理吗?

可以,用 notify_team 动作代替 spawn_fallback_agent。它读取项目里配置的团队并写入消息,不需要启动新的代理:

{
  "type": "notify_team",
  "id": "notify-ops",
  "recipients": ["*"],
  "summary": "Hook chain ${RULE_ID} fired",
  "messageTemplate": "Event=${EVENT_NAME} outcome=${OUTCOME}\nTask=${TASK_ID}\nError=${ERROR}"
}

如果没有配置团队文件,这个动作不会中断整条链:它会被跳过,并记录跳过的原因。这两个动作,以及第三个动作(warm_remote_capacity,提前通知运行时预热远程执行容量),接受同样的一组文本占位符:

占位符填充内容
${EVENT_NAME}触发该规则的事件
${OUTCOME}事件的结果
${RULE_ID}匹配到的规则 id
${TASK_SUBJECT}任务主题
${TASK_DESCRIPTION}任务描述
${TASK_ID}任务标识符
${ERROR}错误信息
${PAYLOAD_JSON}完整的事件负载,JSON 格式

即使不使用远程执行,保留 warm_remote_capacity 的配置也是安全的:当项目策略禁止远程会话,或没有可预热的活跃远程会话时,它会被无错误地跳过。

什么能防止恢复循环无限进行?

三重防护,并且是叠加的。maxChainDepth 会在当前链深度已经达到上限时(默认 2,上限 10)切断触发:一个引发另一个事件的 hook chain 动作,不会演变成无限链条。cooldownMs 会阻止同一条规则在配置的时间过去之前再次触发(默认 30 秒,可按规则调整)。dedupWindowMs 会在窗口期内抑制相同事件和动作组合的重复,因此同一个错误的连续爆发不会让同一个代理连续触发多次。除此之外,还有默认安全的行为:如果当前信号已经被中止,动作会被跳过,而不会尝试在一个已经不存在的状态上运行。

Verboo Code 中 hook chain 的流程图:失败事件、通过 condition 匹配规则、触发动作,以及防止重复触发的安全防护
从事件到动作,附带防止循环的安全防护。已于 2026-09-11 在 verbeux-ai/code 的 src/utils/hookChains.ts 中核实。

每次规则触发 spawn_fallback_agent,都会有一个全新的代理从零开始尝试恢复任务。在同一个错误于 cooldownMs 让规则安静下来之前重复出现几次的夜晚,这意味着连续启动多个恢复代理。在 Verboo Code 中,其中每一个都以不限量的 token 运行,所以第五次恢复尝试和第一次的成本是一样的。

喜欢这篇文章吗?
把知识分享给你的朋友。
// 继续阅读

相关文章