코덱스 압축 실패: "응답 보호를 사용할 수 없음": 문제는 웹 검색이지 당신의 컨텍스트가 아닙니다

AIHubMix8분 분량
코덱스 압축 실패: "응답 보호를 사용할 수 없음": 문제는 웹 검색이지 당신의 컨텍스트가 아닙니다

2026년 10월 8일 이후로 긴 코덱스 세션은 압축을 시도하는 순간 종료되고 있습니다. 오류 메시지는 stream disconnected before completion: response protection is unavailable라고 표시되며, 재시도해도 도움이 되지 않고 대화가 계속되지 않습니다. 대부분의 보고서는 gpt-6.1-sol과 관련이 있지만, gpt-6-astra와 gpt-5.6-sol도 같은 방식으로 실패합니다. 이 문제는 자체 호스팅된 프록시 뒤에서 발생하며, 공식 코덱스 앱에서도 직접 ChatGPT 로그인 시 나타납니다.

간단한 답변: 컨텍스트가 너무 크지 않으며, 당신의 네트워크가 문제는 아닙니다. ChatGPT의 코덱스 백엔드는 이제 이전 웹 검색을 재생하는 요청을 웹 검색 도구를 선언하지 않고 거부합니다. 코덱스의 압축 요청은 도구를 전혀 선언하지 않습니다. 따라서 세션 초반에 단일 웹 검색이 있으면 이후의 모든 압축이 실패하게 됩니다.

지금 할 일:

  • 새 세션: 백엔드나 코덱스가 변경될 때까지 web_search = "disabled"로 설정하세요.
  • 막힌 세션: 작업을 새 세션으로 이동하세요. 이전 세션은 압축되지 않습니다.
  • 코덱스 앞에 자체 게이트웨이를 유지하는 경우: 기록에 검색이 포함된 경우 웹 검색 선언을 추가하세요. 아래 코드를 참조하세요.

이 게시물의 나머지 부분에서는 트리거가 발견된 방법, 커뮤니티 수정 사항이 작동하지 않는 이유, 막힌 세션을 구하는 방법을 설명합니다.

실패의 모습

코덱스에서 다음 중 하나를 보게 될 것입니다:

stream disconnected before completion: response protection is unavailable
Error running remote compact task: stream disconnected before completion: stream closed before response.completed

두 번째 메시지는 일반적인 버전입니다. 코덱스는 항상 상위 오류를 표시하지 않으므로 "stream closed before response.completed"로 실패하는 압축은 동일한 문제일 수 있습니다. 코덱스의 로컬 로그에는 종종 Failed to run pre-sampling compact가 함께 표시됩니다.

하위에서 상위는 두 가지 중 하나를 보냅니다. 때때로 HTTP 502와 함께 이 본문이 전송되며, 이는 gpt-6.1-sol의 ChatGPT Plus 사용자가 OpenAI의 개발자 포럼에 게시한 내용입니다:

{"message": "response protection is unavailable", "type": "internal_error"}

다른 경우에는 HTTP 200이 전송되며, 그 스트림은 response.failed 이벤트로 끝나고 code: "upstream_error"가 있으며 response.completed는 없습니다. HTTP 상태만 확인하는 경우 두 번째 형식을 놓치고 조기 종료된 스트림으로 보고합니다.

패턴은 어디서나 동일합니다:

  • 정상적인 턴은 계속 작동합니다. 오직 압축만 실패합니다.
  • 코덱스는 약 다섯 번 재시도한 후 포기합니다. 한 게이트웨이의 로그에서는 각 실패한 시도가 2초에서 13초가 걸렸으며, 토큰은 0으로 기록되었습니다.
  • 세션을 재개하면 동일한 압축에 부딪히므로 세션이 막힙니다.
  • 새로운 세션은 동일한 조건에 도달할 때까지 작동합니다.

트리거: 기록의 검색, 요청에 검색 도구 없음

코덱스에는 내장된 웹 검색 도구가 있습니다. 모델이 이를 사용할 때 web_search_call 항목이 대화 기록에 추가됩니다. 이후의 모든 요청은 그 기록을 다시 보냅니다.

정상적인 턴은 tools에서 도구를 선언하므로 상위는 재생된 검색을 수락합니다. 압축 요청은 다릅니다. 코덱스는 도구가 필요 없는 요약을 위해 tools: []와 함께 전체 기록을 보냅니다. 이는 사용자 정의 제공업체를 위해 코덱스가 실행하는 로컬 압축과 원격 압축 v2에 적용됩니다.

10월 6일경, ChatGPT 코덱스 백엔드는 web_search_call을 재생하지만 web_search를 선언하지 않는 요청을 거부하기 시작했습니다. 원시 요청을 캡처한 개발자들은 이를 좁혔습니다. 검색 항목의 ID를 변경하거나 제거해도 차이가 없습니다. 함수 도구만 선언해도 실패합니다. web_search를 선언하면 동일한 요청이 성공합니다.

