Przegląd
Oprócz API kompatybilnego z OpenAI GoModel przyjmuje requesty w dialekcie Anthropic Messages API podPOST /v1/messages. Klienty i SDK, które mówią
formatem Anthropic, mogą wskazywać na GoModel bez żadnych zmian.
Request jest tłumaczony na kanoniczny typ czatu GoModel już na wejściu i przechodzi przez
ten sam pipeline co /v1/chat/completions – działają więc modele wirtualne, polityka
workflow, budżety, failover, cache odpowiedzi, śledzenie użycia i kosztów oraz log
audytowy. Ponieważ każdy provider obsługuje chat completion, request w formacie
Anthropic można skierować do dowolnego skonfigurowanego providera (OpenAI, Gemini,
Bedrock i innych), nie tylko do Anthropic.
To coś innego niż passthrough API: /p/anthropic/v1/messages
przekazuje bajty bez zmian wyłącznie do upstreamu Anthropic, natomiast zarządzany endpoint
/v1/messages kieruje requesty gdziekolwiek i jest w pełni zarządzany.
Natywne przekazywanie do Anthropic
Gdy request/v1/messages zostanie rozwiązany do providera Anthropic, GoModel
pomija tłumaczenie w obie strony i przekazuje oryginalne body requestu bez zmian
(nadpisując tylko pole model, gdy alias został rozwiązany do innej nazwy),
a następnie przekazuje natywną odpowiedź providera lub strumień SSE bez zmian.
Zachowuje to wszystko, czego kanoniczne tłumaczenie nie potrafi odwzorować –
breakpointy cache_control, podpisy bloków thinking, nagłówki anthropic-beta –
od czego zależą agenty programistyczne takie jak Claude Code. Rate limity,
budżety, log audytowy i śledzenie użycia nadal działają, zarówno dla odpowiedzi
streamingowych, jak i niestreamingowych.
Natywne przekazywanie działa automatycznie. Requesty wracają do pipeline’u
z tłumaczeniem, gdy w grę wchodzi funkcja działająca na kanonicznym requeście:
modyfikowanie requestu przez guardrails, cache odpowiedzi lub routing z failoverem.
Requesty rozwiązywane do providera innego niż Anthropic są zawsze tłumaczone.
Ponieważ body jest przekazywane bez zmian, na tej ścieżce nie obowiązuje żadne
z ograniczeń tłumaczenia: historia narzędzi serwerowych
(server_tool_use, web_search_tool_result, …), uploady do kontenerów i każdy inny
blok, którego kanoniczny request nie potrafi odwzorować, docierają do Anthropic bez zmian.
Obsługiwane endpointy
Message Batches
/v1/messages/batches współdzieli pipeline natywnych batchy gatewaya z trasą
/v1/batches kompatybilną z OpenAI – obie są widokami tego samego zasobu w różnych
dialektach. ID batchy są wymienne między dialektami (msgbatch_<uuid>
tutaj, batch_<uuid> tam). Wszystkie requesty w jednym batchu muszą być rozwiązane
do jednego providera; wartości custom_id dla każdego elementu są wymagane i muszą być unikalne.
Providerzy, których batch API opiera się na plikach (kompatybilni z OpenAI), otrzymują
requesty inline jako automatycznie uploadowany plik wejściowy JSONL. request_counts
mapuje zagregowane liczniki providera: w trakcie działania batcha niezakończone requesty
są raportowane jako processing; po jego zakończeniu pozostałe są przypisywane według
wyniku batcha (canceled, expired lub errored).
Uwierzytelnianie
Działają oba sposoby przekazywania danych uwierzytelniających, więc oficjalne SDK Anthropic można podłączyć bez zmian:Authorization: Bearer <key>– podstawowy schemat GoModel.x-api-key: <key>– natywny nagłówek Anthropic, akceptowany jako fallback, gdy nie ma nagłówkaAuthorization.
Przykład
type: "message", bloki content,
stop_reason, usage). Błędy używają koperty błędu Anthropic
({"type": "error", "error": {...}}). max_tokens jest wymagane, tak jak w API Anthropic.
Zadziałanie filtra treści providera jest raportowane jako stop_reason: "refusal". Jeśli
provider zawiedzie w trakcie strumienia, strumień kończy się zdarzeniem error
z komunikatem samego providera.
usage stosuje semantykę Anthropic dla każdego providera: input_tokens nie obejmuje
tokenów z cache’u, które są raportowane osobno jako cache_read_input_tokens
i cache_creation_input_tokens. W przypadku providerów kompatybilnych z OpenAI, których
prompt_tokens obejmuje tokeny z cache’u, GoModel przenosi cached_tokens
i cache_write_tokens do tych pól, więc trzy liczniki sumują się do całego
promptu.
Odpowiedzi streamingowe emitują sekwencję zdarzeń SSE Anthropic (message_start,
content_block_start/content_block_delta/content_block_stop, message_delta,
message_stop).
Śledzenie kosztów i logi audytowe
Requesty/v1/messages są śledzone i audytowane dokładnie tak jak trasy kompatybilne
z OpenAI. Koszt jest wyliczany na podstawie providera, który faktycznie obsłużył request,
a użycie jest zapisywane pod endpointem /v1/messages, dzięki czemu można je filtrować
w dashboardzie.
Ograniczenia
Te ograniczenia dotyczą pipeline’u z tłumaczeniem – requestów kierowanych do providera innego niż Anthropic albo do Anthropic, gdy działają guardrails, cache odpowiedzi lub failover. Requesty natywnie przekazywane do Anthropic są zachowywane bajt w bajt, z wyjątkiem wartościmodel, gdy alias został
rozwiązany do innej nazwy, i nic z poniższego ich nie dotyczy.
/v1/messages tłumaczy przez kanoniczny typ czatu GoModel. Funkcje specyficzne dla
Anthropic, które nie mają kanonicznego odpowiednika, nie są zachowywane od początku do końca:
cache_controljest zachowywane w requeście, blokach system/content, niestandardowych narzędziach oraz historii tool-use/tool-result przy kierowaniu do Anthropic.- Wiadomości
{"role": "system"}wewnątrzmessageszachowują swoją pozycję i breakpointycache_controlprzy kierowaniu do modelu z rodziny Claude 4.8+/5 (Claude Code w ten sposób dokleja przypomnienia systemowe, a jego prompt caching zależy od tego, czy pozostaną na miejscu). W starszych modelach Claude, które odrzucają tę rolę, ich tekst jest zamiast tego przenoszony do system promptu najwyższego poziomu. - Bloki
thinkingiredacted_thinkingprzechodzą w obie strony bez zmian, łącznie z podpisami: odpowiedzi zawierająsignaturewydany przez Anthropic (jakosignature_deltaprzy streamingu), a odesłana tura asystenta jest odtwarzana bez zmian, więc rozmowy z włączonym thinking i pętle tool-use działają poprawnie. Inni providerzy nigdy ich nie widzą. - Reasoning od providera, który go nie podpisuje (DeepSeek, Fireworks, …),
jest zwracany jako blok
thinkingzsignature: ""– to pole jest wymagane przez schemat Anthropic, a pusta wartość oznacza, że reasoning nie jest podpisany. Odeślij turę bez zmian: blok trafia z powrotem do tego providera jak każdy inny. Anthropic akceptuje tylko podpisy, które sam wystawił, więc z tury zawierającej niepodpisany blok jest on usuwany przed wysłaniem do Claude (reszta tury jest wysyłana bez zmian). tool_result.is_errorjest zachowywane przy kierowaniu do Anthropic. Inni providerzy nie mają odpowiedniej flagi i otrzymują tylko treść wyniku.tool_use.extra_contentprzenosi stan do odtworzenia należący do innego providera, na przykład thought signature Gemini 3, z powrotem do tego providera. GoModel ustawia go w zwracanych blokachtool_use; odsyłaj go bez zmian. Zobacz Extra content, bloki thinking i thought signatures.- Narzędzia serwerowe/wbudowane (web search, wykonywanie kodu, …) i ich bloki
historii (
server_tool_use,web_search_tool_result, …) są odrzucane z czytelnym400; tłumaczone są tylko narzędzia niestandardowe (typenieobecne lub"custom"). Wyjątkiem jest tool search (zobacz odroczone ładowanie narzędzi poniżej). top_kjest pomijane – nie ma przenośnego odpowiednika kompatybilnego z OpenAI, a providerzy z rodziny OpenAI odrzucają nieznane pola requestu.temperatureitop_psą przekazywane.- Obrazy i dokumenty wewnątrz bloków
tool_result(zrzuty ekranu, pliki obrazów i PDF odczytane przez narzędzie – Claude Code zwraca je w ten sposób) są przekazywane jako natywne blokiimageidocumentprzy kierowaniu do Anthropic. OpenAI otrzymuje je przez swoje Responses API, gdzie model może je zobaczyć (zobacz Requesty OpenAI obsługiwane przez Responses). Inni providerzy otrzymują tylko tekstową część wyniku narzędzia. - Bloki
document(źródła PDF, plain text, URL lubfile_idz Files API) są tłumaczone na część treścifilew stylu OpenAI (file_datadla treści inline,file_urldla zdalnych URL-i,file_iddla uploadów). Anthropic otrzymuje dokument z powrotem natywnie wraz z jegotitle; Gemini otrzymuje tylko dane inline; providerzy kompatybilni z OpenAI otrzymują częśćfilebez zmian. W OpenAI PDF bez tytułu dostaje nazwę pliku (document.pdf), a dokumenty z URL przechodzą przez Responses API. Dokument tekstowy w requeście, który pozostaje na Chat Completions, jest wysyłany jako tekst (poprzedzony swoimtitle), ponieważ akceptowane są tam tylko dane plików PDF; w requeście obsługiwanym przez Responses API, np. z dokumentem tekstowym wewnątrztool_result, pozostaje plikiem. Ustawienia cytowań icontextsą pomijane. Wariant z treścią niestandardową (source.type: "content") degraduje się do tekstu. - Bloki
search_resultdegradują się do tekstu (tytuł, URL źródła i treść); metadane cytowań są pomijane. - Odroczone ładowanie narzędzi jest akceptowane. Narzędzie oznaczone
defer_loading: trueto zwykłe narzędzie niestandardowe, którego schemat API ładuje na żądanie; znacznik nie ma kanonicznego odpowiednika i jest pomijany, więc narzędzie jest wysyłane jak każde inne.tool_reference(dopasowanie tool search) degraduje się do nazwy narzędzia jako tekstu, ponieważ żaden provider za pipeline’em z tłumaczeniem nie ładuje schematów narzędzi przez referencję. Rozmowę, w której działał serwerowy tool search Anthropic, można kontynuować na innym modelu: narzędzie tool search jest pomijane, ponieważ każde odroczone narzędzie jest już wysyłane w całości, a jego historia (server_tool_useitool_search_tool_result) degraduje się do tekstu z nazwą wyszukiwania i znalezionymi narzędziami. Dzięki temu Claude Code może działać zENABLE_TOOL_SEARCHprzez gateway z modelem innym niż Anthropic. - Inne bloki treści (
container_upload, …) są odrzucane z czytelnym błędem400zamiast cicho pomijane. stop_sequencessą respektowane u każdego providera. Providerzy, którzy natywnie raportują dopasowaną sekwencję (Anthropic), zwracają pełny kontrakt:stop_reason: "stop_sequence"wraz z wartościąstop_sequence; tak samo modele reasoning OpenAI (GPT-5 i nowsze, seria o), w których GoModel sam przycina wyjście, ponieważ OpenAI odrzuca dla nichstop. Inne modele z rodziny OpenAI nie odróżniają wfinish_reasonzatrzymania przez parametr stop od naturalnego zakończenia, więc ich odpowiedzi raportująstop_reason: "end_turn"(wyjście jest nadal poprawnie przycięte).output_config:effortustawia reasoning effort (ma pierwszeństwo przed wartością wyprowadzoną zthinking), aformat(lub starsze pole najwyższego poziomuoutput_format) staje się structured output opartym na JSON schema – w trybie strict, gdy schemat spełnia reguły trybu strict OpenAI (additionalProperties: false, każda właściwość wymagana i brak słów kluczowychallOf,notani warunkowych). Pozostałe schematy są wysyłane zstrict: false: ukierunkowują wyjście, ale go nie gwarantują. Format inny niżjson_schemajest odrzucany z400.thinkingw modelu innym niż Anthropic staje się reasoning effort (budżet poniżej 10000 tokenów:low, poniżej 20000:medium, w przeciwnym raziehigh; adaptive:medium), wysyłanym w polu właściwym dla danego providera:reasoning_effortw OpenAI, Groq, Fireworks i xAI. Modele, które odrzucają to pole (OpenAIgpt-4*, modele Groq inne niż gpt-oss i qwen3,-non-reasoningxAI,grok-build,grok-2igrok-3z wyjątkiemgrok-3-mini), otrzymują request bez niego zamiast błędu. Reasoning wraca jako blokithinkingniezależnie od tego, którego pola provider do tego używa (reasoning_contentlubreasoning).count_tokensjest dokładne, gdy provider modelu sam potrafi liczyć tokeny: modele Anthropic są liczone przez własny endpointcount_tokensAnthropic. Przekazywany request zawiera rozwiązany model (alias jest rozwiązywany najpierw) i tylko pola akceptowane przez ten endpoint:messages,system,tools,tool_choice,thinking,cache_controlioutput_config;max_tokens,stream,metadatai parametry samplingu są pomijane, ponieważ Anthropic je tam odrzuca. Modele OpenAI są liczone przez endpoint OpenAI/v1/responses/input_tokensdla requestu w postaci, w jakiej GoModel go wyśle. W GPT-5 i nowszych wynik odpowiada rozliczanemu wejściu (z dokładnością do tokenu): dla requestu z narzędziami obsługiwanego przez Chat Completions doliczany jest stały preambuł narzędzi, za który naliczana jest opłata. W starszych rodzinach modeli taki request może dać wynik o kilka tokenów niższy od rozliczanego wejścia (6 wgpt-4o-mini). Guardrails nie są uruchamiane przy liczeniu, więc gdy workflow requestu ma guardrails promptu, prompt nigdy nie jest wysyłany do providera w celu policzenia i odpowiada oszacowanie (guardrails działające tylko na odpowiedzi i strumieniu zachowują dokładne liczenie). Dla każdego innego providera, a także gdy to wywołanie się nie powiedzie, gateway odpowiada oszacowaniem, które waży tekst według gęstości tokenizacji (proza, kod i JSON, CJK, emoji), dolicza narzut na każdą wiadomość i każde narzędzie oraz system prompt dla tool-use, a obrazy wycenia według ich powierzchni w pikselach. Przy typowym ruchu agentów oszacowanie mieści się w około dziesięciu procentach od dokładnego wyniku tokenizera; surowe base64 w tekście pozostaje niedoszacowane, a obraz, którego rozmiaru nie da się odczytać, jest liczony jako największy rozmiar, jaki zachowuje provider. To samo oszacowanie wypełniausage.input_tokensw streamingowym zdarzeniumessage_start; miarodajne liczniki przychodzą w końcowym zdarzeniumessage_delta, które akumulatory SDK traktują priorytetowo.
/p/anthropic/v1/messages.
Uzasadnienie projektu i kompromisy opisuje
ADR-0007.