CODEX HOOKS 2026 先选生命周期事件,再写最小、可审计的命令处理器

CODEX LIFECYCLE HOOKS GUIDE

2026 Codex Hooks 配置教程:hooks.json、PreToolUse、PostToolUse 与不生效排查

Hooks 能在 Codex 生命周期的确定节点运行脚本,但“文件写了”不等于“脚本会跑”。本页用最小配置解释事件、matcher、信任审核、输入输出、工具覆盖与排错顺序。

发布于 2026 年 7 月 21 日 · 阅读约 15 分钟

先看结论:先用 /hooks 看“是否加载与信任”,再查脚本

Codex Hooks 不执行时,第一步不是反复改 Python 或 Shell,而是在 CLI 中打开 /hooks,确认来源、启用状态、当前定义的信任哈希和是否被禁用。

Codex 会从活动配置层旁边加载 hooks.jsonconfig.toml 中的内联 [hooks]。项目级 Hook 还受到 project trust 约束;新建或修改后的非托管命令 Hook 需要重新审核,未信任时会被跳过。

Hook 是可执行代码,不只是配置

它以会话工作目录为当前目录运行,并能读取通过 stdin 传入的调用信息。不要信任来源不明的 Hook,不要在脚本或输出中写入 API Key、Cookie、Session、源码全文或审批凭证。

Hooks、AGENTS.md、Rules、Sandbox 和 notify 分别管什么

机制适合解决不应承担
Hooks在会话、工具调用、压缩、子代理和停止等节点运行确定性脚本不是完整安全边界,也不保证覆盖全部工具路径
AGENTS.md项目约定、构建测试、目录规范与完成标准不能确定性拦截每次工具调用
Rules按命令参数前缀分类 Sandbox 外的 allow、prompt、forbidden不执行生命周期脚本
Sandbox文件、进程和网络的技术资源边界不表达业务检查逻辑
notify调用外部通知程序不是完整的生命周期 Hook 系统

例如“所有任务结束前检查测试结果”可由 Stop Hook 提供确定性验证;“团队提交前应跑什么测试”写入 AGENTS.md;“某个越界部署命令必须询问”应配置 Rules

hooks.json 放在哪里:用户层、项目层、插件层和托管层

作用域常用位置加载条件
用户级~/.codex/hooks.json~/.codex/config.toml独立于当前项目 trust
项目级<repo>/.codex/hooks.json<repo>/.codex/config.toml项目必须 trusted
插件默认 hooks/hooks.json,也可由 plugin.json 指定插件启用,且 Hook 定义经过审核信任
管理员requirements.toml 内联配置与托管脚本目录由组织策略管理,用户不能禁用托管 Hook

多个来源不会按优先级互相覆盖:所有匹配 Hook 都会加载。多个匹配命令处理器会并发启动,因此不能假设“第一个 Hook 拒绝后,第二个就不会运行”。如果同一配置层同时存在 hooks.json 和内联 [hooks],Codex 会合并两者并在启动时发出警告;建议每层只保留一种写法。

从最小 hooks.json 开始:只观察 Bash 调用

下面配置在本地 Shell 或统一执行工具调用前运行一个命令处理器。先使用无副作用脚本验证加载、匹配和 stdin,再增加检查逻辑:

{
  "description": "Project lifecycle checks",
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^Bash$",
        "hooks": [
          {
            "type": "command",
            "command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py\"",
            "timeout": 30,
            "statusMessage": "Checking Bash command"
          }
        ]
      }
    ]
  }
}

timeout 单位是秒,省略时当前默认值为 600;statusMessage 可选。命令从会话 cwd 启动,因此项目脚本最好从 Git 根目录解析,避免用户在仓库子目录启动 Codex 后相对路径失效。

当前只有 type: "command" 处理器实际运行;promptagent 虽可被解析但会跳过。async 选项也会被解析,但异步命令 Hook 目前不受支持。

PreToolUse、PostToolUse、Stop 应该怎么选

事件运行时机典型用途matcher
SessionStart线程启动、恢复、清理或压缩后加载目录级上下文或会话提示启动来源
SubagentStart子代理启动为特定子代理加入上下文子代理类型
PreToolUse支持的本地工具调用前检查、阻止或改写工具调用工具名
PermissionRequest工具请求权限时对审批请求增加确定性检查工具名
PostToolUse支持的本地工具结束后审核结果、返回反馈、验证副作用工具名
PreCompact / PostCompact上下文压缩前后保存或恢复必要状态manual / auto
UserPromptSubmit用户提示提交时提示输入检查或追加上下文不支持,配置会被忽略
SubagentStop子代理停止检查子任务交付或追加反馈子代理类型
Stop当前回合准备停止执行最终验证或给出继续提示不支持,配置会被忽略

