Błąd kompresji Codex z komunikatem "ochrona odpowiedzi jest niedostępna": to wyszukiwanie w sieci, a nie twój kontekst

AIHubMix8 min czytania
Błąd kompresji Codex z komunikatem "ochrona odpowiedzi jest niedostępna": to wyszukiwanie w sieci, a nie twój kontekst

Od 8 października 2026 roku długie sesje Codex kończą się niepowodzeniem w momencie próby kompresji. Błąd brzmi stream disconnected before completion: response protection is unavailable, ponowne próby nie pomagają, a rozmowa nie może być kontynuowana. Większość zgłoszeń dotyczy gpt-6.1-sol, ale gpt-6-astra i gpt-5.6-sol również kończą się w ten sam sposób. Problem występuje za proxy hostowanymi samodzielnie, a także w oficjalnej aplikacji Codex z bezpośrednim logowaniem do ChatGPT.

Krótka odpowiedź: kontekst nie jest zbyt duży, a twoja sieć nie jest problemem. Backend Codex odrzuca teraz wszelkie żądania, które powtarzają wcześniejsze wyszukiwanie w sieci w swojej historii, nie deklarując jednocześnie narzędzia wyszukiwania w sieci. Żądanie kompresji Codex nie deklaruje żadnych narzędzi. Tak więc pojedyncze wyszukiwanie w sieci na początku sesji wystarczy, aby każde późniejsze żądanie kompresji zakończyło się niepowodzeniem.

Co robić teraz:

  • Nowe sesje: ustaw web_search = "disabled" do czasu, aż backend lub Codex się zmienią.
  • Utknęte sesje: przenieś pracę do nowej sesji. Stara nie skompresuje się.
  • Jeśli utrzymujesz własną bramkę przed Codex: dodaj deklarację wyszukiwania w sieci, gdy historia zawiera wyszukiwanie. Kod znajduje się poniżej.

Reszta tego wpisu wyjaśnia, jak znaleziono wyzwalacz, które poprawki społeczności nie działają i jak uratować utknętą sesję.

Jak wygląda błąd

W Codex zobaczysz jeden z tych komunikatów:

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

Drugi komunikat jest wersją ogólną. Codex nie zawsze pokazuje błąd z upstream, więc kompresja, która kończy się błędem "stream closed before response.completed", może być tym samym problemem. Lokalny dziennik Codex często zawiera Failed to run pre-sampling compact obok niego.

Poniżej, upstream wysyła jedną z dwóch rzeczy. Czasami jest to HTTP 502 z tym ciałem, które użytkownik ChatGPT Plus na gpt-6.1-sol również opublikował na forum deweloperów OpenAI:

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

Innym razem jest to HTTP 200, którego strumień kończy się zdarzeniem response.failed z code: "upstream_error" i bez response.completed. Cokolwiek, co tylko sprawdza status HTTP, przegapia drugą formę i zgłasza to jako strumień, który zakończył się przedwcześnie.

Wzór jest taki sam wszędzie:

  • Normalne tury nadal działają. Tylko kompresja kończy się niepowodzeniem.
  • Codex próbuje około pięciu razy, a potem się poddaje. W dziennikach jednej bramki każdy nieudany prób zajmował od 2 do 13 sekund i rejestrował zero tokenów.
  • Wznawianie sesji napotyka tę samą kompresję, więc sesja pozostaje utknęta.
  • Nowa sesja działa, dopóki nie napotka tych samych warunków.

Wyzwalacz: wyszukiwanie w historii, brak narzędzia wyszukiwania w żądaniu

Codex ma wbudowane narzędzie wyszukiwania w sieci. Kiedy model go używa, element web_search_call trafia do historii rozmowy. Każde późniejsze żądanie wysyła tę historię z powrotem.

Normalne tury deklarują narzędzie w tools, więc upstream akceptuje powtórzone wyszukiwanie. Żądanie kompresji jest inne. Codex wysyła całą historię z tools: [], ponieważ podsumowanie nie potrzebuje narzędzi. To dotyczy lokalnej kompresji, którą Codex wykonuje dla dostawców niestandardowych, oraz zdalnej kompresji v2.

