Essay 010 · AI
Codex Sol 1M 上下文:配置、872K 夹限与验证边界
从 GPT-5.6 Sol 的 1.05M 原生上限出发,拆解 Codex 的 272K/872K catalog 窗口、95% 有效窗口与 90% 自动压缩线,并说明自定义 model catalog 的效果与边界。
首版:拆解 1M 配置、872K 夹限、有效窗口与自动压缩线
Version 1.0Tibo 发了推文
推文链接
推文大意
想在 Codex 里给 GPT-5.6 Sol 开 1M 上下文,改
~/.codex/config.toml 顶层(写在任何 [section]
前面):
model = "gpt-5.6-sol"
model_context_window = 1000000
model_auto_compact_token_limit = 900000第一项选模型。第二项把上下文预算设成 1M。第三项大约 900k 开始自动压缩,留一点余量。
改完后,配置会在新开的 Codex 会话中生效。
也可以不改默认配置,只对单次 CLI 会话试:
codex -m gpt-5.6-sol \
-c model_context_window=1000000 \
-c model_auto_compact_token_limit=900000Tibo 还强调:Codex 默认上下文上限是按性能和成本调过的,现在公开这个配法,是因为很多人要。更大窗口能让 Codex 在摘要旧内容之前,多留代码、工具输出和对话历史。模型本身得支持,GPT-5.6 Sol 文档上的窗口是 1,050,000。
后面他又补了一条:以前 1M 只对 API key 有效,现在 ChatGPT 账号也能用。默认长度有原因,已经调到接近最优;想开就开。
配置实际效果?
model = "gpt-5.6-sol"
model_context_window = 1000000
model_auto_compact_token_limit = 900000配置一,是新开会话默认用哪个模型,跟我们能不能用上 1M 上下文没有必然联系,配不配都行
配置二,设置上下文窗口到 1M,有一定效果,但实际只能到 828k
配置三,设置压缩线到 900k,也有一定效果,但最终其实只能到 785k
关于为啥只能到 828k 和 785k,需要知道以下几个窗口
注:以下只讨论 gpt 5.6 sol / terra / luna
第一个窗口:1.05M
这是模型原生能力支持的窗口,sol / terra / luna 都是 1.05M
第二个窗口:400k / 1M(推定的 Codex 总上下文档位)
从数值关系看,model catalog 中的 272k / 872k,很可能分别来自两个包含输入和输出的总上下文档位:
400k - 128k = 272k
1M - 128k = 872k
不过,客户端源码只直接证明了 catalog 下发的 272k / 872k,没有展示 400k / 1M,也没有展示减去 128k 的过程。因此,这里的来源关系属于根据数值作出的推定。
临时小结
第一个窗口是模型原生能力上限;第二个窗口是推定的 Codex 总上下文档位。下方的 272k / 872k,则是可以从 model catalog 和客户端源码直接验证的 Codex 窗口。
另外需要知道,Codex 配置项中有个叫做 model_catalog_json 的东西,内容可以看下 ~/.codex/models_cache.json
这里节选一些 json 内容
{
// 每个对象代表一个模型;以下只保留本文相关字段。
"models": [
{
"slug": "gpt-5.6-sol", // 模型标识
"context_window": 272000,
"max_context_window": 872000,
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
},
{
"slug": "gpt-5.6-terra",
"context_window": 272000, // 272K token
"max_context_window": 872000, // 872K token
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
},
{
"slug": "gpt-5.6-luna",
"context_window": 272000, // 272K token
"max_context_window": 872000, // 872K token
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
},
{
"slug": "gpt-5.5",
"context_window": 272000, // 272K token
"max_context_window": 272000, // 272K token
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
},
{
"slug": "gpt-5.4",
"context_window": 272000, // 272K token
"max_context_window": 1000000, // 1M token
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
},
{
"slug": "gpt-5.4-mini",
"context_window": 272000, // 272K token
"max_context_window": 272000, // 272K token
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
},
{
"slug": "gpt-5.3-codex-spark",
"context_window": 128000, // 128K token
"max_context_window": 128000, // 128K token
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
},
{
"slug": "codex-auto-review",
"context_window": 272000, // 272K token
"max_context_window": 872000, // 872K token
"effective_context_window_percent": 95,
"auto_compact_token_limit": null
}
]
}
第三个窗口:Codex catalog 窗口 272k / 872k
在 Codex 服务端下发的 model catalog 中,各模型的 context_window 就是 272k
如果想用 1M 的话,Tibo 给的 model_context_window = 1M,就是在配这个
只不过 Codex 会保证它不能超过 model catalog 中的 max_context_window,所以最终该窗口会是 872k
源码:OpenAI Codex 1f41cc5 中的 with_config_overrides:
if let Some(context_window) = config.model_context_window {
model.context_window = Some(
model
.max_context_window
.map_or(context_window, |max_context_window| {
context_window.min(max_context_window)
}),
);
}源码解读:当 model catalog 提供
max_context_window 时,Codex 会在用户配置的
model_context_window 与 max_context_window
之间取最小值;因此 catalog 上限为 872000 时,配置
1000000 最终会被夹到 872000。这段源码只证明
Codex 会按 catalog 上限夹限,并不解释 catalog 为什么把上限设为
872000。
第四个窗口,各模型的最终窗口:258k / 828k
依旧是 model catalog 中,有 effective_context_window_percent = 95
Codex 会用它来从窗口三中裁掉一部分,作为 Codex harness 后续真正使用的各模型窗口
最终就是 272k x 95% = 258k
或者是 872k x 95% = 828k
源码:OpenAI Codex 1f41cc5 中的 TurnContext::model_context_window:
pub(crate) fn model_context_window(&self) -> Option<i64> {
let effective_context_window_percent = self.model_info.effective_context_window_percent;
self.model_info
.resolved_context_window()
.map(|context_window| {
context_window.saturating_mul(effective_context_window_percent) / 100
})
}源码解读:Codex 先取得窗口三,再乘
effective_context_window_percent 并除以 100;按 catalog
中的 95 计算,272000 得到
258400,872000 得到
828400,文中的 258k 和 828k 是取整后的简称。
压缩线 245k / 785k
(model catalog 中,其实有 auto_compact_token_limit 字段,但我看到的都是 null)
Codex 会把窗口三 x 90% 得到压缩线,就是
272k x 90% = 245k
872k x 90% = 785k
源码:OpenAI Codex 1f41cc5 中的 ModelInfo::auto_compact_token_limit:
let context_limit = self
.resolved_context_window()
.map(|context_window| (context_window * 9) / 10);源码解读:(context_window * 9) / 10
就是 90%;这里直接使用 resolved_context_window(),没有经过
95%
的有效窗口折算,因此压缩线基于窗口三计算:272000 × 90% = 244800,872000 × 90% = 784800。
如果配置了 model_auto_compact_token_limit,Codex 会取用户配置 vs 刚才计算得到的最小值
源码(一):OpenAI Codex 1f41cc5 中的
with_config_overrides:
if let Some(auto_compact_token_limit) = config.model_auto_compact_token_limit {
model.auto_compact_token_limit = Some(auto_compact_token_limit);
}源码(二):OpenAI Codex 1f41cc5 中的
ModelInfo::auto_compact_token_limit:
let config_limit = self.auto_compact_token_limit;
if let Some(context_limit) = context_limit {
return Some(
config_limit.map_or(context_limit, |limit| std::cmp::min(limit, context_limit)),
);
}
config_limit源码解读:用户配置的
model_auto_compact_token_limit 会先覆盖模型的
auto_compact_token_limit 字段;真正计算压缩线时,Codex
再将这个配置值与窗口三的 90%
上限取最小值。没有配置值时,map_or 返回默认的 90%
上限;有配置值时,std::cmp::min 返回两者中的较小值。因此
900000 与 784800 比较后,实际压缩线是
784800。
所以即使 model_auto_compact_token_limit = 900k,实际压缩线也就是 785k
不过我没在 codex cli or app 中看到这个线的展示
综上,Tibo 的配置,足以把窗口拉到很大
但想要完全不受 Codex 限制,整些骚操作,就得在 config.toml 中,手动指定使用自己的 model catalog 文件:
- 做一份自己的 model catalog 文件:
可以把原有的 ~/.codex/models_cache.json 复制一份到 “~/.codex/models-1m.json”,然后改以下字段:
"context_window": 272000, // 272K,改成 1000000
"max_context_window": 872000, // 872K,改成 1000000
"effective_context_window_percent": 95, // 改成 100,不留安全余量
- 改 config.toml
加上:
model_catalog_json = "~/.codex/models-1m.json"并且,这几个配置可以删掉了,反正 Codex harness 窗口取值都是从那个 json 来的
model = "gpt-5.6-sol"
model_context_window = 1000000
model_auto_compact_token_limit = 900000- 效果:1M 窗口,900k 压缩线
- 甚至
- 不过,务实不折腾的话,还是别管什么 model catalog json,直接在 toml 里配一个:
model_context_window = 1000000000000 # 只要大于 872k 都一个效果老老实实用 828k 窗口 + 785k 压缩线就行了
查看本文修订记录(1)
- v1.0 · 2026.08.21 首次发布。