先说这篇写给谁:只要你接入本站用的不是 Codex——第三方 Agent、IDE 插件、聊天客户端、自己搭的工作流,都算——建议花两分钟往下看一遍,自查一处设置。
因为在我这边的后台日志里,能看到这么一类高频错误:
{
"error": {
"message": "Your input exceeds the context window of this model. Please adjust your input and try again.",
"type": "upstream_error"
}
}
它最麻烦的地方在于:触发它的人,很多自己完全不知道触发过。我作为管理员能在日志里一条条看到,你在前台却可能一点感觉都没有——所以这件事没法等我来通知你,只能你自己查一遍。
这篇文章讲清楚三件事:这个错误是什么、为什么用 Codex 的人基本遇不到而别的工具会撞、以及为什么有人撞了却毫无察觉。
一、这个错误是什么
type 是 upstream_error,说明这句话是上游模型原样退回来的,我们只是没有加工地转给你。上游给的原始错误码是 context_length_exceeded。
翻译成人话:
你这一次请求送进去的内容,超过了模型一次能读进去的上限。
注意是输入超了,不是输出超了。
这条线的位置是固定的:272,000 token。
二、为什么用 Codex 的人基本遇不到
因为 Codex 自己知道这条线在哪。
它内置就写着 272,000,而且不会等你贴满才动作——它按 95% 的有效窗口系数提前收手,也就是大约 258,400 就开始触发自动压缩(auto-compact),把前面的对话总结成一段短的,腾出空间再继续。
所以 Codex 用户的体感是「聊久了它会自己精简一下」,很少撞到这个错误。
这套机制是 Codex 自带的,不是模型自带的。你换个工具,它就没了。
三、为什么换成别的工具就会撞
第三方 Agent、IDE 插件、聊天客户端、自建工作流,它们要知道窗口有多大,只有两条路:
- 自己写死一个默认值;
- 向 provider 的
/v1/models接口「自动探测」。
第二条路听起来很聪明,实际上是条死路——OpenAI 兼容的 /v1/models 接口,从来就不返回上下文长度。
你现在就可以请求一次本站的 /v1/models,返回的每个模型对象只有这些字段:
{
"id": "gpt-5.6-sol",
"object": "model",
"created": 1704067200,
"owned_by": "openai",
"type": "model",
"display_name": "gpt-5.6-sol"
}
没有 context_length,没有 max_input_tokens,什么都没有。 这不是本站少给了字段,OpenAI 官方的 /v1/models 也是这个样子——这个字段在协议里就不存在,所有走 OpenAI 兼容协议的服务返回结构都一样。
于是「自动探测」必然失败,工具只能回落到自己内置的默认值。而这个默认值是它自己拍的,跟你实际在用的通道没有任何关系。只要它比 272,000 大,裁剪和压缩逻辑就永远不会在正确的时间点触发。
对话在你眼里还很正常,在模型那里已经越界了。
四、Hermes Agent:一个典型例子
用 Hermes Agent 的朋友特别容易中招,因为它的默认行为正好踩在上面这条死路上。
Hermes 的配置里有个 model.context_length,官方文档写得很清楚,它的默认值是:
Autodetected from the provider's model catalog.
正是上一节说的那条探测不出结果的路。
更关键的是,Hermes 的历史压缩不是按绝对值触发的,而是按 context_length 的比例触发的:
compression:
threshold: 0.50 # 到达上下文窗口的 50% 时压缩
target_ratio: 0.20 # 压缩后保留 20% 作为近期尾巴
把两件事拼起来看,结论很干脆:
探测失败后 Hermes 会用自己内置的默认窗口来算 50%。只要那个默认值超过 544,000,压缩就永远轮不到触发——因为 50% 的阈值本身已经越过 272,000 了。
而 544,000 这个门槛,任何一个「往大了猜」的默认值都会轻松超过。
于是压缩永远等不到它该触发的那一刻,请求在半路就被打回来了。
所以对 Hermes 用户来说,手动写死 context_length 不是「调优」,是必须做的一步配置:
model:
context_length: 272000 # 手动填死,别让它猜
compression:
threshold: 0.50
threshold_tokens: 200000 # 保险栓:和比例阈值取更小的那个
这里建议顺手加上 threshold_tokens。它是一个绝对值上限,Hermes 会在「比例阈值」和「绝对值阈值」里取更小的那个触发压缩。好处是以后你换模型、改配置、忘了改 context_length,这道保险栓还在。
五、为什么有人撞了却不知道
这是最值得说的一点。
并不是这个错误看不见。 你在对话框里正常提问,一旦超了,工具一定会把错误返回给你,你当场就能看到。这种情况不会有人不知道。
问题出在工具在背后默默做的那些事。
现在的 Agent 类产品,除了你看得见的对话,背后还跑着一堆你看不见的模型调用——最典型的就是记忆:把这段对话总结一下存进记忆库、把历史记录压缩一轮、更新一下长期上下文。这些调用你没点过,界面上也没有它们的位置。(这类后台调用到底存在到什么程度,可以参考之前那篇 为什么我在使用 Codex 时,会额外使用其他模型?)
而这类后台调用往往比前台对话更容易越过 272K——因为它们要处理的常常是整段历史、整个记忆库,而不是你刚敲进去的那一句话。
关键在于:这些后台任务失败了,工具通常不会报给你。 它们本来就是「锦上添花」的活儿,失败了不影响你眼前这轮对话继续,于是工具默默跳过,错误就这么被吞掉了。
于是就有了这个局面:后台在稳定地报错,前台一切正常,你什么都不知道。 你能察觉到的顶多是些说不清的怪事——比如它好像总是记不住东西,比如上下文时不时就断片了。
而在我这边的后台日志里,这些请求是一条条实打实的失败记录。
六、所以,一句话的建议
只要你用的不是 Codex,就必须自己关注上下文管理。
Codex 之所以不用你操心,是因为它把 272K 这条线和自动压缩都替你做好了。除此之外的任何产品、工具、Agent——不管它看起来多成熟——都要你自己确认一遍:
它知不知道 272,000 这个数?如果不知道,你有没有手动告诉它?
这就是全部要点。具体到每个工具怎么配,翻它的文档找「上下文长度」「历史压缩」「最大 token」这类设置项,把线划在 272,000 以内(建议留点余量,压到 240,000 左右)。
如果你排查完还是复现,把出问题的时间点和用的模型发到工单/群里,我可以从后台调对应请求的 input_tokens 帮你确认是不是它。
xhyapi