Codex `config.toml` 全景:它在哪、有几层、该先改哪几个键
第一次打开 Codex(OpenAI Codex)的官方《Configuration Reference》页,多数人的反应是往下滚了三屏还没到底,然后关掉页面继续用默认值。这个反应其实不算错——大部分键你一辈子都用不上。但有那么十来个键,不动的话你会一直被小事绊住:沙箱把写入吞了、MCP server 启动超时、联网搜索”看起来开了其实是缓存”、改完配置压根没加载。
这篇不重复抄配置表,只回答三个问题:文件在哪、有几层谁压谁、该先改哪几个键。
一、文件在哪:$CODEX_HOME 而不是某个固定路径
官方口径是:配置文件为 $CODEX_HOME/config.toml,默认位置 ~/.codex/config.toml。
注意这个表述的顺序——权威的是环境变量 CODEX_HOME,~/.codex 只是它没被设置时的默认值。所以当你在一台机器上翻遍 ~/.codex 找不到自己写的配置,先确认这台机器上 CODEX_HOME 有没有被指到别处,而不是怀疑文件丢了。
~/.codex/ 目录里不止 config.toml 一个东西。本机实测(codex-cli 0.147.0,Windows 11)这个目录下同时存在 auth.json(登录凭据,官方明确要求当密码看待)、AGENTS.md(全局层自定义指令)、log/、sessions/、archived_sessions/、history.jsonl、memories/、goals_1.sqlite 等条目。这里有个容易被忽略的运维事实:本机 logs_2.sqlite 单个文件就有 763 MB,codex doctor 的 Notes 区还提示 rollouts 占了 3.07 GB。也就是说 CODEX_HOME 不是一个”几 KB 配置目录”,它会长胖,别随手把它放在空间紧张的分区上。
二、有几层:叠加关系决定了”你改的那份到底算不算数”
Codex 的配置不是单文件,而是一叠。下面这些层级关系全部来自官方选项说明与配置参考,按”离命令行有多近”排:
| 手段 | 官方说明 | 什么时候用 |
|---|---|---|
-c, --config <key=value> | 覆盖 ~/.codex/config.toml 里的值,点号路径表示嵌套 | 一次性试验 |
--enable <FEATURE> / --disable <FEATURE> | 可重复,等价于 -c features.<name>=true / =false | 临时开关某特性 |
-p, --profile <CONFIG_PROFILE_V2> | 把 $CODEX_HOME/<name>.config.toml 叠加到基础用户配置之上 | 长期存在的多套用法 |
agents.<name>.config_file | 该角色的 TOML 配置层路径 | 给某个 subagent 单独一套 |
guardian_policy_config | 受管 Markdown 评审策略,覆盖本地策略 | 企业受管场景 |
codex exec --ignore-user-config | 不加载 $CODEX_HOME/config.toml | CI / 干净环境复现 |
读这张表要抓住三处判断依据。
第一,-p 是”叠加”不是”替换”。 profile 文件叠在基础用户配置之上,意味着你在 profile 里没写的键仍然沿用 config.toml。想做一套完全独立、不受主配置干扰的行为,profile 帮不了你——那是 --ignore-user-config 的活儿。
第二,--ignore-user-config 只挡配置不挡登录。 官方原文写得很清楚:不加载 $CODEX_HOME/config.toml,但 auth 仍然使用 CODEX_HOME。所以它能帮你复现”是不是我的配置搞坏了”,不能帮你复现”换个账号会怎样”。这条在排查 CI 与本地行为不一致时特别有用:先用 --ignore-user-config 跑一遍,如果问题消失,那锅就在你的 config.toml。
第三,-c 的值是按 TOML 解析的,解析失败会按字面字符串处理。 官方给的三个例子分别是 -c model="o3"、-c 'sandbox_permissions=["disk-full-read-access"]'、-c shell_environment_policy.inherit=all。留意第一个例子里模型名带着引号——在 Bash 里如果引号被 shell 吃掉,你传进去的可能不是你以为的那个值,而且它不会报错,会安静地当成字符串。这就是”我明明用 -c 覆盖了,行为却没变”的典型来源。
三、改完不生效?先跑这两条验证
配置这件事最耗人的不是写,是”改了没反应”。本机在 codex-cli 0.147.0(Windows 11)上实测了两条边界,都值得记住。
第一条:配置文件写坏了,Codex 不会崩,doctor 会告诉你。 故意执行 codex -c 'features=[unclosed' doctor --summary,命令没有崩溃退出,doctor 照常跑完,但 Notes 区多了一行:
✗ config config could not be loaded - Fix the reported config error, then rerun codex doctor.
结论很实用:改完 config.toml 后第一件事是 codex doctor --summary,专门看 config 这一行。它显示 loaded 才说明你的文件被吃进去了。这比反复试功能快得多。
第二条:--strict-config 不是万能拼写检查。 这个选项官方说明是”config.toml 里出现本版本不认识的字段时直接报错退出”。但本机实测 codex -c model_reasoning_effortt=high --strict-config exec --help(注意 effortt 是故意拼错的)——它正常打印了 help,没有报未知字段错误。说明校验发生在真正加载配置去跑会话的路径上,--help 这类不进入会话的命令不触发。所以别指望在 --help 上验证拼写,也别把它理解成”任何情况下都会拦住笔误”。
顺带一提,codex doctor --json 的官方说明是 “Emit a redacted machine-readable report”,是脱敏的;codex mcp list 的 Env 列也会把环境变量值打成 ***** 只留键名。这两个输出可以相对放心地贴给同事或提 issue 用,auth.json 和 config.toml 原文则不行。
四、该先改哪几个键:按”疼痛顺序”分四组
第 1 组:管得住它——沙箱与审批
sandbox_mode 取值 read-only / workspace-write / danger-full-access;approval_policy 取 untrusted / on-request / never。这两个是全套配置里唯一直接决定”它能对你磁盘做什么”的键,别的都可以拖,这两个先定。
这里有一处结构性的判断依据:approval_policy 既可以写成一个字符串(粗粒度三档),也可以写成一张表(细粒度开关)。表形式下有 approval_policy.granular.sandbox_approval、.rules、.mcp_elicitations、.request_permissions、.skill_approval 五个布尔开关。想要的效果如果是”只放行某一类弹窗、其余自动拒绝”,那必须用表形式,字符串做不到。很多人把 approval_policy 当成只有三个选项的枚举,然后抱怨粒度太粗,其实是没往下翻。
另外提醒一句,never 的官方释义是”从不询问,执行失败直接回传给模型”——它管的是问不问你,不等于把沙箱权限放开了。沙箱边界由 sandbox_mode 决定,两者是正交的。
Windows 侧还有 windows.sandbox,取值 unelevated 或 elevated;以及 windows.sandbox_private_desktop,默认 true,表示默认在私有桌面上运行沙箱子进程。本机 config.toml 里 [windows] sandbox = "elevated"。官方自己对 unelevated 的定位就写了保护更弱,所以这个键该怎么选取决于你更在意隔离强度还是兼容性,不要指望哪一档是”稳妥无风险”的。
第 2 组:跑得顺——模型与详略
model 定模型(官方示例值 gpt-5.5),model_reasoning_effort 取 minimal / low / medium / high / xhigh,model_verbosity 取 low / medium / high,model_reasoning_summary 取 auto / concise / detailed / none。
判断依据是:这四个键分别管想多久和说多少,是两件事。嫌它啰嗦别去调 effort,调 model_verbosity;嫌它想太久才动手,才是 effort 的事。另外 plan_mode_reasoning_effort 可以给 Plan 模式单独覆盖推理强度,review_model 可以给 /review 单独指定模型、不设则继承会话模型——这两个是”只想在特定环节加码”时用的,比整体调高划算。
第 3 组:别被默认值骗——联网搜索
web_search 默认值是 cached,取值 disabled / cached / indexed / live。
请把这条读三遍:默认既不是关闭,也不是实时。CLI 的 --search 对应的是开启实时搜索,官方说明里还带一句「启用后原生 Responses web_search 工具对模型可用,无逐次调用审批」。所以如果你的合规要求是”不许联网”,把 --search 不加上是不够的,得显式设 web_search = "disabled";反过来,如果你觉得它给的信息陈旧,八成是因为你一直跑在 cached 上。
补充一句:features.web_search / web_search_cached / web_search_request 这三个特性开关均已弃用(deprecated),改用顶层 web_search。本机 codex features list 里也确实能看到 web_search_cached、web_search_request 标着 deprecated。看到老教程里写这三个键,直接跳过。
第 4 组:把外挂接住——MCP 超时
mcp_servers.<id>.startup_timeout_sec 默认 10,tool_timeout_sec 默认 60。
十秒对一个要冷启动运行时的 server 来说非常紧。本机 config.toml 里 node_repl 就把 startup_timeout_sec 设成了 120。所以”MCP server 老是连不上”这类问题,先怀疑超时而不是怀疑配置写错了。
同一节还有一处顺序陷阱:disabled_tools 是在 enabled_tools 之后套用的。两个都配的时候以 deny 为准——你在 enabled_tools 里点名放行的工具,如果同时出现在 disabled_tools 里,最终仍然是关的。另有 required 键,含义是启用的 server 初始化失败则启动失败;在 CI 里这是好事(早失败),在本机日常用就未必,看你要哪种。
顺带该看一眼的几个
history.persistence(save-all或none)与history.max_bytes,配合前面说的目录体积问题一起考虑。log_dir,默认$CODEX_HOME/log;想把日志挪出系统盘就动它。check_for_update_on_startup,默认true。本机采集时有个真实观测:开头codex --version是codex-cli 0.131.0,十几分钟后同一台机器同一条命令变成了0.147.0,which -a codex全程只有一个可执行文件。结论是排查任何版本相关问题都要以当次codex --version的实时输出为准,别用记忆里的版本号。file_opener,默认vscode,可选vscode-insiders/windsurf/cursor/none。tui.keymap.<context>.<action>可以绑快捷键,赋空数组[]表示解绑——这个写法不看文档猜不出来。
五、三个名字容易理解反的键
shell_environment_policy.ignore_default_excludes,默认 true。 按字面读像是”忽略默认排除项”,实际含义是过滤前保留含 KEY、SECRET、TOKEN 的变量。也就是说默认状态下这些敏感变量是被保留的。名字和效果的方向感几乎相反,配环境策略时务必对着文档确认,别照名字下判断。
features 里 removed 阶段不等于功能没了。 本机 codex features list 观测到的阶段有 5 种:stable、under development、experimental、deprecated、removed。有意思的是 removed 的特性仍然列在输出里,而且部分 removed 项生效值是 true(例如 steer)。合理的读法是:removed 指这个开关不再需要控制、行为已固化,不是这个能力被砍了。
features.unified_exec 官方标注默认 true,但 Windows 除外。 本机 codex features list 实测 unified_exec 生效值就是 false(Windows 机器),与文档口径一致。所以你在 Windows 上看到它是关的,属于预期,不必去”修”。
六、一段起手配置示例
model_reasoning_effort = "medium"
sandbox_mode = "workspace-write"
approval_policy = "on-request"
web_search = "cached"
[windows]
sandbox = "elevated"
[mcp_servers.example]
command = "node"
args = ["server.js"]
startup_timeout_sec = 120
tool_timeout_sec = 60
以上为按官方文档键位组合的示例,未逐项实测,以官方文档为准。写完记得 codex doctor --summary 看 config 那一行是不是 loaded。
七、什么情况下别动 config.toml
一次性的需求用 -c 就够了,写进文件反而会在几周后变成”我为什么当初这么配”的谜题。标着阶段标签的键更要谨慎:features.network_proxy 是 experimental(本机实测阶段为 experimental、生效值 false),features.code_mode.enabled 与 features.rollout_budget.enabled 都是 under development,features.prevent_idle_sleep 是 experimental。这些可以试,但别写进团队共享的配置,也别在生产流程上依赖它们——阶段和默认值会随版本变,本文所有实测结论也只对 0.147.0 这个版本负责。
最后一个省时间的小事实:官方文档站任何页面 URL 后面加 .md 后缀就能拿到 Markdown 版本,站点还提供 llms.txt(完整页面索引)和 llms-full.txt(合并全文)。查配置键时直接取 .md 版本比在网页上翻快得多。
相关阅读
- Codex CLI 的
-c到底覆盖了什么:四条规则与一次配置加载失败的实测 - Codex CLI 的
--profile:给不同项目挂不同配置层 - Codex 特性开关的五个阶段:removed 不等于功能没了
- Codex 的六个使用面:一张图看懂该用哪个
本文依据 Codex 官方文档(learn.chatgpt.com/docs/ 的《Configuration Reference》《Config basics》《Advanced Configuration》《Command line options / Slash commands in Codex CLI》《Model Context Protocol》页面)整理,核对日 2026-08-09;文中标注「本机实测」的部分基于 codex-cli 0.147.0 / Windows 11 环境下的只读命令输出。产品功能、模型与价格以官方最新说明为准。