Codex 生命周期钩子怎么配:事件、匹配器组与 Windows 专属覆盖
Codex(OpenAI Codex)的生命周期钩子(hooks)是那种”配对了没人夸、配错了排查半天”的功能。它不像模型选择那样有直观反馈,你写完一段配置,重启,然后盯着终端猜它到底跑没跑。更麻烦的是,这套结构在配置参考里是分散在好几个地方的:一个特性开关在 features 下面,实际配置在 hooks 表或者 hooks.json 里,还有一个只对 Windows 生效的命令覆盖键。
这篇不打算把官方那页翻译一遍,而是把这套结构的分层讲清楚,并在每个岔路口给出判断依据:文件和内联这两条路的边界在哪、哪些细节必须回官方文档确认而不能猜、Windows 上为什么不能照抄同事 macOS 的那份配置、以及配完之后拿什么命令验证。
先看清这套结构分几层
官方《Configuration Reference》里,钩子相关的键位是这样的:
| 键 | 说明 |
|---|---|
features.hooks | 启用 hooks.json 或内联配置的生命周期钩子 |
hooks | 可内联配置钩子的表 |
hooks.<Event> | 匹配器组数组,事件名例子:PreToolUse、PostToolUse、SessionStart |
hooks.<Event>[].hooks[] | 处理器 |
additionalContextLimit | 默认 2500,超出则保存超大上下文的 token 阈值 |
commandWindows | 仅 Windows 的命令覆盖 |
读这张表最容易漏掉的是它有两层数组。hooks.<Event> 本身是一个数组,数组里的每一项是一个”匹配器组”;每个匹配器组下面还有一个 hooks[] 数组,里面才是真正干活的处理器。
这个设计意味着什么?意味着”哪些情况触发”和”触发之后做几件事”是分开表达的。你可以在一个事件下面挂多个匹配器组,各自匹配不同的情况;也可以在一个匹配器组下面挂多个处理器,让同一种情况连续跑好几件事。如果你把它理解成”一个事件对应一个脚本”,那么写出来的配置很快就会变成一堆重复的条件判断塞在脚本内部——那正是这两层结构想帮你避免的。
顺带说一句:官方在这里给出的事件名是三个例子(PreToolUse、PostToolUse、SessionStart),不是完整清单。所以别照着这三个名字去反推”那一定还有 SessionEnd、PreCompact”之类的兄弟事件。想知道某个具体事件叫什么,去官方《Hooks》页查,猜出来的事件名写进配置多半只是静静地不生效。
开关:先确认它本来就是开的
features.hooks 是这套功能的总闸。但在动手写配置之前,先确认一下你这台机器上它现在是什么状态,比直接去 config.toml 里加一行更靠谱。
codex features list
codex features list 会列出已知特性、所处阶段与当前生效状态三列。在 codex-cli 0.147.0(Windows 11)本机上,hooks 一行的阶段是 stable、当前生效值是 true。
但这里要拦一句:官方《Configuration Reference》里 features.hooks 这一行没有给出默认值,只写了它的作用是”启用 hooks.json 或内联配置的生命周期钩子”。所以本机看到的 true 只能说明”这台机器上它此刻是开着的”——它可能来自本机 config.toml 的显式设置,不能反推成官方默认值。你自己那台机器上是不是开着,必须以 codex features list 的实际输出为准,别拿别人文章里的截图当结论。
这里有个读法上的提醒。codex features list 输出的第三列是”当前生效值”,它是把配置加载完之后的结果算出来的;而 config.toml 里写了什么只是输入。两者不一致时以 list 为准,因为配置可能压根没加载成功(下面会讲怎么判断)。另外在同一版本上,features list 里还能看到 stable、under development、experimental、deprecated、removed 五种阶段,其中 removed 阶段的项仍然会列出来,而且有些 removed 项生效值还是 true——这说明 removed 指的是”这个开关本身不再需要控制、行为已固化”,不是”功能没了”。第一次读这张表的人几乎都会在这里误判。
真要显式开关,先说带参数的这种写法。注意 codex 不带子命令时,选项是透传给交互式 CLI 的——所以下面这两行不是持久开关,而是带着这个特性开关起一次会话,本次调用生效、不写盘:
codex --enable hooks
codex --disable hooks
--enable <FEATURE> / --disable <FEATURE> 可重复,等价于 -c features.<name>=true / =false。想写进配置文件而不是每次带参数,用 codex features enable / codex features disable,这两个子命令会写进 config.toml。
文件还是内联:一个开关同时管着两条路
features.hooks 的官方说明是”启用 hooks.json 或内联配置的生命周期钩子”。这一句里能确定的信息有三条,值得逐条拆开:
- 存在
hooks.json这条独立文件的路子; config.toml里有一张hooks表,可以把钩子内联写进去;- 两条路共用
features.hooks这一个开关——也就是说关掉它,两条路一起停;排查”钩子没反应”时不必先纠结自己走的是哪一条,开关这一层是共同前提。
至于两条路到底差在哪——hooks.json 放在哪一层(用户级还是项目级)、能不能随代码仓库分发给同事——官方《Hooks》页才有明确说明,本文不推断。这一点我要单独提醒一句:不少配置片段会默认你把 hooks.json 扔进仓库根目录就能生效,但”文件放哪儿会被读到”是个事实性问题,猜错的后果不是报错,是它安安静静地不被加载,而你还在改钩子内容。动手前先去官方《Hooks》页把文件位置这件事确认掉,比事后排查省时间得多。
如果你只想在自己这台机器上先试起来,那走内联这条路的键位是明确的:config.toml 里的 hooks 表,事件、匹配器组、处理器三层直接往里写,不用多管一个文件。
有个第三条路要提醒:不要试图用 -c 在命令行里临时塞一整段钩子配置。-c, --config <key=value> 支持点号路径表示嵌套,value 按 TOML 解析,解析失败则按字面字符串处理——注意是”按字面字符串处理”而不是报错。钩子配置是嵌套数组套表的结构,用 -c 拼一行很容易拼错,而拼错的后果不是红字报警,是它被当成一个普通字符串静静地吃掉了。临时覆盖单个标量值(比如 -c features.hooks=false)没问题,塞结构体则不合适。
按官方键位组合出来的骨架大致长这样:
[features]
hooks = true
# 第一层数组:事件下面的「匹配器组」
[[hooks.PreToolUse]]
# 第二层数组:这一组匹配上之后要跑的「处理器」
[[hooks.PreToolUse.hooks]]
匹配器组和处理器内部具体有哪些字段名,官方《Hooks》页才是权威来源,本文不替你编。以上为按官方文档键位组合的示例,未逐项实测,以官方文档为准。
additionalContextLimit 默认 2500 意味着什么
这个键的官方说明是:默认 2500,超出则保存超大上下文的 token 阈值。
翻译成人话就是——钩子往对话里回注上下文这件事是有预算的,超过阈值的部分不会原样进对话,而是走”保存”这条路。这条约束应该直接影响你写钩子的方式:钩子的输出要给结论,不要给原始日志。一个把整份构建输出往回吐的钩子,跟一个只回一行”3 处 lint 未通过,见 xxx”的钩子,前者大概率触发这条”超出即保存”的路径,不会原样出现在对话里;后者才真的把信息送到了模型面前。
如果你的场景确实需要更大的回注量,additionalContextLimit 是可调的;但先问一句这是不是在拿上下文预算换本来该由人看的东西。
Windows 专属:commandWindows 为什么必须存在
commandWindows 的官方说明只有一句:仅 Windows 的命令覆盖。键位说明短,但它解决的问题在中文开发者这边非常常见——同一份钩子配置,在 macOS/Linux 同事那儿跑得好好的,到你 Windows 机器上就废了,因为钩子里那条命令的写法根本不通用。
正确做法不是在钩子脚本里自己写平台判断,而是用 commandWindows 给 Windows 单独指定一条命令。这样跨平台仓库里那份配置只有一份,平台差异由配置层吸收,脚本本身保持干净。
值得多说一句的是,Codex 在 Windows 上”默认值跟别的平台不一样”并不是孤例,这也是我建议你别照抄别人配置的原因:
features.unified_exec官方标注默认true,但明确写了 Windows 除外。在 codex-cli 0.147.0(Windows 11)上,codex features list里unified_exec的生效值实测就是false,和文档口径一致。执行工具这一层在 Windows 上走的路子本来就和别处不同。- 沙箱实现也是分叉的:官方文档说明,macOS 用系统内置的 Seatbelt,Linux/WSL2 需要装
bubblewrap,Windows 则是在 PowerShell 中使用原生 Windows 沙箱。你的钩子命令是在这套边界里跑的,所以”在 Linux 上这条命令能写文件”不构成”在 Windows 上也能”的证据。
综合这两点:跨平台仓库里的钩子,Windows 那一路一定要单独验证一次,不能靠推理。
一条容易被误用的开关:--dangerously-bypass-hook-trust
Codex CLI 顶层有个选项 --dangerously-bypass-hook-trust,官方原文写的是 “DANGEROUS. Intended only for automation that already vets hook sources”(危险。仅用于已经对钩子来源做过审核的自动化场景)。
这个选项的存在本身就透露了一条信息:钩子的来源是被信任机制管着的。钩子是会被自动触发去执行命令的东西,一份从别处拉来的仓库如果自带钩子配置,那就等于自带了在你机器上跑命令的入口。所以这里的判断依据很简单:
- 日常在本机开发 → 不要加这个参数,让信任提示该出现就出现。
- 只有在你完全掌控钩子来源、并且已经对来源做过审核的自动化流水线里 → 才轮得到考虑它。
官方给的定位就到这一步,具体的信任提示长什么样、怎么逐条批准,以官方《Hooks》页为准,本文不推断。
配完之后怎么确认它真的生效
改完配置直接开会话看”感觉”,是最费时间的验证方式。按下面的顺序走,能把问题范围快速切小。
第一步,确认配置文件本身被加载了。
codex doctor --summary
在 codex-cli 0.147.0(Windows 11)上做过一次故意构造的实验:给一段语法不合法的 TOML(codex -c 'features=[unclosed' doctor --summary),命令没有崩溃退出,doctor 照常跑完,但输出里出现了这么一行:
✗ config config could not be loaded - Fix the reported config error, then rerun codex doctor.
这条一手结论的价值在于:配置坏了,Codex 不一定当场报错给你看,它可能就是”什么都没发生”。所以”钩子配了没反应”的第一步永远是跑 doctor 看 config 这一行,而不是去改钩子内容。
第二步,确认开关的生效值。 回到 codex features list,看 hooks 那一行的第三列。如果第一步 config 没加载成功,这一列反映的就是”没有你那份配置时”的结果,而不是你写进去的值——两步连起来看才有意义。
第三步,别指望 --strict-config 帮你抓拼写错误。 --strict-config 的说明是”config.toml 里出现本版本不认识的字段时直接报错退出”,听起来像个拼写检查器。但在 codex-cli 0.147.0(Windows 11)上实测:codex -c model_reasoning_effortt=high --strict-config exec --help 正常打印了 help,没有报未知字段错误。也就是说,这个校验发生在真正加载配置去跑会话的时候,--help 这类不进入会话的路径不触发它。想让它替你把关,必须用真正会进入会话的命令去验,拿 --help 试等于没试。
第四步,日志。 日志目录默认是 $CODEX_HOME/log(也就是 ~/.codex/log/),可用 log_dir 改。
什么时候别用钩子
最后给个边界。钩子适合做确定性的、每次都一样的动作:会话开始时准备点什么、工具调用前后做一次固定检查。它不适合两类活儿:
一是需要根据情况做判断的活儿——那本来就该交给模型或者人,塞进钩子只会让行为变得难以预测,出问题时你还得先分清是模型干的还是钩子干的。
二是产出体量大的活儿——additionalContextLimit 默认 2500 这个阈值摆在那儿,把大段输出往回注的设计从一开始就不成立。
还要记住一点:钩子相关的默认值、阶段标注都可能随版本变化。上面所有标了”实测”的结论都来自 codex-cli 0.147.0(Windows 11),换一台机器、换一个版本,先跑一遍 codex --version 和 codex features list 再说,别拿记忆里的版本号排查问题。
相关阅读
- Codex 多代理配置怎么定:并发上限、子代理默认模型与角色定义
- Codex Memories 的 11 个配置键:它为什么有时候不生成记忆
- Codex CLI 的 TUI 定制:状态栏、主题、快捷键与解绑到底怎么配
- Codex 的六个使用面:一张图看懂该用哪个
本文依据 Codex 官方文档(learn.chatgpt.com/docs/ 的《Hooks》《Configuration Reference》《Windows sandbox》页面)整理,核对日 2026-08-09;文中标注「本机实测」的部分基于 codex-cli 0.147.0 / Windows 11 环境下的只读命令输出。产品功能、模型与价格以官方最新说明为准。