Wokół 6 października backend Codex ChatGPT zaczął odrzucać żądania, które powtarzają web_search_call, ale nie deklarują web_search. Deweloperzy, którzy uchwycili surowe żądania, zawęzili to. Zmiana lub usunięcie identyfikatora elementu wyszukiwania nie ma znaczenia. Deklarowanie tylko narzędzia funkcji również kończy się niepowodzeniem. Deklarowanie web_search sprawia, że to samo żądanie kończy się sukcesem.

Ten sam wynik pojawia się z oficjalnym, niezmodyfikowanym codex-cli zalogowanym na konto ChatGPT. Historia z trzema elementami wyszukiwania nie mogła się skompresować. Ta sama historia z usuniętymi tylko tymi elementami skompresowała się poprawnie. Drugi reporter w tym wątku uchwycił żądanie kompresji z jednym web_search_call i tools: []. Dodanie deklaracji web_search naprawiło to, a także usunięcie elementu wyszukiwania.

To wyjaśnia, dlaczego wygląda to jak problem z rozmiarem kontekstu. Kompresja działa tylko w długich sesjach, a długie sesje to te, które najprawdopodobniej używały wyszukiwania w pewnym momencie. Wyszukiwanie w sieci jest również domyślnie włączone w Codex (domyślny tryb to "cached"), więc sesja może zawierać wyszukiwanie, o które użytkownik nigdy nie prosił.

Dowody

Co najmniej cztery grupy przeprowadziły testy A/B niezależnie i uzyskały ten sam wynik. Wiersze poniżej łączą testy opublikowane na trackerze openai/codex oraz w trackerach problemów kilku projektów bramek open-source. OpenAI nie potwierdziło tej zasady ani nie odpowiedziało w żadnym z tych wątków.

Historia żądania Zadeklarowane narzędzia Wynik
Tylko wiadomości i rozumowanie Brak Zakończone
Zawiera wynik wywołania funkcji Brak Zakończone
Zawiera web_search_call Brak Niepowodzenie
Zawiera web_search_call Tylko narzędzie funkcji Niepowodzenie
Zawiera web_search_call web_search Zakończone
To samo, usunięto elementy wyszukiwania Brak Zakończone

Testy wykluczają rozmiar. Jeden tester ustawił próg automatycznej kompresji na 2000 tokenów z -c model_auto_compact_token_limit=2000. Sesja bez użycia narzędzi skompresowała się poprawnie. Sesja, która raz wyszukiwała, nie mogła się skompresować sześć razy z rzędu. Inny tester odkrył, że usunięcie elementów rozumowania nie pomogło, podczas gdy usunięcie jedynego elementu wyszukiwania zadziałało.

W jednym teście wersja z zadeklarowanym web_search zakończyła się w 2,63 sekundy i nie wykonała żadnych nowych wyszukiwań. Deklarowanie narzędzia nie powoduje ponownego wyszukiwania przez model.

Co próbowała społeczność i co naprawdę działa

Wątek LINUX DO, który zainspirował ten wpis, przeszedł przez większość typowych przypuszczeń:

Sugestia Pomaga? Dlaczego
Zmniejsz kontekst, kompresuj wcześniej Nie Rozmiar nie jest wyzwalaczem
Połącz przez IP, zmień nginx Nie Błąd pochodzi z upstream
Przełącz na WebSocket Niepewne To samo ciało żądania w obu przypadkach
Zaloguj się bezpośrednio do ChatGPT Nie Oficjalne logowanie również kończy się niepowodzeniem
Nowa sesja, przekaż kontekst Tymczasowe rozwiązanie Znowu się psuje po wyszukiwaniu
Wyłącz wyszukiwanie w sieci Tak, dla nowych sesji Brak wyszukiwania, brak wyzwalacza
Zadeklaruj web_search w żądaniu Tak Spełnia wymóg

Niektóre z tych sugestii wymagają dodatkowego wyjaśnienia.