동일한 결과는 공식 수정되지 않은 codex-cli에서 ChatGPT 계정으로 로그인했을 때도 나타납니다. 세 개의 검색 항목이 포함된 기록은 압축에 실패했습니다. 동일한 기록에서 해당 항목만 제거하면 압축이 잘 됩니다. 해당 스레드의 두 번째 보고자는 하나의 web_search_call와 tools: []가 포함된 압축 요청을 캡처했습니다. web_search 선언을 추가하니 해결되었고, 검색 항목을 제거하는 것도 효과가 있었습니다.

이것이 왜 컨텍스트 크기 문제처럼 보이는지를 설명합니다. 압축은 긴 세션에서만 실행되며, 긴 세션은 대부분 어느 시점에서 검색을 사용했을 가능성이 높습니다. 웹 검색은 코덱스에서 기본적으로 활성화되어 있으므로(기본 모드는 "cached") 세션에는 사용자가 요청하지 않은 검색이 포함될 수 있습니다.

증거

최소 네 그룹이 독립적으로 A/B 테스트를 수행하고 동일한 결과를 얻었습니다. 아래 행은 openai/codex 트래커와 여러 오픈 소스 게이트웨이 프로젝트의 이슈 트래커에 게시된 테스트를 결합한 것입니다. OpenAI는 이 규칙을 확인하지 않았고, 해당 스레드에서 응답하지 않았습니다.

요청 기록 선언된 도구 결과
메시지 및 추론만 포함 없음 완료됨
함수 호출 출력 포함 없음 완료됨
web_search_call 포함 없음 실패
web_search_call 포함 함수 도구만 실패
web_search_call 포함 web_search 완료됨
동일, 검색 항목 제거됨 없음 완료됨

테스트는 크기를 배제합니다. 한 테스터는 자동 압축 임계값을 2,000 토큰으로 설정했습니다: -c model_auto_compact_token_limit=2000. 도구 사용이 없는 세션은 잘 압축되었습니다. 한 번 검색한 세션은 여섯 번 연속 실패했습니다. 또 다른 테스터는 추론 항목을 제거해도 도움이 되지 않았고, 단일 검색 항목을 제거하니 효과가 있었습니다.

한 테스트에서 web_search가 선언된 버전은 2.63초 만에 완료되었고 새로운 검색 호출은 없었습니다. 도구를 선언해도 모델이 다시 검색하지는 않습니다.

커뮤니티가 시도한 것과 실제로 작동하는 것

이 게시물을 촉발한 LINUX DO 스레드는 대부분의 일반적인 추측을 거쳤습니다:

제안 도움이 됨? 이유
컨텍스트 축소, 더 일찍 압축하기 아니요 크기가 트리거가 아닙니다
IP로 연결, nginx 변경 아니요 오류는 상위에서 발생합니다
WebSocket으로 전환 신뢰할 수 없음 요청 본체는 동일합니다
ChatGPT에 직접 로그인 아니요 공식 로그인도 실패합니다
새 세션, 컨텍스트 전달 임시방편 검색 후 다시 실패합니다
웹 검색 비활성화 예, 새로운 세션에 대해 검색이 없으면 트리거가 없습니다
요청에 web_search 선언 예 검사를 만족합니다

이 중 몇 가지는 더 설명이 필요합니다.

Nginx 및 IP. 시간 초과 및 유휴 연결은 다른 "스트림 연결 해제" 오류를 유발할 수 있지만, 이 메시지를 생성할 수는 없습니다. 관련된 프록시의 유지 관리자는 이 메시지가 프록시에서 생성되지 않으며, 상위 제공업체에서 발생한다고 확인했습니다. 메시지가 있다면 네트워크가 요청을 통과시켰다는 의미입니다.

WebSocket. 작동하는 게이트웨이 패치는 HTTP뿐만 아니라 WebSocket 경로도 커버해야 했습니다. 왜냐하면 WebSocket 요청은 동일한 본체를 전달하기 때문입니다. "복구된" 세션은 기록에 검색이 없었을 가능성이 높습니다.

공식 로그인. openai/codex 트래커의 보고서에는 프록시 없이 ChatGPT 계정으로 직접 로그인한 데스크탑 앱과 codex-cli가 포함되어 있습니다. 2026년 10월 10일 현재, 코덱스 0.162.1 또는 0.163.0 알파는 수정 사항을 언급하지 않으며, 문제에 대한 유지 관리자의 응답이 없습니다.

지금 할 수 있는 일

새 세션에 대해 웹 검색 비활성화

~/.codex/config.toml에서 검색을 끄세요:

web_search = "disabled"

코덱스 구성 참조에는 네 가지 값이 나열되어 있습니다: disabled, cached (기본값), indexed 및 live. --yolo 또는 다른 전체 액세스 샌드박스와 함께 시작된 세션은 기본적으로 live로 설정되므로 명시적으로 설정하세요.

