文章目录

在这里插入图片描述

Pre

OMC - 01 用 19 个 Agent 打造你的 Claude Code“工程团队”:oh-my-claudecode 深度解析与实战指南

OMC - 02 五分钟起步,走向多智能体协作:深入解析 oh-my-claudecode 快速开始与架构设计

OMC - 03 从 0 到高效:Oh My ClaudeCode 安装与实践全指南

OMC - 04 用好 Oh-My-ClaudeCode 的 30 个会话技能:从“帮我写点代码”到端到端自动交付

OMC - 05 从单人到多 Agent:Oh-my-claudecode 的插件架构解析

OMC - 06 从“大模型管家”到“十九人专家团队”:oh-my-claudecode 的多 Agent 工程实践

OMC - 07 把「选模型」当成一门工程学:oh-my-claudecode 的三层模型路由实践

OMC - 08 在多 Agent 时代,如何优雅地「分工协作」:oh-my-claudecode 委托分类体系深度解读

OMC - 09 oh-my-claudecode 的多 Agent 编排实战

OMC - 10 从创意到“免看管生产力”:深入解析 Oh-My-ClaudeCode 的 Autopilot 与 Ralph 模式

OMC - 11 跨供应商 CCG 合成:让 Claude、Codex、Gemini 一起给你“做代码评审”

OMC - 12 把 Claude Code 变成「可编程开发同事」:oh-my-claudecode 技能系统深度解析


大型 AI 编排系统想要真正“聪明地工作”,离不开一套精细的生命周期与 Hook 机制。Oh My ClaudeCode(下文简称 OMC)正是通过一个覆盖 11 个生命周期事件、20+ 个 Hook 的体系,把 Claude Code 从“单轮对话工具”升级为“可持续协作的自动化工作伙伴”。

这篇文章面向具备一定工程经验的开发者、Agent 架构设计者以及对 AI 编排系统感兴趣的技术爱好者,系统拆解 OMC 的 Hook 生命周期设计:它如何接住 Claude Code 抛出的每一个事件、如何把 Shell、TypeScript 与状态文件编织成可观测、可控制的执行平面,以及如何在不中断 AI 自由发挥前提下实现“软约束”的自动驾驶体验。


一、整体观:一个三层管道与 11 个事件

1.1 三层架构:从事件到状态的完整闭环

在这里插入图片描述

