资讯详情

Codex 上下文压缩机制:先限流工具输出,再用本地或远端 compaction 接续任务

📅 2026/10/13 0:00:18 | 华诺云谱 👁 阅读
Codex 上下文压缩机制:先限流工具输出,再用本地或远端 compaction 接续任务
1. Codex 长会话为什么会撑爆上下文工具输出限流与 compaction 的真实链路Codex 上下文压缩机制说白了就是一套让长任务能跨过 context window 限制继续跑的续航方案。它能做什么把几万行终端输出、几十轮工具调用、反复的 diff 和测试结果收拢成一份能接续任务的压缩表示。适合谁适合用 Codex 跑长链路工程任务的人——修一个跨多文件的 bug、盯一个 PR 反复跑测试、让 Agent 连续改代码直到通过。我先把结论摆出来Codex 不是把整个 session 永远原样塞回模型。它先控制单个工具输出体积再在上下文接近阈值时压缩 active history。本地压缩有明文 handoff prompt远端压缩没有 Codex 本地可见的明文压缩 prompt。长任务能继续跑靠的是这条链路工具输出限流 - token 使用量达到阈值 - 触发本地或远端 compaction - 压缩结果替换 active history - 下一次请求重新注入当前权限、环境、AGENTS.md、skills、plugins 等运行上下文这里有个容易混淆的点压缩解决的是当前会话的 active context 过大问题不是长期记忆。长期记忆、AGENTS.md、skills、rollout 和 compaction 是不同层。你把它们混在一起想就会得出「Codex 会记住一切」或者「压缩后权限就丢了」这种错误结论。举个真实场景。你说「把失败测试修到通过」模型跑测试终端输出几万行。Codex 不会把这几万行完整放进模型下一轮上下文而是先对工具输出做体积控制。模型后续看到的通常是这种形态Total output lines: 999 EXEC-LINE-0001 ... EXEC-LINE-0002 … 8941 tokens truncated… EXEC-LINE-0998 ... EXEC-LINE-0999这里有三个关键信息。开头保留模型能看到命令最早输出了什么结尾保留模型能看到最终失败、错误尾部、最后状态中间标记模型知道这里发生了截断不会误以为日志本来就这么短。这一步不是 compaction。它发生在 compaction 之前目标是防止单个工具结果先把上下文撑爆。很多人一看到「上下文压缩」就以为只有一层其实 Codex 是两层先限流单条工具输出再压缩整体历史。第一层是预防第二层是收拢。相关配置字段是tool_output_token_limit和truncation_policy。前者可以覆盖模型 metadata 里的默认截断预算后者决定按 bytes 还是 approximate tokens 截断。这段不是模型可见 prompt而是运行时策略。模型并不会「决定要不要截断工具输出」工具返回进入 active history 前Codex 已经做了截断。需要注意这里的 token 是工程近似值不是精确 tokenizer。Codex 用近似预算换取稳定、快速、足够保守的输出控制。你如果拿精确 tokenizer 去核对数字会对不上这是正常的。那为什么限流之后还需要压缩因为即使每个工具输出都被截断整个会话还是会增长用户输入、模型解释、工具调用、工具输出、代码 diff、测试结果、用户纠正、下一轮工具调用……所以 Codex 还需要第二层机制当 active history 接近模型上下文窗口时把旧历史替换成更短的压缩表示。控制这个触发点的是model_auto_compact_token_limit。没有显式配置时Codex 会根据模型 context window 推导默认阈值通常按窗口的 90% 左右触发。比如模型 context window 是 400k默认自动压缩阈值约 360k。压缩触发位置有三类。pre-turn新一轮采样前发现上下文已经太大先压缩再发请求。mid-turn模型刚调用完工具还需要继续 follow-up但上下文已到阈值于是同一轮中途压缩。model-downshift用户切到更小上下文窗口的模型Codex 先按旧模型能力压缩再交给新模型继续。mid-turn 很重要。它解释了为什么长任务中工具循环还没结束时Codex 也能先「收拢上下文」再继续做下一步。你如果只理解 pre-turn就会觉得「一轮没结束怎么压缩」其实 mid-turn 就是为工具循环设计的。2. TaoToken 前置把 Base URL、Key、Model ID 三件套配好在动手调 compaction 之前得先让 Codex 能正常发请求。这一步是把接入信息配齐不是注册教程。你需要三样东西Base URL、API Key、Model ID。缺任何一个后面看到的报错都会指向不同方向排查起来很费时间。TaoToken 的 API 地址是https://taotoken.net/api官网入口是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。API Key 在控制台生成模型对话入口可以用来先验证模型是否通接入文档里有各客户端的配置样例。我建议的顺序是先去模型对话页面发一条最简单的消息确认 Key 有效、模型能回。这一步能排掉 401 和模型名写错两类问题。然后再去配 Codex 的配置文件。Codex 的配置通常落在~/.codex/config.toml认证信息在~/.codex/auth.json。如果你用的是 CC Switch 这类多配置切换工具或者 Cline MCP、Codex auth.json 这套组合记住三件套必须同时对齐Base URL 指向https://taotoken.net/apiKey 用控制台生成的Model ID 用你实际要调的模型名。三者里任何一个和另外两个不匹配都会出现「Key 没错但请求失败」的迷惑现象。这里有个坑我踩过有人把 Base URL 写成带/v1的完整路径有人写成不带/api的裸域名结果一个 404 一个连不上。以接入文档里的样例为准别自己拼。配好之后先别急着跑长任务。用一条短请求验证链路通不通再进入 compaction 的调参环节。顺序反了的话你分不清是配置问题还是压缩问题。3. 可复制配置工具输出限流阈值与 compaction 触发条件这一节给可直接复制的片段。路径和字段名以你本地 Codex 版本为准字段含义按上一节讲的对应。先看工具输出限流。核心是两个字段tool_output_token_limit和truncation_policy。前者是单条工具输出的 token 预算后者决定截断单位。# ~/.codex/config.toml # 工具输出限流控制单条工具结果进入 active history 的体积 tool_output_token_limit 8000 truncation_policy tokens # 可选 bytes 或 tokens # 自动压缩阈值active history 接近该值时触发 compaction # 不写则按模型 context window 的约 90% 推导 model_auto_compact_token_limit 360000tool_output_token_limit调小单条日志截得更狠上下文增长慢但模型可能看不到中间关键错误。调大模型信息更全但更容易提前触发 compaction。8000 是个偏保守的起点你可以按任务类型调。跑测试日志多的任务可以压到 4000 到 6000读代码、看 diff 为主的任务可以放到 12000。truncation_policy选tokens更贴近模型预算选bytes更贴近原始输出体积。两者都不是精确 tokenizer别拿它当计费依据。再看 compaction 触发。model_auto_compact_token_limit是自动触发线。如果你想让压缩更早发生、留更多余量把它调低比如 300000。如果你想让单次会话尽量少压缩、多保留原始历史把它调高但别超过模型窗口否则请求会直接超限报错。如果你用的是 JSON 形式的配置部分客户端或 MCP 场景结构类似{ model: your-model-id, base_url: https://taotoken.net/api, tool_output_token_limit: 8000, truncation_policy: tokens, model_auto_compact_token_limit: 360000 }注意base_url用https://taotoken.net/api不要自己加/v1。model填你实际要调的 Model ID。这三件套和上一节说的一致。关于本地压缩和远端压缩的差异配置层面你控制不了远端行为。远端压缩走 provider 原生能力Codex 不追加本地 handoff prompt。本地压缩才会用那段明文提示词。你能配的是触发阈值和工具输出预算压缩走哪条路由由 provider 决定。本地压缩的 handoff prompt 长这样你可以把它当成理解压缩行为的参照You are performing a CONTEXT CHECKPOINT COMPACTION. Create a handoff summary for another LLM that will resume the task. Include: - Current progress and key decisions made - Important context, constraints, or user preferences - What remains to be done (clear next steps) - Any critical data, examples, or references needed to continue Be concise, structured, and focused on helping the next LLM seamlessly continue the work.这段 prompt 的重点不是「总结聊天记录」而是「写给接手模型的 handoff summary」。它要求保留的是继续任务最关键的信息当前进展、已做出的技术决策、用户约束和偏好、剩余任务、关键文件与错误与命令与测试结果与例子。本地 summary 生成后Codex 会在前面加一段固定前缀Another language model started to solve this problem and produced a summary of its thinking process. You also have access to the state of the tools that were used by that language model. Use this to build on the work that has already been done and avoid duplicating work. Here is the summary produced by the other language model, use the information in this summary to assist with your own analysis:这段前缀的作用是给后续模型一个解释框架这不是普通用户闲聊这不是新任务这是接手任务时必须使用的交接状态。本地压缩后active history 大致变成最近一段真实用户消息 带 SUMMARY_PREFIX 的压缩摘要。最近用户消息会保留一段预算当前常量约是 20000 tokens。这解释了为什么 Codex 通常不会忘掉最近用户刚刚纠正过什么。远端压缩则不同。远端 v1 调用/responses/compact请求里带模型、当前输入历史、当前 instructions、当前 tools、reasoning 与 service tier 等请求设置但不追加本地那段 handoff prompt。远端 v2 不调用/responses/compact而是在普通 Responses 输入末尾追加一个协议项ResponseItem::CompactionTrigger服务端返回ResponseItem::Compaction { encrypted_content }。所以你在远端压缩历史里经常看到compaction:encryptedtrue而不是一段可读的 handoff summary。4. 验证请求压缩前后 token 占用对比怎么做配好之后要验证。验证的目标不是「压缩有没有发生」而是「压缩前后 token 占用变化是否符合预期任务能不能接续」。第一步跑一个会产生大量工具输出的任务。比如让 Codex 跑一个会打印很多行的测试命令或者读一个超大日志文件。观察工具输出是否被截断成头尾保留、中间带 truncated marker 的形态。如果没截断检查tool_output_token_limit是否生效、truncation_policy是否写对。第二步看 token 使用量。Codex 在会话中会显示或记录 token 使用情况。你要观察的是随着轮次增加token 使用量是否在接近model_auto_compact_token_limit时触发压缩。触发后active history 的 token 占用应该明显下降而不是继续线性增长。第三步对比压缩前后。压缩前记录一次 token 占用压缩后再记录一次。正常情况下压缩后占用会回落到阈值以下留出继续跑的空间。如果压缩后占用没降可能是压缩没真正替换 active history或者你看到的只是 rollout 里的历史事件而不是 active context。第四步验证任务接续。压缩后继续发「继续」看模型是否还记得当前进展、下一步该做什么。如果它开始重复已完成的工作或者忘了用户约束说明 summary 没覆盖到关键信息。这时候可以检查是不是本地压缩的 handoff prompt 没生效或者远端压缩的 encrypted item 让信息不可读。远端压缩的验证要换个思路。因为你看不到明文 summary只能通过行为判断压缩后模型是否还能接续任务、是否还遵守 AGENTS.md 和权限约束。如果行为正常说明 provider 的 compaction 工作正常。如果行为异常先确认是不是走了远端路径再考虑切到本地压缩路径对比。这里有个实用技巧在长任务里定期手动记录一次「当前进展 下一步」相当于你自己写一份 handoff。这样即使压缩丢了细节你也能用这份记录快速恢复。这不是替代 compaction而是给自己留一份可读的备份。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节对照真实报错。每个报错指向不同层别混着改。401 Unauthorized。这是认证问题。先检查 API Key 是否有效、是否过期、是否复制时带了空格。再去模型对话页面发一条消息验证 Key。如果模型对话能通但 Codex 报 401检查auth.json里的 Key 和config.toml里的 Base URL 是否配套。三件套里 Key 和 Base URL 必须来自同一套配置。local proxy failed。这通常是本地代理或网络层问题。检查你的 Base URL 是否写成了本地地址、是否有多余的端口、是否有本地服务没启动。如果你用了 CC Switch 或类似工具切换配置确认切换后的配置指向https://taotoken.net/api而不是残留的旧地址。这个报错和 compaction 无关别去调压缩阈值。reading choices 相关报错。这类错误通常出现在响应解析阶段模型返回格式和客户端预期不一致。先确认 Model ID 是否写对再确认 Base URL 是否带了多余的路径。如果最近改过truncation_policy或tool_output_token_limit先改回默认值排除配置干扰。压缩本身不会导致 reading choices 错误但如果压缩后返回的 item 形态和客户端解析逻辑不匹配也可能触发。这时候对比压缩前后的请求形态。OAuth 相关报错。如果你用的是需要 OAuth 的客户端或 MCP 场景检查 token 是否过期、回调地址是否配好。OAuth 问题和 API Key 是两套认证别把 OAuth 报错当成 Key 问题去改。Cline MCP 场景下确认 MCP server 配置里的 Base URL、Key、Model ID 三件套完整。还有一个隐蔽的坑压缩后权限或 AGENTS.md 约束看起来「失效」了。这通常不是压缩丢了权限而是你把运行规则和任务状态混在一起了。运行规则由下一次请求前重新注入不靠 summary 保存。如果确实失效检查注入环节而不是压缩环节。远端压缩的 encrypted item 不可读这是设计如此不是 bug。你如果需要在压缩后审计内容切到本地压缩路径或者自己维护一份 handoff 记录。6. 语义一致 CTA按你的场景选入口排障和接入类问题先去 API Keys 页面拿 Key再对照接入文档配三件套。文档里有各客户端的配置样例比你自己拼路径靠谱。API Keys 入口在控制台里接入文档在文档区。验证模型是否通、想先发一条消息试试用模型对话入口。这一步能快速排掉 Key 和 Model ID 问题再进入 Codex 配置。长期编码、跑 Agent 任务、需要 Coding Plan 的场景去 Coding Plan 入口看。长任务正是 compaction 发挥作用的场景配好阈值和工具输出预算能让会话跑得更久。具体入口模型对话、coding-plan、console、api-keys、doc 都在官网导航里。API 地址统一用https://taotoken.net/api不要自己加路径。最后说个真实经验压缩是续航机制不是无限记忆机制。同一个 bug 没修完、同一个 PR 还在跑测试、目标稳定文件范围稳定适合继续压缩。任务目标换了、旧线程经历过多次压缩、需要审计很早以前的完整细节、远端 encrypted compaction 让你无法确认内容、上下文里混了多个不相关的大任务更适合开新会话。判断标准很简单最近上下文比早期闲聊更重要就继续早期细节比最近进展更重要就开新会话。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