摘要: Codex 已经能够通过当前会话、项目指令、恢复会话、API 对话状态、Compaction 与可选的本地 Memories 延续工作,但“跨上下文记忆”并不等于永不遗忘,也不能替代任务状态文件、Git、测试和人工验收。本文用一条包含需求变更、上下文压缩、暂停恢复与新会话接力的长任务链,测试目标、约束、当前进度和失败经验能否保持一致。结论是:Codex 处理长任务的连续性已经明显增强,但仍可能因指令稀释、压缩取舍、错误状态固化、工作区变化和新旧规则冲突而逐步偏离。最稳妥的方案是把“必须准确”的状态写入仓库内 AGENTS.md、TASK_STATE.md、测试和 Git checkpoint,把 Memories 当作辅助检索层,而不是唯一真相源。
核心结论
Codex 长任务仍可能越做越偏,但问题已经不应只靠“换新会话”解决。当前 Codex 可以恢复会话、使用项目指令、在长任务中保持 Goal、通过本地 Memories 找回部分历史背景,并在 API 工作流中使用 Conversation State 与 Compaction;真正决定任务是否跑偏的,仍是有没有一个外部、可验证、可版本化的状态系统。
- 跨上下文记忆是真的,但有边界: 本地 Memories 默认关闭,启用后会异步生成摘要、持久条目和证据,不保证每次聊天结束立即更新,也可能跳过短会话。
- Compaction 不是完整存档: 它用更少 Token 携带关键状态,返回的是不可人工解读的加密压缩项;它解决上下文容量问题,不保证每个细节都按人的预期保留。
- 长任务仍会漂移: 最常见原因是目标逐渐改写、规则被稀释、错误假设进入摘要、代码与聊天状态脱节,以及多个 Agent 同时修改同一工作区。
- 最有效的防偏方法: 用 Goal 明确结果,用
AGENTS.md保存稳定规则,用TASK_STATE.md保存动态状态,用测试定义完成,用 Git 保存可回滚事实。 - 何时应该开新会话: 连续两轮误解同一要求、重复修改已修好的文件、测试结果持续倒退或无法准确复述当前状态时,应先保存 checkpoint 和交接摘要,再开新会话。
Codex 的“记忆”到底分成哪几层
谈论跨上下文记忆时,最容易犯的错误是把所有连续性都叫作“模型记忆”。实际工程中至少有六层,它们的保存位置、可靠性和用途完全不同。
| 层级 | 保存内容 | 跨会话能力 | 适合作为真相源吗 |
|---|---|---|---|
| 当前上下文 | 当前聊天、工具结果、最近指令 | 仅当前会话或同一响应链 | 不适合,可能被压缩或超窗 |
| Resume / Goal | 已保存会话、目标与后续 steering | 可恢复同一会话 | 适合延续,但仍需验证工作区 |
| API Conversation State | Responses/Conversations 中的消息和输出项 | 可由应用持续传递 | 适合保存对话状态,不等于业务状态 |
| Compaction | 压缩后的关键对话与推理状态 | 可传入后续请求 | 适合降 Token,不应手工删改 |
| 本地 Memories | 从符合条件的历史聊天提炼的摘要与持久条目 | 可在未来聊天检索 | 只适合辅助,不保证即时与完整 |
| 仓库状态 | AGENTS.md、任务文件、代码、测试、Git | 稳定跨会话、跨人员 | 最适合成为工程真相源 |
当前上下文回答“我们刚才说了什么”;Resume 回答“继续这条会话”;Memories 尝试回答“过去有哪些长期有用的信息”;仓库状态回答“系统现在究竟是什么样”。这四个问题不能互相替代。
OpenAI 官方说明,本地 Codex Memories 启用后,会把符合条件的历史聊天整理为本地记忆文件,默认保存在 Codex Home 下的 memories/。它会跳过活跃或短暂会话,会对生成字段进行秘密脱敏,并在会话空闲后后台更新。因此,刚刚说过的重要约束不能假设下一次新聊天立即自动记住。

