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 obiekcieextra_content z kluczami według dostawcy (vendora).
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_contentbez 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 zaszyfrowanythoughtSignature 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
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ścithinking 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: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 blokthinking 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.