

# 使用双向 API 处理输入事件
<a name="sonic-input-events"></a>

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

## 概述
<a name="sonic-input-overview"></a>

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

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

## 对话历史
<a name="sonic-conversation-history"></a>

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

## 音频流
<a name="sonic-audio-streaming"></a>

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

## 关闭会话
<a name="sonic-closing-session"></a>

在对话结束或需要终止之后，必须正确关闭所有打开的流并按正确的顺序结束会话。要正确结束会话并避免资源泄漏，必须遵循特定的顺序关闭：
+ 关闭 `contentEnd` 事件中所有打开的音频流。
+ 发送引用原始 `promptName` 的 `promptEnd` 事件。
+ 发送 `sessionEnd` 事件。

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

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

![](http://docs.aws.amazon.com/zh_cn/nova/latest/nova2-userguide/images/Closing-the-session_2.png)


## 输入事件流
<a name="sonic-input-event-flow"></a>

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

### 1. RequestStartEvent（会话开始）
<a name="sonic-session-start-event"></a>

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

**推理配置：**
+ `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"
            }
        }
    }
}
```

### 2. PromptStartEvent
<a name="sonic-prompt-start-event"></a>

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

有关可用语音 ID 的列表，请参阅[语言支持和多语言功能](https://docs.aws.amazon.com/nova/latest/nova2-userguide/sonic-language-support.html)

```
{
    "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": "{}"
                            }
                        }
                    }
                ]
            }
        }
    }
}
```

### 3. InputContentStartEvent
<a name="sonic-content-start-event"></a>

#### 文本
<a name="sonic-content-start-text"></a>

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

**交互参数：**
+ `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"
            }
        }
    }
}
```

#### 音频
<a name="sonic-content-start-audio"></a>

```
{
    "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
<a name="sonic-content-start-tool"></a>

```
{
    "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"
                }
            }
        }
    }
}
```

### 4. TextInputContent
<a name="sonic-text-input-event"></a>

```
{
    "event": {
        "textInput": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string", // unique identifier for the content block
            "content": "string"
        }
    }
}
```

### 5. AudioInputContent
<a name="sonic-audio-input-event"></a>

```
{
    "event": {
        "audioInput": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string", // same unique identifier from its contentStart
            "content": "base64EncodedAudioData"
        }
    }
}
```

### 6. ToolResultContentEvent
<a name="sonic-tool-result-event"></a>

```
"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 
    }
}
```

### 7. InputContentEndEvent
<a name="sonic-content-end-event"></a>

```
{
    "event": {
        "contentEnd": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string" // same unique identifier from its contentStart
        }
    }
}
```

### 8. PromptEndEvent
<a name="sonic-prompt-end-event"></a>

```
{
    "event": {
        "promptEnd": {
            "promptName": "string" // same unique identifier from promptStart event
        }
    }
}
```

### 9. RequestEndEvent
<a name="sonic-session-end-event"></a>

```
{
    "event": {
        "sessionEnd": {}
    }
}
```