版本号自己变了:Codex CLI 自动更新与版本口径排查
有一类问题特别容易让人怀疑人生:你上午照着一篇教程敲命令,一切正常;下午同一台机器同一个终端,某个选项突然”不认识”了,或者你截图发给同事,同事说”我这儿输出跟你不一样”。往回倒查一圈,最后发现变量不是配置、不是网络,是版本号自己变了。
Codex(OpenAI Codex)的 CLI 具备自更新能力,这一点我们在本机是撞上过的。下面按排查文章的老规矩走:现象 → 怎么确认 → 怎么处置 → 处置后怎么验证 → 什么情况说明根本不是这个原因。
一、现象长什么样
三种典型表现,都指向同一个根因:
表现 1:同一台机器,短时间内 codex --version 输出不同。
这不是玄学。本机实测记录得很清楚:在 codex-cli 采集过程中,开头执行 codex --version 得到的是 codex-cli 0.131.0,十几分钟后再执行同一条命令,得到的是 codex-cli 0.147.0。中间我们没有手动跑过任何安装或升级命令。同时 which -a codex 全程只解析出一个可执行文件,也就是说这不是”PATH 上有两个 codex 打架”的经典问题——就是同一个入口,它自己变了。
表现 2:教程里的选项,你机器上没有。
比如你看到某篇文章写某个子命令带某个标志,你敲上去 CLI 直接报参数错误。这类问题里,版本差是最常见的解释,因为 CLI 的选项集合本来就随版本走。
表现 3:特性阶段跟别人对不上。
codex features list 会打出三列:特性名、所处阶段、当前生效值。在 codex-cli 0.147.0(Windows 11)上,我们观测到的阶段取值一共有五种:stable、under development、experimental、deprecated、removed。同一个特性名,在不同版本上完全可能处在不同阶段——今天是 under development,明天可能就转 stable,或者反过来被标 deprecated。所以”我这儿是 experimental,你那儿怎么是 stable”,先别急着查配置,先对版本。
二、怎么确认是这个问题:四条判定命令
判定的核心思路是:别信记忆里的版本号,只信当次命令的实时输出。
1. 先拿实时版本号
codex --version
任何涉及”某个选项存不存在""某个特性处于什么阶段”的讨论,第一步都得是这条。你在群里贴问题时也该把这一行贴上,否则别人没法复现。
2. 用 doctor 看清楚”这个 codex 是从哪来的”
codex doctor --summary
在 codex-cli 0.147.0(Windows 11)上,这条命令的抬头会打成 Codex Doctor v<版本> · <平台三元组>(本机是 windows-x86_64),下面按 Notes / Environment / Configuration / Updates / Connectivity / Background Server 分组。排查版本问题,重点看这几行:
- Environment 组的
runtime:会明确告诉你当前这个 codex 是从哪种渠道装的、可执行文件与资源目录在哪。本机是 npm 全局安装,这一行就标出npm与对应的包路径。 - Environment 组的
install:本机显示consistent。这一行是判断”我是不是装了好几遍、现在到底在跑哪个”的最快入口,比自己去翻 PATH 顺手得多。 - Updates 组的
updates:本机显示update configuration is locally consistent。
状态符号本机观测到四种:✓(ok)、○(idle)、⚠(notes/warn)、✗(fail)。结尾会给一行统计,形如 17 ok · 1 idle · 1 notes · 0 warn · 0 fail,并提示可以用 --all 展开被截断的列表、用 --json 输出报告。
3. 确认 PATH 上只有一个入口
which -a codex
如果这条命令给你吐出多行,那才是”多个安装打架”,处理方式和自更新完全不同——那时候你要先决定留哪一个。本机实测是只有一行,所以我们能把版本变化归到自更新这条线上。
4. 确认自更新这条链路确实存在
有两处配置层面的依据可以佐证 CLI 具备自更新能力:codex features list 里存在 in_app_updates 这一项,config 里有 check_for_update_on_startup,官方给的默认值是 true。
这里要说句实在话:我们只观测到”版本号变了”这个结果,以及上面这两处开关的存在,并没有观测到更新过程本身。所以本文不会去描述它是怎么下载、什么时候触发的——那超出我们能证实的范围。
三、处置:把版本口径固定下来
主动升到最新,而不是等它自己变
codex 的子命令表里有专门一项:
| 子命令 | 官方说明 |
|---|---|
update | Update Codex to the latest version |
codex update
Homebrew 安装的用户,官方给的升级命令是:
brew upgrade --cask codex
其它安装渠道,官方文档给出的安装方式分别是 macOS / Linux 的 curl -fsSL https://chatgpt.com/codex/install.sh | sh、Windows 的 powershell -ExecutionPolicy ByPass -c "irm https://chatgpt.com/codex/install.ps1 | iex"、以及 npm install -g @openai/codex。用哪个渠道装的,就用对应渠道的方式管理,别混着来——doctor 的 runtime 行就是拿来回答”我当初是用哪个渠道装的”这个问题的。
关于 check_for_update_on_startup
配置文件 ~/.codex/config.toml 里有这个键,官方给的默认值是 true:
check_for_update_on_startup = true
需要提醒的是:官方在本次核对范围内给出的信息,只到”这个键存在、默认为 true”这一层。它的语义是启动时检查更新,别把它当成一把能锁死版本的总闸——我们没有验证过关掉它之后所有更新路径是否都不再发生。如果你的场景确实需要严格的版本一致性(比如一条 CI 流水线),更稳妥的做法是在每次运行时把 codex --version 的输出记进日志,让版本成为可追溯的事实,而不是靠一个开关去赌。
版本变了之后,配置也要跟着核一遍
版本一动,配置键的认识范围可能跟着动。CLI 提供了一个顶层选项:
codex --strict-config <后续命令>
它的作用是:config.toml 里出现本版本不认识的字段时直接报错退出。听起来像一把万能的拼写检查,但它有边界。本机实测:执行 codex -c model_reasoning_effortt=high --strict-config exec --help(注意 effortt 是故意拼错的),结果是正常打印 help,没有报未知字段错误。说明校验发生在真正加载配置去跑会话的路径上,--help 这类不进入会话的调用不触发它。所以别把 --strict-config 理解成”任何情况下都会拦住拼写错误”。
四、处置后怎么验证
按顺序跑三条,缺一不可:
codex --version
codex doctor --summary
codex features list
分别看三件事:
codex --version的输出是不是你期望的那个号。如果你是 npm 渠道,还可以拿doctor的runtime行给出的包路径去对照——本机实测中,npm 包package.json里的version字段与codex --version的输出是一致的(都是 0.147.0)。两者对不上,说明有东西没换干净。codex doctor --summary的install行是否仍是consistent,updates行是否仍是update configuration is locally consistent,以及结尾统计里fail是不是 0。codex features list里,你关心的那个特性现在处在哪个阶段、生效值是多少。这一步很关键——升级之后特性阶段可能已经变了,你之前的结论要重新下一遍。
如果要把诊断结果发给别人或贴到工单里,用:
codex doctor --json
官方对这个选项的说明是 “Emit a redacted machine-readable report”,也就是输出是脱敏的。这一点对”能不能把诊断结果贴出去”是有直接结论意义的。顺带一提,codex mcp list 也自带脱敏:本机实测它的 Env 列只显示环境变量的键名,值会被打成 *****。
五、什么情况说明不是版本的锅
这一节是为了防止你一条道走到黑。下面这些症状看起来像”版本回退了”,其实另有原因:
改完配置没生效 —— 先看配置有没有加载成功。 本机实测过一个很有价值的行为:执行 codex -c 'features=[unclosed' doctor --summary(故意传一段语法不合法的 TOML),命令没有崩溃退出,doctor 照常跑完,但报告里出现了这一行:
✗ config config could not be loaded - Fix the reported config error, then rerun codex doctor.
也就是说,配置坏了 doctor 依然能跑,并且会明确告诉你配置没加载成功。所以”我改了配置怎么没反应”,第一步不是怀疑版本,是跑 doctor 看这一行。
某个特性显示 removed,但你觉得功能还在。 在 codex-cli 0.147.0(Windows 11)上我们观测到:removed 阶段的特性仍然会出现在 features list 里,而且部分 removed 项的生效值是 true(例如 steer)。合理的读法是——removed 指的是这个开关本身不再需要你去控制、行为已经固化了,不等于功能没了。这是最容易误读的一处,别拿它当”我装了个残缺版本”的证据。
Windows 上 unified_exec 生效值是 false。 这是平台差异,不是版本降级。官方对 features.unified_exec 标注的默认值是 true,但明确写了 Windows 除外;本机 codex features list 实测在 Windows 上生效值确实是 false,两者互相印证。你拿一台 Windows 和一台 Linux 对着比这一项,永远比不出结果。
CLI 有的功能,桌面应用没有。 这大概率不是你 CLI 装坏了,而是两个面各自的版本不同。官方文档给的做法是分别查版本:CLI 用 codex --version,macOS 上的桌面应用用 /Applications/Codex.app/Contents/Resources/codex --version。桌面应用这一侧我们没有实测,以官方说明为准。
登录相关的报错。 那是另一条线,先用 codex login status 看状态(本机实测这条命令输出一行 Logged in using ChatGPT),登录失败的诊断信息写在配置的日志目录里的 codex-login.log。跟版本号没关系。
MCP server 起不来。 先怀疑超时而不是版本:mcp_servers.<id>.startup_timeout_sec 官方给的默认值只有 10 秒,启动慢的 server 必须显式调大。
最后一句实操建议
把”贴版本号”变成肌肉记忆。你在写内部文档、发问题、做录屏的时候,开头带一行 codex --version 的实时输出,成本几乎为零,但能省掉后面大量的来回确认。我们自己这批素材就是这么要求的:任何一条实测结论,都必须写清楚是在 codex-cli 0.147.0(Windows 11)上得到的——因为特性阶段、默认值、选项集合都会随版本变,脱离版本谈结论,等于没有结论。
相关阅读
~/.codex悄悄吃掉几个 GB:rollout 会话与 SQLite 日志的磁盘占用排查- Codex 的日志、SQLite 状态库与 OTel 遥测:先分清三层,再决定开什么
- 看懂
codex doctor的每一行:六个分组逐条读法与排查判定 - Codex 的六个使用面:一张图看懂该用哪个
本文依据 Codex 官方文档(learn.chatgpt.com/docs/ 的《Codex CLI》《Configuration Reference》《Troubleshooting》《Authentication》页面)整理,核对日 2026-08-09;文中标注「本机实测」的部分基于 codex-cli 0.147.0 / Windows 11 环境下的只读命令输出。产品功能、模型与价格以官方最新说明为准。桌面应用与云端部分为官方文档口径,非本机实测。