手写html代码调用Azure OpenAI Realtime api打造实时语音ai助手

手写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,它控制调用者与模型之间的数据流处理方式:

  • server_vad:将使用语音活动检测器(VAD)组件评估传入的用户音频(通过 input_audio_buffer.append 发送),并在检测到语音结束时自动使用该音频发起响应生成。可以在指定 server_vad 检测模式时配置静音检测。
  • none:依赖调用者发起的 input_audio_buffer.commitresponse.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.updatedresponse.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代码

{{collectdata}}

网友评论0