助手
扣子 AI 帮助与支持
你好,我是 扣子 文档问答助手 🎉 你在阅读当前文档的过程中,无论对文档概念的解释,还是文档内容方面的疑问,都可以随时向我提问,我会全力为你解答
推荐问题
如何快速了解这个空间的核心内容?
有哪些近期更新的重点文档?
我应该从哪些文档开始阅读?
文档反馈

硬件设备基于 WebSocket 实现语音交互

更新于: 2026-06-24 15:47:07

本文介绍硬件设备通过 WebSocket 实现语音交互的完整流程。WebSocket 技术为硬件设备提供了低延迟的语音交互能力,支持按键说话、普通自由对话和语义判停自由对话三种模式,适用于智能音箱、车载系统、智能家居控制、在线客服、游戏语音聊天等场景,满足不同使用场景的需求。

WebSocket 语音功能介绍

扣子编程 WebSocket 提供了高效且灵活的语音交互解决方案,以下是其核心功能:

  • 语音模式
    扣子编程 WebSocket 语音通话支持按键说话、普通自由对话和语义判停自由对话三种模式,默认为按键说话模式,三种模式的对比说明如下:

    特性

    按键说话模式 (client_interrupt)

    普通自由对话模式 (server_vad)

    语义判停自由对话模式(semantic_vad)

    控制方式

    用户通过物理按键或屏幕按钮精确控制语音识别的开始和结束。

    由云端语音活动检测 (VAD) 算法自动判断用户是否在说话。

    由服务端识别语义来判断是否停止说话。

    核心优势

    精准控制:避免背景噪音干扰,只有在用户主动操作时才传输音频,保障了通信的私密性和准确性。

    自然流畅:用户无需任何额外操作,像正常交谈一样即可开始和结束对话,提供了“解放双手”的无缝体验。

    智能语义感知:基于语义理解判断语句完整性,在语义完整时自动判停,从而加速模型响应,提升交互效率。

    典型场景

    • 在线游戏:避免键盘、鼠标声干扰团队语音。
    • 智能玩具:故事机等具备实体按键的智能玩具,防止儿童误触发,同时增强互动趣味性。
    • 语音助手:与智能设备进行自然语言交互。
    • 智能客服:在呼叫中心等场景下进行流畅的语音问答。
    • 智能客服:快速识别用户咨询意图完整性,在用户描述问题后立即触发处理流程,提升客服响应速度。
    • 智能家居:识别多指令语义完整后判停,快速执行组合操作,无需用户停顿等待。例如 “帮我把客厅灯打开,再把空调调到 26 度”。
  • 音频编码格式
    扣子编程 WebSocket 支持多种音频编码格式,以满足不同设备和网络环境的需求:

    • 输入音频:支持 PCM、OPUS、G711A 和 G711U 格式。
    • 输出音频:支持 PCM、OPUS、G711A 和 G711U 格式,默认为采样率 24000 的 PCM 片段。
  • 低延迟交互
    扣子 WebSocket 具备低延迟的语音交互体验, 按键说话场景的时延低至 1.2 秒,自由对话场景的时延低至 1.8 秒。

按键说话场景的实现流程

1 检查智能体配置

在接入硬件设备之前,确保智能体的配置无误,且通话延迟小于两秒。可以通过以下步骤进行测试和验证:

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

2 设备侧接入

整体交互流程

Image

步骤一:建立 WebSocket 连接

与扣子编程建立 WebSocket 连接,具体请参见基于 WebSocket OpenAPI 实现音频通话

步骤二:发送 chat.update 事件更新配置

与扣子编程 WebSocket 连接成功后,立即发送 chat.update 事件更新对话配置。以下是配置示例:

说明

实际使用时需要去掉代码中的注释。

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

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

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

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

步骤三:发送音频数据

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

步骤四:接收音频事件

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

步骤五:打断对话

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

自由对话场景的实现流程

扣子编程 WebSocket 方案支持自由对话,扣子编程云端会进行 VAD 的检测。

1 检查智能体配置

在接入硬件设备之前,确保智能体的配置无误,且通话延迟小于两秒。可以通过以下步骤进行测试和验证:

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

2 设备侧接入

整体交互流程

Image

步骤一:建立 WebSocket 连接

与扣子编程建立 WebSocket 连接,具体请参见基于 WebSocket OpenAPI 实现音频通话

步骤二:发送 chat.update 事件更新配置

与扣子编程 WebSocket 连接成功后,立即发送 chat.update 事件更新对话配置。
配置语音检测模式为自由对话模式(data.turn_detection.type=server_vad)。
示例代码:

说明

实际使用时需要去掉代码中的注释。

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

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

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

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

步骤三:开启录音

通过 input_audio_buffer.append 事件持续发送音频给扣子编程,事件的详细说明请参见流式上传音频片段
如果上行是 PCM 编码的音频,每次发送 10ms ~ 20ms 的音频数据给扣子编程,例如每间隔 20ms,发送 20ms 的音频数据,对应字节数 = 采样率 * 位深/8 * 通道数 * 0.02。
如果上行是 OPUS 编码的音频,每次发送 20ms/40ms 帧长的 OPUS 音频数据是最优的选择。

步骤四:接收音频事件

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

步骤五:停止播放声音

设备端收到以下两个事件后,需要停止播放声音,并清空播放缓冲区:

  1. 收到扣子编程返回的 input_audio_buffer.speech_started 事件后,表示扣子编程服务端识别到用户正在说话。事件说明请参见用户开始说话
  2. 收到扣子返回的 conversation.chat.canceled 事件后,表示扣子编程服务器打断了智能体说话。事件说明请参见智能体输出中断

语义判停场景的实现流程

说明

  • 套餐限制:仅扣子企业旗舰版原企业版支持语义判停功能。
  • 语言限制:语义判停仅适用于中文场景,其他语种建议使用 server_vad 模式。

步骤一:建立 WebSocket 连接

与扣子编程建立 WebSocket 连接,具体请参见基于 WebSocket OpenAPI 实现音频通话

步骤二:发送 chat.update 事件更新配置

与扣子编程 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:当语义检测判断该语句未结束时,持续静音多久后,扣子编程认定语音结束。

示例代码:

说明

实际使用时需要去掉代码中的注释。

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

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

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

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

步骤三:开启录音

通过 input_audio_buffer.append 事件持续发送音频给扣子编程,事件的详细说明请参见流式上传音频片段
如果上行是 PCM 编码的音频,每次发送 10ms ~ 20ms 的音频数据给扣子编程,例如每间隔 20ms,发送 20ms 的音频数据,对应字节数 = 采样率 * 位深/8 * 通道数 * 0.02。
如果上行是 OPUS 编码的音频,每次发送 20ms/40ms 帧长的 OPUS 音频数据是最优的选择。

步骤四:接收音频事件

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

步骤五:停止播放声音

设备端收到以下两个事件后,需要停止播放声音,并清空播放缓冲区:

  1. 收到扣子编程返回的 input_audio_buffer.speech_started 事件后,表示扣子编程服务端识别到用户正在说话。事件说明请参见用户开始说话
  2. 收到扣子编程返回的 conversation.chat.canceled 事件后,表示扣子编程服务器打断了智能体说话。事件说明请参见智能体输出中断