多个事件处于不同作用域:工具、权限、压缩、用户提示和 Stop 等多数事件按 turn 运行;SessionStartSubagentStart 在线程或子代理启动层运行。不要因为脚本名叫 pre_hook.py 就认为它会在所有动作前执行,真正时机由事件键决定。

matcher 是正则,但匹配的是事件定义的值

matcher 是正则字符串;"*"、空字符串或省略可匹配支持该字段的全部事件。最常见错误不是正则语法,而是匹配对象写错:

  • Shell 与 exec_command 使用工具名 Bash
  • apply_patch 可匹配 apply_patch,也兼容 EditWrite
  • MCP 工具使用完整名称,例如 mcp__filesystem__read_file
  • 其他本地函数工具使用实际工具名;spawn_agent 也可匹配 Agent
  • 托管的 WebSearch 等 Hosted tools 当前不走本地函数工具 Hook 路径。
"matcher": "^Bash$"
"matcher": "^apply_patch$"
"matcher": "mcp__filesystem__.*"
"matcher": "startup|resume|clear|compact"

Hooks 只是有用的 guardrail,不是完整强制边界。部分特殊工具路径可能选择不走默认 Hook 通道;涉及文件、网络和越界命令时仍要依赖 Sandbox、审批、Rules、系统权限和服务端权限。

等价的 config.toml 内联 Hooks 写法

不想维护单独 JSON 时,可以在同一活动配置层的 config.toml 中内联:

[[hooks.PreToolUse]]
matcher = "^Bash$"