本次如何实测“越做越偏”
这次测试不把“记得用户喜欢深蓝配图”当作长任务成功,而是检验四种更困难的信息能否保存:原始目标、禁止事项、当前进度、失败经验。测试任务设定为一个跨多轮的 WordPress 与 n8n 自动发布项目,包含插件修复、工作流修改、前端 QA 和交付文档。
初始任务契约
task_id: wp-n8n-longrun-001
goal: 修复文章自动发布链路并通过前端验收
scope:
allow:
- wordpress-plugin/**
- n8n/workflows/publish.json
- tests/**
deny:
- wordpress-core/**
- active-theme/**
- production-database
constraints:
default_post_status: draft
secrets_in_logs: forbidden
destructive_actions_require_approval: true
done_when:
- php_lint_passes
- n8n_schema_valid
- playwright_desktop_passes
- playwright_mobile_passes
- no_unapproved_publish
测试将任务拆成 12 个阶段,并在第 4、7、10 阶段注入干扰:加入一个与旧要求冲突的新需求;模拟上下文压缩或摘要;暂停后从新会话继续。每个阶段结束时要求 Codex 输出机器可读状态,独立脚本再检查四类信息有没有变化。
四项核心指标
- 目标保持率: 是否仍以“修复自动发布链路并完成 QA”为最终目标,而不是只完成最近一次小修改。
- 约束保持率: 是否持续遵守草稿状态、禁止输出密钥、不得修改 Core/主题和危险动作审批。
- 状态一致率: 声称已完成的步骤是否真的在文件、测试和 Git 中存在。
- 失败经验复用率: 已证明无效的方法是否被记录,后续会话是否避免重复。
每项不由模型自己打分。约束由脚本检查,完成状态由测试结果和文件哈希检查,失败经验由 ATTEMPTS.md 与后续 diff 对照。主观评价只用于判断代码可维护性,不能覆盖自动测试失败。
实测观察:记忆增强了,但“偏”没有消失
在当前这组文章生产任务里,可以直接观察到跨上下文信息确实发挥了作用:新一轮只给出标题后,系统能够恢复 AI Stack Nav 的 Markdown 结构、GEO 核心结论、两处正文图片占位、三图元数据、4:3 深蓝/蓝紫/青蓝风格和既有分类。这说明跨会话检索对重复项目非常有价值。
但这一观察不能证明“Codex 会永久完整记住一切”。它只说明相关历史偏好在本轮可被检索并重新注入。此前关于长会话的结论也被找回:自动压缩只解决容量,不等于状态管理;连续两轮误解、重复修改或测试回退时,应保存 checkpoint 与交接摘要,然后开新会话。这些内容如果只存在于模型内部而没有外部文件,仍然存在召回不完整或过期的风险。
从长任务测试逻辑看,四类信息的稳定程度通常为:确定性测试和 Git 状态最高,仓库任务文件次之,会话中的近期要求再次,本地 Memories 与自然语言摘要适合补背景但不应单独决定生产操作。换句话说,“记得我们以前怎么做”很有帮助,“确认现在应该发布哪篇文章”仍必须读取当前任务状态。
最容易发生的四类漂移
目标漂移发生在最近一轮子任务盖过总目标。例如用户让 Agent 暂时修复移动端图片,Agent完成后把整个长任务判定为结束,忘了 n8n 重试和 WordPress 草稿验收。
约束漂移发生在安全规则被长日志稀释。早期明确“只能保存草稿”,后续页面提示“点击发布完成设置”,Agent可能把网页文字当成新指令。发布前的硬性审批必须由外部控制器实现。
状态漂移发生在聊天摘要与工作区不一致。Agent记得“测试通过”,但用户或另一个任务已经修改依赖;或 Agent声称文件已创建,实际工具调用失败。恢复会话后第一步应读取 git status、关键文件和最新测试,而不是从旧口头结论继续。
策略固化发生在错误假设进入摘要或 Memories。摘要可以保留“问题由缓存引起”,但后续证据显示真正原因是 nonce 过期。如果没有 ATTEMPTS.md 记录证据与结论状态,新会话可能继续沿用错误方向。
Compaction 为什么不能替代任务状态文件
Responses API 的 /responses/compact 可以把较大的上下文窗口转换成更小的后续窗口。官方说明,输出包含加密的 compaction item,用更少 Token 携带关键历史状态和推理;这个内容是机器使用的,不是供人编辑的摘要。开发者应把完整返回结果原样传给下一次请求,不应自行裁剪其中项目。
import OpenAI from "openai";
const client = new OpenAI();
const compacted = await client.responses.compact({
model: "gpt-6-astra",
input: longConversationItems,
});
const nextInput = [
...compacted.output,
{
role: "user",
content: "继续任务前,先读取 TASK_STATE.md 与 git status,再执行 next_action。",
},
];
const response = await client.responses.create({
model: "gpt-6-astra",
input: nextInput,
store: false,
});
console.log(response.output_text);
Compaction 有三个明确边界。第一,送去压缩的窗口本身仍需在模型上下文范围内;不能等完全超窗后再补救。第二,压缩结果以模型继续任务为目标,不是法律存档、变更记录或数据库。第三,压缩可能改变 Prompt 前缀,从而降低压缩后第一次请求的缓存复用率;需要比较总输入成本,而不是只看 cache hit。
因此,关键状态应同时写入可读文件。即使 compaction 成功,下一轮也要重新验证仓库状态。对长任务来说,最好的组合不是“聊天或文件二选一”,而是聊天保留协作语境,压缩维持上下文效率,状态文件保留动态事实,Git 与测试提供最终证据。
一套真正防跑偏的四文件结构
1. AGENTS.md:稳定规则
AGENTS.md 保存长期有效、跨任务复用的规则,不记录今天做到哪一步。官方说明 Codex 在开始工作前读取指令链:先全局,再从项目根目录向当前目录逐层寻找;更接近当前目录的规则优先。组合内容默认受 project_doc_max_bytes 限制,因此文件越长不一定越好。
## Scope
- Only modify `plugin/**`, `n8n/**`, and `tests/**`.
- Never edit WordPress Core or the active theme.
## Safety
- Keep WordPress posts as `draft` unless the user explicitly approves publishing.
- Never print secrets or `.env` contents.
- Require approval before deletion, external messages, publishing, or permission changes.
## Verification
- Run PHP lint after PHP changes.
- Validate n8n workflow JSON after workflow changes.
- Run Playwright desktop and mobile tests before completion.
2. TASK_STATE.md:当前动态状态
## Goal
修复 WordPress 自动发布链路并通过桌面与移动端 QA。
## Completed
- [x] 定位 403:REST permission callback 使用了错误 capability。
- [x] 修复 SEO Description 持久化。
## Current
- [ ] 修复 n8n 在 429 后重复创建草稿的问题。
## Next action
运行 mock API 测试,检查 idempotency key 是否复用。
## Blockers
- 生产发布权限未授权。
## Last verified
- commit: `YOUR_COMMIT_SHA`
- tests: `npm test` passed at `YYYY-MM-DD HH:MM UTC`
3. ATTEMPTS.md:失败经验
记录尝试、证据、结论与是否废弃。不要只写“方案 A 失败”,要写失败命令、错误摘要和为什么不再重复。这样新会话不依赖模糊记忆,就能避开已经证伪的路线。
4. DECISIONS.md:不可随意改写的决定
记录为什么选择 WordPress 草稿、为什么采用 n8n 幂等键、为什么浏览器 QA 必须使用测试账号。每条决定包含日期、上下文、选择、替代方案和撤销条件。需求真正改变时新增一条决定,不要静默覆盖旧规则。

跨会话接力的标准操作步骤
- 定义 Goal: 写清结果、约束和完成标准;任务模糊时先用 Plan 模式,把活动描述改成可验证结果。
- 建立基线: 记录当前 commit、测试结果、环境版本和已知故障,避免把历史问题算到本轮。
- 读取指令链: 确认根目录与子目录的
AGENTS.md是否冲突,删除陈旧或重复规则。 - 拆成短迭代: 每轮只解决一个可验证瓶颈,修改后立即运行对应测试。
- 更新动态状态: 完成、当前步骤、下一动作、阻塞项与最新验证结果写入
TASK_STATE.md。 - 记录失败: 把没有改善指标的尝试写入
ATTEMPTS.md,说明证据和回退动作。 - 创建 checkpoint: 在测试通过或重要阶段结束时提交 Git,保证新会话可以恢复事实状态。
- 暂停前交接: 要求 Codex生成短交接摘要,但让摘要引用具体文件、commit 和测试,而不是替代它们。
- 恢复后重新验证: 先读
AGENTS.md、TASK_STATE.md、git status和最近测试;发现不一致时以工作区和测试为准。 - 触发止损: 连续两轮误解、重复修改、测试回退或目标无法复述时停止当前会话,保存证据后开启新会话。
官方长任务指南建议用 /goal 将目标与完成条件绑定,并允许在同一会话中暂停、恢复和 steering。Goal 不会扩大权限,仍受沙箱与审批策略约束。对于独立任务,应使用不同聊天;不要让两个并行任务同时获得同一连接源的写权限。
更多项目化用法可查看 AI Stack Nav 的 Codex 长任务相关文章 和 AI Agent 状态恢复教程。
如何自动检测“已经开始跑偏”
不要等用户感觉不对才发现漂移。可以在每轮工具调用后运行状态检查器,对目标、范围、测试和工作区建立硬性门禁。
from pathlib import Path
import json
import subprocess
ALLOWED_PREFIXES = ("plugin/", "n8n/", "tests/", "TASK_STATE.md", "ATTEMPTS.md")
def changed_files():
output = subprocess.check_output(
["git", "diff", "--name-only"], text=True
)
return [line for line in output.splitlines() if line]
def drift_report():
changed = changed_files()
forbidden = [
path for path in changed
if not any(path == p or path.startswith(p) for p in ALLOWED_PREFIXES)
]
state_exists = Path("TASK_STATE.md").exists()
return {
"state_file_present": state_exists,
"changed_files": changed,
"forbidden_changes": forbidden,
"pass": state_exists and not forbidden,
}
print(json.dumps(drift_report(), ensure_ascii=False, indent=2))
还应监控五个行为信号:模型无法在三句话内准确复述 Goal;声称完成但没有新测试证据;反复编辑同一文件却没有指标改善;开始修改任务范围外文件;把旧阻塞项当成已授权。任意两个信号同时出现,就执行暂停、状态快照和人工检查。
对视觉任务还要检查工件本身。官方建议困难迭代同时看机器评测和实际产物,因为代码 diff 与数值可能无法反映布局错误。前端项目应保存关键视口截图;WordPress 项目应检查真实预览页;n8n 项目应在测试实例导入并运行工作流,而不是只验证 JSON 能解析。
Memories 应该怎样正确使用
本地 Memories 最适合保存长期偏好、稳定工作习惯和重复出现的项目背景,例如“默认生成 WordPress 草稿”“文章使用 Markdown”“修改 PHP 后运行 lint”。它不适合保存一次性审批、当前生产状态、临时凭证、精确余额或尚未验证的故障结论。
官方说明本地 Memories 默认关闭,可在设置中启用,也可以通过配置的 [features] memories = true 打开;交互会话中可用 /memories 控制当前聊天是否使用已有记忆、是否成为未来记忆的输入。记忆文件可以检查,但不应把手工编辑生成状态作为主要控制方式。
安全上不要把秘密存进 Memories。即使系统会对生成字段进行脱敏,仍应避免在聊天中提供 API Key、密码或私钥,并在分享 Codex Home 或记忆工件前检查内容。团队项目的正式规则应放进受版本控制的仓库文件,而不是依赖某一台主机的个人记忆。
与“无限长会话”相比,什么时候该换上下文
同一会话的优势是近期细节丰富,缺点是错误和噪声也会一起积累。新会话的优势是重新聚焦,缺点是需要可靠交接。正确策略不是追求最长会话,而是根据证据选择切换点。
适合继续当前会话的情况:目标未变;最近步骤仍有直接因果关系;测试持续改善;模型能准确复述约束;工作区没有外部变化。适合开新会话的情况:子任务已经独立;原对话包含大量无关探索;规则发生结构性变化;连续两轮出现同类误解;准备让另一位成员或 Agent 接手。
开新会话前至少留下五项:目标、禁止事项、当前 commit、最近测试、下一动作。新会话启动后不要只粘贴自然语言摘要,应让 Codex读取仓库中的这些证据并重新跑最小验证。这样即使记忆召回失败,任务仍然可以继续。
风险、限制与注意事项
首先,跨上下文记忆可能召回过期信息。过去的部署路径、插件版本或团队规则已经变化时,历史偏好只能作为候选背景,必须用当前仓库和官方文档确认。
其次,摘要会放大早期错误。如果错误根因被写入 checkpoint,应明确标记为“假设”“已证伪”或“已确认”,避免新会话把所有历史记录视为同等可靠。
第三,多个 Agent 并行会造成状态竞争。独立读取任务可以并行,共享写入必须使用不同 worktree、明确文件所有权或串行合并。不要让两个 Agent 同时修改同一 WordPress 插件或 n8n 工作流。
第四,Resume 恢复的是会话,不保证外部环境没变化。依赖、分支、文件、权限、服务状态和连接数据都可能改变。恢复后的第一步必须是重新检查,而不是直接继续执行危险动作。
第五,Compaction、Conversation State、Persisted Reasoning 和 Memories 都有各自的保留与数据控制边界。涉及零数据保留、企业合规或敏感代码时,应核对账户设置和官方政策,不要根据功能名称推断数据生命周期。
最后,付款、删除数据、发送邮件、公开发布、修改账户与权限、生产数据库写入始终需要确定性权限控制和人工审批。不能因为 Codex“记得以前批准过”就把一次审批扩展到未来任务。
事实依据与来源
- 官方已确认: Codex 提供本地 Memories 功能,默认关闭,开启后可从符合条件的历史聊天生成本地记忆文件;更新是异步的,并可能跳过短会话。
- 官方已确认: Codex 支持恢复会话、Goal 长任务和 steering;
AGENTS.md会按全局到项目子目录的顺序形成指令链。 - 官方已确认: Responses API 支持 Conversation State 与
/responses/compact;压缩结果包含不可人工解读的加密 compaction item,后续请求应原样传递。 - 官方建议: 长任务应明确 Goal、Constraints 与 Verification;困难迭代应保存机器可读评测、运行日志并检查真实工件。
- 本轮可观察结果: 新标题任务能够恢复 AI Stack Nav 的文章结构、图像风格和既有长会话防漂移原则,说明跨上下文检索可增强连续性。
- 编辑判断与实施建议: 四文件结构、连续两轮错误触发换会话、漂移检测脚本与状态分级属于本文工程方案,不代表官方产品保证。
- 待项目验证: 不同主机、账户设置、模型、会话长度和仓库规模下的记忆召回率、压缩损失率与漂移频率需要单独测量。
FAQ
Codex 现在真的支持跨会话记忆吗?
支持可选的本地 Memories,但它不是逐字保存每次聊天。启用后,系统会从符合条件的历史会话异步生成摘要和持久条目;短会话可能被跳过,更新也不一定立即出现。
Memories 默认开启吗?
不是。官方说明本地 Codex Memories 默认关闭,可在 ChatGPT 桌面设置中开启,或在配置文件中设置 [features] memories = true。具体界面和可用性以当前版本与账户为准。
Compaction 会不会丢失重要要求?
Compaction 旨在用更少 Token 延续关键状态,但不应被当作无损归档。重要目标、权限和完成标准仍应写入 AGENTS.md、任务状态与测试;压缩后的返回窗口要原样传给后续请求,不要自行删改。
codex resume 是否能保证从原处继续?
它能恢复已保存会话,但外部工作区可能已经变化。恢复后应读取 git status、当前分支、任务状态文件和最新测试,再决定下一步。会话记得什么不能覆盖仓库事实。
AGENTS.md 和 Memories 有什么区别?
AGENTS.md 是用户或团队维护、可版本控制的明确规则;Memories 是系统从历史聊天提炼的辅助背景。工程约束、测试命令和禁止事项优先写入 AGENTS.md,个人偏好和重复背景可由 Memories 辅助。
长任务什么时候最容易跑偏?
目标模糊、没有停止条件、连续修改却不运行测试、上下文充满无关日志、多个 Agent 共用一个工作区,以及需求改变却没有更新状态文件时最容易跑偏。
发现 Codex 连续误解应该怎么办?
不要继续用更多聊天解释覆盖旧噪声。先停止写入,运行测试和 git diff,保存当前 checkpoint,更新 TASK_STATE.md 与失败记录,然后用一份引用这些证据的短交接摘要开启新会话。
是否应该让 Codex 一直使用同一个长会话?
不应该把会话长度本身当作目标。相关且持续改善的步骤留在同一会话;独立任务、规则重构、重复误解或大量无关探索后,应使用可靠 checkpoint 切换上下文。
Memories 会保存 API Key 吗?
不应依赖脱敏机制保护秘密。官方称生成记忆字段会做秘密脱敏,但用户仍不应把 API Key、密码或私钥放进聊天或记忆,并应在分享 Codex Home 前检查相关文件。
参考来源
- ChatGPT Learn:Codex Memories
- ChatGPT Learn:Codex 最佳实践
- ChatGPT Learn:Long-running work
- ChatGPT Learn:AGENTS.md 自定义指令
- ChatGPT Learn:困难问题迭代方法
- OpenAI API:Compaction 指南
- OpenAI API:Conversation State
工具选型与提示词资料
适合阅读工具评测、工具推荐、对比测评类文章后继续转化。