> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coze.cn/llms.txt
> Use this file to discover all available pages before exploring further.

本文介绍硬件设备通过 WebSocket 实现语音交互的完整流程。WebSocket 技术为硬件设备提供了低延迟的语音交互能力，支持按键说话、普通自由对话和语义判停自由对话三种模式，适用于智能音箱、车载系统、智能家居控制、在线客服、游戏语音聊天等场景，满足不同使用场景的需求。
## WebSocket 语音功能介绍 {#633dad12}
扣子编程 WebSocket 提供了高效且灵活的语音交互解决方案，以下是其核心功能：

* **语音模式**
   扣子编程 WebSocket 语音通话支持按键说话、普通自由对话和语义判停自由对话三种模式，默认为按键说话模式，三种模式的对比说明如下：
   <!-- @cols-width: 100,274,228,242 -->
   | | | | | \
   |**特性** |**按键说话模式 (client_interrupt)** |**普通自由对话模式 (server_vad)** |**语义判停自由对话模式（semantic_vad）** |
   |---|---|---|---|
   | | | | | \
   |**控制方式** |用户通过物理按键或屏幕按钮精确控制语音识别的开始和结束。 |由云端语音活动检测 (VAD) 算法自动判断用户是否在说话。 |由服务端识别语义来判断是否停止说话。 |
   | | | | | \
   |**核心优势** |**精准控制**：避免背景噪音干扰，只有在用户主动操作时才传输音频，保障了通信的私密性和准确性。 |**自然流畅**：用户无需任何额外操作，像正常交谈一样即可开始和结束对话，提供了“解放双手”的无缝体验。 |**智能语义感知**：基于语义理解判断语句完整性，在语义完整时自动判停，从而加速模型响应，提升交互效率。 |
   | | | | | \
   |**典型场景** |* **在线游戏**：避免键盘、鼠标声干扰团队语音。 |\
   | |* **智能玩具**：故事机等具备实体按键的智能玩具，防止儿童误触发，同时增强互动趣味性。 |* **语音助手**：与智能设备进行自然语言交互。 |\
   | | |* **智能客服**：在呼叫中心等场景下进行流畅的语音问答。 |* **智能客服**：快速识别用户咨询意图完整性，在用户描述问题后立即触发处理流程，提升客服响应速度。 |\
   | | | |* **智能家居**：识别多指令语义完整后判停，快速执行组合操作，无需用户停顿等待。例如 “帮我把客厅灯打开，再把空调调到 26 度”。 |

* **音频编码格式**
   扣子编程 WebSocket 支持多种音频编码格式，以满足不同设备和网络环境的需求：
   * **输入音频**：支持 PCM、OPUS、G711A 和 G711U 格式。
   * **输出音频**：支持 PCM、OPUS、G711A 和 G711U 格式，默认为采样率 24000 的 PCM 片段。
*  **低延迟交互**
   扣子 WebSocket 具备低延迟的语音交互体验， 按键说话场景的时延低至 1.2 秒，自由对话场景的时延低至 1.8 秒。

## 按键说话场景的实现流程 {#3ff60bdb}
### 1 检查智能体配置 {#07822d0f}
在接入硬件设备之前，确保智能体的配置无误，且通话延迟小于两秒。可以通过以下步骤进行测试和验证：

