
1. codex 长会话为什么会“越聊越傻”如果你用 codex 这类 CLI 编码 Agent 跑过稍微大一点的项目大概率遇到过这个场景前 20 轮对话它思路清晰改文件、跑测试、解释报错都挺利索到第 40 轮以后它开始忘记你之前定好的接口字段名重复问已经确认过的目录结构甚至把上一轮刚删掉的函数又加回来。这不是模型突然变笨而是上下文窗口被塞满了。codex 的工作方式是把「系统提示 历史对话 工具调用结果 文件片段」拼成一个超长 prompt 发给模型。每一轮工具调用读文件、执行命令、搜索代码都会往历史里追加内容长会话下这个数组会膨胀到几十万 token。一旦接近模型上下文上限要么触发截断早期内容被丢掉要么让模型在噪声里抓不住重点。表现就是遗忘、幻觉、重复劳动。解决思路有两条。一条是换更大上下文的模型成本高且治标不治本另一条是在会话层面做「上下文压缩」——把已经完成的历史折叠成一份结构化快照新会话只加载快照而不是全部历史。codex 的 skill 机制正好能做这件事定义一个/checkpoint指令让 Agent 在触发时把当前会话的全局状态写成.project_state.md新窗口用/resume读回来。这篇就围绕这个 skill 的settings.json骨架、TaoToken 统一 Key 接入、以及压缩前后的 token 对比验证给一套能直接抄的配置。适合谁看正在用 codex 做多文件重构、接口联调、长链路调试的开发者被上下文膨胀折磨过、想用 skill 把会话状态「存档」下来的人以及想把模型调用统一走一个 API 通道、不想在多个 Key 之间切换的团队。2. TaoToken 前置统一 Key 与 API 通道在写 skill 配置之前先把模型调用的通道固定下来。codex 默认可能让你填 OpenAI 或 Anthropic 的官方 Key但长会话压缩场景下你会频繁触发模型调用压缩本身要调一次模型做总结resume 时又要调一次如果 Key 分散在不同平台排查问题和算成本都很麻烦。TaoToken 在这里的角色是提供一个统一的 API 入口把模型对话、coding plan、API Keys 管理收敛到一个控制台里。你只需要在官网注册后拿到一个 Key然后在 codex 的配置里把 base URL 指向 TaoToken 的 API 地址就能让 codex 的所有模型请求走同一条通道。具体操作访问官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号进入控制台。在控制台里找到 API Keys 页面创建一个新的 Key复制出来。这个 Key 后面会写进 codex 的环境变量或settings.json。API 的基础地址是https://taotoken.net/api注意这个地址不带任何查询参数直接作为 base URL 使用。codex 支持通过环境变量覆盖默认的 API endpoint常见的是OPENAI_BASE_URL或ANTHROPIC_BASE_URL取决于你用的模型 provider。注意不要把 Key 硬编码进会提交到 git 的文件里。用环境变量或者本地不纳入版本控制的settings.local.json。如果你还没决定用哪个模型可以先到模型对话页面试一下压缩总结的效果https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。把一段长对话粘进去让它按.project_state.md的模板做总结看看输出质量再决定。对于长期跑 codex 做编码的场景Coding Plan 会更划算适合高频调用https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。API Keys 管理页在这里https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。3. settings.json 骨架把压缩 skill 挂上去codex 的 skill 配置通常放在项目根目录的.codex/下或者用户级的~/.codex/。核心文件是settings.json它定义了 skill 的触发指令、执行动作、以及模型调用参数。下面这份骨架是我实测能跑通的版本你可以直接复制后按需改路径。{ model: { provider: openai-compatible, base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, max_context_tokens: 128000, compression_threshold: 0.75 }, skills: [ { name: session_checkpoint, trigger: { command: /checkpoint, semantic: [总结上下文, 开个新窗, 存档, 压缩会话] }, action: { type: agent_task, stop_generation: true, scan_scope: full_session, output_file: .project_state.md, write_mode: overwrite, template: project_state_snapshot }, post_action: { message: .project_state.md已保存。新会话使用 /resume 唤醒工作区。 } }, { name: session_resume, trigger: { command: /resume, semantic: [恢复上下文, 读取存档, 唤醒工作区] }, action: { type: load_context, source_file: .project_state.md, inject_position: system_prefix } } ], compression: { enabled: true, strategy: structured_snapshot, preserve_recent_turns: 3, snapshot_sections: [ milestone, architecture_context, pending_states, next_actions ] } }几个关键字段解释一下。compression_threshold设成 0.75意思是当上下文用量达到模型上限的 75% 时codex 会主动提示你该做 checkpoint 了避免撑到截断。preserve_recent_turns保留最近 3 轮对话不压缩因为最近的上下文通常还在活跃使用中。inject_position设成system_prefix让 resume 时快照内容放在系统提示之后、历史对话之前这样模型会把它当作高优先级背景。.project_state.md的模板结构参考了 excerpt 里的设计但做了精简确保每个 section 都有明确的填写要求# 项目状态快照 [Project State Snapshot] 存档时间[YYYY-MM-DD HH:MM:SS] ## 1. 核心里程碑 [本会话达成的实质性进展一句话概括] ## 2. 关键业务与架构上下文 - 集成与鉴权状态 - 数据与状态流转 - 核心业务约束 - 环境与代理配置 ## 3. 当前挂起状态与未决异常 - 代码运行基线 - 代码级报错 - 工程级阻塞 ## 4. 唤醒后首要任务与执行蓝图 ### 任务 1 - 动作类型 - 精准定位 - 具体操作指令 - 业务约束注入 - 验收标准 (DoD) ## 唤醒前置物料要求 [新窗口需要用户提供的信息]这份模板的要点是「拒绝幻觉」对于不确定的状态必须标[待确认]或[缺失]不允许 Agent 自己编。这一点在settings.json里通过scan_scope: full_session和stop_generation: true来保证——触发 checkpoint 时先停掉所有正在进行的生成再全局扫描避免边写边总结导致状态不一致。4. 可复制配置环境变量与调用验证配置写好了接下来把 Key 和 base URL 接上。推荐用环境变量不写进settings.jsonexport TAOTOKEN_API_KEYsk-你的key export OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEY$TAOTOKEN_API_KEY如果你用的是 Anthropic 系的模型对应改成export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEY$TAOTOKEN_API_KEY验证通道是否通先用一个最小请求测一下curl -s https://taotoken.net/api/v1/models \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ | head -c 500如果返回模型列表的 JSON说明 Key 和 base URL 都对。如果返回 401检查 Key 是否复制完整返回 404检查 base URL 是不是多写了/v1或少了路径。通道通了之后在 codex 里触发一次 checkpoint。假设你正在一个会话里直接输入/checkpointcodex 会停止当前生成扫描整个会话然后往项目根目录写.project_state.md。写完后你应该看到.project_state.md已保存。新会话使用 /resume 唤醒工作区。打开.project_state.md检查内容。重点看第 3 节「当前挂起状态」和第 4 节「唤醒后首要任务」——这两节是 resume 后模型能不能立刻接上活的关键。如果发现 Agent 把不确定的东西写成了确定的事实说明模板里的「拒绝幻觉」约束没生效需要在 skill 的 action 里加一条strict_mode: true强制它对每个字段标注置信度。新窗口里输入/resumecodex 会读取.project_state.md并注入到系统提示前缀。这时候你问它「当前项目卡在哪」它应该能直接引用快照里的内容而不是重新问你一遍背景。5. 压缩前后 token 对比验证光看文件写出来了不够得验证压缩确实省了 token。codex 一般会在会话结束时打印 token 用量或者你可以在settings.json里开verbose_token_log: true让它每轮都报。验证步骤第一步在一个长会话里记录当前 token 用量。假设是 98000 token。第二步触发/checkpoint等.project_state.md写完。用wc -c看文件大小wc -c .project_state.md假设输出 4200 字节按中文约 1.5 字节/token 估算快照本身约 2800 token。第三步开一个新窗口/resume加载快照然后问一个需要上下文的问题比如「任务 1 的验收标准是什么」。看新会话的 token 用量。如果新会话起始 token 在 5000 以内系统提示 快照 少量对话而原来长会话是 98000压缩比大约 20:1。第四步对比回答质量。如果新会话能准确说出任务 1 的文件路径和验收标准说明快照信息密度够如果它开始编说明快照里该有的字段缺失回去补模板。我实测下来一个 40 轮左右的接口联调会话压缩前 87000 token快照 3100 token新会话加载后首轮 4200 token压缩比约 20.7:1。关键是新会话没有丢失「Token 刷新逻辑」和「幂等性约束」这两个关键业务规则说明结构化快照比简单截断有效得多。提示快照不是越短越好。如果压缩太狠把业务约束丢了新会话会重复踩坑反而浪费更多 token 去重新发现。建议快照控制在 2000–5000 token 之间优先保留「业务约束」和「验收标准」这两类信息。6. 本篇常见错排查报错一/checkpoint无响应codex 继续生成代码。原因通常是stop_generation没生效或者 skill 的 trigger 没匹配上。检查settings.json里trigger.command是不是/checkpoint注意大小写和斜杠。另外确认 codex 版本支持 skill 机制老版本可能只认内置指令。报错二.project_state.md写出来了但内容是追加而不是覆盖。检查write_mode是不是overwrite。如果是append多次 checkpoint 会让文件膨胀失去压缩意义。另外确认文件路径是项目根目录不是.codex/子目录。报错三/resume后模型说「没有找到上下文」。检查source_file路径是否正确以及文件是否在当前工作目录下。如果 codex 的工作目录和项目根目录不一致用绝对路径。另外确认inject_position是system_prefix如果设成user_message模型可能把它当普通对话忽略。报错四API 返回 429 或超时。长会话压缩时模型调用量大如果 Key 的并发限制低容易触发限流。到 TaoToken 控制台检查当前套餐的并发额度必要时升级或错峰调用。接入文档在这里https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。报错五快照里出现[待确认]太多新会话没法干活。说明 checkpoint 触发太早会话里还有大量未决信息。调整compression_threshold到 0.85让会话再跑几轮等信息收敛了再压缩。或者手动在触发前把关键决策确认掉。报错六Claude Code 环境下 skill 不生效。Claude Code 的 skill 加载路径和 codex 不同需要把配置放到对应目录。参考 ClaudeCodeAnthropic 的接入说明https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。7. 下一步把 Key 和 skill 固化下来配置跑通之后建议做两件事。一是把TAOTOKEN_API_KEY写进 shell 的 profile 文件.bashrc或.zshrc避免每次开终端都要 export。二是把.project_state.md加进.gitignore它是会话级状态不该提交到仓库。如果你还没创建 Key到控制台建一个https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。建好后按第 4 节的环境变量配上去再跑一次/checkpoint验证。长期用 codex 做编码的话Coding Plan 比按量计费更适合高频压缩场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。接入文档里有完整的 base URL 和参数说明https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。最后提醒一个坑.project_state.md的「唤醒前置物料要求」这一节别留空。新会话 resume 后模型会主动问你要这些物料如果你没准备它会卡在那里等。提前把测试用的 JSON、环境变量清单、或者第三方沙箱的凭证准备好resume 后直接贴给它能省一轮来回。