Nginx i IP. Czas oczekiwania i nieaktywne połączenia mogą powodować inne błędy "strumień rozłączony", ale nie mogą generować tego komunikatu. Utrzymujący proxy potwierdzili, że komunikat nie jest generowany przez proxy; pochodzi od dostawcy upstream. Jeśli komunikat jest obecny, sieć przesłała żądanie i otrzymała odpowiedź.

WebSocket. Poprawki bramek, które działały, musiały obejmować zarówno ścieżkę WebSocket, jak i HTTP, ponieważ żądania WebSocket mają to samo ciało. Sesja, która "odzyskała" po przełączeniu transportu, najprawdopodobniej nie miała wyszukiwania w swojej historii.

Oficjalne logowanie. Raporty na trackerze openai/codex obejmują aplikację desktopową i codex-cli zalogowane bezpośrednio na konto ChatGPT, bez zaangażowania proxy. Na 10 października ani Codex 0.162.1, ani alfy 0.163.0 nie wspominają o poprawce, a problemy nie mają odpowiedzi od utrzymujących.

Co możesz zrobić teraz

Wyłącz wyszukiwanie w sieci dla nowych sesji

Wyłącz wyszukiwanie w ~/.codex/config.toml:

web_search = "disabled"

Referencja konfiguracji Codex wymienia cztery wartości: disabled, cached (domyślnie), indexed i live. Sesje rozpoczęte z --yolo lub innym pełnym dostępem domyślnie ustawiają się na live, więc ustaw to wyraźnie.

Stosuj to do nowych sesji. Stara sesja ma już elementy web_search_call w swojej historii. Przy wyłączonym wyszukiwaniu normalne tury przestaną również deklarować narzędzie, więc te tury mogą również zacząć kończyć się niepowodzeniem. To wynika z powyższej zasady, ale nikt jeszcze nie zgłosił testowania tego.

Kosztuje to, że Codex nie może przeszukiwać sieci. Dla sesji, która potrzebuje wyszukiwania, otwórz osobną krótką sesję lub pozwól modelowi zapisać wyniki do pliku, który długa sesja odczyta.

Uratuj utknętą sesję

Nic po twojej stronie nie sprawi, że utknęta sesja skompresuje się, gdy backend działa w ten sposób. Aby zachować pracę:

  1. Zostaw utknętą sesję taką, jaka jest. Jej historia nadal znajduje się na dysku w ~/.codex/sessions/.
  2. Rozpocznij nową sesję z wyłączonym wyszukiwaniem w sieci.
  3. Wskaź ją na stary plik sesji lub wklej krótki przekaz: cel, zmienione pliki, podjęte decyzje i co pozostało.
  4. Przestań wysyłać podpowiedzi do starej sesji. Każda próba ponownie próbuje kompresji i kończy się niepowodzeniem.

Jeśli utrzymujesz własną bramkę

Poprawka, która działa, podąża za jedną zasadą. Jeśli input zawiera web_search_call i nie zadeklarowano żadnego narzędzia web_search*, dodaj jedno. Jeśli wywołujący nie zadeklarował żadnych narzędzi, ustaw tool_choice na "none", aby narzędzie nie mogło działać. Pozostaw input bez zmian.

def declare_replayed_web_search(body: dict) -> dict:
    """Pozwól upstream zaakceptować powtórzone web_search_call w żądaniu bez narzędzi."""
    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)
    # Tylko indeks podręczny: deklaracja istnieje, aby spełnić wymóg, a nie do wyszukiwania.
    body["tools"] = tools + [{"type": "web_search", "external_web_access": False}]
    if not caller_had_tools:
        body["tool_choice"] = "none"
    return body

Żądania Lite są wyjątkiem. Zwracają 400, jeśli web_search znajduje się w górnym poziomie tools. Działające poprawki umieszczają je w pierwszym elemencie additional_tools zamiast tego, a wszelkie końcowe compaction_trigger pozostają na końcu. Alternatywa, usunięcie elementów wyszukiwania z żądań kompresji, również działa, ale podsumowanie traci to, co znalazło wyszukiwanie.

Jeśli wolisz nie polegać na backendzie subskrypcyjnym

