Codex 会话续跑与分叉实战:resume、`--last` 与 fork 怎么用才不丢上下文
用命令行跑 AI 编码,最常见的一个尴尬时刻是:一件事做到一半,终端关了、机器重启了、或者你临时切去处理别的分支,回来的时候前面攒的那一堆上下文没了,只能从”我们刚才在改一个 XXX”重新讲一遍。
Codex(OpenAI Codex)的 CLI 对这件事是有专门命令的:resume 续跑一个已有会话,fork 从一个已有会话分叉出一条新线。这两个命令的存在感很低,--help 里各自只有一句话,所以很多人压根没注意到。这篇就围绕这两个命令,把「命令怎么写、跑完东西落在哪、怎么确认真的续上了、什么情况别指望它」四件事说清楚。
先交代口径:本文所有命令和选项来自 codex-cli 0.147.0(Windows 11)上执行的只读命令输出与官方文档。我们没有发起过任何模型对话请求,所以下文不会出现”我续跑了一次,它花了多久、返回了什么”这类内容——那部分不在可核实范围内。
一、这三个命令各自管什么
在 codex-cli 0.147.0(Windows 11)上执行 codex --help,子命令表里与会话生命周期相关的有这么几条:
| 子命令 | 官方说明(原文) | 补充 |
|---|---|---|
resume | Resume a previous interactive session | 默认弹会话选择器,--last 直接续最近一次 |
fork | Fork a previous interactive session | 从既有会话分叉出一条新线 |
archive / unarchive | — | 按 id 或会话名归档 / 取消归档已保存会话 |
delete | — | 按 id 或会话名永久删除已保存会话 |
codex exec(别名 e,官方说明 Run Codex non-interactively)自己还带了一个 resume 子命令,支持按 id 续或者 --last。也就是说,交互式和非交互式两条路都能续,但入口不是同一个。
这四个命令读一遍就能看出设计意图:会话不是一次性的临时缓冲,而是被当作有 id、有名字、可归档、可删除的持久对象在管理。理解了这一点,后面的目录结构和磁盘占用问题就都顺理成章了。
二、命令怎么写
交互式:接着昨天那条线干
# 弹出会话选择器,从列表里挑一个续
codex resume
# 不挑了,直接续最近一次
codex resume --last
两条的差别不在功能而在场景。--last 适合”刚关掉又想起来还有一步没做”,省掉一次翻列表;而只要你中间穿插过别的任务,“最近一次”就不一定是你要的那次,这时候老老实实用选择器更稳妥。从命令语义上讲,更稳妥的默认做法是用不带参数的 codex resume 从选择器里挑,只有在确定中间没插过别的会话时才用 --last。
需要提醒的是,交互式 resume 这一侧,我们核实到的用法只有「默认弹选择器」和 --last 两种。它是否还接受直接传 id,请自己跑一次 codex resume --help 看当前版本的说明,别照抄别处的写法。
非交互式:把续跑塞进脚本
# 续最近一次非交互会话
codex exec resume --last
codex exec 这一层的输入规则值得单独记一下(这是 0.147.0 上 codex exec --help 的原文口径):位置参数 [PROMPT] 不给参数或者给 - 时从 stdin 读;如果 stdin 是管道并且你同时给了 prompt,stdin 的内容会作为一个 <stdin> 块追加上去。这条规则很实用——你可以把上一步脚本的输出直接管道喂进来,同时用位置参数写清楚”拿这段东西干什么”,两者不会互相覆盖。
至于 exec resume 这个子命令具体还接受哪些参数,请以 codex exec resume --help 为准,我们只核实到它支持按 id 续与 --last 两种方式。
分叉:同一个起点,跑两套方案
codex fork
fork 的官方说明只有一句 Fork a previous interactive session。它的用途在真实工作里其实很明确:某个会话已经把背景铺垫好了(读过哪些文件、确认过哪些约束),接下来你想试两条不同的技术路线,又不想让两条线互相污染上下文——这时候分叉比”新开一个会话重讲一遍背景”划算得多。具体参数同样以 codex fork --help 为准。
配套配置:resume 之后你人在哪个目录
这是最容易被忽略、又最容易踩的一个点。官方《Configuration Reference》的 TUI 一节里有这么一个键:
| 配置键 | 取值枚举(官方给出) |
|---|---|
tui.resume_cwd | current / session |
这里必须把话说明白:官方《Configuration Reference》只给出了这个键名与两个取值,并没有给出每个取值对应的具体行为描述,本机也没有实测过它。 按键名和取值字面去理解,它管的是”续跑时工作根目录跟谁走”——current 一侧对应你当前所在的目录,session 一侧对应原会话那边的目录;但这只是按字面的理解,具体行为以官方文档和你当前版本的实际表现为准,别当成确定结论去写脚本。
之所以还要专门点出这个键,是因为它提示了一件事:续跑之后,工作根目录未必是你以为的那个。如果你经常在多个仓库之间跳,同样一句”把刚才那个文件再改一下”,工作根目录不同,指向的文件就完全不同。这个风险是客观存在的,至于这个键的两个取值分别落在哪一侧,请自己在当前版本上确认一次再固化到配置里。
想临时试一下不改配置文件,可以用顶层的 -c 覆盖:
codex -c tui.resume_cwd=session resume --last
-c 的规则是覆盖 ~/.codex/config.toml 里的值,点号路径表示嵌套,value 按 TOML 解析、解析失败则按字面字符串处理。另外顶层还有个 -C, --cd <DIR> 可以直接指定 agent 的工作根目录,跟 resume_cwd 解决的是同一类问题、但更直接。
以上为按官方文档键位组合的示例,未逐项实测,以官方文档为准。
想让会话别留下来:--ephemeral
codex exec 有一个 --ephemeral 选项,官方说明是不把会话文件落盘。它跟本文主题是反向的——用了它,这次会话就不存在于可续跑的列表里。跑一次性的批处理、或者处理你不希望留痕的内容时用它;但用完就别指望 resume --last 能把它捞回来。
三、产出物长什么样
会话文件落在哪
在 codex-cli 0.147.0(Windows 11)上查看 ~/.codex/(也就是 CODEX_HOME)目录,与会话相关的条目有这些:
sessions/:会话 rollout 落盘目录,按年份分子目录archived_sessions/:归档后的会话history.jsonl:历史记录logs_2.sqlite(连同-shm、-wal):SQLite 日志库
所谓”续跑”,续的就是 sessions/ 里那些 rollout 文件。archive 把它挪进 archived_sessions/,unarchive 挪回来,delete 是永久删除——这三个动作的可逆性差异,从目录结构上看得清清楚楚。
这里要泼一盆冷水:这些文件是真的占地方。在本机 codex-cli 0.147.0(Windows 11)上,codex doctor --summary 的 Notes 区里 rollouts 一行提示的是 405 active files · 3.07 GB on disk,而 logs_2.sqlite 单个文件就有 763 MB。这不是异常状态,就是长期使用的自然结果。所以”会话都留着,反正以后可能续”这个想法,得配合定期 archive / delete 一起用,不然磁盘会安静地被吃掉几个 GB。
如果你想控制历史记录的存量,官方《Configuration Reference》给了两个键:history.persistence(取值 save-all 或 none)和 history.max_bytes。
非交互续跑的输出
如果你走的是 codex exec 这条路,输出形态由这几个选项决定(均为 0.147.0 上 codex exec --help 的原文):
--json:事件以 JSONL 形式打到 stdout-o, --output-last-message <FILE>:把 agent 的最后一条消息写到指定文件--output-schema <FILE>:给一个 JSON Schema 文件路径,描述模型最终回复的结构--color <COLOR>:always/never/auto,默认auto
组合起来,续跑在脚本里就有了确定的接口:--json 给你逐事件的流,方便中途监控;-o 给你一份干净的最终结论文件,方便下一个环节直接读。要写进日志文件的话记得配 --color never,否则转义序列会把日志弄得没法看。
至于 JSONL 里具体有哪些字段——这个我们没有实测数据,别照着别处的字段名写解析器,自己跑一次把第一行打出来看是最靠谱的。
四、怎么验收
续跑这件事的验收,重点不在”命令有没有报错”,而在你以为续上的那个会话,是不是真的是它。按这个顺序检查:
第一处:工作目录。 续上之后先确认当前工作根目录是哪个。这是最容易错、错了又最难察觉的一步——因为整个会话不会报任何错,它只是在错误的目录里干活。不要预设”它一定会回到原来那个项目目录”,也不要预设”它一定跟着我现在的目录”——上一节说过,tui.resume_cwd 的两个取值分别对应什么行为,官方文档只给了枚举、我们没有实测,所以这一处只能靠你自己每次看一眼当前工作根目录来确认。真要减少不确定性,顶层的 -C, --cd <DIR> 更直接:把工作根目录显式写死,就不用猜了。
第二处:会话本体。 如果用的是 --last,务必回想一下中间有没有插过别的会话;不确定就退出来改用 codex resume 从选择器里挑。
第三处:配置到底加载成功没有。 这是本机实测得到的一条很有价值的结论:在 codex-cli 0.147.0(Windows 11)上,故意执行 codex -c 'features=[unclosed' doctor --summary(-c 传了语法不合法的 TOML),命令没有崩溃退出,doctor 照常跑完,但 Notes 区多了一行:
✗ config config could not be loaded - Fix the reported config error, then rerun codex doctor.
也就是说,配置写坏了不一定有明显的报错,程序会带着”没加载上配置”继续跑。所以只要你改过 config.toml(比如刚加了 tui.resume_cwd)却感觉没生效,第一件事就是:
codex doctor --summary
去看 Configuration 分组里的 config 那一行是不是 loaded。同一份输出里还有一个 threads 检查项,本机观测到的描述是 rollout files and state DB thread inventory agree——即 rollout 文件和状态库里的会话清单对得上。这一项对”会话列表里为什么少了几条”这类问题是有指示意义的。
顺便说一句排查礼仪:codex doctor --json 的官方说明是 Emit a redacted machine-readable report,是脱敏的,所以贴到 issue 里相对稳妥;而 --summary 的文本输出里可能带你的本地路径,往外贴之前自己扫一眼。
还有一个坑值得单独点名:别指望 --strict-config 帮你兜住所有配置拼写错误。在 codex-cli 0.147.0(Windows 11)上执行 codex -c model_reasoning_effortt=high --strict-config exec --help(键名故意多打了一个 t),结果是正常打印 help,没有报未知字段错误。说明这个校验发生在真正加载配置去跑会话的时候,--help 这类不进入会话的路径不触发。所以”我加了 --strict-config,没报错就说明配置没问题”这个推论是不成立的。
五、什么情况别用这套
跑过 --ephemeral 的会话,没得续。 这是它的设计目的,不是 bug。
已经 delete 掉的会话,没得续。 archive 是可逆的、delete 不是,这两个命令的手感很像但后果差很远,敲之前看清楚。
换了机器就别想了。 会话 rollout 是落在本机 ~/.codex/sessions/ 里的本地文件,本文范围内没有任何依据说明它会跨机器同步。
依赖”会话记得某个环境细节”的活儿,别靠续跑兜底。 续跑恢复的是会话上下文,不是你的机器状态——你在两次会话之间改过的分支、装过的依赖、删掉的文件,都不在里面。真要保证一致,把关键前提重新写在这一轮的指令里,比赌它记得划算。
版本本身也在漂。 一个真实观测:同一台机器上,采集开头 codex --version 是 codex-cli 0.131.0,十几分钟后同一条命令变成了 codex-cli 0.147.0,而 which -a codex 全程只有一个可执行文件。Codex 具备自更新能力(config 里的 check_for_update_on_startup 默认 true),所以”我昨天看到的版本号和今天不一样”是正常现象。这对续跑的含义是:排查任何跟 resume/fork 有关的行为差异,都要先看当次 codex --version 的实时输出,别拿记忆里的版本号讨论问题,也别把本文的实测结论当成永久成立。
桌面应用那一侧是另一套东西。 官方《Troubleshooting》里”找不到已归档的聊天”给的做法是在 Settings 里找归档聊天,取消归档后回到原侧栏位置——这是桌面应用的操作路径,跟 CLI 的 archive / unarchive 不是一回事,别混着用。这部分我们没有实测,属于官方文档口径。
云端更要单独说。 codex cloud 在 0.147.0 上的标注是 [EXPERIMENTAL](官方说明为 Browse tasks from Codex Cloud and apply changes locally),本文讨论的本地会话续跑和它不是同一条链路,别把两边的行为互相套用。
最后给一个能直接抄走的最小工作流:干活前想清楚这条线要不要留(要留就别加 --ephemeral);第二天回来用 codex resume 从选择器里挑,别图省事按 --last;续上先确认工作目录;每隔一段时间跑一次 codex doctor --summary 看 rollouts 那行的文件数和体积,该 archive 的归档、确定不要的再 delete。这套流程里没有什么高级技巧,但能省掉”我明明续上了怎么改错了文件”这一类最费时间的返工。
相关阅读
- Codex 会话管理实战:归档、取消归档、删除与按名字找回
codex review的三种评审范围怎么挑:—uncommitted、—base 与 —commit- 提交前自查工作流:
codex review --uncommitted到底该怎么写 - Codex 的六个使用面:一张图看懂该用哪个
本文依据 Codex 官方文档(learn.chatgpt.com/docs/ 的《Codex CLI》《Command line options / Slash commands in Codex CLI》《Non-interactive mode》《Configuration Reference》《Troubleshooting》页面)整理,核对日 2026-08-09;文中标注「本机实测」的部分基于 codex-cli 0.147.0 / Windows 11 环境下的只读命令输出。产品功能、模型与价格以官方最新说明为准。桌面应用与云端部分为官方文档口径,非本机实测。