在 OMC 中,Hook 系统像一根贯穿上下游的“中枢神经”,整体分为三层:

  • 最上层:Claude Code 运行时
    • 负责发出生命周期事件(如 SessionStartUserPromptSubmitPreToolUsePostToolUseStopSessionEnd 等)。
  • 中间层:Manifest + Shell + TypeScript Bridge
    • hooks/hooks.json:声明哪些事件会触发哪些脚本、超时预算是多少、匹配条件如何。
    • Shell 脚本(templates/hooks/*.mjs):负责与实际文件系统、工具环境交互,处理轻量逻辑。
    • TypeScript 桥接层(src/hooks/bridge.ts):集中承载复杂业务逻辑、状态读写、策略决策。
  • 最下层:状态与记忆层
    • .omc/state/:持久化各种模式状态、错误记录、技能执行状态等。
    • .omc/notepad.md.omc/project-memory.json:负责长期项目记忆、任务笔记与上下文补全。

整体的数据流可以概括为:Runtime 事件 → hooks.json 路由 → Shell 脚本 → TypeScript Bridge → 状态读写 & JSON 输出 → 回注 Claude Code 上下文

这样一来,Claude Code 本身只需要专注于对话和工具调用,而所有关于“该不该继续”“应该怎么约束”“如何记住长期目标”的决策,都由 Hooks 系统统一处理。

1.2 事件与 Hook 清单:一张表看懂全局

OMC 为 11 个核心生命周期事件注册了对应的 Hook,清单大致如下(简化整理自 hooks.json):

事件 注册的 Hook 总超时预算
UserPromptSubmit keyword-detector, skill-injector 8s
SessionStart session-start, project-memory-session, wiki-session-start, setup-init*, setup-maintenance* 15s / 75s(初始化)
PreToolUse pre-tool-enforcer 3s
PermissionRequest permission-handler 5s
PostToolUse post-tool-verifier, project-memory-posttool, post-tool-rules-injector 9s
PostToolUseFailure post-tool-use-failure 3s
SubagentStart subagent-tracker start 3s
SubagentStop subagent-tracker stop, verify-deliverables 10s
PreCompact pre-compact, project-memory-precompact, wiki-pre-compact 18s
Stop context-guard-stop, persistent-mode, code-simplifier 20s
SessionEnd session-end 30s

每个事件下 Hook 的执行顺序是声明顺序即优先级顺序,并且每个 Hook 都有明确的超时预算,这保证了整体系统在复杂场景下仍然可预估,避免“一个 Hook 卡死全局”的情况。


二、桥接层:让 Hook 真正“长出大脑”的 TypeScript 模块

2.1 HookInput / HookOutput:统一协议

所有 Hooks 最终都会通过 run.cjs 调用 TypeScript 桥接层的 processHook(),桥接层定义了一套统一协议:

  • HookInput 核心字段:

    • sessionId:当前会话 ID
    • prompt:用户当前输入(或相关文本)
    • toolName / toolInput / toolOutput:工具调用上下文
    • directory:当前工作目录
  • HookOutput 核心字段:

    • continue:是否继续后续流程
    • message:追加到对话中的普通消息
    • systemMessage:追加到系统消息中的约束与指令
    • modifiedInput:对原始输入进行修改后的版本
    • hookSpecificOutput:各 Hook 的扩展输出,如 additionalContext

这种统一接口有几个实际好处:一是可以集中管理序列化、安全检查;二是便于新 Hook 的扩展;三是所有生命周期决策都可以在一个地方观察与调试。

2.2 防止“假继续”的防护:sanitizeHookOutputForSerialization()

桥接层中特别强调了一个函数:sanitizeHookOutputForSerialization()。它会在输出前剥离掉空字符串等无意义字段,尤其是空的 systemMessage

为什么这很重要?

  • 如果在 Task 或 Agent 实际“已经完成”后仍然注入了空的系统消息,有可能让上层 runtime 误以为还有内容需要处理,从而引发虚假的“继续执行”行为。
  • 通过提前清洗,可以保证只有真正有意义的指令才会进入下游,避免莫名其妙的续写或循环。

2.3 HookType:明确每一类 Hook 的责任边界

桥接层为所有可处理的 Hook 定义了统一的 HookType 联合字面量,包括:keyword-detectorpersistent-modepre-tool-usepost-tool-usesession-startsession-endsubagent-startsubagent-stoppre-compact 等共 16 类。

这使得每个 Hook 都有明确的职责边界,避免逻辑耦合在一起难以维护:

  • “谁在管模式持久化”?看 persistent-mode 系列。
  • “谁负责关键字检测和模式激活”?看 keyword-detector
  • “谁控制工具调用前的策略”?看 pre-tool-use

三、会话生命周期:从 SessionStart 到 SessionEnd 的完整旅程

3.1 SessionStart:恢复模式、加载记忆、初始化知识库

当一个新的 Claude Code 会话启动时,SessionStart 事件会依次触发以下 Hook:

  1. session-start.mjs

    • .omc/state/ 恢复持久化模式状态,例如某个自动驾驶或长任务是否仍在进行。
    • 执行版本检查,并为结果设置 24 小时缓存,避免每轮都检查。
    • 加载记事本中的高优先级上下文,并应用 2 小时陈旧阈值,清理过期模式状态。
    • 模式状态文件通常包含:active, started_at, session_id, prompt, iteration, max_iterations, linked_ultrawork 等字段。
  2. project-memory-session.mjs

    • .omc/project-memory.json 加载项目级记忆,将一些长期有效的知识(如架构约定、项目约束)注入上下文。
  3. wiki-session-start.mjs

    • 初始化 wiki 子系统,加载与当前会话相关的知识库条目,为后续问答提供背景知识。

特殊会话类型:

  • init 会话触发 setup-init,以 30 秒超时完成初次设置向导。
  • maintenance 会话触发 setup-maintenance,用 60 秒处理周期性维护任务。

3.2 UserPromptSubmit:魔法关键词与技能系统的前置入口

每一条用户输入在真正进入 Claude Code 之前,会经过两个关键 Hook:

  1. keyword-detector.mjs

    • 先对提示进行“安全清洗”:移除代码块、XML 标签、URL、文件路径等,减少误报可能性。
    • 然后按照预先定义的优先级链匹配关键词,并根据匹配结果写入对应的模式状态文件。
    • 当匹配到特定模式(如 ralphautopilotultrawork 等)时,会通过 additionalContext 注入技能调用指令。
    • 通过 OMC_TEAM_WORKER 环境变量保护子代理工作者,避免在它们内部意外触发无限生成循环。
  2. skill-injector.mjs

    • 读取当前“活动技能”,把其对应的提示模板注入上下文,使之前激活的技能保持持续有效。

关键词优先级链明确定义了冲突策略,例如:
cancel(最高且排他) → ralph → autopilot → ultrawork → ccg → ralplan → deep-interview → ai-slop-cleaner → tdd → code-review → security-review → ultrathink → deepsearch → analyze

这条链决定了当多个关键词同时出现时,哪种模式的意图更强。比如用户同时提到“取消”和“自动驾驶”,最终会以“取消”为准。


四、工具调用生命周期:让 AI 不再“盲开车”

4.1 PreToolUse:写前检查与技能保护

PreToolUse 是整个系统里非常关键的一环,负责“工具调用前”的最后一道关口,由 pre-tool-enforcer.mjs 承担:

1. 委派强制执行(防止乱写源文件)

  • 维护了一组白名单路径,如 .omc/.claude/CLAUDE.mdAGENTS.md
  • 定义了一组源文件扩展名,如 .ts.py.go 等。
  • 当检测到对“非白名单路径的源文件”执行写操作时,会注入警告,引导编排器不要直接改生产代码,而是交给专门的 Agent 或走更谨慎流程。

2. 技能活动状态激活(防止任务半途被掐断)

  • 钩子在技能工具调用时写入 skill-active-state.json,记录当前有技能任务正在进行。

  • 不同技能根据预期执行时长有不同保护等级和 TTL,例如:

    • none:不加保护(如 autopilot、ralph、ultrawork、cancel,本身有专门模式状态)。
    • light:重试保护较轻,TTL 约 5 分钟(tdd、analyze、skill 等)。
    • medium:重试保护中等,TTL 约 15 分钟(code-review、plan、ralplan、ccg 等)。
    • heavy:保护最重,TTL 可达 30 分钟(deepinit 等)。
  • 当技能调用成功后,还会清除模式状态文件中的 awaiting_confirmation 标志,将模式从“待确认”转变为“已激活”。

4.2 PostToolUse:验证结果、更新记忆、注入规则

当工具成功执行后,PostToolUse 会触发三个 Hook:

  1. post-tool-verifier.mjs

    • 对工具输出进行“质量审查”。
    • Read 操作,可能建议并行读取更多文件。
    • Write / Edit 操作,会检查输出完整性,例如是否覆盖了必要范围。
    • 对“表面上成功但输出中有错误模式”的 Bash 命令,注入修正建议。
  2. project-memory-posttool.mjs

    • 解析工具输出中来自子代理工作者的特定标记内容,并将其写入 .omc/notepad.md 中不同优先级区域,形成项目记忆。
  3. post-tool-rules-injector.mjs

    • 根据本次工具操作涉及的文件路径,查找对应的项目规则(例如 .claude/rules/),并把这些规则注入到后续上下文中,让后续操作遵守相应规范。

4.3 PostToolUseFailure:失败跟踪与重试策略升级

当工具调用失败时,PostToolUseFailure 钩子负责记录错误并管理重试策略:

  • 失败信息写入 .omc/state/last-tool-error.json,包括 tool_nametool_input_preview(截断至 200 字符)、error(截断至 500 字符)、timestampretry_count
  • 区分“用户中断”和“真实错误”,对用户中断不做多余提示。
  • 在 60 秒窗口内,如果同一工具连续失败达到一定次数(如 5 次),会从“建议分析并重试”升级为“明确建议停止重试、尝试不同路径”。

五、子代理与 Stop:把长程任务“跑完跑好”

5.1 子代理:从生成到完成的全程跟踪

当 Claude 通过 TaskAgent 工具生成子代理(例如专门写代码的 Agent、专门跑 QA 的 Agent)时,对应的生命周期事件是 SubagentStartSubagentStop

  • SubagentStart

    • subagent-tracker.mjs start 记录 Agent 名称、启动时间、会话信息。
    • 配合 session-replay.ts 跟踪文件访问,为后续“重放”和审计提供数据。
  • SubagentStop

    • subagent-tracker.mjs stop 记录完成指标。
    • verify-deliverables.mjs 检查子代理是否产出预期交付物。
    • 桥接层通过正则 /agentId:\s*([a-zA-Z0-9_-]+)/ 从输出中提取 agentId,并通过标记和 XML 标签跟踪后台任务生命周期。

这意味着,OMC 不只是“能生成子代理”,还可以对它们的“生命周期与交付质量”进行精细化管理。

5.2 Stop 事件:温和但坚定的“继续工作”机制

Stop 事件发生在 Claude 决定结束当前轮次时,OMC 在这里织入了自己非常独特的一层行为:

触发 Hook 包括:

  1. context-guard-stop.mjs

    • 监控上下文窗口使用情况,在接近临界阈值时发出警告,让系统提前做压缩或调整策略。
  2. persistent-mode.mjs

    • 扫描 .omc/state/ 中所有活动模式状态文件(ralphautopilotultraworkultraqateampipelineskill-active 等)。
    • 若发现仍有活动模式且未过期(通常 2 小时内),会注入带有“继续工作”意味的强化消息,避免任务被轻易放弃。
    • 管理 awaiting_confirmation 状态,确保模式只有在被真正确认后才持续生效。
  3. code-simplifier.mjs

    • 可选 Hook,用于在 Stop 时自动分析最近的 git diff,对热点文件进行自动简化与整理,减少技术债。

这里非常重要的一点是:stop-continuation.mjs 的哲学是“软强制”——它总是返回 { continue: true, suppressOutput: true },不会从协议层面禁止 Claude 停止,只是注入建议和强化信息。


六、PreCompact 与 SessionEnd:让上下文压缩与会话结束不留遗憾

6.1 PreCompact:在压缩前保存关键信息

当上下文即将溢出时,Claude Code 会触发 PreCompact 事件,此时 OMC 的目标是“在丢掉历史之前把重要的东西先挪走”。

Hook 包括:

  1. pre-compact.mjs

    • 总结当前工作状态、未完成事项和关键上下文,写成一个紧凑版本,避免在摘要阶段被完全遗忘。
  2. project-memory-precompact.mjs

    • 刷新项目记忆到持久化存储,确保有价值的信息不只存在于对话历史中。
  3. wiki-pre-compact.mjs

    • 特别保护 wiki 相关的上下文条目,避免对知识库关联内容造成损失。

整体思路是:在正常过程中不断写入记事本/项目记忆,在压缩前再做一次“兜底保存”

6.2 SessionEnd:销毁、清理与指标上报

当会话真正结束时,SessionEnd 事件负责做“收尾工作”:

  • 将会话摘要(包括 Agent 活动情况、Token 使用量、持续时长等)写入 .omc/sessions/,形成历史记录。
  • 如果配置了通知渠道,会向 Discord、Telegram 或 Slack 推送带有会话指标的完成回调,便于团队协作与监控。
  • 通过 session-end/callbacks.ts 清理模式状态,防止陈旧模式污染后续不相关会话。

七、状态管理:.omc/state/ 背后的设计哲学

7.1 双层状态模型:会话隔离与全局回退

OMC 的状态管理采用双层结构:

  • 会话级状态:.omc/state/sessions/{sessionId}/
    • 针对具体会话的局部状态,如某一次任务的中间进度。
  • 全局回退状态:.omc/state/
    • 作为默认数据来源,在缺少会话级信息时提供兜底值。

桥接层优先读取会话级状态,只有在不存在时才回退到全局状态,这种设计天然支持多实例并行、不同会话之间的状态隔离。

7.2 原子写入与 awaiting_confirmation

所有状态文件使用“写临时文件再重命名”的原子写入策略,防止并发访问时出现脏写或部分写入。

模式状态的结构一般为:{ active: boolean, started_at: string, session_id?: string, last_checked_at: string },并根据模式类型追加字段。

其中 awaiting_confirmation 标志尤其关键:

  • 当通过关键词检测到某种模式时,先将该模式状态写为 awaiting_confirmation: true
  • 只有在对应技能工具真正被调用(经 PreToolUsePostToolUse 确认)后才清除此标志。
  • 这样可以防止“只是提到一个词”就被当成模式激活,既提升体验,又保证安全性。

八、TypeScript 模块与可扩展性:如何在现有体系上继续搭建

8.1 index.ts:功能域清晰的模块划分

src/hooks/index.ts 重新导出了 30+ 个子模块,把 Hook 体系拆解为多个职责域,例如:

  • 关键字检测:keyword-detector/,负责提示清洗、模式匹配、冲突解决。
  • Ralph 循环:ralph/,负责循环状态管理、PRD 追踪、进度持久化、架构师验证。
  • 规则注入:rules-injector/,按路径发现规则、做内容哈希去重。
  • 自动驾驶:autopilot/,管理从扩展 → 规划 → 执行 → QA → 验证的阶段转换。
  • 子代理追踪:subagent-tracker/,记录 Agent 生成与完成、支持会话回放与流追踪。

这类清晰的职能划分让开发者可以在某个子领域做深度定制,而不用担心动到其他模块。

8.2 钩子禁用与自定义

对于调试或集成场景,OMC 提供了灵活的禁用机制:

  • 环境变量 DISABLE_OMC=1:直接全局关闭所有 OMC Hook。
  • 环境变量 OMC_SKIP_HOOKS="keyword-detector,notepad":以逗号分隔的方式禁用指定 Hook。

此外,还可以通过 examples/hooks.json 学习 Claude Code 原生 Hook 格式:

  • 支持 commandmessageblock 等类型。
  • 采用模式匹配方式对工具进行绑点。
  • 与 OMC 内部清单是平行、独立的一套机制,方便在不修改 OMC 的前提下做本地定制。

九、实践建议:如何在自己的 AI 编排系统中借鉴这套设计

结合 OMC Hooks 生命周期的设计,可以提炼出一套对一般 AI 编排系统同样适用的实践思路:

  1. 事件驱动是核心

    • 明确生命周期事件(会话开始、用户输入、工具前后、压缩前、停止、结束等),并围绕这些事件设计 Hook。
  2. 逻辑与状态分层

    • 用脚本或外部服务处理环境相关逻辑,把业务策略集中在一个“桥接层”里统一管理。
  3. 状态必须可观测且可恢复

    • 所有关键模式、长任务状态都写入持久化存储,不依赖单次对话上下文。
    • 提供清晰的回放路径(如 session replay、notepad、project memory)。
  4. “软强制”优于“硬阻断”

    • Stop 事件那样,通过上下文与系统消息引导模型行为,而不是从协议层面死卡。
    • 保留模型的创造性空间,只在关键点上拉一把。
  5. 安全与体验并重

    • 通过白名单、关键字确认、awaiting_confirmation 等机制避免误操作。
    • 在工具失败、上下文即将溢出等场景下给出友好提示,而不是简单报错。

结语

OMC 的 Hooks 生命周期,把一个“会话 + 工具调用”的基础框架,打磨成了一套覆盖会话全程、具备记忆能力、能进行模式化自治的 AI 协作系统。 它的精妙之处,不在于某一个单独的 Hook,而在于:事件化的视角、统一的桥接协议、严谨的状态管理,以及对“软约束”的偏爱。

如果你正在设计自己的 Agent 框架、AI IDE 插件或多 Agent 编排系统,不妨参考这套思路:先画出生命周期,再设计 Hook,再搭建桥接层和状态层。做到这一步,系统就不再只是“能跑起来”,而是能够“持续、可靠、可控地长时间工作”。

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