自2026年10月8日起,长时间的Codex会话在尝试压缩时会立即崩溃。错误信息为 stream disconnected before completion: response protection is unavailable,重试无效,谈话无法继续。大多数报告涉及gpt-6.1-sol,但gpt-6-astra和gpt-5.6-sol也以相同方式失败。该问题出现在自托管代理后面,也出现在使用直接ChatGPT登录的官方Codex应用中。
简短的回答是:上下文并不太大,您的网络也不是问题。ChatGPT的Codex后端现在拒绝任何重放其历史中早期网络搜索的请求,而不声明网络搜索工具。Codex的压缩请求根本没有声明任何工具。因此,在会话早期进行一次网络搜索就足以使后续的每次压缩失败。
现在该怎么做:
- 新会话:在后端或Codex更改之前,将
web_search = "disabled"设置为禁用。 - 卡住的会话:将工作移到一个新的会话中。旧会话无法压缩。
- 如果您在Codex前面维护自己的网关:当历史中包含搜索时,添加网络搜索声明。代码如下。
本文的其余部分解释了如何发现触发器,哪些社区修复无效,以及如何拯救一个卡住的会话。
失败的表现
您将在Codex中看到以下信息:
stream disconnected before completion: response protection is unavailable
Error running remote compact task: stream disconnected before completion: stream closed before response.completed
第二条消息是通用版本。Codex并不总是显示上游错误,因此以“stream closed before response.completed”失败的压缩可能是同样的问题。Codex的本地日志中通常会有 Failed to run pre-sampling compact 的记录。
在其背后,上游发送两种信息之一。有时是带有此主体的HTTP 502,ChatGPT Plus用户在gpt-6.1-sol上也在OpenAI开发者论坛上发布过:
{"message": "response protection is unavailable", "type": "internal_error"}
其他时候是HTTP 200,其流以 response.failed 事件结束,带有 code: "upstream_error",且没有 response.completed。任何仅检查HTTP状态的请求都会错过第二种形式,并将其报告为提前结束的流。
模式在各处都是相同的:
- 正常的交互仍然可以工作。只有压缩失败。
- Codex大约重试五次,然后放弃。在一个网关的日志中,每次失败的尝试耗时2到13秒,并记录为零个令牌。
- 恢复会话会遇到相同的压缩,因此会话保持卡住。
- 新会话在遇到相同条件之前可以正常工作。
触发器:历史中的搜索,请求中没有搜索工具
Codex有一个内置的网络搜索工具。当模型使用它时,web_search_call 项会进入对话历史。每个后续请求都会将该历史发送回去。
正常的交互在 tools 中声明工具,因此上游接受重放的搜索。压缩请求则不同。Codex发送整个历史,tools: [],因为摘要不需要工具。这适用于Codex为自定义提供者运行的本地压缩,以及远程压缩v2。
大约在10月6日,ChatGPT Codex后端开始拒绝重放 web_search_call 但未声明 web_search 的请求。捕获原始请求的开发者缩小了范围。更改或删除搜索项的ID没有区别。仅声明一个功能工具仍然失败。声明 web_search 使相同的请求成功。
在使用官方未修改的codex-cli并使用ChatGPT账户登录时也出现相同的结果。包含三个搜索项的历史无法压缩。仅删除这些项的历史可以正常压缩。该线程中的第二位报告者捕获了一个包含一个 web_search_call 和 tools: [] 的压缩请求。添加 web_search 声明修复了它,删除搜索项也有效。
这解释了为什么看起来像是上下文大小的问题。压缩仅在长会话中运行,而长会话最有可能在某个时刻使用过搜索。网络搜索在Codex中也是默认开启的(默认模式为 "cached"),因此会话中可能包含用户从未请求过的搜索。
证据
至少有四个小组独立进行A/B测试,并得到了相同的结果。下面的行结合了在openai/codex跟踪器和几个开源网关项目的问题跟踪器中发布的测试。OpenAI尚未确认该规则或在任何线程中作出回应。
| 请求历史 | 声明的工具 | 结果 |
|---|---|---|
| 仅消息和推理 | 无 | 完成 |
| 包含功能调用输出 | 无 | 完成 |
| 包含一个web_search_call | 无 | 失败 |
| 包含一个web_search_call | 仅功能工具 | 失败 |
| 包含一个web_search_call | web_search | 完成 |
| 相同,删除搜索项 | 无 | 完成 |
这些测试排除了大小问题。一位测试者将自动压缩阈值设置为2000个令牌,使用 -c model_auto_compact_token_limit=2000。没有工具使用的会话可以正常压缩。进行过一次搜索的会话连续失败六次。另一位测试者发现,删除推理项没有帮助,而删除单个搜索项则有效。
在一次测试中,声明了 web_search 的版本在2.63秒内完成,并且没有新的搜索调用。声明工具不会使模型再次搜索。
社区尝试了什么,实际上有效的是什么
促使这篇文章的LINUX DO线程经过了大多数常见的猜测:
| 建议 | 有帮助吗? | 原因 |
|---|---|---|
| 缩小上下文,提前压缩 | 没有 | 大小不是触发因素 |
| 通过IP连接,更改nginx | 没有 | 错误来自上游 |
| 切换到WebSocket | 不可靠 | 请求体无论如何都是相同的 |
| 直接登录ChatGPT | 没有 | 官方登录也失败 |
| 新会话,交接上下文 | 临时解决方案 | 在搜索后再次失败 |
| 禁用网络搜索 | 是的,对于新会话 | 没有搜索,就没有触发 |
| 在请求中声明web_search | 是的 | 满足检查条件 |
其中一些需要更多解释。
Nginx和IP。 超时和空闲连接可能导致其他“流断开”错误,但它们无法产生此消息。相关代理的维护者确认该消息不是由代理生成的;它来自上游提供者。如果消息存在,网络请求已成功传递并返回。
WebSocket。 有效的网关补丁必须同时覆盖WebSocket路径和HTTP,因为WebSocket请求携带相同的主体。一个在切换传输后“恢复”的会话很可能在其历史中没有搜索。
官方登录。 在openai/codex跟踪器上的报告包括桌面应用程序和直接使用ChatGPT账户登录的codex-cli,没有涉及代理。截至2026年10月10日,Codex 0.162.1或0.163.0 alpha版本均未提及修复,且问题没有维护者回应。
您现在可以做什么
为新会话禁用网络搜索
在 ~/.codex/config.toml 中关闭搜索:
web_search = "disabled"
Codex配置参考列出了四个值: disabled、 cached(默认值)、 indexed 和 live。使用 --yolo 或其他完全访问沙盒启动的会话默认设置为 live,因此请明确设置。
将此应用于新会话。旧会话的历史中已经有 web_search_call 项。禁用搜索后,正常的交互也停止声明工具,因此这些交互可能也会开始失败。这遵循上述规则,但尚未有人报告对此进行测试。
代价是Codex无法搜索网络。对于需要搜索的会话,请打开一个单独的短会话,或者让模型将发现写入文件,以便长会话读取。
拯救一个卡住的会话
在后端以这种方式运行时,您无法通过任何方式使卡住的会话压缩。为了保留工作:
- 保持卡住的会话不变。它的历史仍然保存在
~/.codex/sessions/中。 - 启动一个新的会话,禁用网络搜索。
- 将其指向旧会话文件,或粘贴一个简短的交接:目标、已更改的文件、做出的决定和剩余的工作。
- 停止向旧会话发送提示。每次尝试都会重试压缩并再次失败。
如果您维护自己的网关
有效的修复遵循一个规则。如果 input 包含 web_search_call 且未声明任何 web_search* 工具,则添加一个。如果调用者未声明任何工具,则将 tool_choice 设置为 "none",以便工具无法运行。保持 input 不变。
def declare_replayed_web_search(body: dict) -> dict:
"""让上游接受在没有工具的请求中重放的web_search_call。"""
items = body.get("input")
if not isinstance(items, list):
return body
if not any(isinstance(i, dict) and i.get("type") == "web_search_call" for i in items):
return body
tools = body.get("tools") or []
if any(isinstance(t, dict) and str(t.get("type", "")).startswith("web_search") for t in tools):
return body
caller_had_tools = bool(tools)
# 仅缓存索引:声明存在是为了满足检查,而不是为了搜索。
body["tools"] = tools + [{"type": "web_search", "external_web_access": False}]
if not caller_had_tools:
body["tool_choice"] = "none"
return body
Responses Lite请求是一个例外。如果 web_search 位于顶层 tools 中,它将返回400。有效的补丁将其放在第一个 additional_tools 输入项中,并保持任何后续的 compaction_trigger 在最后。另一种选择是从压缩请求中剥离搜索项,但这样摘要将失去搜索找到的内容。
如果您不想依赖订阅后端
我们找到的每个报告都经过ChatGPT的订阅后端,这是Codex使用ChatGPT登录的端点。其规则没有文档记录,并且这一规则在没有通知的情况下发生了变化。
Codex还可以使用公共Responses API和API密钥。我们尚未在该路径上看到此错误的报告,但我们也没有在该路径上进行过重现,因此将其视为观察,而不是保证。要使用AIHubMix密钥设置Codex,请遵循Codex CLI教程:
model = "gpt-6.1-sol"
model_provider = "aihubmix"
[model_providers.aihubmix]
name = "AIHubMix"
base_url = "https://aihubmix.com/v1"
wire_api = "responses"
env_key = "AIHUBMIX_API_KEY"
API定价按令牌计算,而不是按订阅计算。费率在gpt-6.1-sol模型页面上。
检查清单
- 错误文本包含“响应保护不可用”,或者压缩失败,出现“流在响应完成前关闭”。
- 正常交互仍然有效,只有压缩失败。
- 会话曾在某个时刻使用过网络搜索,可能没有被请求。
- 新会话的web_search设置为禁用。
- 卡住的工作已移至新会话,并附有交接说明。
- 您维护的网关在历史中包含搜索时添加了网络搜索声明。
- Nginx和代理网络设置保持不变。它们不是原因。
常见问题
Codex中的“响应保护不可用”是什么意思?
这是来自ChatGPT的Codex后端的错误,而不是Codex本身或您的代理。自2026年10月初以来,当请求重放早期的网络搜索但未声明网络搜索工具时,就会出现此错误,这正是压缩请求所做的。
我的上下文窗口太大了吗?
不。测试者在2000个令牌的压缩阈值下重现了此问题,而没有搜索的相同大小的会话可以正常压缩。它看起来与大小有关,仅仅是因为压缩仅在长会话中运行。
它会影响使用ChatGPT登录的官方Codex应用吗?
是的。桌面应用程序和codex-cli的用户在直接使用ChatGPT登录时报告了此问题,没有涉及代理。截至2026年10月10日,没有Codex版本提到修复。
我如何判断一个会话是否会遇到此问题?
如果会话在任何时候使用过网络搜索,则其下一个压缩很可能会失败。Codex将每次搜索记录为会话文件中的web_search_call项,位于.codex/sessions文件夹下。
禁用网络搜索会修复已经卡住的会话吗?
可能不会。旧历史仍然包含搜索,一旦禁用搜索,正常交互可能会停止声明工具并也失败。使用该设置用于新会话并将工作移过来。
切换到WebSocket或更改nginx有帮助吗?
没有。请求体在两种传输中都是相同的,错误来自上游,因此网络设置无法消除它。其他流错误可能来自超时,但不是这个错误。
当Codex使用API密钥而不是ChatGPT订阅时会发生此问题吗?
到目前为止,所有报告都涉及订阅后端。没有人报告在公共Responses API上发生此问题,尽管尚未直接测试。
继续阅读:GPT-6.1 Sol系列
- 如果此错误在您将Codex切换到GPT-6.1 Sol后立即出现,迁移指南涵盖了可能破坏设置的其他更改:迁移到GPT-6.1 Sol:9个可能出现的问题
- 长代理会话是设置最重要的地方,影响速度以及接近压缩的速度:为GPT-6.1 Sol选择推理努力:从低到高
来源
- Windows Codex桌面:上下文压缩始终失败 (openai/codex)
- 恢复托管web_search_call历史后远程压缩失败 (openai/codex)
- Codex远程压缩失败,出现502“响应保护不可用” (OpenAI开发者社区)
- Codex配置参考 (OpenAI)
- Codex CLI + AIHubMix集成教程 (AIHubMix)