Każdy raport, który znaleźliśmy, przechodzi przez subskrypcyjny backend ChatGPT, punkt końcowy, którego Codex używa z logowaniem do ChatGPT. Jego zasady nie są udokumentowane, a ta zmieniła się bez powiadomienia.

Codex może również korzystać z publicznego API Responses z kluczem API. Nie widzieliśmy dotąd raportu o tym błędzie na tej ścieżce, ale nie przeprowadziliśmy tam reprodukcji, więc traktuj to jako obserwację, a nie gwarancję. Aby skonfigurować Codex z kluczem AIHubMix, postępuj zgodnie z samouczkiem 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"

Ceny API obowiązują za token, a nie za subskrypcję. Stawki znajdują się na stronie modelu gpt-6.1-sol.

Lista kontrolna

  • Tekst błędu zawiera "ochrona odpowiedzi jest niedostępna", lub kompresja kończy się błędem "strumień zamknięty przed zakończeniem odpowiedzi".
  • Normalne tury nadal działają, a tylko kompresja kończy się niepowodzeniem.
  • Sesja używała wyszukiwania w sieci w pewnym momencie, być może bez pytania.
  • Nowe sesje mają ustawione web_search na wyłączone.
  • Utknięta praca została przeniesiona do nowej sesji z notatką przekazującą.
  • Bramka, którą utrzymujesz, dodaje deklarację wyszukiwania w sieci, gdy historia zawiera wyszukiwanie.
  • Ustawienia Nginx i proxy zostały pozostawione w spokoju. Nie są przyczyną.

FAQ

Co oznacza "ochrona odpowiedzi jest niedostępna" w Codex?
To błąd z backendu Codex ChatGPT, a nie z samego Codexu ani twojego proxy. Od początku października 2026 roku pojawia się, gdy żądanie powtarza wcześniejsze wyszukiwanie w sieci, ale nie deklaruje narzędzia wyszukiwania w sieci, co dokładnie robi żądanie kompresji.

Czy moje okno kontekstowe jest za duże?
Nie. Testerzy odtworzyli to z progiem kompresji 2000 tokenów, a sesje o tym samym rozmiarze bez wyszukiwania kompresują się normalnie. Wygląda to tylko na problem z rozmiarem, ponieważ kompresja działa tylko w długich sesjach.

Czy to wpływa na oficjalną aplikację Codex z logowaniem do ChatGPT?
Tak. Użytkownicy aplikacji desktopowej i codex-cli zgłaszają to przy bezpośrednich logowaniach do ChatGPT bez proxy. Na 10 października 2026 roku żadna wersja Codex nie wspomina o poprawce.

Jak mogę sprawdzić, czy sesja napotka ten problem?
Jeśli sesja używała wyszukiwania w sieci w jakimkolwiek momencie, jej następna kompresja najprawdopodobniej zakończy się niepowodzeniem. Codex rejestruje każde wyszukiwanie jako element web_search_call w plikach sesji w folderze .codex/sessions.

Czy wyłączenie wyszukiwania w sieci naprawi sesję, która już utknęła?
Prawdopodobnie nie. Stara historia nadal zawiera wyszukiwanie, a po wyłączeniu wyszukiwania normalne tury mogą przestać deklarować narzędzie i również zakończyć się niepowodzeniem. Użyj tego ustawienia dla nowych sesji i przenieś pracę.

Czy przełączenie na WebSocket lub zmiana nginx pomaga?
Nie. Ciało żądania jest takie samo w obu transportach, a błąd pochodzi z upstream, więc ustawienia sieciowe nie mogą go usunąć. Inne błędy strumieniowe mogą pochodzić z czasów oczekiwania, ale nie ten.

Czy to się zdarza, gdy Codex używa klucza API zamiast subskrypcji ChatGPT?
Wszystkie dotychczasowe raporty dotyczą backendu subskrypcyjnego. Nikt nie zgłosił tego w publicznym API Responses, chociaż to nie zostało przetestowane bezpośrednio.

Czytaj dalej: seria GPT-6.1 Sol

Źródła