
先说一个特别典型的场景你在终端里用 Codex 跑了一个耗时很长的后台任务——比如批量重构模块、补测试、分析一堆文件终端滚动刷完了界面看起来“结束了”。你心想很好那我接着问它“下一步怎么处理”结果敲回车、敲命令都没反应界面就像死了一样。更气人的是你干脆退出重开发现之前那个对话根本没留下之前的上下文全没了。这个问题的关键词其实是“后台任务”和“会话状态”。Codex 并不是坏了而是你把“任务执行完成”和“交互式对话还在等我”这两件事搞混了。今天这篇就把这个问题拆开讲透为什么任务结束了不能直接接着用底层机制是什么以及正确的继续使用方式长什么样。适合所有在用 Codex CLI、也踩过类似坑的人尤其是习惯跑长任务、批量执行、反复调试 API 配置的开发者。1. 先弄清楚“后台任务结束了”到底是什么意思1.1 交互式会话和无头执行是两回事Codex CLI 本质上有两种运行方式很多人没有意识到它们是两个完全不同的物种。第一种是交互式会话。你在终端里敲codex进入一个 REPL 式的对话界面输入问题它回答你再输入它再回答。这跟你和一个同事坐在工位前聊天是一样的整个上下文是有状态的Codex 会记住你们聊到哪了。这个状态会落盘通常在~/.codex/sessions/目录下每个会话是一个带时间戳的 JSON 文件。这个模式才是“聊完还能接着聊”的载体。第二种是无头执行对应codex exec这类命令。你给它一个任务它跑完就退出不保留任何“等你继续输入”的交互入口。这更像你给外包小哥发了一个工单他干完活交了成果就走了不会留在你工位旁边问你“还有没有其他吩咐”。标题里说的“后台任务结束了”绝大多数情况指的是第二种。而“不能直接接着用”是因为你的预期是第一种。这个错位是整个问题的根源。1.2 三种常见的“以为结束了”的假象我在实际使用中见过三种特别容易让人误判的情况假象一输出停了就是结束了。很多长任务跑完后终端只是一屏一屏地滚动输出最后停下来。你以为 Codex 还在等你实际上进程可能已经退出了你看到的只是屏幕上的历史缓冲区而已。此时怎么敲键盘都不会有反应因为根本没有任何进程在接收你的输入。假象二CtrlZ 挂到后台就是后台任务。有人在交互式 Codex 里跑任务时按了 CtrlZ 把整个进程挂起然后去干别的。回来以后fg恢复发现还能继续于是觉得“后台任务结束了也能接着用”。但这个“能接着用”是因为你挂起的是交互式会话不是无头任务。如果你挂起的是一个codex exec无头进程恢复前台后你会发现它要么早就跑完退出了要么根本没有会话可以恢复。假象三日志里显示完成就等于整个流程完成。Codex 的任务往往分多步模型生成、执行命令、读取结果、再次生成。日志里的某条“完成”可能只是其中一步整个进程可能还在跑后面的步骤或者卡在一个等待响应的状态里。你急着继续输入当然没反应。这三种情况对应不同的处理方式后面第三章会逐个给出排查方法。2. 为什么结束之后没法直接接着聊底层原因拆解2.1 执行模式决定了会话不会等你这是最核心的一点。codex exec默认的行为是执行完输入的任务进程退出。它不会在结束之后为你保留一个交互式提示符更不会自动进入“对话模式”。这是设计如此不是 bug。有人会问那我刚才跑的任务上下文都还在啊为什么不能基于它继续答案是上下文确实落盘了但落盘不等于给你提供了一个“随时回来接着聊”的入口。如果你想继续你需要显式地恢复这个会话比如用--continue或--resume参数把那个已经落盘的会话重新加载起来。问题又来了如果你跑codex exec时没有显式指定--sessionCodex 会给你生成一个随机会话 ID跑完之后你根本不知道这个 ID 是什么自然也谈不上恢复。一句话总结无头模式默认不为你保留“等待继续”的状态执行完即走人。你要续聊就得在发起任务时就把会话身份固定下来。2.2 终端作业控制带来的挂起陷阱再讲一个很多人踩过的坑终端作业控制。你在 shell 里按 CtrlZ实际上是给进程发送了一个 SIGTSTP 信号让进程挂起而不是结束。此时进程还在内存里只是被冻结了jobs命令能看到它fg能把它拉回前台。这个机制本身没问题但放在 Codex 身上就有两个坑。第一个坑是如果你挂起的是一个codex exec无头任务那么这个进程本来就不持有交互会话你fg拉回来它可能已经执行完毕退出了shell 只给你一句Done。你以为你能接着聊它压根没给你留下“聊”的入口。第二个坑是如果你挂起的是交互式会话拉回前台通常可以继续但 Codex 内部有会话超时机制。挂起太长时间恢复后它去校验 token 或会话有效期时可能直接报auth token is unavailable或者告诉你这个会话不可恢复。你看连“能接着用”的交互式会话都有失效的可能。2.3 资源没释放残留进程、锁与日志句柄还有一个容易被忽略的层面进程虽然结束了但资源没有完全释放。Codex 运行时会写日志、创建会话文件、启动本地沙箱或者模拟器进程去执行代码。如果你用 CtrlC 强制中断或者任务本身异常退出这些子进程或临时文件可能没来得及清理。最常见的结果是你再启动一个新的 Codex 会话时发现它一直卡在初始化状态或者在读取某个锁文件时迟迟拿不到权限。我自己遇到过一次很典型的场景后台任务正常跑完了但我急着开新会话连续起了三个codex进程结果前两个因为沙箱容器未释放一直卡在“等待初始化”。用ps一看一堆残留的 codex 子进程还挂在系统里。把这些残留进程清掉之后新会话立刻恢复正常。所以“任务结束了”在业务层面可能是结束了但在系统层面它可能还欠着一屁股资源债没还清。这也是“不能直接接着用”的一个重要原因。3. 现场排查三板斧进程、日志、配置3.1 第一步用命令确认进程到底还在不在遇到“没反应”先别急着重启终端。按顺序跑这几条命令确认 Codex 到底是什么状态# 看当前 shell 的后台作业 jobs -l # 看系统里所有 codex 相关进程 ps aux | grep codex pgrep -fl codex # 如果担心有残留子进程可以看进程树 pstree -ap | grep codex不同现象对应的判断如下现象初步判断jobs里有Stopped状态的作业进程被挂起了用fg拉回前台ps里找不到 codex 进程进程已退出界面只是缓冲区残留ps里能找到 codex 主进程但一直无输出进程可能在等待网络响应或卡在初始化ps里有一堆 codex 相关进程有残留子进程先确认再清理确认进程状态之后该fg的fg该kill的kill。注意kill默认发的是 TERM 信号给 Codex 一个优雅退出的机会。如果 TERM 信号之后进程还赖着不走再用kill -KILL强制结束。杀进程这事必须确认当前任务确实不需要继续了再做否则你正在跑的长任务可能直接中断。3.2 第二步翻日志和会话记录找病根进程状态确认完如果还是不知道问题出在哪翻日志是最高效的路径。Codex 的默认数据目录在~/.codex日志在~/.codex/log/下打开最新的日志文件ls -lt ~/.codex/log/ | head tail -n 200 ~/.codex/log/最新日志文件日志里能看到每个请求的 request id、API 调用耗时、报错信息。如果出现request timed out说明是请求超时如果出现endpoint相关的路由错误说明是 API 端点配置问题如果是auth token is unavailable那方向就明确是认证问题。同时看一下会话记录ls -lt ~/.codex/sessions/ | head每个会话都是 JSON 文件打开之后能看到这个会话关联的模型、时间、消息记录。如果你在跑无头任务时没有指定--session这里的文件名就是那个随机生成的会话 ID以后要恢复它就得靠这个文件名了。3.3 第三步检查认证状态与端点路由配置日志看完了锁定是认证或配置问题就按这两步检查。认证方面确认~/.codex/auth.json是否存在、内容是否过期。如果你用的是环境变量方式确认OPENAI_API_KEY或者你自定义的 key 变量是否在当前 shell 里生效echo ${OPENAI_API_KEY:已设置}不行就重新登录一次在交互式会话里执行codex login按提示完成认证即可。一个很常见的坑是你在终端 A 里登录过然后在另一个终端 B 里新开的 Codex 报 token 不可用其实是环境变量优先级覆盖了已有的登录态。配置方面打开~/.codex/config.toml看两样东西模型名和 API 端点。热搜里有条the gpt-5.6-sol model is not supported when using codex...就是典型的模型名与端点服务不匹配——你在配置里写了一个模型名但实际提供 API 的服务商不支持它。改配置里的model字段为你服务商真正支持的模型即可。至于报错cc switch local proxy failed while handling codex endpoint /responses这个通常出在使用第三方 API 配置切换工具时本地转发服务处理 Codex 的/responses这个端点路径时报错。检查方向是转发服务的路由表里到底有没有配置/responses这个路径Codex 走的请求路径和转发服务能处理的路径是否一致。4. 三种实操方案让“接着用”变成顺手的事4.1 方案A无头模式显式指定会话之后用 --continue 续聊如果你习惯用codex exec跑批量任务又希望跑完还能继续交代后面的工作一定要在发起任务时显式指定会话名codex exec --session pay-module-refactor 重构支付模块保持对外接口兼容任务跑完后这个会话会以pay-module-refactor这个名字存在本地。等你想继续只要再执行codex exec --continue 给重构后的支付模块补边界测试Codex 会自动加载同名会话的历史上下文相当于“接着上次的聊”。注意不同版本参数名可能不一样有的版本是--continue直接续接最近会话有的版本支持--session加--continue组合指定续接某个特定会话。拿不准的时候先跑一下codex exec --help确认。这个方案的好处是每次执行都是独立的进程不会因为终端关闭、网络波动而丢失上下文完全规避了“进程挂起/终端绑定”的问题。代价是你必须养成分组命名会话的习惯否则会话列表一大就找不到了。4.2 方案B交互式会话里跑长任务用 tmux 保底如果你更享受对话式的工作方式那就老老实实待在交互式会话里codex在交互式会话里发长任务等它跑完直接输入下一句就行——这是真正的“接着用”。但问题是有时候任务太长你不能一直守着终端。这时别用 CtrlZ也别直接关终端用 tmux 兜底tmux new -s pay-fix codex需要离开时按CtrlB再按D脱离detach整个过程不中断。回来时tmux attach -t pay-fixCodex 依然是同一个进程同一个伪终端标准输入输出始终绑定在它身上。你离开多久都无所谓回来后它还在等你下一句话。这个方案我用得非常熟它解决的是“交互式会话 长时间离开”的矛盾。只要 Codex 进程在 tmux 里就永远不存在“任务结束没入口”的问题。4.3 方案C配置文件一次调好避免模型和端点打架很多“不能接着用”的现场其实是被配置问题卡住了。把配置一次性调对能省掉大量排查时间。一个比较完整的~/.codex/config.toml长这样model gpt-5.6-sol [api] base_url http://127.0.0.1:8080 [call] timeout 300重点检查两个地方。第一是model必须是你实际 API 服务商支持的名字写错就会得到model is not supported的报错。第二是base_url如果你接入了第三方 API 服务这个地址必须指向你自建的转发服务或者兼容端点而且这个服务要能正确处理 Codex 发出的/responses路径请求。验证端点最简单的方法是用 curl 直接打一下curl -X POST http://127.0.0.1:8080/responses \ -H Content-Type: application/json \ -d {model:gpt-5.6-sol,input:ping}看返回是不是一个正常的 JSON而不是404 Not Found或者路由错误。把这一步放在工作流里比等 Codex 报错再排查高效得多。5. 高频故障速查表与三个避坑经验5.1 常见报错与处理对照现象 / 报错常见原因推荐处理任务跑完后敲键盘没反应进程已退出无头模式不会等待输入确认ps用--continue恢复会话CtrlZ 后fg没动静挂起的是无头任务本就没有会话入口改在交互式会话里跑任务配合 tmuxauth token is unavailabletoken 缺失或过期codex login重新认证检查环境变量request timed outAPI 响应慢超时设置太短调大[call] timeout检查端点服务状态model is not supported配置文件模型名与实际服务不匹配修改config.toml中的model字段cc switch local proxy failed ... /responses本地转发服务无法处理/responses路径检查转发路由表验证端点路径重启后找不到上次对话无头任务未指定会话名ID 随机查看 sessions 目录用会话 ID 恢复新会话一直卡在初始化旧进程或沙箱子进程残留pgrep -fl codex找到残留并清理5.2 三个通用文档里不写、但我实测有效的经验经验一用两套心智模型来对待 Codex。需要持续对话、反复调整需求时老老实实用交互式会话并套上 tmux需要一次性批量处理时用codex exec并显式指定有意义的会话名。别指望无头任务跑完还会“顺便”给你留个对话入口那不是它的职责。经验二跑大任务之前先预检认证和超时。我吃过亏一个任务跑到一半token 过期报auth token is unavailable整个会话前功尽弃。现在我的习惯是跑长任务前先确认 auth.json 有效然后在 config.toml 里把 timeout 调大到 300 秒以上把这类中途翻车的概率降到最低。经验三长任务结束前把关键输出复制落到本地文件。终端缓冲区有限一旦输出被冲掉你只能靠日志找回上下文。每次跑完重要任务第一时间把最终结果、文件路径、修改清单这些关键信息复制到自己的笔记里。这样即使 Codex 的会话因为各种原因坏了你的工作成果也还在。我自己的体会是刚接触 Codex 时我也觉得“任务结束不能接着用”是个设计缺陷后来把执行模式和会话机制理清楚之后反而觉得这种设计很合理执行是无状态的对话是有状态的两者不该混为一谈。现在我跑长任务要么 tmux 包一个交互式会话要么exec加命名会话再也没有出现过“想继续却找不到入口”的尴尬。最后再分享一个小技巧每天开工前花十秒钟跑一下codex exec --list-sessions看一眼昨天的会话列表把要续的会话名记在待办里这个习惯能让你的上下文管理顺畅一大截。