Сжатие Codex завершается неудачей с ошибкой "защита ответа недоступна": это веб-поиск, а не ваш контекст

AIHubMix8 мин чтения
Сжатие Codex завершается неудачей с ошибкой "защита ответа недоступна": это веб-поиск, а не ваш контекст

С 8 октября 2026 года длинные сессии Codex завершаются неудачей в момент, когда они пытаются сжаться. Ошибка гласит stream disconnected before completion: response protection is unavailable, повторные попытки не помогают, и разговор не может продолжаться. Большинство отчетов касаются gpt-6.1-sol, но gpt-6-astra и gpt-5.6-sol завершаются неудачей аналогичным образом. Это проявляется за самохостинговыми прокси, а также в официальном приложении Codex с прямым входом в ChatGPT.

Краткий ответ: контекст не слишком велик, и ваша сеть не является проблемой. Бэкенд Codex теперь отклоняет любые запросы, которые воспроизводят ранний веб-поиск в своей истории, не объявляя также инструмент веб-поиска. Запрос на сжатие Codex не объявляет никаких инструментов. Таким образом, один веб-поиск в начале сессии достаточно, чтобы сделать каждое последующее сжатие неудачным.

Что делать прямо сейчас:

  • Новые сессии: установите web_search = "disabled" до тех пор, пока бэкенд или Codex не изменятся.
  • Застрявшие сессии: перенесите работу в новую сессию. Старая не сможет сжаться.
  • Если вы поддерживаете свой собственный шлюз перед 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.

Около 6 октября бэкенд Codex ChatGPT начал отклонять запросы, которые воспроизводят web_search_call, но не объявляют web_search. Разработчики, которые захватили сырые запросы, сузили круг поиска. Изменение или удаление идентификатора элемента поиска не имеет значения. Объявление только функции инструмента все равно завершается неудачей. Объявление 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 включают настольное приложение и codex-cli, вошедшие в систему напрямую с аккаунтом ChatGPT, без участия прокси. На 10 октября ни Codex 0.162.1, ни альфа-версии 0.163.0 не упоминают об исправлении, и проблемы не получили ответа от поддерживающих.

Что вы можете сделать сейчас

Отключить веб-поиск для новых сессий

Отключите поиск в ~/.codex/config.toml:

web_search = "disabled"

Справка по конфигурации Codex перечисляет четыре значения: disabled, cached (по умолчанию), indexed и live. Сессии, начатые с --yolo или другого режима полного доступа, по умолчанию устанавливаются на live, поэтому установите это явно.

Примените это к новым сессиям. Старая сессия уже имеет элементы web_search_call в своей истории. С отключенным поиском нормальные повороты также перестают объявлять инструмент, поэтому эти повороты могут начать завершаться неудачей. Это следует из вышеупомянутого правила, но пока никто не сообщал о его тестировании.

Цена в том, что Codex не может искать в интернете. Для сессии, которая нуждается в поиске, откройте отдельную короткую сессию или заставьте модель записать результаты в файл, который длинная сессия прочитает.

Спасение застрявшей сессии

Ничто с вашей стороны не заставит застрявшую сессию сжаться, пока бэкенд ведет себя таким образом. Чтобы сохранить работу:

  1. Оставьте застрявшую сессию как есть. Ее история все еще на диске в ~/.codex/sessions/.
  2. Начните новую сессию с отключенным веб-поиском.
  3. Укажите ее на файл старой сессии или вставьте короткую передачу: цель, измененные файлы, принятые решения и что осталось.
  4. Перестаньте отправлять запросы в старую сессию. Каждая попытка повторяет сжатие и снова завершается неудачей.

Если вы поддерживаете свой собственный шлюз

Исправление, которое работает, следует одному правилу. Если 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

Запросы Lite являются исключением. Они возвращают 400, если web_search находится в верхнем уровне tools. Рабочие патчи помещают его в первый элемент additional_tools вместо этого и оставляют любой завершающий compaction_trigger последним. Альтернатива, удаление элементов поиска из запросов на сжатие, также работает, но резюме тогда теряет все, что нашел поиск.

Если вы предпочитаете не зависеть от подписного бэкенда

Каждый отчет, который мы нашли, проходит через подписной бэкенд ChatGPT, конечную точку, которую Codex использует с входом в ChatGPT. Его правила не задокументированы, и это правило изменилось без предупреждения.

Codex также может использовать публичный API Responses с ключом API. Мы не видели отчетов об этой ошибке по этому пути, но мы также не проводили воспроизведение там, поэтому рассматривайте это как наблюдение, а не как гарантию. Чтобы настроить Codex с ключом AIHubMix, следуйте учебнику 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?
Это ошибка от бэкенда Codex ChatGPT, а не от самого Codex или вашего прокси. С начала октября 2026 года она появляется, когда запрос воспроизводит ранний веб-поиск, но не объявляет инструмент веб-поиска, что именно и делает запрос на сжатие.

Мой контекст слишком велик?
Нет. Тестировщики воспроизвели это с порогом сжатия в 2000 токенов, и сессии того же размера без поиска сжимаются нормально. Это выглядит связанным с размером только потому, что сжатие происходит только в длинных сессиях.

Это влияет на официальное приложение Codex с входом в ChatGPT?
Да. Пользователи настольного приложения и codex-cli сообщают об этом при прямом входе в ChatGPT без прокси. На 10 октября 2026 года ни один релиз Codex не упоминает об исправлении.

Как я могу узнать, столкнется ли сессия с этой проблемой?
Если сессия использовала веб-поиск в любой момент, ее следующее сжатие, скорее всего, завершится неудачей. Codex записывает каждый поиск как элемент web_search_call в файлах сессии в папке .codex/sessions.

Поможет ли отключение веб-поиска исправить сессию, которая уже застряла?
Вероятно, нет. Старая история все еще содержит поиск, и как только поиск отключен, нормальные повороты могут перестать объявлять инструмент и также завершиться неудачей. Используйте настройку для новых сессий и перенесите работу.

Помогает ли переключение на WebSocket или изменение nginx?
Нет. Тело запроса одинаково при любом транспорте, и ошибка исходит от сервера, поэтому сетевые настройки не могут ее устранить. Другие ошибки потока могут возникать из-за тайм-аутов, но не эта.

Происходит ли это, когда Codex использует ключ API вместо подписки ChatGPT?
Все отчеты до сих пор касаются подписного бэкенда. Никто не сообщал об этом в публичном API Responses, хотя это не тестировалось напрямую.

Продолжайте читать: серия GPT-6.1 Sol

Источники