Crea un livello di compatibilità dell'API di risposta in un gateway API AI
Un gateway API di risposta non è semplicemente un proxy di completamento chat con un nuovo percorso. Preserva gli elementi di risposta, lo stato, le chiamate agli strumenti, i flussi, la continuità del ragionamento, l'attribuzione dell'utilizzo e il comportamento di downgrade con un livello di compatibilità di prima classe.
Non implementare /v1/responses traducendo ogni richiesta in /v1/chat/completions e sperando che la forma sia abbastanza simile. Tale adattatore può restituire testo, ma può perdere silenziosamente le parti a cui tengono gli sviluppatori: elementi di risposta, stato lato server, chiamate agli strumenti, continuità del ragionamento, eventi del ciclo di vita del flusso, semantica di cancellazione e attribuzione di utilizzo a livello di elemento.
L'obiettivo pratico è un livello di compatibilità che tratti l'API Responses come un protocollo più ricco. Mantieni il supporto di Completamenti chat per i client esistenti, ma crea Responses come una propria superficie gateway con il proprio modello di stato, normalizzatore del flusso, registro delle chiamate agli strumenti, matrice di capacità e regole di fallback.
Cosa sono i fatti, cos'è la politica e cos'è la previsione?
Fatti: OpenAI descrive l'API Responses come funzionalità unificanti che in precedenza erano suddivise tra completamenti chat e assistenti, incluso il supporto per strumenti come ricerca web, ricerca di file e utilizzo del computer. L'API espone campi come previous_response_id, streaming, selezione degli strumenti e strumenti integrati. La documentazione dell'SDK mostra che previous_response_id può fornire continuità alla conversazione, mentre le istruzioni precedenti non vengono automaticamente riportate e devono essere inviate nuovamente quando dovrebbero ancora essere applicate. Il riferimento allo streaming di OpenAI include cicli di vita di risposta ed eventi di output distinti anziché solo delta dei token.
Consigli: un gateway dovrebbe preservare queste semantiche anziché appiattirle per impostazione predefinita. Dovrebbe rifiutare o eseguire esplicitamente il downgrade delle richieste quando un provider di destinazione non può supportare il comportamento richiesto.
Previsione: un numero maggiore di carichi di lavoro degli agenti dipenderà dalla struttura degli elementi di risposta, dalle tracce di esecuzione dello strumento e dal contesto di ragionamento con stato. I gateway che modellano questi concetti ora saranno più facili da estendere rispetto ai gateway che trattano le risposte come un endpoint cosmetico.
Definire un contratto di compatibilità separato per le risposte
Il primo errore di implementazione è presupporre che la compatibilità con OpenAI significhi uno schema di richiesta e risposta universale. In pratica, /v1/chat/completions e /v1/responses dovrebbero essere contratti di compatibilità separati.
Mantieni un livello condiviso di autenticazione, fatturazione, quota e routing, ma separa il livello del protocollo:
- Superficie dei completamenti della chat: messaggi, scelte, delta, chiamate agli strumenti in formato chat, comportamento del client legacy.
- Superficie delle risposte: elementi di input, elementi di output, ID di risposta, riferimenti a risposte precedenti, eventi di strumenti più completi, eventi di flusso del ciclo di vita, campi relativi al ragionamento e stato della risposta finale.
Questa suddivisione è importante per i test di conformità. Un adattatore del provider che supera i test di chat potrebbe comunque fallire i test di risposta perché non è in grado di preservare previous_response_id, ordinamento degli elementi, struttura di rifiuto, metadati dello strumento ospitato o nomi di eventi di streaming.
Un contratto di compatibilità minima dovrebbe rispondere:
- Quali campi della richiesta vengono accettati, rifiutati, trasformati o ignorati?
- Quali tipi di elementi di risposta vengono conservati?
- Quali tipi di strumenti sono supportati per fornitore e modello?
- Il provider può mantenere lo stato della conversazione o il gateway deve mantenerlo?
- Cosa succede quando viene richiesto
store=false? - Quali eventi in streaming sono garantiti?
- Come vengono registrati l'annullamento, il timeout e l'utilizzo parziale?
Se disponi già di un gateway API AI, tratta il supporto di Responses come un'espansione del protocollo, non come un alias di route.
Utilizza un modello di elemento di risposta canonico
L'API Responses restituisce più di un messaggio dell'assistente. Può rappresentare diversi elementi ed eventi di output. Il tuo gateway necessita di un modello canonico interno prima di essere mappato a qualsiasi provider.
Uno pratico schema di elementi interni può iniziare in questo modo:
{ "gateway_response_id": "gw_resp_...", "provider_response_id": "resp_...", "tenant_id": "dieci_123", "key_id": "chiave_456", "model_alias": "agente-default", "fornitore": "openai", "oggetti": [ { "item_id": "articolo_1", "tipo": "testo", "ruolo": "assistente", "content": [{ "type": "output_text", "text": "..." }], "stato": "completato" }, { "item_id": "item_2", "tipo": "funzione_chiamata", "call_id": "call_abc", "nome": "ordine_ricerca", "arguments_json": "{\"order_id\":\"123\"}", "stato": "completato" } ], "utilizzo": { "token_input": 0, "output_tokens": 0, "reasoning_tokens": null, "unità_strumento": [] }, "stato": "completato" }
Includi i tipi di articoli anche prima che ogni fornitore possa produrli. Le categorie utili includono:
- Output di testo
- Rifiuti
- Chiamate di funzioni
- Output della funzione inviati dall'applicazione
- Sintesi delle motivazioni o metadati relativi alle motivazioni, ove disponibili
- Riferimenti ai file
- Ricerca sul Web, ricerca di file, utilizzo del computer o altri eventi di strumenti ospitati
- Utilizzo finale e metadati di fatturazione
Il punto non è esporre uno schema proprietario agli utenti. Il punto è impedire al gateway di eliminare informazioni prima di poterle controllare, fatturare, trasmettere in streaming, riprodurre o trasformare.
Crea un registro statale di proprietà del gateway
previous_response_id è il campo che espone maggiormente la differenza tra proxy di chat stateless e compatibilità delle risposte. Se un client fa riferimento a una risposta precedente, il gateway deve sapere cosa significa tale ID, se il tenant è autorizzato a utilizzarlo e se il provider può continuare da esso.
Crea un libro mastro statale con chiave per tenant e ID di risposta:
{ "gateway_response_id": "gw_resp_789", "provider_response_id": "resp_provider_789", "previous_gateway_response_id": "gw_resp_456", "tenant_id": "dieci_123", "user_id": "utente_999", "key_id": "chiave_456", "modello": "gpt-...", "fornitore": "openai", "store_mode": "provider|gateway|none", "retention_policy": "standard|zero_retention|custom_30d", "instructions_hash": "sha256:...", "tool_policy_id": "tools_readonly_v3", "created_at": "...", "expires_at": "...", "eliminato_at": null }
Regola importante: non emulare automaticamente previous_response_id riproducendo la cronologia completa della chat a meno che il tenant non abbia esplicitamente consentito tale comportamento di conservazione e costo. La riproduzione può aumentare il costo dei token, modificare la posizione sulla privacy e alterare il comportamento del modello. È più sicuro restituire un chiaro errore di funzionalità piuttosto che inviare silenziosamente il contenuto della conversazione memorizzata che l'applicazione non si aspettava che conservassi o riutilizzassi.
Modalità di gestione da parte dello Stato
- Stato del provider: il provider upstream memorizza un contesto sufficiente e il gateway associa gli ID di risposta del gateway agli ID di risposta del provider.
- Stato del gateway: il gateway memorizza gli elementi precedenti necessari e ricostruisce il contesto quando consentito.
- Nessuno stato: la richiesta utilizza
store=falseo la policy del tenant vieta la conservazione.previous_response_iddovrebbe essere rifiutato a meno che il provider non possa onorare la richiesta senza conservazione del gateway e la policy lo consenta.
Ricorda inoltre che potrebbe essere necessario inviare nuovamente le istruzioni precedenti al cliente quando dovrebbero continuare ad applicarsi. Il gateway non dovrebbe inventare istruzioni nascoste per compensare, a meno che tale comportamento non faccia parte di una politica del tenant esplicita.
Convalida gli strumenti prima della spedizione
Le risposte rendono l'utilizzo degli strumenti più centrale. Un livello di compatibilità dovrebbe gestire due grandi categorie:
- Strumenti applicativi: definizioni di funzioni fornite dal cliente, eseguite all'esterno del fornitore del modello, con output reinviati all'API.
- Strumenti del provider in hosting: ricerca sul Web, ricerca di file, utilizzo del computer, esecuzione di codice, messa a terra o strumenti simili eseguiti dal provider o dall'infrastruttura controllata dal gateway.
All'ingresso, convalida gli schemi degli strumenti prima del routing:
- Rifiuta anticipatamente lo schema JSON non valido.
- Applica la dimensione massima dello schema e la profondità di nidificazione.
- Controlla i nomi degli strumenti per la compatibilità del fornitore.
- Applica ambiti tenant, chiave, utente e ambiente.
- Richiedi controlli di approvazione per strumenti che scrivono dati, spendono denaro, accedono a sistemi sensibili o chiamano connettori esterni.
Per la chiamata alle funzioni dell'applicazione, è necessario un ID chiamata stabile. Il modello emette una chiamata di funzione con call_id; l'applicazione invia l'output dello strumento facendo riferimento a tale ID; il gateway registra entrambi nella stessa traccia. Senza quella chiave di unione, i registri di controllo e i tentativi diventano ambigui.
Per gli strumenti ospitati, prenota il budget prima della spedizione e stabilisci i costi in seguito. Gli strumenti ospitati possono aggiungere costi al di fuori della normale contabilità dei token, quindi collega il registro degli strumenti alla fatturazione API AI unificata anziché nascondere tali costi all'interno di un totale generico di model-call.
Normalizza lo streaming come eventi, non come testo token
Un proxy di chat spesso riesce a farla franca inoltrando i delta dei token. Un gateway di risposte non può. Il flusso ha un significato legato al ciclo di vita: una risposta può iniziare, gli elementi di output possono iniziare e completarsi, il testo può arrivare in delta, le chiamate allo strumento possono essere assemblate in modo incrementale, l'utilizzo può arrivare alla fine o durante il flusso e la risposta può fallire o essere annullata.
Definisci uno schema di eventi del gateway, quindi associa ogni flusso del provider al suo interno:
evento: risposta_iniziata
dati: { "response_id": "gw_resp_123", "status": "in_progress" }
evento: output_item_starteddati: { "item_id": "item_1", "type": "text" }
evento: text_delta
dati: { "item_id": "item_1", "delta": "Ciao" }
evento: tool_call_delta
dati: { "item_id": "item_2", "call_id": "call_abc", "arguments_delta": "{\"order" }
evento: utilizzo_delta
dati: { "output_tokens": 12 }
evento: completato
dati: { "response_id": "gw_resp_123", "usage": { ... } }
Eventi normalizzati consigliati:
risposta_avviataoutput_item_startedoutput_elemento_completatotext_deltarifiuto_deltatool_call_deltarisultato_strumento_ricevutousage_deltacompletatoannullatonon riuscito
Quando il client si disconnette, propaga la cancellazione a monte se il provider lo supporta. Registrare lo stato di risposta parziale in entrambi i casi. Se il provider successivamente restituisce l'utilizzo finale tramite una richiamata ritardata o un blocco finale, riconciliare il registro. La compatibilità dello streaming riguarda tanto la contabilità e il ciclo di vita quanto la latenza.
Crea una matrice di capacità del fornitore
Il routing multimodello è utile solo quando il gateway comprende cosa può essere instradato in sicurezza. Aggiungi funzionalità specifiche per le risposte al tuo catalogo di modelli:
{ "model_alias": "agente-default", "percorsi": [ { "fornitore": "openai", "modello": "...", "supports_responses": vero, "supports_previous_response_id": vero, "supports_store_false": vero, "supports_builtin_web_search": vero, "supports_function_calling": vero, "supports_stream_lifecycle_events": vero, "supports_reasoning_context_continuity": vero, "max_tool_schema_bytes": 65536 }, { "fornitore": "fornitore_b", "modello": "...", "supports_responses": falso, "chat_adapter_available": vero, "loss_profile": ["no_previous_response_id", "no_hosted_tools", "flattened_stream"] } ] }
Il fallback dovrebbe essere in grado di riconoscere le perdite. Se la richiesta richiede la ricerca web integrata e il provider di fallback non può eseguirla, non rispondere silenziosamente senza ricerca. Se la richiesta dipende da un contesto di ragionamento preservato e il percorso di fallback non può preservarlo, restituisce un errore di funzionalità o una risposta di downgrade a cui il client ha esplicitamente aderito.
Un'opzione di richiesta utile è:
{ "modello": "predefinito dell'agente", "ingresso": "...", "politica_fallback": { "allow_lossy": falso, "perdite_permesse": [] } }
Per casi d'uso meno sensibili, i tenant possono consentire specifici downgrade con perdita di dati:
{ "politica_fallback": { "allow_lossy": vero, "allowed_losses": ["flattened_stream", "no_reasoning_summary"] } }
In ogni caso, il gateway dovrebbe registrare la decisione di fallback. Ciò rende possibile il debug successivo quando un agente si comporta in modo diverso dopo l'interruzione del provider o il reindirizzamento del modello.
Utilizzo degli attributi a livello di risposta e di elemento
Le chiamate di risposta possono costare più dei completamenti equivalenti della chat perché possono includere l'esecuzione di strumenti, contesto più lungo, token di ragionamento, ricerca di file, ricerca sul Web o istruzioni ripetute. Un singolo conteggio di token aggregati non è sufficiente per una dashboard di analisi dell'utilizzo dell'API AI.
Registra l'utilizzo a due livelli:
- Livello di risposta: tenant, chiave, utente, modello, fornitore, latenza, stato finale, token di input, token di output, token di ragionamento ove segnalato, costo totale e percorso di fallback.
- Livello elemento/strumento: nome dello strumento, ID chiamata, unità dello strumento ospitato, ID file, conteggio delle query di ricerca se disponibile, latenza dello strumento, costo dello strumento e risultato dei criteri di approvazione.
Ciò consente agli sviluppatori di rispondere a domande concrete:
- I costi sono aumentati a causa di uno stato più lungo, di sforzi di ragionamento, di chiamate a strumenti o di fallback?
- Quale tenant o chiave API genera addebiti per gli strumenti ospitati?
- Quale risposta non è riuscita dopo una chiamata allo strumento ma prima del testo finale?
- Quali flussi annullati sono ancora soggetti a utilizzo upstream?
Gestisci la conservazione zero e l'eliminazione come un comportamento di prima classe
Lo stato lato server è utile, ma modifica gli obblighi di conservazione del gateway. Costruisci la policy nel livello del protocollo invece di trattarla come un'impostazione di registrazione.
Per ogni richiesta di risposta, risolvi:
- Politica di fidelizzazione del tenant
- Preferenza
negozioa livello di richiesta - Compatibilità di conservazione del provider
- Se la riproduzione del gateway è consentita
- Se gli input e gli output dello strumento possono essere memorizzati
- Comportamento di scadenza ed eliminazione per lo stato della risposta
Se la conservazione è disabilitata, il gateway potrebbe comunque conservare una quantità minima di metadati operativi: timestamp, ID, stato, conteggi di token, costi e decisioni relative alle policy. Evita di archiviare prompt non elaborati, output completi dello strumento o cronologia ricostruita a meno che la politica non lo consenta.
Dispositivi di conformità da aggiungere prima del lancio
Non fare affidamento su test manuali felici. Aggiungi dispositivi che verificano il comportamento del protocollo su percorsi OpenAI diretti, percorsi adattati dal provider e scenari di fallback.
Set di test minimo
- Risposta di base: l'elemento di testo viene restituito con ID di risposta e utilizzo stabili.
- Stato multi-turno: la seconda richiesta fa riferimento a
previous_response_id; il gateway convalida la proprietà del tenant e la modalità stato. - Istruzioni ripetute: verifica che le istruzioni omesse non vengano inventate silenziosamente dal gateway.
- Funzione chiamata andata e ritorno: il modello emette l'ID chiamata; l'applicazione invia l'output; la risposta finale unisce entrambi i record.
- Politica sugli strumenti ospitati: lo strumento integrato non autorizzato viene bloccato prima dell'invio.
- Ordine di streaming: l'inizio della risposta, l'inizio dell'elemento, i delta, il completamento dell'elemento, l'utilizzo e il completamento vengono emessi in ordine valido.
- Annullamento del flusso: la disconnessione del client attiva l'annullamento a monte, ove supportato, e registra l'utilizzo parziale.
- Rifiuto di fallback: il provider senza la semantica delle risposte richieste restituisce un errore di funzionalità.
- Attivazione fallback con perdite: la richiesta con perdite consentite riceve un indicatore di downgrade esplicito.
- Modalità di conservazione zero: la riproduzione dello stato e la conservazione dei prompt lato gateway sono bloccate.
Sequenza di implementazione consigliata
- Esponi un percorso beta. Aggiungi
/v1/responsessenza modificare il comportamento della chat esistente. - Implementa prima il pass-through per i fornitori con supporto nativo di Responses. Conserva ID, elementi, flussi, utilizzo ed errori.
- Aggiungi il registro statale. Mappa gli ID gateway sugli ID provider e applica la proprietà del tenant.
- Aggiungi elementi canonici. Memorizza i metadati degli elementi necessari per il controllo, la fatturazione e la ricostruzione del flusso.
- Aggiungi la governance degli strumenti. Convalida gli schemi, applica gli ambiti e registra i join delle chiamate degli strumenti.
- Aggiungi la normalizzazione dello streaming. Converti flussi specifici del provider in eventi del ciclo di vita del gateway.
- Aggiungi routing basato sulle funzionalità. Consenti solo fallback sicuri per impostazione predefinita.
- Aggiungi analisi e fatturazione. Attribuisci token, ragionamento e utilizzo dello strumento separatamente.
- Pubblica note di compatibilità. Indica agli sviluppatori quali campi sono nativi, emulati, non supportati o con perdita di dati.
Conclusione attuabile
Un livello di compatibilità dell'API Responses dovrebbe preservare il significato del protocollo, non limitarsi a restituire testo plausibile. Costruiscilo attorno a cinque oggetti durevoli: un modello di elemento di risposta canonico, un registro dello stato delle conversazioni, un registro delle chiamate agli strumenti, un normalizzatore di eventi di streaming e una matrice di capacità del provider.
L'impostazione predefinita più sicura è la compatibilità rigorosa: se una route non è in grado di preservare lo stato, gli strumenti, il contesto di ragionamento, gli eventi di flusso o il comportamento di conservazione richiesti, restituisce un chiaro errore di capacità. Aggiungi il fallback con perdita di attivazione solo quando gli sviluppatori capiscono cosa verrà eliminato. Questo approccio potrebbe sembrare meno conveniente dell'appiattimento automatico, ma impedisce la modalità di errore peggiore: un'applicazione che appare compatibile mentre perde silenziosamente la semantica che le ha fatto utilizzare l'API Responses in primo luogo.