Bouw een Responses API-compatibiliteitslaag in een AI API Gateway
Een Responses API-gateway is niet alleen een Chat Completions-proxy met een nieuwe route. Behoud responsitems, status, toolaanroepen, streams, redeneringscontinuïteit, gebruiksattributie en downgradegedrag met een eersteklas compatibiliteitslaag.
Implementeer /v1/responses niet door elk verzoek te vertalen naar /v1/chat/completions en te hopen dat de vorm dichtbij genoeg is. Die adapter kan tekst retourneren, maar kan in stilte de onderdelen verliezen waar ontwikkelaars om geven: responsitems, status aan de serverzijde, toolaanroepen, continuïteit van de redenering, gebeurtenissen in de stream-levenscyclus, annuleringssemantiek en gebruiksattributie op itemniveau.
Het praktische doel is een compatibiliteitslaag die de Responses API als een rijker protocol behandelt. Behoud de ondersteuning voor Chat Completions voor bestaande klanten, maar bouw Responses als een eigen gateway-oppervlak met een eigen statusmodel, streamnormalizer, tool-call ledger, mogelijkhedenmatrix en fallback-regels.
Wat is feitelijk, wat is beleid en wat is voorspelling?
Feiten: OpenAI beschrijft de Responses API als verenigende mogelijkheden die voorheen verdeeld waren over Chat Voltooiingen en Assistenten, inclusief ondersteuning voor tools zoals zoeken op internet, zoeken naar bestanden en computergebruik. De API maakt velden zichtbaar zoals previous_response_id, streaming, toolselectie en ingebouwde tools. SDK-documentatie laat zien dat previous_response_id conversatiecontinuïteit kan bieden, terwijl eerdere instructies niet automatisch worden overgedragen en opnieuw moeten worden verzonden wanneer ze nog steeds van toepassing zouden moeten zijn. De streamingreferentie van OpenAI omvat verschillende responslevenscyclus- en uitvoergebeurtenissen in plaats van alleen tokendelta's.
Aanbevelingen: een gateway moet deze semantiek behouden in plaats van deze standaard af te vlakken. Het moet verzoeken afwijzen of expliciet downgraden wanneer een doelprovider het vereiste gedrag niet kan ondersteunen.
Voorspelling: De werklast van meer agenten zal afhangen van de structuur van de responsitems, de traceringen van de uitvoering van tools en de context van stateful redeneren. Gateways die deze concepten nu modelleren, zullen gemakkelijker uit te breiden zijn dan gateways die Responsen als een cosmetisch eindpunt beschouwen.
Definieer een afzonderlijk compatibiliteitscontract voor reacties
De eerste implementatiefout is dat we ervan uitgaan dat OpenAI-compatibel één universeel verzoek- en antwoordschema betekent. In de praktijk zouden /v1/chat/completions en /v1/responses afzonderlijke compatibiliteitscontracten moeten zijn.
Behoud een gedeelde authenticatie-, facturerings-, quota- en routeringslaag, maar scheid de protocollaag:
- Chatvoltooiingen komen naar voren: berichten, keuzes, delta's, toolaanroepen in chatformaat, verouderd klantgedrag.
- Reactiesoppervlak: invoeritems, uitvoeritems, reactie-ID's, eerdere reactiereferenties, rijkere toolgebeurtenissen, levenscyclusstroomgebeurtenissen, redeneringsgerelateerde velden en uiteindelijke reactiestatus.
Deze splitsing is van belang voor conformiteitstests. Een provideradapter die de chattests doorstaat, kan nog steeds de Response-tests niet doorstaan, omdat deze de previous_response_id, de volgorde van items, de weigeringsstructuur, de metagegevens van de gehoste tool of de namen van streaminggebeurtenissen niet kan behouden.
Een minimaal compatibiliteitscontract zou het volgende moeten beantwoorden:
- Welke verzoekvelden worden geaccepteerd, afgewezen, getransformeerd of genegeerd?
- Welke typen antwoorditems blijven behouden?
- Welke tooltypen worden per aanbieder en model ondersteund?
- Kan de provider de gespreksstatus behouden, of moet de gateway deze onderhouden?
- Wat gebeurt er als
store=falsewordt aangevraagd? - Welke streamevenementen zijn gegarandeerd?
- Hoe worden annuleringen, time-outs en gedeeltelijk gebruik geregistreerd?
Als je al een AI API-gateway hebt, behandel Response-ondersteuning dan als een protocoluitbreiding en niet als een routealias.
Gebruik een canoniek responsitemmodel
De Responses API retourneert meer dan één assistentbericht. Het kan verschillende uitvoeritems en gebeurtenissen vertegenwoordigen. Uw gateway heeft een intern canoniek model nodig voordat deze aan een provider kan worden gekoppeld.
Een praktisch intern itemschema kan als volgt beginnen:
{
"gateway_response_id": "gw_resp_...",
"provider_response_id": "resp_...",
"tenant_id": "tien_123",
"key_id": "key_456",
"model_alias": "agent-default",
"provider": "openai",
"artikelen": [
{
"item_id": "item_1",
"type": "tekst",
"rol": "assistent",
"content": [{ "type": "output_text", "text": "..." }],
"status": "voltooid"
},
{
"item_id": "item_2",
"type": "function_call",
"call_id": "call_abc",
"name": "lookup_order",
"arguments_json": "{\"order_id\":\"123\"}",
"status": "voltooid"
}
],
"gebruik": {
"invoer_tokens": 0,
"output_tokens": 0,
"reasoning_tokens": null,
"tool_units": []
},
"status": "voltooid"
Voeg itemtypen toe nog voordat elke aanbieder ze kan produceren. Nuttige categorieën zijn onder meer:
- Tekstuitvoer
- Weigeringen
- Functieaanroepen
- Functie-uitvoer ingediend door de applicatie
- Redeneringssamenvattingen of redeneringsgerelateerde metadata, indien beschikbaar
- Bestandsreferenties
- Zoeken op internet, zoeken naar bestanden, computergebruik of andere gehoste toolgebeurtenissen
- Metagegevens voor eindgebruik en facturering
Het gaat er niet om een bedrijfseigen schema aan gebruikers bloot te stellen. Het gaat erom te voorkomen dat de gateway informatie weggooit voordat deze deze kan controleren, factureren, streamen, opnieuw afspelen of transformeren.
Een staatsgrootboek bouwen dat eigendom is van de gateway
previous_response_id is het veld dat het verschil tussen stateless chat-proxying en Response-compatibiliteit het beste blootlegt. Als een client verwijst naar een eerder antwoord, moet de gateway weten wat die ID betekent, of de tenant deze mag gebruiken en of de provider ermee verder kan gaan.
Maak een grootboek, gecodeerd op tenant- en antwoord-ID:
{
"gateway_response_id": "gw_resp_789",
"provider_response_id": "resp_provider_789",
"previous_gateway_response_id": "gw_resp_456",
"tenant_id": "tien_123",
"user_id": "user_999",
"key_id": "key_456",
"model": "gpt-...",
"provider": "openai",
"store_mode": "provider|gateway|geen",
"retention_policy": "standaard|zero_retention|custom_30d",
"instructions_hash": "sha256:...",
"tool_policy_id": "tools_readonly_v3",
"created_at": "...",
"expires_at": "...",
"verwijderde_at": nul
Belangrijke regel: emuleer previous_response_id niet automatisch door de volledige chatgeschiedenis opnieuw af te spelen, tenzij de huurder dit retentie- en kostengedrag expliciet heeft toegestaan. Herhaling kan de tokenkosten verhogen, de privacyhouding veranderen en het modelgedrag veranderen. Het is veiliger om een duidelijke capaciteitsfout te retourneren dan om stilletjes opgeslagen gespreksinhoud te verzenden waarvan de toepassing niet had verwacht dat u deze zou bewaren of hergebruiken.
Statusverwerkingsmodi
- Providerstatus: De upstreamprovider slaat voldoende context op en de gateway wijst gateway-antwoord-ID's toe aan respons-ID's van de provider.
- Gatewaystatus: De gateway slaat de noodzakelijke eerdere items op en reconstrueert de context wanneer dit is toegestaan.
- Geen status: het verzoek maakt gebruik van
store=falseof het tenantbeleid verbiedt retentie.previous_response_idmoet worden afgewezen, tenzij de provider het verzoek kan honoreren zonder gateway-retentie en het beleid dit toestaat.
Houd er ook rekening mee dat eerdere instructies mogelijk opnieuw door de klant moeten worden verzonden, terwijl ze van toepassing moeten blijven. De gateway mag geen verborgen instructies verzinnen om dit te compenseren, tenzij dat gedrag deel uitmaakt van een expliciet tenantbeleid.
Tools valideren vóór verzending
Responses maken het gebruik van tools centraler. Een compatibiliteitslaag zou twee brede categorieën moeten verwerken:
- Applicatietools: Functiedefinities geleverd door de klant, uitgevoerd buiten de modelaanbieder, waarbij de uitvoer wordt teruggestuurd naar de API.
- Hulpprogramma's van gehoste providers: zoeken op internet, zoeken naar bestanden, computergebruik, code-uitvoering, aarden of vergelijkbare tools die worden uitgevoerd door de provider of door de gateway gecontroleerde infrastructuur.
Bij binnenkomst valideert u de toolschema's voordat u deze doorstuurt:
- Ongeldig JSON-schema vroegtijdig afwijzen.
- Dwing maximale schemagrootte en nestdiepte af.
- Controleer de namen van de tools op compatibiliteit met providers.
- Pas tenant-, sleutel-, gebruikers- en omgevingsbereiken toe.
- Vereist goedkeuringspoorten voor tools die gegevens schrijven, geld uitgeven, toegang krijgen tot gevoelige systemen of externe connectoren aanroepen.
Voor het aanroepen van applicatiefuncties is een stabiele oproep-ID vereist. Het model zendt een functieaanroep uit met call_id; de applicatie verzendt de tooluitvoer die naar die ID verwijst; de gateway registreert beide in dezelfde trace. Zonder die deelnamesleutel worden auditlogboeken en nieuwe pogingen dubbelzinnig.
Voor gehoste tools reserveert u een budget vóór verzending en rekent u de kosten daarna af. Gehoste tools kunnen kosten toevoegen buiten de gewone token-accounting, dus koppel het toolgrootboek aan uniforme AI API-facturering in plaats van deze kosten te verbergen binnen een generiek model-call-totaal.
Normaliseer streaming als gebeurtenissen, niet als tokentekst
Een chatproxy kan vaak wegkomen met het doorsturen van tokendelta's. Een Responses-gateway kan dat niet. De stream heeft levenscyclusbetekenis: een antwoord kan starten, uitvoeritems kunnen starten en voltooien, tekst kan in delta's aankomen, toolaanroepen kunnen stapsgewijs worden samengesteld, gebruik kan aan het einde of tijdens de stream aankomen, en het antwoord kan mislukken of worden geannuleerd.
Definieer een gatewaygebeurtenisschema en wijs vervolgens elke providerstream hieraan toe:
gebeurtenis: response_started
gegevens: { "response_id": "gw_resp_123", "status": "in_progress" }
gebeurtenis: output_item_startedgegevens: { "item_id": "item_1", "type": "tekst" }
gebeurtenis: tekst_delta
data: { "item_id": "item_1", "delta": "Hallo" }
gebeurtenis: tool_call_delta
data: { "item_id": "item_2", "call_id": "call_abc", "arguments_delta": "{\"bestelling" }
gebeurtenis: gebruik_delta
gegevens: { "output_tokens": 12 }
evenement: voltooid
data: { "response_id": "gw_resp_123", "usage": { ... }
Aanbevolen genormaliseerde gebeurtenissen:
response_startedoutput_item_startedoutput_item_completedtext_deltaweigering_deltatool_call_deltatool_result_receivedusage_deltavoltooidgeannuleerdmislukt
Wanneer de client de verbinding verbreekt, voer dan de annulering stroomopwaarts door als de provider dit ondersteunt. Noteer hoe dan ook de gedeeltelijke responsstatus. Als de provider later het eindgebruik retourneert via een vertraagde callback of een laatste deel, stemt u het grootboek af. Bij streamingcompatibiliteit gaat het zowel om boekhouding en levenscyclus als om latentie.
Maak een capaciteitsmatrix voor providers
Multi-model routering is alleen nuttig als de gateway begrijpt wat veilig kan worden gerouteerd. Voeg Response-specifieke mogelijkheden toe aan uw modelcatalogus:
{
"model_alias": "agent-default",
"routes": [
{
"provider": "openai",
"model": "...",
"supports_responses": waar,
"supports_previous_response_id": waar,
"supports_store_false": waar,
"supports_builtin_web_search": waar,
"ondersteunt_function_calling": waar,
"supports_stream_lifecycle_events": waar,
"supports_reasoning_context_continuity": waar,
"max_tool_schema_bytes": 65536
},
{
"provider": "provider_b",
"model": "...",
"supports_responses": false,
"chat_adapter_available": waar,
"loss_profile": ["no_previous_response_id", "no_hosted_tools", "flattened_stream"]
}
]
Fallback moet verliesbewust zijn. Als voor het verzoek een ingebouwde webzoekopdracht vereist is en de fallback-provider dit niet kan uitvoeren, beantwoord dan niet stilletjes zonder te zoeken. Als het verzoek afhankelijk is van de bewaarde redeneringscontext en de fallback-route deze niet kan behouden, retourneert u een capaciteitsfout of een downgrade-antwoord waarvoor de client zich expliciet heeft aangemeld.
Een nuttige verzoekoptie is:
{
"model": "agent-default",
"invoer": "...",
"fallback_policy": {
"allow_lossy": vals,
"allowed_losses": []
}
Voor minder gevoelige gebruiksscenario's kunnen huurders specifieke downgrades met verlies toestaan:
{
"fallback_policy": {
"allow_lossy": waar,
"allowed_losses": ["flattened_stream", "no_reasoning_summary"]
}
De gateway moet de fallback-beslissing hoe dan ook registreren. Dat maakt later debuggen mogelijk wanneer een agent zich anders gedraagt na een providerstoring of een modelomleiding.
Toeschrijven van gebruik op respons- en itemniveau
Response-oproepen kunnen meer kosten dan gelijkwaardige chat-voltooiingen, omdat ze het uitvoeren van tools, een langere context, redeneringstokens, zoeken naar bestanden, zoeken op internet of herhaalde instructies kunnen omvatten. Eén verzameld tokenaantal is niet genoeg voor een dashboard voor AI API-gebruiksanalyse.
Registreer het gebruik op twee niveaus:
- Reactieniveau: huurder, sleutel, gebruiker, model, provider, latentie, eindstatus, invoertokens, uitvoertokens, redeneringstokens indien gerapporteerd, totale kosten en terugvalroute.
- Item-/toolniveau: toolnaam, oproep-ID, gehoste tool-eenheden, bestands-ID's, aantal zoekopdrachten, indien beschikbaar, toollatentie, toolkosten en resultaat van het goedkeuringsbeleid.
Hiermee kunnen ontwikkelaars concrete vragen beantwoorden:
- Zijn de kosten gestegen vanwege langere status, redeneerinspanningen, tool calls of fallback?
- Welke tenant of API-sleutel genereert kosten voor gehoste tools?
- Welk antwoord mislukte na een tooloproep maar vóór de definitieve tekst?
- Welke geannuleerde streams hadden nog steeds upstream-gebruik?
Behandel zero-retentie en verwijdering als eersteklas gedrag
De status aan de serverzijde is nuttig, maar verandert de bewaarverplichtingen van de gateway. Bouw beleid in de protocollaag in, in plaats van het te behandelen als een loginstelling.
Los voor elk antwoordverzoek het volgende op:
- Beleid voor het behoud van huurders
- Voorkeur voor
winkelop verzoekniveau - Compatibiliteit met het bewaren van providers
- Of gateway-herhaling is toegestaan
- Of gereedschapsinvoer en -uitvoer mag worden opgeslagen
- Verloop- en verwijderingsgedrag voor de reactiestatus
Als retentie is uitgeschakeld, behoudt de gateway mogelijk nog steeds minimale operationele metagegevens: tijdstempels, ID's, status, tokenaantallen, kosten en beleidsbeslissingen. Vermijd het opslaan van onbewerkte aanwijzingen, volledige tooluitvoer of gereconstrueerde geschiedenis, tenzij het beleid dit toestaat.
Conformiteitsarmaturen die vóór de lancering moeten worden toegevoegd
Vertrouw niet op handmatige tests met een gelukkig pad. Voeg armaturen toe die het protocolgedrag verifiëren via directe OpenAI-routes, door de provider aangepaste routes en fallback-scenario's.
Minimale testset
- Basisreactie: tekstitem wordt geretourneerd met stabiele reactie-ID en gebruik.
- Multi-turn status: tweede verzoekreferenties
previous_response_id; gateway valideert het eigendom van de tenant en de statusmodus. - Herhaalde instructies: verifieer dat weggelaten instructies niet stilletjes door de gateway zijn bedacht.
- Functie oproep retour: model zendt oproep-ID uit; applicatie verzendt uitvoer; het uiteindelijke antwoord voegt beide records samen.
- Beleid voor gehoste tools: ongeautoriseerde ingebouwde tools worden vóór verzending geblokkeerd.
- Streamingvolgorde: start van reactie, start van item, delta's, voltooiing van item, gebruik en voltooiing worden in geldige volgorde verzonden.
- Stream-annulering: het ontkoppelen van de client activeert upstream-annulering waar dit wordt ondersteund en registreert gedeeltelijk gebruik.
- Fallback-afwijzing: provider zonder vereiste respons-semantiek retourneert een capaciteitsfout.
- Opt-in voor terugval met verlies: verzoek met toegestane verliezen ontvangt een expliciete downgrademarkering.
- Modus zonder retentie: statusherhaling en promptretentie aan de gatewayzijde zijn geblokkeerd.
Aanbevolen implementatievolgorde
- Ontwerp een bètaroute. Voeg
/v1/responsestoe zonder het bestaande chatgedrag te veranderen. - Implementeer eerst pass-through voor providers met ondersteuning voor native Responses. Bewaar ID's, items, streams, gebruik en fouten.
- Voeg het staatsgrootboek toe. Wijs gateway-ID's toe aan provider-ID's en dwing huurdereigendom af.
- Voeg canonieke items toe. Bewaar metagegevens van items die nodig zijn voor auditing, facturering en reconstructie van streams.
- Voeg toolbeheer toe. Valideer schema's, dwing scopes af en leg joins van toolaanroepen vast.
- Voeg streamingnormalisatie toe. Converteer providerspecifieke streams naar gateway-levenscyclusgebeurtenissen.
- Voeg capaciteitsbewuste routering toe. Sta standaard alleen veilige terugval toe.
- Voeg analyses en factureringsafrekening toe. Schrijf token-, redenering- en toolgebruik afzonderlijk toe.
- Publiceer compatibiliteitsopmerkingen. Vertel ontwikkelaars welke velden native, geëmuleerd, niet-ondersteund of verliesgevend zijn.
Bruikbare conclusie
Een Responses API-compatibiliteitslaag moet de protocolbetekenis behouden en niet alleen plausibele tekst retourneren. Bouw het rond vijf duurzame objecten: een canoniek antwoorditemmodel, een grootboek voor de conversatiestatus, een grootboek voor tooloproepen, een normalisatie voor streaminggebeurtenissen en een matrix voor de mogelijkheden van de provider.
De veiligste standaard is strikte compatibiliteit: als een route de vereiste status, tools, redeneercontext, streamgebeurtenissen of retentiegedrag niet kan behouden, retourneert u een duidelijke capaciteitsfout. Voeg opt-in lossy fallback alleen toe als ontwikkelaars begrijpen wat er zal worden geschrapt. Deze aanpak voelt misschien minder handig dan automatische afvlakking, maar voorkomt de ergste mislukking: een applicatie die compatibel lijkt, terwijl ze stilletjes de semantiek verliest die ervoor zorgde dat de Responses API in de eerste plaats werd gebruikt.