Skip to main content

Czym jest extra content

Niektórzy providerzy dołączają do odpowiedzi nieprzezroczysty stan i oczekują, że w następnej turze otrzymają go z powrotem bez zmian. Gemini 3 podpisuje swoje wywołania funkcji thought signature i odrzuca historię, która odtwarza wywołanie bez niej. Anthropic wymaga, aby bloki thinking tury asystenta, łącznie z podpisami, znalazły się przed kontynuowaną turą tool-use. Taki stan nie ma pola kompatybilnego z OpenAI, więc GoModel przenosi go w jednym miejscu: w obiekcie extra_content z kluczami według dostawcy (vendora).
GoModel niczego nie przechowuje. Stan trafia do klienta w odpowiedzi i wraca w historii wiadomości klienta. Klienci, którzy kopiują wiadomości asystenta do historii dosłownie – a tak robią SDK OpenAI, Anthropic i Responses – nie wymagają żadnych zmian. Struktura odpowiada własnemu endpointowi Google kompatybilnemu z OpenAI, więc klienci zbudowani pod niego działają bez zmian.

Gdzie się pojawia

Stan znajduje się na jednostce, która odpowiada jednej części po stronie providera. Wywołanie narzędzia staje się jednym part w Gemini, więc podpis per wywołanie siedzi na wywołaniu narzędzia. Bloki thinking należą do całej tury asystenta, więc siedzą na wiadomości.

Zasady

  • Każde tłumaczenie przenosi go dalej. Wejście Chat, Responses i Anthropic Messages, streaming oraz echo tury asystenta przenoszą extra_content bez zaglądania do środka.
  • Tylko właściwy provider widzi obiekt swojego vendora. Zanim request zostanie wysłany do providera, GoModel usuwa każdy obiekt vendora, którego ten provider nie jest właścicielem. Podpis Gemini nigdy nie trafia do Anthropic ani OpenAI, a historia przeniesiona między providerami nie kończy się błędem z powodu obcych pól.
  • Tylko właściwy adapter odczytuje lub zapisuje jego zawartość. Nic innego w gatewayu nie interpretuje tej zawartości.
  • Odsyłaj go dosłownie. Nie przepisuj, nie zmieniaj kolejności ani nie skracaj tego pola.

Zachowywanie thought signatures

Gemini 3 dołącza zaszyfrowany thoughtSignature do emitowanych wywołań funkcji. Następny request musi zawierać ten sam podpis na tym samym wywołaniu, inaczej Gemini odpowiada HTTP 400 „Function call is missing a thought_signature”. Jedna tura z wywołaniem narzędzia przez Chat Completions wygląda tak. Pokazano tylko istotne pola.
1

Klient zadaje pytanie z dostępnym narzędziem

2

Gemini odpowiada wywołaniem funkcji i podpisem

GoModel tłumaczy request na natywną strukturę generateContent Gemini. Gemini zwraca część functionCall, która zawiera podpis.
3

GoModel zwraca wywołanie z podpisem w extra_content

4

Klient uruchamia narzędzie i odsyła pełną historię

Wiadomość asystenta jest dołączana w otrzymanej postaci, więc extra_content trafia z powrotem bez dodatkowej pracy.
5

GoModel odtwarza podpis na odpowiadającej części Gemini

Gemini akceptuje odtworzoną historię i odpowiada tekstem. GoModel zwraca zwykłe chat completion.
To samo pole pojawia się na streamowanych deltach tool_calls, na elementach function_call w Responses API, na blokach tool_use w Anthropic Messages, a w przypadku tur wyłącznie tekstowych – na samej wiadomości asystenta. W Responses API podpis tury wyłącznie tekstowej jest przenoszony na elemencie wyjściowym reasoning przed wiadomością, bez własnego tekstu reasoning; odeślij ten element, a podpis trafi na turę asystenta. Podpis ma tylko pierwsze wywołanie z równoległego batcha. Akceptowane jest też płaskie pole thought_signature lub thoughtSignature na wywołaniu narzędzia, dzięki czemu klienci zbudowani pod inne gatewaye nadal działają. Gdy historia Gemini 3 zawiera wywołanie funkcji bez żadnego podpisu – bo rozmowa zaczęła się u innego providera albo klient usunął to pole – GoModel wysyła udokumentowany przez Google placeholder zamiast zwracać błąd 400. Zawsze, gdy masz prawdziwą wartość, odsyłaj ją; placeholder kosztuje utratę ciągłości reasoningu w tej turze. Szczegóły po stronie providera znajdziesz w sekcji Gemini thought signatures.

