很多人用 Codex 时,重点都放在“让它帮我写代码、改文件、跑命令”。这当然是 Codex 最直观的能力,但如果只停留在这里,很容易忽略一个更适合进阶使用的功能:Hook。
Hook 的价值不在于让 Codex 更会写代码,而在于让 Codex 更按规矩工作。它可以在 Codex 的关键生命周期事件里运行自定义脚本,例如用户提交提示词时、工具调用前、工具调用后、请求权限时、会话停止时等。这样一来,你可以把团队规则、安全检查、隐私保护和自动化记录放进 Codex 的工作流里,而不是每次都靠人工提醒。
一个典型例子是隐私检查:当用户把 prompt 发给 Codex 前,先用 Hook 扫一遍是否包含 API key、token、私钥、手机号、内部地址或其他敏感信息。如果命中规则,就阻止这次提交,或者给出明确提示,让用户先清理内容。
Hook 是什么
Codex Hook 可以理解为 Codex 工作流里的生命周期处理器。它会在指定事件发生时触发,并把当前上下文以 JSON 形式传给你的脚本。脚本可以返回提示信息、附加上下文,也可以在部分事件里阻止后续动作。
官方文档里提到,Hook 可以用于这些场景:
- 把对话发送到自定义日志或分析系统;
- 扫描团队 prompt,阻止误贴 API key;
- 自动总结对话,生成持久记忆;
- 在一轮对话结束时运行自定义校验;
- 根据当前目录补充特定提示或规则。
所以 Hook 更像一层“工作流控制”和“安全护栏”,而不是普通的提示词技巧。提示词告诉 Codex 应该怎么做,Hook 则能在 Codex 做事前后插入检查、记录和约束。
Hook 放在哪里
Codex 可以从 hooks.json 加载 Hook,也可以从 config.toml 里的 [hooks] 表加载内联配置。常用位置有四个:
~/.codex/hooks.json~/.codex/config.toml<repo>/.codex/hooks.json<repo>/.codex/config.toml
用户级 Hook 适合放个人通用规则,例如“不要把疑似密钥发送出去”“每次结束时做摘要”。项目级 Hook 适合放仓库规范,例如“禁止直接改生成目录”“提交前检查 front matter”“运行命令前拦截危险操作”。
需要注意的是,项目级 .codex/ 配置只有在该项目层被信任后才会加载;用户级 Hook 则不依赖项目是否被信任。这个设计很重要,因为项目里的 Hook 本质上是会执行本地脚本的配置,不能对陌生仓库无条件信任。
常见触发时机
Hook 不是只有一个触发点。不同事件适合不同用途。
UserPromptSubmit 发生在用户 prompt 即将提交时。它适合做隐私检查、敏感词检查、提示词规范检查。比如发现 prompt 里疑似包含 sk- 开头的 key,就直接阻止提交。
PreToolUse 发生在 Codex 调用工具前。它适合拦截命令、文件写入或 MCP 工具调用。例如检测到 rm -rf、向系统目录写文件、读取敏感路径,就返回拒绝理由。
PermissionRequest 发生在 Codex 准备请求权限时。它适合自动批准或拒绝某些明确的权限请求。比如团队可以允许固定的测试命令自动通过,但拒绝访问某些目录。
PostToolUse 发生在工具执行后。它适合检查命令输出、扫描生成文件、提醒后续步骤。它不能撤销已经发生的副作用,但可以让 Codex 在继续前看到额外反馈。
SessionStart 发生在会话开始或恢复时。它适合加载项目约定、团队规范、常用上下文或本地提示。
Stop 发生在一轮响应准备停止时。它适合做收尾检查,例如确认是否运行测试、是否还存在 TODO、是否需要继续补一轮验证。
一个隐私检查 Hook 应该怎么设计
隐私检查最适合放在 UserPromptSubmit,因为它发生在用户内容真正进入 Codex 工作流之前。设计时不要追求一步到位,先覆盖最容易误贴的内容就够了。
可以优先检查这些模式:
- OpenAI、GitHub、云厂商等 API key;
-----BEGIN PRIVATE KEY-----这类私钥块;.env文件片段;- 访问令牌、Bearer token、JWT;
- 内网域名、数据库连接串;
- 身份证、手机号、邮箱等个人信息。
Hook 脚本接收 JSON 输入后,读取其中的 prompt 字段,使用正则或规则表扫描。如果发现问题,可以返回阻止结果:
|
|
也可以不阻止,只返回额外上下文,让 Codex 在后续回答中注意某些约束。不过对于密钥、私钥和令牌这类高风险内容,更稳妥的做法是直接阻止。
hooks.json 配置示例
如果使用仓库级配置,可以创建 .codex/hooks.json:
|
|
对应的脚本可以从标准输入读取 JSON:
|
|
这个示例只演示思路,实际使用时应该把规则拆成可维护的列表,并控制误报。比如普通文档里出现 Bearer 示例不一定就是泄露,项目里也可能有专门用于测试的假 key。规则越严格,越容易误拦;规则越宽松,越容易漏掉真正的风险。
config.toml 内联写法
如果不想单独维护 hooks.json,也可以写在 config.toml 里。官方文档示例中,内联 TOML Hook 和 hooks.json 使用同样的事件结构:
|
|
如果同一层配置里同时存在 hooks.json 和内联 [hooks],Codex 会同时加载并给出警告。实际项目里最好二选一,避免规则分散后难以排查。
使用 Hook 时要注意什么
第一,Hook 会执行本地命令,所以一定要审查来源。非托管 Hook 需要被 review 和 trust 后才会运行;Hook 内容变化后,也需要重新信任。陌生仓库里的 .codex/hooks.json 不应该随便放行。
第二,多个匹配的 Hook 可能都会运行。不要假设只有一个 Hook 能拦住所有事情,也不要把规则写得互相冲突。团队环境里要明确哪些是用户级规则,哪些是项目级规则,哪些是管理员托管规则。
第三,Hook 是护栏,不是完整安全边界。比如 PreToolUse 可以拦截很多工具调用,但官方也明确提示,它还不能覆盖所有 shell 调用路径,也不能拦截所有非 shell、非 MCP 工具。真正高风险的场景仍然需要权限配置、沙箱、代码审查和最小权限配合。
第四,Hook 脚本要快。隐私扫描、命令审查这类 Hook 发生在交互链路中,如果脚本每次跑几十秒,会直接拖慢体验。能用规则完成的事情,不要每次都调用大型外部服务。
第五,输出格式要严格。不同事件支持的返回字段不完全一样。比如 UserPromptSubmit 可以用 decision: "block" 阻止 prompt,PreToolUse 则有自己的 hookSpecificOutput 结构。写 Hook 前先看对应事件的输入输出约定,不要混用字段。
哪些场景最值得先做 Hook
如果刚开始用 Hook,不建议一下子做成复杂的企业级策略系统。可以先从三个小场景开始。
第一个是隐私检查。它最容易带来真实收益,也最适合个人和团队通用。误贴密钥、token、.env 片段,是 AI 编程工作流里很现实的问题。
第二个是危险命令拦截。可以针对 Bash 的 PreToolUse 做基础规则,例如阻止递归删除、阻止改写系统目录、阻止向未知远端上传文件。
第三个是收尾检查。用 Stop 或 PostToolUse 提醒 Codex 在结束前确认测试、构建、格式化、文档和未提交改动。这类 Hook 不一定要强制阻断,但能显著减少“差一步就收工”的情况。
结论
Codex Hook 的进阶之处,不是让 Codex 多一个花哨功能,而是把“规则”接进了 Codex 的执行循环。
普通用法里,你靠 prompt 告诉 Codex 应该怎么做;进阶用法里,你用 Hook 在关键节点检查它是否按规矩做。隐私检查、命令审查、权限策略、会话摘要、结束前校验,这些都可以从口头提醒变成可执行的工作流。
如果你已经开始把 Codex 用在真实项目里,Hook 值得尽早配置。它不替代人工判断,也不替代沙箱和权限控制,但它能把很多容易遗忘的安全和流程要求,变成每次都会自动触发的默认动作。
参考来源:OpenAI Codex Advanced Configuration - Hooks、OpenAI Codex Hooks