1. 在 [WebSocket 实时语音 Demo](https://www.coze.cn/open-platform/realtime/websocket) 页面右上角的 **Settings** 中配置个人访问令牌（PAT）和智能体 ID ，具体步骤请参见[集成 WebSocket 实时语音 Web SDK](/dev_how_to_guides/install_wschat_sdk)。
2. 与智能体进行语音对话。测试对话的延迟，如果延迟较高，建议检查智能体的配置，例如是否配置了插件或工作流。可以先去掉这些配置进行测试，正常体感延迟应控制在 2 秒左右。

### 2 设备侧接入 {#dc6400a6}
#### 整体交互流程 {#ccf0fdbf}

![Image=600x556](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/bedd0c8c878e4067af83a9f5f1931a08~tplv-goo7wpa0wc-image.image)
#### 步骤一：建立 WebSocket 连接 {#27dda9b9}
与扣子编程建立 WebSocket 连接，具体请参见[基于 WebSocket OpenAPI 实现音频通话](/dev_how_to_guides/websocket_openapi)。
#### 步骤二：发送 chat.update 事件更新配置 {#85d4845e}
与扣子编程 WebSocket 连接成功后，立即发送 `chat.update` 事件更新对话配置。以下是配置示例：
:::tip 说明
实际使用时需要去掉代码中的注释。
:::

:::: tabs
@tab 输入输出音频都是 PCM
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM格式 
               "codec": "pcm",         // 输入音频编码。 支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 按需配置采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "pcm",      // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "pcm_config": { 
                   "sample_rate": 16000,  // 默认  24000 
                   "frame_size_ms": 50, 
                   "limit_config": { 
                       "period": 1, 
                       "max_frame_num": 22 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281"    // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "event_subscriptions": [
               "error",
               "conversation.chat.camplete",
               "conversation.chat.canceled",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


@tab 输入是 PCM，输出是 OPUS
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM 格式 
               "codec": "pcm",         // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "opus",      // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "opus_config": { 
                   "bitrate": 48000,   // 码率 
                   "use_cbr": true,     // 是否使用 cbr 编码 
                   "frame_size_ms": 60,   // 帧长(单位ms) 
                   "limit_config": { 
                       "period": 1,   // 周期（单位 s） 
                       "max_frame_num": 17 // 周期内返回最大 opus 帧数量 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281"  // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "event_subscriptions": [
               "error",
               "conversation.chat.camplete",
               "conversation.chat.canceled",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


@tab 输入是 OPUS，输出是 PCM
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM格式 
               "codec": "opus",         // 输入音频编码。 支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 按需配置采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "pcm",        // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "pcm_config": { 
                   "sample_rate": 16000,  // 默认  24000 
                   "frame_size_ms": 50, 
                   "limit_config": { 
                       "period": 1, 
                       "max_frame_num": 22 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281"    // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "event_subscriptions": [
               "error",
               "conversation.chat.camplete",
               "conversation.chat.canceled",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


@tab 输入输出都是 OPUS
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM 格式 
               "codec": "opus",         // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "opus",      // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "opus_config": { 
                   "bitrate": 48000,   // 码率 
                   "use_cbr": true,     // 是否使用 cbr 编码 
                   "frame_size_ms": 60,   // 帧长(单位ms) 
                   "limit_config": { 
                       "period": 1,   // 周期（单位 s） 
                       "max_frame_num": 17 // 周期内返回最大 opus 帧数量 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281"  // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "event_subscriptions": [
               "error",
               "conversation.chat.camplete",
               "conversation.chat.canceled",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


::::

#### 步骤三：发送音频数据 {#7bee8227}

1. 用户按下录音键，开始录音，通过 `input_audio_buffer.append` 事件持续发送音频数据给扣子编程，事件说明请参见[流式上传音频片段](/developer_guides/streaming_chat_event#98463f78)。
   如果是上行是 PCM 编码的音频，每次发送 10ms ~ 20ms 的音频数据给扣子编程，例如每间隔 20ms，发送 20ms 的音频数据，对应字节数 = 采样率 * 位深/8 * 通道数 * 0.02。
   如果上行是 OPUS 编码的音频，每次发送 20ms/40ms 帧长的 OPUS 音频数据是最优的选择。
2. 用户松开录音键，结束录音，发送 `input_audio_buffer.complete` 事件告诉扣子编程音频发送完毕。事件说明请参见[提交音频](/developer_guides/streaming_chat_event#d53cac91)。

#### 步骤四：接收音频事件 {#834b1df4}

1. 收到扣子编程返回的 `conversation.audio.delta` 事件后，解析其中的 `content` 字段，进行 Base64 解码后获取二进制音频数据。事件说明请参见[增量语音 ](/developer_guides/streaming_chat_downlink_event#d0850e28)。
2. 将音频数据放入播放缓冲区队列，由单独的线程从缓冲区取音频数据进行播放。

#### 步骤五：打断对话 {#f543e06e}

1. 智能体正在播放时，用户按下录音键，需要发送 `conversation.chat.cancel` 事件告诉扣子编程打断智能体输出。事件说明请参见[打断智能体输出](/developer_guides/streaming_chat_event#0554db7d)。
2. 扣子编程接收到 `conversation.chat.cancel` 事件后，会停止返回音频数据，并返回 `conversation.chat.canceled` 事件。
3. 设备侧接收到 `conversation.chat.canceled` 事件后，需要停止播放并清空播放缓冲区的数据。

## 自由对话场景的实现流程 {#222cae64}
扣子编程 WebSocket 方案支持自由对话，扣子编程云端会进行 VAD 的检测。
### 1 检查智能体配置 {#b842079a}
在接入硬件设备之前，确保智能体的配置无误，且通话延迟小于两秒。可以通过以下步骤进行测试和验证：

1. 在 [WebSocket 实时语音 Demo](https://www.coze.cn/open-platform/realtime/websocket) 页面右上角的 **Settings** 中配置个人访问令牌（PAT）和智能体 ID ，具体步骤请参见[集成 WebSocket 实时语音 Web SDK](/dev_how_to_guides/install_wschat_sdk)。
2. 与智能体进行语音对话。测试对话的延迟，如果延迟较高，建议检查智能体的配置，例如是否配置了插件或工作流。可以先去掉这些配置进行测试，正常体感延迟应控制在 2 秒左右。

### 2 设备侧接入 {#0a34ecca}
#### 整体交互流程 {#a1172dc8}
![Image=800x401](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/110a438fe04c4cf78e0067239fc40cb7~tplv-goo7wpa0wc-image.image)
#### 步骤一：建立 WebSocket 连接 {#0cc42236}
与扣子编程建立 WebSocket 连接，具体请参见[基于 WebSocket OpenAPI 实现音频通话](/dev_how_to_guides/websocket_openapi)。
#### 步骤二：发送 chat.update 事件更新配置 {#cde339b2}
与扣子编程 WebSocket 连接成功后，立即发送 `chat.update` 事件更新对话配置。
配置语音检测模式为自由对话模式（`data.turn_detection.type=server_vad`）。
示例代码：
:::tip 说明
实际使用时需要去掉代码中的注释。
:::

:::: tabs
@tab 输入输出音频都是 PCM
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM 格式
               "codec": "pcm",         // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "pcm",      // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "pcm_config": { 
                   "sample_rate": 16000,  // 默认  24000 
                   "frame_size_ms": 50, 
                   "limit_config": { 
                       "period": 1, 
                       "max_frame_num": 22 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281" // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "server_vad"   // 配置为自由对话模式，默认是客户端打断（按键说话）
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


@tab 输入是 PCM，输出是 OPUS
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID。按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM 格式 
               "codec": "pcm",         // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "opus",     // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "opus_config": { 
                   "bitrate": 48000,   // 码率 
                   "use_cbr": false,     // 是否使用 cbr 编码 
                   "frame_size_ms": 60,   // 帧长(单位ms) 
                   "limit_config": { 
                       "period": 1,   // 周期（单位 s） 
                       "max_frame_num": 17 // 周期内返回最大 opus 帧数量 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281"   // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "server_vad"  // 配置为自由对话模式，默认是客户端打断（按键说话）
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


@tab 输入是 OPUS，输出是 PCM
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM 格式
               "codec": "opus",         // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "pcm",      // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000  
               "pcm_config": { 
                   "sample_rate": 16000,  // 默认  24000 
                   "frame_size_ms": 50, 
                   "limit_config": { 
                       "period": 1, 
                       "max_frame_num": 22 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281" // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "server_vad"   // 配置为自由对话模式，默认是客户端打断（按键说话）
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


@tab 输入输出都是 OPUS
   ```JSON
   { 
       "id": "event_id", 
       "event_type": "chat.update", 
       "data": { 
           "chat_config": { 
               "auto_save_history": true, // 保存历史记录。默认 true 
               "conversation_id": "", // 会话 ID。按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",  // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串 
               "meta_data": {}, // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 
               "custom_variables": {}, // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 
               "extra_params": {},   // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 
               "parameters": {"custom_var_1": "测试"} 
           }, 
           "input_audio": {         // 输入音频格式 
               "format": "pcm",       // 输入音频格式，支持 PCM 格式 
               "codec": "opus",         // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm 
               "sample_rate": 24000,  // 采样率 
               "channel": 1, // 通道数 
               "bit_depth": 16 // 位深 
           }, 
           "output_audio": {        // 输出音频格式 
               "codec": "opus",     // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000 
               "opus_config": { 
                   "bitrate": 48000,   // 码率 
                   "use_cbr": false,     // 是否使用 cbr 编码 
                   "frame_size_ms": 60,   // 帧长(单位ms) 
                   "limit_config": { 
                       "period": 1,   // 周期（单位 s） 
                       "max_frame_num": 17 // 周期内返回最大 opus 帧数量 
                   } 
               }, 
               "speech_rate": 0,  // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速 
               "voice_id": "7426720361733046281"   // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "server_vad"  // 配置为自由对话模式，默认是客户端打断（按键说话）
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       } 
   }
   ```


::::

#### 步骤三：开启录音 {#1856a0c4}
通过 `input_audio_buffer.append` 事件持续发送音频给扣子编程，事件的详细说明请参见[流式上传音频片段](/developer_guides/streaming_chat_event#98463f78)。
如果上行是 PCM 编码的音频，每次发送 10ms ~ 20ms 的音频数据给扣子编程，例如每间隔 20ms，发送 20ms 的音频数据，对应字节数 = 采样率 * 位深/8 * 通道数 * 0.02。
如果上行是 OPUS 编码的音频，每次发送 20ms/40ms 帧长的 OPUS 音频数据是最优的选择。
#### 步骤四：接收音频事件 {#ce622566}

1. 收到扣子编程返回的 `conversation.audio.delta` 事件后，解析其中的 `content` 字段，进行 Base64 解码后获取二进制音频数据。事件说明请参见[增量语音 ](/developer_guides/streaming_chat_downlink_event#d0850e28)。
2. 将音频数据放入播放缓冲区队列，由单独的线程从缓冲区取音频数据进行播放。

#### 步骤五：停止播放声音 {#ea5f617f}
设备端收到以下两个事件后，需要停止播放声音，并清空播放缓冲区：

1. 收到扣子编程返回的 `input_audio_buffer.speech_started` 事件后，表示扣子编程服务端识别到用户正在说话。事件说明请参见[用户开始说话](/developer_guides/streaming_chat_downlink_event#a66ac0e1)。
2. 收到扣子返回的 `conversation.chat.canceled` 事件后，表示扣子编程服务器打断了智能体说话。事件说明请参见[智能体输出中断](/developer_guides/streaming_chat_downlink_event#fd2f7a20)。

## 语义判停场景的实现流程 {#1d8ccda6}
:::tip 说明
* **套餐限制**：仅扣子**企业旗舰版**、**原企业版**支持语义判停功能。
* **语言限制**：语义判停仅适用于中文场景，其他语种建议使用 `server_vad` 模式。
:::
#### 步骤一：建立 WebSocket 连接 {#6b37c830}
与扣子编程建立 WebSocket 连接，具体请参见[基于 WebSocket OpenAPI 实现音频通话](/dev_how_to_guides/websocket_openapi)。
#### 步骤二：发送 chat.update 事件更新配置 {#eb879651}
与扣子编程 WebSocket 连接成功后，立即发送 `chat.update` 事件更新对话配置。
配置语音检测模式为语义判停模式（`data.turn_detection.type=semantic_vad`），根据需要配置判定语音停止的语义检测策略：

* `data.turn_detection.semantic_vad_config.silence_threshold_ms`：当用户暂停说话时，持续静音多久后，触发语义判停检测。
* `data.turn_detection.semantic_vad_config.semantic_unfinished_wait_time_ms`：当语义检测判断该语句未结束时，持续静音多久后，扣子编程认定语音结束。

示例代码：
:::tip 说明
实际使用时需要去掉代码中的注释。
:::

:::: tabs
@tab 输入输出音频都是 PCM
   ```JSON
   {
       "id": "event_id",
       "event_type": "chat.update",
       "data": {
           "chat_config": {
               "auto_save_history": true,  // 保存历史记录。默认 true
               "conversation_id": "",      // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，可通过查看会话列表 API 的返回参数中获取 conversation_id
               "user_id": "xxx",           // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串
               "meta_data": {},            // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息
               "custom_variables": {},     // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线
               "extra_params": {},         // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314
               "parameters": {"custom_var_1": "测试"}
           },
           "input_audio": {
               "format": "pcm",            // 输入音频格式，支持 PCM 格式
               "codec": "pcm",             // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm
               "sample_rate": 24000,       // 采样率
               "channel": 1,               // 通道数
               "bit_depth": 16             // 位深
           },
           "output_audio": {
               "codec": "pcm",             // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "pcm_config": {
                   "sample_rate": 16000,   // 默认 24000
                   "frame_size_ms": 50,
                   "limit_config": {
                       "period": 1,
                       "max_frame_num": 22
                   }
               },
               "speech_rate": 0,           // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速
               "voice_id": "7426720361733046281"  // 音色id，可通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "semantic_vad",  //配置为语义判停模式
               "semantic_vad_config": {
                   "silence_threshold_ms": 300,           // 当用户暂停说话时，持续静音多久后，触发语义判停检测。单位为 ms。默认为 300ms
                   "semantic_unfinished_wait_time_ms": 500  // 当语义检测判断该语句未结束时，持续静音多久后，扣子认定语音结束。单位为 ms。默认为 500ms。取值范围：100~2000
               }
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       }
   }
   ```


@tab 输入是 PCM，输出是 OPUS
   ```JSON
   {
       "id": "event_id",
       "event_type": "chat.update",
       "data": {
           "chat_config": {
               "auto_save_history": true,  // 保存历史记录。默认 true
               "conversation_id": "",      // 会话 ID。按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",           // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串
               "meta_data": {},            // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。
               "custom_variables": {},     // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。
               "extra_params": {},         // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。
               "parameters": {"custom_var_1": "测试"}
           },
           "input_audio": {
               "format": "pcm",            // 输入音频格式，支持 PCM 格式
               "codec": "pcm",             // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm
               "sample_rate": 24000,       // 采样率
               "channel": 1,               // 通道数
               "bit_depth": 16             // 位深
           },
           "output_audio": {
               "codec": "opus",            // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "opus_config": {
                   "bitrate": 48000,       // 码率
                   "use_cbr": false,       // 是否使用 cbr 编码
                   "frame_size_ms": 60,    // 帧长(单位ms)
                   "limit_config": {
                       "period": 1,        // 周期（单位 s）
                       "max_frame_num": 17 // 周期内返回最大 opus 帧数量
                   }
               },
               "speech_rate": 0,           // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速
               "voice_id": "7426720361733046281"  // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "semantic_vad",   //配置为语义判停模式
               "semantic_vad_config": {
                   "silence_threshold_ms": 300,           // 当用户暂停说话时，持续静音多久后，触发语义判停检测。单位为 ms。默认为 300ms
                   "semantic_unfinished_wait_time_ms": 500  // 当语义检测判断该语句未结束时，持续静音多久后，扣子认定语音结束。单位为 ms。默认为 500ms。取值范围：100~2000
               }
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       }
   }
   ```


@tab 输入是 OPUS，输出是 PCM
   ```JSON
   {
       "id": "event_id",
       "event_type": "chat.update",
       "data": {
           "chat_config": {
               "auto_save_history": true,  // 保存历史记录。默认 true
               "conversation_id": "",      // 会话 ID，按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",           // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串
               "meta_data": {},            // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。
               "custom_variables": {},     // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。
               "extra_params": {},         // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。
               "parameters": {"custom_var_1": "测试"}
           },
           "input_audio": {
               "format": "pcm",            // 输入音频格式，支持 PCM 格式
               "codec": "opus",            // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm
               "sample_rate": 24000,       // 采样率
               "channel": 1,               // 通道数
               "bit_depth": 16             // 位深
           },
           "output_audio": {
               "codec": "pcm",             // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "pcm_config": {
                   "sample_rate": 16000,   // 默认 24000
                   "frame_size_ms": 50,
                   "limit_config": {
                       "period": 1,
                       "max_frame_num": 22
                   }
               },
               "speech_rate": 0,           // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速
               "voice_id": "7426720361733046281"  // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "semantic_vad",   //配置为语义判停模式
               "semantic_vad_config": {
                   "silence_threshold_ms": 300,           // 当用户暂停说话时，持续静音多久后，触发语义判停检测。单位为 ms。默认为 300ms
                   "semantic_unfinished_wait_time_ms": 500  // 当语义检测判断该语句未结束时，持续静音多久后，扣子认定语音结束。单位为 ms。默认为 500ms。取值范围：100~2000
               }
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       }
   }
   ```


@tab 输入输出都是 OPUS
   ```JSON
   {
       "id": "event_id",
       "event_type": "chat.update",
       "data": {
           "chat_config": {
               "auto_save_history": true,  // 保存历史记录。默认 true
               "conversation_id": "",      // 会话 ID。按需配置，可以不设置，不设置就去掉这行配置，不要传空!，你可以通过查看会话列表 API 的返回参数中获取 conversation_id。
               "user_id": "xxx",           // 标识当前与智能体的用户，由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户，不同的 user_id，其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离，可将此参数固定为一个任意字符串
               "meta_data": {},            // 附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。
               "custom_variables": {},     // 智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。
               "extra_params": {},         // 附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。
               "parameters": {"custom_var_1": "测试"}
           },
           "input_audio": {
               "format": "pcm",            // 输入音频格式，支持 PCM 格式
               "codec": "opus",            // 输入音频编码。支持 pcm/g711a/g711u/opus。默认 pcm
               "sample_rate": 24000,       // 采样率
               "channel": 1,               // 通道数
               "bit_depth": 16             // 位深
           },
           "output_audio": {
               "codec": "opus",            // 支持 pcm/g711a/g711u/opus。默认 pcm。如果是 g711a/g711u，pcm_config 的 sample_rate 只能是 8000
               "opus_config": {
                   "bitrate": 48000,       // 码率
                   "use_cbr": false,       // 是否使用 cbr 编码
                   "frame_size_ms": 60,    // 帧长(单位ms)
                   "limit_config": {
                       "period": 1,        // 周期（单位 s）
                       "max_frame_num": 17 // 周期内返回最大 opus 帧数量
                   }
               },
               "speech_rate": 0,           // 回复的语速，取值范围 [-50, 100]，默认为 0，-50 表示 0.5 倍速，100 表示 2倍速
               "voice_id": "7426720361733046281"  // 音色id，你可以通过查看音色列表 API 获取可用的音色，具体请参见https://www.coze.cn/open/docs/developer_guides/list_voices
           },
           "turn_detection": {
               "type": "semantic_vad",   //配置为语义判停模式
               "semantic_vad_config": {
                   "silence_threshold_ms": 300,           // 当用户暂停说话时，持续静音多久后，触发语义判停检测。单位为 ms。默认为 300ms
                   "semantic_unfinished_wait_time_ms": 500  // 当语义检测判断该语句未结束时，持续静音多久后，扣子认定语音结束。单位为 ms。默认为 500ms。取值范围：100~2000
               }
           },
           "event_subscriptions": [
               "error",
               "input_audio_buffer.speech_started",
               "input_audio_buffer.speech_stopped",
               "conversation.audio.delta",
               "conversation.chat.failed"
           ]
       }
   }
   ```


::::

#### 步骤三：开启录音 {#1366c4f8}
通过 `input_audio_buffer.append` 事件持续发送音频给扣子编程，事件的详细说明请参见[流式上传音频片段](/developer_guides/streaming_chat_event#98463f78)。
如果上行是 PCM 编码的音频，每次发送 10ms ~ 20ms 的音频数据给扣子编程，例如每间隔 20ms，发送 20ms 的音频数据，对应字节数 = 采样率 * 位深/8 * 通道数 * 0.02。
如果上行是 OPUS 编码的音频，每次发送 20ms/40ms 帧长的 OPUS 音频数据是最优的选择。
#### 步骤四：接收音频事件 {#008c4903}

1. 收到扣子编程返回的 `conversation.audio.delta` 事件后，解析其中的 `content` 字段，进行 Base64 解码后获取二进制音频数据。事件说明请参见[增量语音 ](/developer_guides/streaming_chat_downlink_event#d0850e28)。
2. 将音频数据放入播放缓冲区队列，由单独的线程从缓冲区取音频数据进行播放。

#### 步骤五：停止播放声音 {#50e2135b}
设备端收到以下两个事件后，需要停止播放声音，并清空播放缓冲区：

1. 收到扣子编程返回的 `input_audio_buffer.speech_started` 事件后，表示扣子编程服务端识别到用户正在说话。事件说明请参见[用户开始说话](/developer_guides/streaming_chat_downlink_event#a66ac0e1)。
2. 收到扣子编程返回的 `conversation.chat.canceled` 事件后，表示扣子编程服务器打断了智能体说话。事件说明请参见[智能体输出中断](/developer_guides/streaming_chat_downlink_event#fd2f7a20)。