Bloki thinking

Extended thinking w Anthropic zwraca bloki treści thinking i redacted_thinking w turze asystenta. Gdy ta tura kończy się wywołaniem narzędzia, kolejny request musi odtworzyć te bloki, łącznie z podpisami, przed blokiem tool_use. Przez Anthropic Messages API przepływ wygląda tak:
1

Klient wysyła historię zawierającą bloki thinking

2

GoModel przechowuje bloki w extra_content.anthropic

Wewnętrznie historia ma strukturę chatu. Bloki thinking są przenoszone na wiadomości asystenta, a is_error na wyniku narzędzia. Żadne z nich nie ma pola kompatybilnego z OpenAI, więc oba trafiają pod vendora anthropic. is_error jest zapisywane tylko wtedy, gdy wynik zakończył się błędem.
3

Anthropic otrzymuje bloki dosłownie

Gdy trasa prowadzi do Anthropic, bloki thinking wracają przed blok tool_use dokładnie w wysłanej postaci, a is_error zostaje przywrócone na tool_result. Każdy inny provider otrzymuje tylko wywołanie narzędzia i tekst wyniku.

W drodze powrotnej

Anthropic podpisuje każdy zwracany blok thinking i odrzuca późniejszą turę, która odtwarza blok bez jego podpisu:
Dlatego bloki trafiają do klienta w taki sam sposób, w jaki z niego przychodzą. Anthropic Messages API renderuje je jako prawdziwe bloki treści, łącznie z podpisem, bo właśnie to klient Anthropic odsyła z powrotem:
Streaming emituje podpis jako signature_delta wewnątrz bloku thinking, zanim ten blok się zamknie – dokładnie tak jak Anthropic.

Reasoning od providerów, którzy go nie podpisują

DeepSeek, Fireworks i inni providerzy zwracają tekst reasoningu bez niczego, co pozwalałoby go uwierzytelnić. Anthropic Messages API nadal renderuje go jako blok thinking z signature: "" – schemat oznacza to pole jako wymagane, więc klient ze ścisłym typowaniem odrzuciłby blok bez niego. Streaming otwiera blok z pustym podpisem i nie wysyła signature_delta, czyli tak samo, jak Anthropic streamuje blok przed nadejściem prawdziwego podpisu. Odeślij turę bez zmian: blok zostanie odtworzony u tego providera jak każdy inny. Anthropic akceptuje wyłącznie podpisy, które sam wygenerował (brak podpisu kończy się błędem signature: Field required, każda inna wartość błędem Invalid `signature` in `thinking` block), więc gdy taka historia jest kierowana do Anthropic, niepodpisany blok jest usuwany, a reszta tury jest wysyłana normalnie. Pozostałe dialekty nie mają bloku thinking, więc przenoszą te same dane w extra_content.anthropic.thinking_blocks – na wiadomości asystenta w Chat Completions i na elemencie wyjściowym reasoning w Responses API. Streamowane delty chatu przenoszą tę wartość po zakończeniu bloku thinking, przed jakimkolwiek tekstem, i jest ona kumulatywna: ostatnia otrzymana zawiera całą turę.
reasoning_content pozostaje tym, czym było zawsze: czytelnym tekstem, który nie służy do odtwarzania. Blok redacted_thinking nie ma w ogóle czytelnego tekstu, więc przenosi go wyłącznie extra_content. Dołącz turę asystenta do historii w otrzymanej postaci, a odtworzenie nastąpi automatycznie. Skierowanie tej historii do innego providera usuwa to pole – tak jak każdy obcy obiekt vendora – a rozmowa toczy się dalej bez niego.

Przenoszenie historii między providerami

Rozmowa może zacząć się u jednego providera i być kontynuowana u innego. Zasada jest prosta: każdy obiekt vendora, którego właścicielem nie jest docelowy provider, jest usuwany przed wysłaniem – na każdej trasie i w każdym dialekcie. Historia po stronie klienta nigdy nie jest modyfikowana. Filtrowanie odbywa się na kopii, którą GoModel wysyła do upstreamu.

Dokumentacja referencyjna vendorów

Ostatnia modyfikacja 24 października 2026