Gestione degli eventi di input con l’API bidirezionale
L’API di streaming bidirezionale utilizza un’architettura basata sugli eventi con eventi di input e output strutturati. La comprensione del corretto ordine degli eventi è fondamentale per implementare applicazioni conversazionali di successo e mantenere lo stato di conversazione corretto durante le interazioni.
La conversazione di Nova Sonic segue una sequenza di eventi strutturata. Si inizia inviando un evento sessionStart che contiene i parametri di configurazione dell’inferenza, come i limiti di temperatura e token. Successivamente, si invia promptStart per definire il formato dell’output audio e le configurazioni degli strumenti, assegnando un identificatore promptName univoco che deve essere incluso in tutti gli eventi successivi.
Per ogni tipo di interazione (prompt di sistema, audio e così via), segui uno schema in tre parti: usa contentStart per definire il tipo di contenuto e il ruolo del contenuto (SYSTEM, USER, ASSISTANT, TOOL), poi fornisci l’evento di contenuto effettivo e concludi con contentEnd per chiudere il segmento. L’evento contentStart specifica se stai inviando i risultati dello strumento, lo streaming audio o un prompt di sistema. L’evento contentStart include un identificatore contentName univoco.
Una cronologia delle conversazioni può essere inclusa una sola volta, dopo il prompt di sistema e prima dell’inizio dello streaming audio. Segue lo stesso schema contentStart/textInput/contentEnd. I ruoli USER e ASSISTANT devono essere definiti nell’evento contentStart per ogni messaggio storico. Ciò fornisce un contesto essenziale per la conversazione attuale, ma deve essere completato prima che inizi qualsiasi nuovo input da parte dell’utente.
Lo streaming audio funziona con un campionamento continuo del microfono. Dopo l’invio di un contentStart iniziale, i frame audio (circa 32 ms ciascuno) vengono acquisiti direttamente dal microfono e inviati immediatamente come eventi audioInput utilizzando lo stesso contentName. Questi campioni audio devono essere trasmessi in streaming in tempo reale man mano che vengono acquisiti, mantenendo la naturale cadenza di campionamento del microfono per tutta la conversazione. Tutti i frame audio condividono un singolo container di contenuti fino al termine della conversazione e alla sua chiusura esplicita.
Dopo che la conversazione è terminata o deve essere interrotta, è fondamentale chiudere correttamente tutti gli stream aperti e terminare la sessione nella sequenza corretta. Per terminare correttamente una sessione ed evitare perdite di risorse, devi seguire una sequenza di chiusura specifica:
-
Chiudi tutti gli streaming flussi audio aperti con l’evento
contentEnd. -
Invia un evento
promptEndche fa riferimento alpromptNameoriginale. -
Invia l’evento
sessionEnd.
Saltare uno qualsiasi di questi eventi di chiusura può portare a conversazioni incomplete o alla creazione di risorse orfane.
Questi identificatori creano una struttura gerarchica: i promptName collegano tutti gli eventi di conversazione, mentre ciascun contentName segna i confini di blocchi di contenuto specifici. Questa gerarchia garantisce che il modello mantenga il contesto corretto durante l’interazione.
Flusso di eventi di input
La struttura del flusso di eventi di input è riportata in questa sezione.
-
RequestStartEvent{ "event": { "sessionStart": { "inferenceConfiguration": { "maxTokens": "int", "topP": "float", "temperature": "float" } } } } -
PromptStartEvent{ "event": { "promptStart": { "promptName": "string", // unique identifier same across all events i.e. UUID "textOutputConfiguration": { "mediaType": "text/plain" }, "audioOutputConfiguration": { "mediaType": "audio/lpcm", "sampleRateHertz": 8000 | 16000 | 24000, "sampleSizeBits": 16, "channelCount": 1, "voiceId": "matthew" | "tiffany" | "amy" | "lupe" | "carlos" | "ambre" | "florian" | "greta" | "lennart" | "beatrice" | "lorenzo", "encoding": "base64", "audioType": "SPEECH", }, "toolUseOutputConfiguration": { "mediaType": "application/json" }, "toolConfiguration": { "tools": [{ "toolSpec": { "name": "string", "description": "string", "inputSchema": { "json": "{}" } } }] } } } } -
InputContentStartEvent-
Text{ "event": { "contentStart": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // unique identifier for the content block "type": "TEXT", "interactive": false, "role": "SYSTEM" | "USER" | "ASSISTANT", "textInputConfiguration": { "mediaType": "text/plain" } } } } -
Audio{ "event": { "contentStart": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // unique identifier for the content block "type": "AUDIO", "interactive": true, "role": "USER", "audioInputConfiguration": { "mediaType": "audio/lpcm", "sampleRateHertz": 8000 | 16000 | 24000, "sampleSizeBits": 16, "channelCount": 1, "audioType": "SPEECH", "encoding": "base64" } } } } -
Tool{ "event": { "contentStart": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // unique identifier for the content block "interactive": false, "type": "TOOL", "role": "TOOL", "toolResultInputConfiguration": { "toolUseId": "string", // existing tool use id "type": "TEXT", "textInputConfiguration": { "mediaType": "text/plain" } } } } }
-
-
TextInputContent{ "event": { "textInput": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // unique identifier for the content block "content": "string" } } } -
AudioInputContent{ "event": { "audioInput": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // same unique identifier from its contentStart "content": "base64EncodedAudioData" } } } -
ToolResultContentEvent"event": { "toolResult": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // same unique identifier from its contentStart "content": "{\"key\": \"value\"}" // stringified JSON object as a tool result } } -
InputContentEndEvent{ "event": { "contentEnd": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string" // same unique identifier from its contentStart } } } -
PromptEndEvent{ "event": { "promptEnd": { "promptName": "string" // same unique identifier from promptStart event } } } -
RequestEndEvent{ "event": { "sessionEnd": {} } }