이 설정은 새로운 세션에 적용하세요. 이전 세션은 이미 web_search_call 항목이 기록에 있습니다. 검색이 비활성화되면 정상적인 턴도 도구를 선언하지 않게 되어, 이러한 턴도 실패할 수 있습니다. 이는 위의 규칙에 따라 발생하지만, 아직 테스트한 보고는 없습니다.

비용은 코덱스가 웹을 검색할 수 없다는 것입니다. 검색이 필요한 세션의 경우, 별도의 짧은 세션을 열거나 모델이 발견한 내용을 파일에 작성하게 하여 긴 세션이 읽도록 하세요.

막힌 세션 구하기

당신의 쪽에서 막힌 세션이 압축되도록 만들 수 있는 방법은 없습니다. 작업을 유지하려면:

  1. 막힌 세션을 그대로 두세요. 그 기록은 여전히 ~/.codex/sessions/에 디스크에 저장되어 있습니다.
  2. 웹 검색이 비활성화된 새 세션을 시작하세요.
  3. 이전 세션 파일을 가리키거나 짧은 인수인계를 붙여넣으세요: 목표, 변경된 파일, 내린 결정 및 남은 작업.
  4. 이전 세션에 프롬프트를 보내지 마세요. 모든 시도가 압축을 재시도하고 다시 실패합니다.

자체 게이트웨이를 유지하는 경우

작동하는 수정 사항은 하나의 규칙을 따릅니다. input에 web_search_call가 포함되어 있고 web_search* 도구가 선언되지 않은 경우, 하나를 추가하세요. 호출자가 도구를 선언하지 않았다면 tool_choice를 "none"로 설정하여 도구가 실행되지 않도록 하세요. input은 그대로 두세요.

def declare_replayed_web_search(body: dict) -> dict:
    """Let the upstream accept a replayed web_search_call in a tool-less request."""
    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)
    # Cached index only: the declaration exists to satisfy the check, not to search.
    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의 구독 백엔드를 거치며, 코덱스가 ChatGPT 로그인으로 사용하는 엔드포인트입니다. 그 규칙은 문서화되어 있지 않으며, 이 규칙은 예고 없이 변경되었습니다.

코덱스는 API 키로 공개 Responses API를 사용할 수도 있습니다. 이 경로에서 이 오류에 대한 보고는 없지만, 우리가 직접 재현해 보지 않았으므로 보장할 수는 없습니다. AIHubMix 키로 코덱스를 설정하려면 코덱스 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 및 프록시 네트워크 설정은 그대로 두었습니다. 이들은 원인이 아닙니다.

자주 묻는 질문

코덱스에서 "응답 보호를 사용할 수 없음"은 무엇을 의미하나요?
이는 코덱스 자체나 프록시에서 발생하는 오류가 아니라 ChatGPT의 코덱스 백엔드에서 발생하는 오류입니다. 2026년 10월 초부터 이전 웹 검색을 재생하지만 웹 검색 도구를 선언하지 않을 때 나타납니다. 이는 압축 요청이 하는 일입니다.

내 컨텍스트 창이 너무 큰가요?
아니요. 테스터들은 2,000 토큰 압축 임계값으로 재현했으며, 검색 없이 동일한 크기의 세션은 정상적으로 압축됩니다. 압축이 긴 세션에서만 실행되기 때문에 크기와 관련이 있는 것처럼 보입니다.

공식 코덱스 앱에 ChatGPT 로그인 시 영향을 미치나요?
예. 데스크탑 앱과 codex-cli 사용자는 프록시 없이 직접 ChatGPT 로그인 시 이를 보고합니다. 2026년 10월 10일 현재, 코덱스 릴리스는 수정 사항을 언급하지 않습니다.

세션이 이를 겪을지 어떻게 알 수 있나요?
세션이 어느 시점에서 웹 검색을 사용했다면, 다음 압축은 대부분 실패할 것입니다. 코덱스는 각 검색을 세션 파일의 .codex/sessions 폴더에 있는 web_search_call 항목으로 기록합니다.

웹 검색을 비활성화하면 이미 막힌 세션이 해결되나요?
아마도 아닙니다. 이전 기록에는 여전히 검색이 포함되어 있으며, 검색이 비활성화되면 정상적인 턴도 도구를 선언하지 않게 되어 실패할 수 있습니다. 이 설정은 새로운 세션에 사용하고 작업을 이동하세요.

WebSocket으로 전환하거나 nginx를 변경하면 도움이 되나요?
아니요. 요청 본체는 두 전송 방식 모두에서 동일하며, 오류는 상위에서 발생하므로 네트워크 설정으로 제거할 수 없습니다. 다른 스트림 오류는 시간 초과에서 발생할 수 있지만, 이 오류는 아닙니다.

코덱스가 ChatGPT 구독 대신 API 키를 사용할 때 발생하나요?
지금까지 모든 보고서는 구독 백엔드를 포함합니다. 공개 Responses API에서 이 오류가 발생했다는 보고는 없지만, 이는 직접 테스트되지 않았습니다.

계속 읽기: GPT-6.1 Sol 시리즈

출처