View a markdown version of this page

使用双向 API 处理输入事件 - Amazon Nova

使用双向 API 处理输入事件

双向流式 API 使用具有结构化输入和输出事件的事件驱动架构。对于成功实施对话式应用程序,并在整个交互过程中保持适当的对话状态而言,理解正确的事件顺序至关重要。

概述

Nova Sonic 的对话遵循结构化事件顺序。首先,发送一个包含推理配置参数(例如温度和词元限制)的 sessionStart 事件。接下来,您发送 promptStart 以定义音频输出格式和工具配置,并且分配一个唯一的 promptName 标识符,该标识符必须包含在所有后续事件中。

对于每种交互类型(系统提示、音频等),遵循由三个部分组成的模式:使用 contentStart 定义内容类型和内容的角色(SYSTEMUSERASSISTANTTOOLSYSTEM_SPEECH),然后提供实际的内容事件,最后以 contentEnd 结束片段。contentStart 事件指定了您是在发送工具执行结果、流式音频还是系统提示。contentStart 事件包含一个唯一的 contentName 标识符。

对话历史

对话历史仅可添加一次,位置在系统提示之后、音频流开始之前。其遵循相同的 contentStart/textInput/contentEnd 模式。在 contentStart 事件中,必须为每条历史消息定义 USERASSISTANT 角色。这可为当前对话提供基本上下文信息,但必须在任何新用户输入开始之前完成。

音频流

音频流式传输通过连续麦克风采样运行。发送初始 contentStart 后,音频帧(每帧约 32 毫秒)将直接从麦克风捕获音频帧,并立即使用相同的 contentName 作为 audioInput 事件发送。这些音频样本应在捕获时实时流式传输,并在整个对话过程中保持自然的麦克风采样节奏。所有音频帧在对话结束并明确关闭之前都共享一个内容容器。

关闭会话

在对话结束或需要终止之后,必须正确关闭所有打开的流并按正确的顺序结束会话。要正确结束会话并避免资源泄漏,必须遵循特定的顺序关闭:

  • 关闭 contentEnd 事件中所有打开的音频流。

  • 发送引用原始 promptNamepromptEnd 事件。

  • 发送 sessionEnd 事件。

跳过这些正在关闭的事件中的任何一个,都可能导致对话不完整或资源被孤立。

这些标识符创建了这样的层次结构:promptName 将所有对话事件联系在一起,而每个 contentName 都标记了特定内容块的边界。这种层次结构可确保模型在整个交互过程中保持恰当的上下文信息。

输入事件流

本节对输入事件流的结构进行说明。

会话开始事件通过推理配置和轮次检测设置完成对话初始化。

推理配置:

  • maxTokens:响应中生成的最大词元数

  • topP:核采样参数(0.0 至 1.0),用于控制随机性

  • temperature:控制生成内容的随机性(0.0 至 1.0)

轮次检测配置:endpointingSensitivity 参数控制 Nova Sonic 在用户说完话后检测到的速度:

  • HIGH:可快速检测停顿,从而加快响应速度,但可能会打断语速较慢的说话者

  • MEDIUM:大多数对话场景的均衡灵敏度(推荐默认值)

  • LOW:等待更长的时间才能检测到说话结束,对于深思熟虑或犹豫不决的说话者而言更好

{ "event": { "sessionStart": { "inferenceConfiguration": { "maxTokens": "int", "topP": "float", "temperature": "float" }, "turnDetectionConfiguration": { "endpointingSensitivity": "HIGH" | "MEDIUM" | "LOW" } } } }

示例:

{ "event": { "sessionStart": { "inferenceConfiguration": { "maxTokens": 2048, "topP": 0.9, "temperature": 0.7 }, "turnDetectionConfiguration": { "endpointingSensitivity": "MEDIUM" } } } }

提示开始事件定义对话配置,包括输出格式、语音选择和可用工具。

有关可用语音 ID 的列表,请参阅语言支持和多语言功能

{ "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" | "olivia" | "lupe" | "carlos" | "ambre" | "florian" | "lennart" | "beatrice" | "lorenzo" | "tina" | "carolina" | "leo" | "kiara" | "arjun", "encoding": "base64", "audioType": "SPEECH" }, "toolUseOutputConfiguration": { "mediaType": "application/json" }, "toolConfiguration": { "tools": [ { "toolSpec": { "name": "string", "description": "string", "inputSchema": { "json": "{}" } } } ] } } } }

文本

文本内容开始事件用于系统提示、对话历史和跨模态文本输入。

交互参数:

  • true:启用跨模态输入,支持在语音会话进行中发送文本消息

  • false:系统提示和对话历史的标准文本输入

角色类型:

  • SYSTEM:系统说明和提示

  • USER:对话历史或跨模态输入中的用户消息

  • ASSISTANT:对话历史中的助手回复

  • SYSTEM_SPEECH:控制印地语语码转换的转录格式(拉丁字母/天城文/混合书写)

{ "event": { "contentStart": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // unique identifier for the content block "type": "TEXT", "interactive": "boolean", // true for cross-modal input "role": "SYSTEM" | "USER" | "ASSISTANT" | "TOOL" | "SYSTEM_SPEECH", "textInputConfiguration": { "mediaType": "text/plain" } } } }

示例 – 系统提示:

{ "event": { "contentStart": { "promptName": "conv-12345", "contentName": "system-prompt-1", "type": "TEXT", "interactive": false, "role": "SYSTEM", "textInputConfiguration": { "mediaType": "text/plain" } } } }

示例 – 跨模态输入:

{ "event": { "contentStart": { "promptName": "conv-12345", "contentName": "user-text-1", "type": "TEXT", "interactive": true, "role": "USER", "textInputConfiguration": { "mediaType": "text/plain" } } } }

音频

{ "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" } } } } }
{ "event": { "textInput": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // unique identifier for the content block "content": "string" } } }
{ "event": { "audioInput": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string", // same unique identifier from its contentStart "content": "base64EncodedAudioData" } } }
"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 } }
{ "event": { "contentEnd": { "promptName": "string", // same unique identifier from promptStart event "contentName": "string" // same unique identifier from its contentStart } } }
{ "event": { "promptEnd": { "promptName": "string" // same unique identifier from promptStart event } } }
{ "event": { "sessionEnd": {} } }