
“持久模式”这几个字一出现我就知道自己对这个功能的理解必须重新校准。过去很长一段时间我终端里的 Codex 更像一个非常聪明的临时工你给它一段任务它给出一段结果。你关掉终端它也把刚才的思路几乎一起忘掉了。下一次启动配置要重新确认、上下文要重新贴、需求要重新解释甚至上次已经确认过的实现方案也要再讲一遍。对一个用来提高开发效率的工具来说这种体验最大的问题不是“效率不够高”而是“工作流是断的”。所以 OpenAI 为 Codex 测试持久模式真正值得关注的不是“它能记得更多对话”而是它可能把编码代理从一个“无状态工具”推进到“有状态的工作单元”。这篇文章我会从实际开发工作流出发拆一下持久模式可能意味着什么、它到底想解决什么问题以及在它真正落地之前我们这些一线开发者应该怎么理解、怎么试验、怎么避免被“持久”两个字误导。1. 为什么“持久模式”会比单纯的“更聪明”更影响日常开发1.1 单次会话的 Codex其实一直在“重复热身”很多人第一次用 Codex 的时候会觉得它已经足够聪明能读懂仓库结构、能改文件、能跑测试、能解释报错。但只要你把任务拉长问题就出来了。比如你让它做一个跨多个文件的重构。第一轮它理解了旧的接口设计给出了迁移方案。第二轮你发现某个边界情况没有覆盖让它调整。第三轮它改到一半终端会话因为网络波动或窗口关闭中断了。等你重新打开 Codex它问你“我需要了解项目背景你能描述一下这个模块的职责吗”你会觉得荒谬。刚才明明已经讲过的内容为什么还要重新讲一遍更深层的问题在于单次会话的代理本质上是一个“没有记忆的执行器”。它靠当前上下文窗口里的内容做判断。上下文窗口一旦结束之前的推理过程、用户偏好、已验证的选择、正在进行的计划全部归零。这意味着每开一个新会话你都得重复“热身”。1.2 从“一次性问答”到“长期协作对象”持久模式如果真能落地它改变的并不是模型的单次推理能力而是代理和开发者之间的协作关系。过去我们使用编码代理的方式更像是在用搜索引擎加实时对话这一轮问完了下一轮重新开始。而持久模式下的代理理论上应该更接近一个“长期协作对象”它知道这个项目的技术栈记得你上一轮已经确认过的方案理解你习惯的代码风格也清楚哪些任务已经完成、哪些还悬而未决。这才是它真正吸引人的地方。不是“多记住几段对话”而是任务的连续性得到了保证。但问题是连续性的实现方式决定了它能可靠到什么程度。如果只是把历史对话无脑拼接到上下文里那长期看一定会撞到上下文窗口的天花板。如果它会自动做状态压缩、任务总结、关键决策提取那这就走向了一种新的工程范式代理不是一次性的执行器而是一个可以持续运行、可恢复、可变更状态的工作单元。从开发者的角度看这个变化比“模型能力提升一档”更值得关注因为它改变的是工作流本身。2. 它真正想解决的是编码任务跨会话连续性的问题2.1 跨会话任务的真实成本上下文重建、决策丢失、代码审查成本我在实际项目里统计过自己使用编码代理的时间构成。如果只是“写一个函数”“补一个单测”单次会话的效率可以很高。但只要任务是“改完这个功能模块同时保证旧接口兼容、测试全部跑过、文档同步更新”时间成本就会急剧上升。上升的部分主要来自三块。第一块是上下文重建成本。每次新开会话我都要重新告诉代理项目的目录结构、技术栈、依赖关系、本次任务的目标、验收标准。这些内容占用的时间本身不长但它们打断了我原本的思维流。我要从“专注在任务上”切换成“把任务翻译成 prompt”。第二块是决策丢失成本。上一轮会话里已经做过的技术取舍、已经否决的方案、已经确认的设计原则一旦没有持久化下一轮就可能会被代理用新的角度推翻。这不是说代理不能换一种思路而是说它可能在一个你已经验证过的岔路口上重新探索。第三块是代码审查成本。如果每一步都是临时会话你很难追溯代理当时为什么做出这个改动。没有决策记录就没有可审查性。长期维护时这种成本会逐渐变成一个负面资产。2.2 持久模式的三种能力层次如果只是从功能上猜测我倾向于把持久模式拆成三个能力层次来理解。第一个层次是“记忆持久”。这是最基础的。代理能把当前项目上下文、用户偏好、历史决策保存下来并在下次会话中读取。第二个层次是“任务状态持久”。它比记忆更进一步。代理不仅知道之前聊过什么还知道当前任务做到哪一步了哪些文件已经改完哪些测试还没跑哪些问题需要用户确认哪些输出已经被验证过。这个状态不一定适合塞进模型的上下文但可以用结构化的形式保存在本地比如任务状态文件、变更清单、待办列表。第三个层次是“工作流持久”。到这个阶段代理就不再只是处理单个请求了。它可能维护着一个长期运行的执行计划按阶段推进任务中途可以在等待输入时暂停也可以在多轮会话之间恢复。如果持久模式测试的目标只是第一层那它对普通开发的改变有限更像是“聊天历史自动归档”。如果目标是第二层和第三层那它确实会改变编码代理的使用方式也会让工具从“帮你写代码”变成“帮你管理一段完整的编码过程”。第三层的实现难度显然更大也更值得关注。3. 测试持久模式前先把 Codex 的基础链路弄清楚3.1 CLI、IDE 插件与模型路由是三个独立环节在讨论持久模式怎么用之前我建议先把 Codex 的日常使用链路理清楚。因为在实际环境里Codex 并不是一个单一的“对话窗口”它至少包含三个独立环节CLI 工具、IDE 插件、模型与 API 路由。CLI 工具是最底层的执行入口。它负责接收任务、调用模型、执行代码、读取结果。IDE 插件只是对 CLI 的一层封装把终端里的交互搬到了编辑器侧边栏或面板里。而模型与 API 路由决定了你实际使用的是哪个模型、通过哪个端点访问、使用什么协议。这三个环节一旦没对齐就会出现各种“看起来能用但实际不稳”的情况。3.2 先解决“找不到 Codex CLI 二进制文件”这一类环境问题很多人在 IDE 里第一次启动 Codex 时遇到的不是模型能力问题而是环境配置问题。比如经常会看到这样的报错ChatGPT failed to start. Unable to locate the codex CLI binary. Set codex_cli_path or ensure the Electron app can access the CLI.这个错误的本质是IDE 插件找不到 CLI 可执行文件。它要么需要你在配置里明确指定codex_cli_path要么需要系统环境变量里能正确找到codex命令。从排查顺序看我一般会这样处理先在终端里确认 CLI 是否真的可用codex --version。再确认 PATH 里是否存在 codex 对应的可执行目录which codex。如果终端可用但 IDE 里报错就去 IDE 的配置项里设置codex_cli_path直接指向二进制文件的绝对路径。如果 IDE 是桌面应用改完环境变量后需要完全退出再重启因为很多桌面应用不会实时读取新环境变量。如果仍然失败检查权限。部分系统上普通用户能访问的目录和应用沙箱能访问的目录并不一致。这类问题看似简单但会直接影响持久模式的体验。因为如果 IDE 连 CLI 都找不到那无论它支持多少“保持上下文”“跨会话恢复”的能力都无从谈起。3.3 模型和端点的差异会影响你判断“持久”是否生效还有一个容易踩的坑Codex 作为一个客户端可以配置不同的模型和端点。比如允许走 OpenAI 官方 API 协议也可以接第三方兼容服务。接口协议相似但模型能力差异极大。举例来说有的报错会直接指出The gpt-5.6-sol model is not supported when using Codex with an API.这种情况说明你在配置里指定的模型名和当前端点支持的模型列表不匹配。遇到这类错误时先不要再调任务内容了问题出在路由层。在测试持久模式时我特别建议使用稳定、官方支持且自己熟悉的模型链路。为什么因为持久模式本身依赖模型具备良好的上下文总结、指令遵循和状态恢复能力。如果你用一个上下文能力很弱的模型去测试“跨会话恢复”得到的结论很可能是错误的不是功能不可用而是模型不理解状态文件里的指令。这里可以先用一个简单验证方法在同一个目录下发起一个任务明确要求它“把当前项目结构和已完成改动写入一个 AGENTS.md 文件”然后关闭会话重新打开再让它读取该文件并继续任务。如果这一条链路稳定再继续深入。4. 我建议的“持久化 Agent 工作流”设计方法4.1 第一步给每个任务定义明确边界不要一开始就试图让代理记住“所有东西”。持久化的粒度应该是任务而不是通用对话。我习惯把任务分成三层一次性提问不需要持久化。比如“这个函数的时间复杂度是多少”。答案看完就行。短任务需要几次交互但能在一次会话内完成。比如“给这个接口增加一个参数校验”。可以依赖会话记忆但不需要专门做状态持久。长任务跨越多个阶段、涉及多文件、需要多轮验证。比如“把整个用户认证模块从 session 改造成 JWT同时保持现有接口兼容”。这类任务才真正需要持久模式。给长任务写一个明确的任务说明至少包括目标、范围、非目标、验收标准、当前进度、已知决策、待确认问题。这个文件本身就是最可靠的持久化载体。4.2 第二步把上下文总结成项目级文档现在很多项目里会放一个AGENTS.md或CLAUDE.md用来给代理提供项目级背景。这个做法在持久模式下会变得更加重要。因为代理一旦跨会话运行它不太可能记住所有历史细节。但如果它能主动读取一份最新的项目状态文档效果会好很多。你可以把文档理解成代理的“外部记忆”不依赖上下文窗口不随会话丢失任何新会话都能重新加载。具体写法上我建议包括这么几块技术栈和目录结构常见的构建、测试、运行命令代码风格约定当前正在进行的任务和进度已确认的决策和已否决的方案已知容易踩的坑文档不用写得很长重点是让一个新启动的代理能在五秒钟内知道“这个项目在做什么、现在做到哪一步了”。4.3 第三步建立日志、核查点与恢复流程持久模式不是“把所有东西记住就完事”。工程上更关键的是恢复能力。我通常会在长任务里设置几个核查点任务启动时记录初始状态。每完成一个可独立验证的阶段更新一次进度文档。每次结束会话前让代理输出一个简短的“当前状态摘要”包括已完成、未完成、阻塞点、下一步。重新开会话时先让它读取摘要再让我确认状态是否准确。这样即使代理的持久功能不稳定我们也能靠外部记录恢复工作流。这也是我认为最稳的降级方案。4.4 四步模板持久化工作流的落地顺序如果你在一线项目里试一个持久模式可以考虑这个顺序第一步确认工具链路可用CLI、插件、模型路由 第二步用一个真实长任务做验证但保持任务边界清晰 第三步任务开始时创建状态文档结束时更新 第四步开新会话读取状态文档从“断点”继续这个顺序的核心是这样一条原则先跑通再优化先把外部状态做好再依赖工具内部的记忆能力。注意不要一上来就把批量任务和长时自动化拉满。持久化的价值在于可控而不是让代理在后台无限运行。5. 持久模式的工程难点决定了它不会一开始就完美5.1 状态存哪里、存什么、谁有权限如果持久模式要把状态持久化到本地那“存在哪里”就是一个非常现实的问题。是存在项目目录里还是存在用户配置目录里是多项目共享一个状态仓库还是每个项目单独隔离如果状态文件包含代码路径、依赖信息、环境变量那是否应该有权限控制如果是团队协作多个开发者是否能访问同一个状态仓库这些都不是小问题。状态存错了位置轻则隐私泄露重则把项目环境搞乱。比如代理把本机的环境变量写进状态文件然后被其他项目读取可能引发完全不同的问题。从工程角度看我更偏好“项目目录内、明确命名、可忽略”的文件方案类似.codex/目录。它既能在本地跟踪又能通过 .gitignore 排除不会污染代码仓库。5.2 上下文窗口不可能无限增长即使可以在本地保存很多状态模型本身的上下文窗口仍然是有限的。持久模式如果要长期运行一定会遇到“历史信息太多放不进上下文”的问题。解决这个问题通常有三种思路截断只保留最近 N 轮对话。优点是实现简单缺点是把更早的重要决策忘掉了。摘要把历史内容浓缩成一段结构化的摘要。优点是能保留核心信息缺点是摘要过程会损失细节。检索把历史状态向量化按需读取。优点是在信息量和成本之间取得平衡缺点是引入了额外的检索基础设施。如果是测试阶段可以先观察它采用的是哪种策略。如果只是简单截断那持久模式的价值会大打折扣。如果能做摘要或检索那就意味着它真的在尝试维护长期任务状态。5.3 陈旧状态会让“记住”变成“误导”持久化还有一个隐藏风险状态过期。比如代理在三天前记住了“这个模块使用 MySQL 数据库”但现在数据库已经切换成了 PostgreSQL。如果代理没有检查最新代码只知道读取旧状态就会给出完全错误的修改建议。这是比“记不住”更危险的问题。因为“不记得”至少会促使代理重新探查项目而“记住了但记错了”会让代理自信地做错误决策。所以持久模式真正考验的不只是存储和读取能力还有状态失效检测和更新机制。一个可靠的持久化代理应该在发现现实与状态不一致时主动说“这里的记录已经过时我需要重新验证”而不是闷头继续执行。注意任何持久的记忆都可能陈旧。在使用代理输出前先让关键决策回到代码、测试和文档上去验证而不是直接采信。6. 使用边界谁适合、谁不适合、怎么开始6.1 真正值得用持久模式的场景从现有编码代理的使用规律看有几类场景特别值得尝试。第一类是大型重构项目。重构往往持续数天涉及多个模块决策链条很长。如果没有持久状态每次会话都要重新解释现状效率极低。第二类是“维护型任务”集中的项目。比如持续修 bug、补测试、改进文档的项目。代理可以通过持久模式逐渐积累对项目的理解越用越熟练。第三类是团队需要“可追溯自动修改”的项目。持久模式如果能把历史决策记录下来代码审查者就能看到代理为什么这样做而不是只看到一段改动。6.2 不要追着“持久”跑的场景反过来有些场景其实不太需要持久模式。一次性的探险式提问不需要。比如“这个第三方库有哪些已知坑”这类问题跟项目状态无关开新会话反而干净。临时验证也不需要。比如“这个正则表达式写法对不对”“这行代码的覆盖率是多少”。这些任务一旦完成就没有继续维护状态的意义。还有一个小众但很现实的场景如果项目里存在大量敏感信息比如密钥、客户数据、内部网络结构就不要轻易让代理把状态持久化到本地。因为“状态越完整泄露面越大”。6.3 测试阶段怎么做比较稳妥目前公开信息还看不出持久模式的具体实现方案更多是刚进入测试阶段。在这种状态下我的建议是不要直接在重要生产项目上全面铺开而是先在局部场景里验证。你可以从这三个问题开始它能不能准确维护“任务进度”而不是“聊天记录”跨会话恢复后它能不能主动读取项目状态并继续执行当项目实际状态和它的记忆不一致时它会不会重新校验如果这三个答案都是肯定的那这个功能已经具备进入日常开发的基本条件。如果答案是否定的那它现阶段更像一个尚在验证阶段的实验品可以保持关注但不必强行依赖。7. 我的判断持久模式不会替代人的判断但它会改变工具的使用方式持久模式这个名字容易让人产生一种期待以后代理可以一直运行自动完成所有事情。我的看法是这个方向最终会让人和工具的分工发生变化但不是把“人的判断”省掉。它真正改变的是我们和工具之间需要重复交接的部分。过去每次新会话都要从零解释背景未来这个成本有望被压到极低。代理负责维护状态人类负责校正方向。这更接近一个合理的协作关系。长期来看编码代理的竞争力不只取决于模型推理能力还取决于它对自己工作状态的管理能力。一次能解出多难的算法题只是一个维度的比拼能在真实项目里持续运行、恢复、更新状态、保持可追溯性是另一个维度的比拼。持久模式如果走通等于是在第二个维度上给编码代理补上了一块关键拼图。现在更值得做的不是急着给所有任务开启持久运行而是先梳理清楚你自己真正需要跨会话维护的任务是什么。然后尝试用一个简单的状态文档让代理记住关键进度。等工具本身的持久模式足够成熟再迁移过去。不要高估持久记忆的价值也别低估跨会话连续性对开发效率的影响。对一个长期在一线写代码的人来说这两者之间的分寸可能才是真正决定开发体验的东西。