手写html代码调用Azure OpenAI Realtime api打造实时语音ai助手
最近openai开放了gpt4o的realtime实时语音聊天api,也就是普通的开发者就能实现一个类似真人的实时语音聊天助手了,于此同时,azure ai也支持了gpt4o的realtime实时语音对话的api,由于我们不是openai的pro付费用户,所有没办法测试openai的realtime api,但是azure openai也是用的openai的模型,所以两者的接口通讯协议是一样的,都是基于websocket双工通讯。
今天我来一步一步教大家用html写一个调用openai的realtime api打造一个实时语音ai聊天的网页应用
一、注册登录azure
先打开网页注册登录azure,然后进入控制台,部署一个gpt4o的realtime模型:地址:https://ai.azure.com/
模型部署完成可以在操场中进行体验,可选择不同的音色,设置参数和提示词
在部署列表中可以查看到部署好的gpt4o realtime模型的秘钥,记得复制保存:
二、熟悉realtime websocket协议的内容
准备工作做完了,我们来调用api,由于realtime api是websocket,所以azure openai的url地址如下:
wss://你的endpoint地址/openai/realtime?api-version=2024-10-01-preview&deployment=gpt-4o-realtime-preview&api-key=第一步获取的key秘钥。
通讯过程如下:
详细的api文档
一旦与 /realtime
的 WebSocket 连接会话建立并经过身份验证,功能交互将通过发送和接收 WebSocket 消息进行,这里称为“命令”,以避免与已有的内容承载“消息”概念混淆。这些命令的形式均为 JSON 对象。命令可以并行发送和接收,应用程序应通常同时异步处理它们。
会话配置和轮转处理模式
通常,调用者在新建立的 /realtime
会话中发送的第一个命令将是 session.update
负载。该命令控制输入和输出行为的一系列宽泛设置,输出和响应生成部分可以通过 response.create
属性在稍后进行覆盖(如果需要)。
一个关键的会话设置是 turn_detection
,它控制调用者与模型之间的数据流处理方式:
input_audio_buffer.append
发送),并在检测到语音结束时自动使用该音频发起响应生成。可以在指定 server_vad
检测模式时配置静音检测。input_audio_buffer.commit
和 response.create
命令来推进对话并生成输出。这对于推到说话应用或具有外部音频流控制(如调用者侧 VAD 组件)的情况很有用。请注意,这些手动信号仍可在 server_vad
模式下用于补充 VAD 发起的响应生成。用户输入音频的转录通过 input_audio_transcription
属性选择;在此配置中指定转录模型(whisper-1
)将启用 conversation.item.audio_transcription.completed
事件的发送。
以下是一个配置会话多个方面的 session.update
示例,包括工具。请注意,所有会话参数都是可选的;不需要配置所有内容!
{ "type": "session.update", "session": { "voice": "alloy", "instructions": "Call provided tools if appropriate for the user's input.", "input_audio_format": "pcm16", "input_audio_transcription": { "model": "whisper-1" }, "turn_detection": { "threshold": 0.4, "silence_duration_ms": 600, "type": "server_vad" }, "tools": [ { "type": "function", "name": "get_weather_for_location", "description": "gets the weather for a location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state e.g. San Francisco, CA" }, "unit": { "type": "string", "enum": [ "c", "f" ] } }, "required": [ "location", "unit" ] } } ] } }
请求:从调用者发送到 /realtime
端点的命令
类型 | 描述 |
---|---|
会话配置 | |
session.update | 配置对话会话的连接行为,如共享音频输入处理和常见响应生成特性。通常在连接后立即发送,但也可以在会话的任何时候发送以重新配置行为(如果当前响应已完成)。 |
输入音频 | |
input_audio_buffer.append | 将音频数据追加到共享用户输入缓冲区。该音频在服务器 VAD 轮转检测模式下不会处理,直到检测到语音结束或发送手动 response.create 。 |
input_audio_buffer.clear | 清除当前的音频输入缓冲区。请注意,这不会影响已经在处理中的响应。 |
input_audio_buffer.commit | 将用户输入缓冲区的当前状态提交到已订阅的对话中,包括作为下一个响应的信息。 |
项目管理 | 用于建立历史或包含非音频项信息 |
conversation.item.create | 将新项目插入对话中,可根据 previous_item_id 定位。可以提供用户的新非音频输入(如文本消息)、工具响应或来自其他交互的历史信息,以形成生成前的对话历史。 |
conversation.item.delete | 从现有对话中删除项目。 |
conversation.item.truncate | 手动缩短消息中的文本和/或音频内容,这在实时模型生成产生了大量额外数据后可能很有用,这些数据在被中断时被跳过。 |
响应管理 | |
response.create | 开始处理未处理的对话输入,标志着调用者逻辑轮转的结束。server_vad 轮转检测模式将在语音结束时自动触发生成,但在其他情况下(文本输入、工具响应、none 模式等)必须调用 response.create 。请注意,在响应工具调用时,response.create 应在模型的 response.done 命令之后调用,该命令确认所有工具调用和其他消息已提供。 |
response.cancel | 取消正在进行的响应。 |
响应:由 /realtime 端点发送给调用者的命令
类型 | 描述 |
---|---|
session.created | 连接成功建立后立即发送。提供可能有助于调试或日志记录的连接特定 ID。 |
session.updated | 响应于 session.update 事件,反映对会话配置所做的更改。 |
调用者项目确认 | |
conversation.item.created | 提供对新对话项目已插入对话的确认。 |
conversation.item.deleted | 提供对已从对话中删除现有对话项目的确认。 |
conversation.item.truncated | 提供对对话中现有项目已被缩短的确认。 |
响应流 | |
response.created | 通知对话已开始生成新响应。此时快照输入状态并开始生成新项目。在 response.done 表示响应结束之前,响应可能通过 response.output_item.added 创建项目,后者通过增量命令填充。 |
response.done | 通知对话的响应生成已完成。 |
rate_limits.updated | 在 response.done 之后立即发送,提供在消耗刚完成的响应后的当前速率限制信息。 |
响应中的项目流
类型 | 描述 |
---|---|
response.output_item.added | 通知正在创建新的服务器生成对话项目;内容将通过增量 add_content 消息填充,最终通过 response.output_item.done 命令标志项目创建完成。 |
response.output_item.done | 通知新对话项目已完成添加到对话中。对于模型生成的消息,这会在 response.output_item.added 和增量命令之后发生,这些命令开始并填充新项目。 |
响应项目中的内容流
类型 | 描述 |
---|---|
response.content_part.added | 通知正在创建对话项目中的新内容部分。在到达 response.content_part.done 之前,内容将通过适当的增量命令逐步提供。 |
response.content_part.done | 标志新创建的内容部分已完成,将不再接收进一步的增量更新。 |
response.audio.delta | 提供由模型生成的二进制音频数据内容部分的增量更新。 |
response.audio.done | 标志音频内容部分的增量更新已完成。 |
response.audio_transcript.delta | 提供与由模型生成的输出音频相关联的音频转录的增量更新。 |
response.audio_transcript.done | 标志与输出音频相关的音频转录的增量更新已完成。 |
response.text.delta | 提供对对话消息项目中的文本内容部分的增量更新。 |
response.text.done | 标志对文本内容部分的增量更新已完成。 |
response.function_call_arguments.delta | 提供对对话中 |
项目的函数调用参数的增量更新。 response.function_call_arguments.done
标志增量函数调用参数已完成,累积参数现在可以完整使用。
用户输入音频
类型 | 描述 |
---|---|
input_audio_buffer.speech_started | 在使用配置的语音活动检测时,该命令通知在特定音频样本索引处检测到用户语音的开始。 |
input_audio_buffer.speech_stopped | 在使用配置的语音活动检测时,该命令通知在特定音频样本索引处检测到用户语音的结束。这将在配置时自动触发响应生成。 |
conversation.item.input_audio_transcription.completed | 通知用户输入音频缓冲区的补充转录已可用。此行为必须通过在 session.update 中的 input_audio_transcription 属性选择。 |
conversation.item.input_audio_transcription.failed | 通知输入音频转录失败。 |
input_audio_buffer.committed | 提供确认当前用户音频输入缓冲区的状态已提交到已订阅的对话。 |
input_audio_buffer.cleared | 提供确认待处理的用户音频输入缓冲区已被清除。 |
其他
类型 | 描述 |
---|---|
error | 指示在处理会话中的数据时出现问题。包括提供额外详细信息的错误消息。 |
请根据具体需求进行适当的调整和扩展。
三、html代码实现
下面我们根据api文档用html写一个调用openai realtime的html示例代码,实现了语音交互和语音打断对话。
主要通过麦克风实时采集单声道(mono)、16位PCM、采样率为24kHz的音频数据通过websocket发送给openai api接口,openai通过音频来检测是否有人声进行打断处理,openai 通过实时的输出base64格式的音频数据给客户端来进行播放,这里面播放采用队列,打断的时候进行队列清空处理。
完整的html代码
网友评论0