[[hooks.PreToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py"'
timeout = 30
statusMessage = "Checking Bash command"

[[hooks.PostToolUse]]
matcher = "^Bash$"

[[hooks.PostToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use_review.py"'
timeout = 30

Hooks 默认启用。若需要关闭,在 config.toml 中使用:

[features]
hooks = false

hooks 是当前规范 feature key;旧的 codex_hooks 仍作为弃用别名接受。不要在排障时同时设置两个相反的值。

命令处理器收到什么:stdin JSON、cwd、超时和输出限制

每个命令 Hook 都会从 stdin 收到一个 JSON 对象。常用共享字段包括:

字段含义注意
session_id当前 Codex 会话 ID子代理 Hook 使用父会话 ID
turn_id当前回合 ID出现在 turn scope 事件中
cwd会话工作目录不要假设一定是仓库根目录
hook_event_name当前事件名用于一个脚本处理多个事件
model当前模型 slugCodex 扩展字段
transcript_path会话记录路径或 null格式不是稳定 Hook 接口
permission_mode当前权限模式部分生命周期事件提供

不同事件还有自己的输入和输出字段。退出码 0 且无输出表示成功继续;SessionStart、压缩、用户提示、子代理和 Stop 等事件可返回共享控制字段,PreToolUsePermissionRequestPostToolUse 支持范围不同。不要把某一事件的 JSON 输出原样复制到另一事件。

每条模型可见 Hook 输出当前约限制为 2,500 tokens;超长内容可能被保存到本地文件并只提供首尾预览。由于输出可能落盘,脚本必须主动移除密钥、会话材料、个人数据和不必要的源码。

Codex Hooks 不执行、不生效或被跳过的排查顺序

  1. 用 /hooks 确认来源和状态

    检查 Hook 是否被发现、是否启用、来自用户、项目、插件还是托管配置层。

  2. 审核并信任当前定义

    非托管命令 Hook 按当前定义哈希记录信任;脚本、命令或配置改变后会重新进入待审核并被跳过。

  3. 检查项目 trust 和实际 host

    untrusted 项目会跳过项目级 .codex/。macOS、WSL、SSH、容器或 IDE host 可能读取不同的 HOME 与 CODEX_HOME。

  4. JSON 与 TOML 只保留一套

    同层两套会合并并警告,重复事件可能让你误判脚本执行次数和来源。

  5. 核对事件名、大小写和 matcher

    Bash 不是 bash;Stop 和 UserPromptSubmit 不支持 matcher;Hosted tools 可能不经过本地工具 Hook。

  6. 核对命令路径和工作目录

    显式写解释器和稳定路径;项目脚本从 Git 根目录解析;Windows 使用 commandWindowscommand_windows 覆盖。

  7. 确认处理器类型受支持

    当前只运行 command;async、prompt 和 agent 处理器会被跳过。

  8. 先用无副作用输入调试

    不要用部署、删除、付款或凭证访问证明 Hook 有效;先验证 stdin JSON、退出码、超时和最小输出。

  9. 检查多来源并发

    所有匹配 Hook 都会运行,多个命令处理器并发启动;不要依赖执行顺序或把一个 Hook 当成其他 Hook 的前置开关。

不建议用跳过信任参数作为日常修复

--dangerously-bypass-hook-trust 只适合已经在 Codex 外部完成 Hook 来源审计的一次性自动化。交互使用应通过 /hooks 审核定义,而不是永久取消信任门槛。按时间周期触发的需求应使用 Codex Scheduled tasks,不要硬塞进生命周期 Hook。

团队、requirements.toml 与插件 Hooks 的治理

企业管理员可以在 requirements.toml 中定义托管 Hooks,并通过 [features].hooks = true 强制启用;allow_managed_hooks_only = true 可忽略用户、项目、会话和插件 Hook,只保留管理员来源。托管脚本应由 MDM 或企业工具安装到明确目录,Codex 不负责分发脚本本身。

插件默认从 hooks/hooks.json 加载,也能由 .codex-plugin/plugin.json 指定相对插件根目录的 Hook 路径。安装或启用插件不会自动信任其中的命令 Hook;用户仍需审核当前定义。

团队评审至少应记录:负责人、作用域、事件与 matcher、脚本来源、输入数据、输出落盘、失败行为、超时、Windows/macOS/Linux 差异、回滚与紧急禁用方式。涉及强制策略时还要区分“项目建议”和“管理员不可绕过要求”。

Codex Hooks 配置与不生效常见问题

Codex Hooks 是什么?

它是在 Codex 生命周期事件周围运行确定性处理器的扩展框架,可用于检查工具调用、追加上下文、审核结果或停止前验证。

Codex Hooks 配置文件放在哪里?

用户层通常使用 ~/.codex/hooks.json~/.codex/config.toml;项目层使用仓库中的 .codex/hooks.json.codex/config.toml,并要求项目 trusted。

为什么 hooks.json 写了却不执行?

先用 /hooks 检查是否发现和信任,再排查项目 trust、事件名、matcher、路径、解释器、处理器类型、超时和输出格式。

修改脚本后为什么又被跳过?

非托管命令 Hook 的信任与当前定义哈希绑定;定义改变后会重新标记为待审核,需要在 /hooks 中重新确认。

PreToolUse 和 PostToolUse 有什么区别?

PreToolUse 在支持的本地工具调用前运行,可检查或改写调用;PostToolUse 在工具结束后运行,适合审核结果和返回反馈。

Stop Hook 的 matcher 为什么不起作用?

当前 Stop 与 UserPromptSubmit 不支持 matcher,配置的 matcher 会被忽略。应让脚本根据 stdin 中的事件数据自行判断。

Shell 命令 matcher 应该写 bash 还是 Bash?

当前本地 Shell 和统一执行工具匹配为 Bash,大小写和正则必须正确。

Hooks 能拦截 WebSearch 吗?

当前 Hosted tools(例如 WebSearch)不走本地函数工具 Hook 路径。不要把 Hooks 当成覆盖全部工具的安全边界。

hooks.json 和 config.toml 可以同时使用吗?

可以,但同一配置层会合并并发出启动警告。为减少重复和排错复杂度,通常每层只选择一种。

Hook 脚本从哪个目录运行?

从当前 Codex 会话的 cwd 运行。项目脚本建议通过 git rev-parse --show-toplevel 或绝对路径定位。

async Hook 可以后台运行吗?

当前 async 选项会被解析,但异步命令 Hook 不受支持,处理器会被跳过。

可以用 Hooks 代替 Rules 或 Sandbox 吗?

不能。Hooks 是生命周期扩展和辅助护栏;Sandbox、审批、Rules、系统权限和服务端权限仍是独立边界。

Hooks 与套餐额度有关吗?

通常无关。Plus、Pro 或 Credits 不会自动启用、信任或修复本地 Hook;应先排查客户端配置与脚本运行环境。

来源与利益关系说明

本文由 Hi Codex 服务团队根据 OpenAI 当前 HooksAdvanced configuration 文档整理。Hook 事件、工具覆盖、输出字段和受支持处理器会随 Codex 版本变化,应以当前官方资料及本机 /hooks 显示为准。

团队提供独立人工充值协助,与 ChatGPT / Codex 套餐主题存在商业利益关系;与 OpenAI 不存在隶属、代理或官方授权关系。本文不要求共享账号、API Key、Cookie、Session、私有代码或 Hook 审批凭证,也不提供绕过 Sandbox、管理员要求与系统安全策略的方法。

想判断两套 Hook、权限与配置资产的迁移成本?查看 2026 Codex vs Claude Code 工作流对比

Hooks 不执行通常先修配置和信任,不是先升级套餐Plus ¥140 · Pro 5x ¥745 · Pro 20x ¥1320

先用 /hooks 确认来源和信任,最小化事件与 matcher;只有确认真实用量长期不足后再比较套餐。

查看套餐与价格