你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
适用于语音和音频的 Azure OpenAI GPT 实时 API 是 GPT-4o 模型系列的一部分,该系列支持低延迟的“语音传入,语音传出”对话交互。
可以通过 WebRTC、SIP 或 WebSocket 使用实时 API 将音频输入发送到模型并实时接收音频响应。 按照本文中的说明通过 SIP 开始使用实时 API。
SIP 是用于通过 Internet 拨打电话的协议。 使用 SIP 和实时 API,可以将传入电话呼叫定向到 API。
支持的模型
GPT 实时模型可用于美国东部 2 和瑞典中部地区的全局部署。
-
gpt-4o-mini-realtime-preview(2024-12-17) -
gpt-4o-realtime-preview(2024-12-17) -
gpt-realtime(版本 2025-08-28) -
gpt-realtime-mini(版本 2025-10-06)
先决条件
在使用 GPT 实时音频之前,需要:
- Azure 订阅 - 免费创建订阅。
- Microsoft Foundry 资源 - 在一个受支持的区域中创建 Microsoft Foundry 资源。
- 如本文中的“支持的模型”部分所述,在受支持的区域中部署
gpt-4o-realtime-preview、gpt-4o-mini-realtime-preview、gpt-realtime或gpt-realtime-mini模型。- 在 Microsoft Foundry 门户中,加载项目。 在右上方菜单中选择“ 生成 ”,然后选择左窗格中的“ 模型 ”选项卡,然后 部署基本模型。 搜索所需的模型,然后选择“模型”页上的“ 部署 ”。
- Azure 订阅 - 免费创建订阅。
- 在 受支持的区域中创建的 Azure OpenAI 资源。 有关详细信息,请参阅使用 Azure OpenAI 创建资源和部署模型。
- 如本文中的“支持的模型”部分所述,在受支持的区域中部署
gpt-4o-realtime-preview、gpt-4o-mini-realtime-preview、gpt-realtime或gpt-realtime-mini模型。 可以从 Foundry 模型目录 或 Microsoft Foundry 门户中的项目部署模型。
连接到 SIP
如果要将电话号码连接到实时 API,请使用 SIP 中继提供程序(例如 Twilio)。 中继提供商是将电话呼叫转换为 IP 流量的服务。 从 SIP 中继提供商处购买电话号码后,请按照此处所示的说明进行作。
首先,使用 Azure OpenAI Webhook 服务为传入调用创建 Webhook。 我们有一个 REST API ,可用于创建、更新、查看和删除 Webhook 终结点。
然后,使用 Azure 资源的内部 ID 将 SIP 中继指向 Azure OpenAI SIP 终结点。 示例:
- 获取 Azure Open AI 资源的内部 ID。 可以通过单击你资源中的
JSON View来查找内部 ID。 - 项目 ID =
"proj_<internalId>"这可能类似于"proj_88c4a88817034471a0ba0fcae24ceb1b"
你的 sip 邀请将此项目 ID 用作用户:例如 sip:proj_88c4a88817034471a0ba0fcae24ceb1b@<region>.sip.ai.azure.com;transport=tls。
目前支持的地区为 swedencentral 和 eastus2。
处理传入呼叫
当 Azure OpenAI 收到与项目关联的 SIP 流量时,Webhook 终结点将收到传入事件消息。 为 sip 调用触发的事件类型为 realtime.call.incoming,类似于此处所示的示例。
POST https://my_website.com/webhook_endpoint
user-agent: OpenAI/1.0 (+https://platform.openai.com/docs/webhooks)
content-type: application/json
webhook-id: wh_685342e6c53c8190a1be43f081506c52 # unique ID for idempotency
webhook-timestamp: 1750287078 # timestamp of delivery attempt
webhook-signature: v1,Signature # signature to verify authenticity from OpenAI
{
"object": "event",
"id": "evt_685343a1381c819085d44c354e1b330e",
"type": "realtime.call.incoming",
"created_at": 1750287018, // Unix timestamp
"data": {
"call_id": "some_unique_id",
"sip_headers": [
{ "name": "From", "value": "sip:+142555512112@sip.example.com" },
{ "name": "To", "value": "sip:+18005551212@sip.example.com" },
{ "name": "Call-ID", "value": "rtc_xyz"}
]
}
}
通过 Webhook 终结点,可以使用 webhook 事件中的 call_id 值接受、拒绝或转发此呼叫。 接受呼叫时,为实时 API 会话提供所需的配置(说明、语音等)。 建立后,可以设置 WebSocket 并照常监视会话。 以下部分介绍了接受、拒绝、监视、引用和挂起调用的 API。
接受呼叫
使用接受呼叫终结点批准入站呼叫,并配置应答它的实时会话。 发送创建客户端机密所需的相同参数。 可以包含将在 session.update 消息中使用的任何值,但需要类型、模型和说明。
注释
对于授权,可以使用 API 密钥标头或持有者令牌,如下所示。 请记住,模型名称实际上是部署的名称。
curl -X POST "https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/accept" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "realtime",
"model": "gpt-realtime",
"instructions": "You are Alex, a friendly concierge for Example Corp."
}'
请求路径必须包含
- realtime.call.incoming webhook 事件的 call_id
- 授权(或 API 密钥)头
当 SIP 会话分支正在响铃并且实时会话正在建立时,终结点将返回 200 OK。
拒接电话
如果不想处理传入呼叫(例如,来自不受支持的国家/地区代码),请使用拒绝呼叫终结点拒绝邀请。若要控制发回运营商的响应,请提供可选的 SIP 状态代码以及所需的call_id路径参数。 此处的示例显示了发送 486 的请求,这表示系统太忙,无法接听呼叫。
curl -X POST "https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/reject" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status_code": 486}'
如果未提供状态代码,sip 服务器会将状态代码 603 发送给客户,作为拒绝消息的一部分。 OpenAI 提供 SIP 响应后,成功的请求响应为 200 OK。
重定向呼叫
使用“Refer”呼叫端点转移活动呼叫。 提供应放置在 SIP Refer-To 标头中的call_id和target_uri(例如 +14155550123 或 sip:agent@example.com)。
curl -X POST "https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/refer" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"target_uri": "tel:+14155550123"}'
当 REFER 中继到 SIP 提供程序后,OpenAI 将返回 200 OK。 下游系统处理调用方剩余的调用流。
监视呼叫事件并发出会话命令和更新
接受调用后,打开与同一会话的 WebSocket 连接以流式传输事件并发出实时 API 命令。 若要创建对现有调用的 Websocket,必须使用call_id参数。 模型参数未使用,因为在接受调用时,该参数被配置为 json 的一部分。 此处的示例演示了一个常见方案,发出“response.create”消息,以指示实时 API 系统“接听电话并说 hello”。
下面是对特定 SIP 调用的 WebSocket 请求的示例。
GET wss://<your azure resource name>.openai.azure.com/openai/v1/realtime?call_id={call_id}
查询参数
| 参数 | 类型 | Description |
|---|---|---|
| call_id | 字符串 | realtime.call.incoming webhook 中的标识符。 |
Headers
授权:Bearer $TOKEN(或 API-Key:你的 API 密钥)
WebSocket 的行为与任何其他实时 API 连接完全相同。
可以发送“response.create”或“session.update”等消息来控制调用,并侦听正在返回的服务器事件以跟踪进度。
以下代码片段说明了如何建立 Websocket 连接。
import WebSocket from "ws";
const callId = "rtc_u1_9c6574da8b8a41a18da9308f4ad974ce";
const ws = new WebSocket(`wss://<your azure resource name>.openai.azure.com/openai/v1/realtime?call_id=${callId}`, {
headers: {
api-key: `${process.env.OPENAI_API_KEY}`,
},
});
ws.on("open", () => {
ws.send(
JSON.stringify({
type: "response.create",
})
);
});
挂断呼叫
当应用程序需要断开调用方的连接时,通过“挂断”终结点来结束电话会话。 此终结点可用于终止 SIP 和 WebRTC 实时会话。
curl -X POST "https://<your azure resoure name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/hangup" \
-H "Authorization: Bearer $TOKEN"
The API responds with 200 OK when it starts tearing down the call.
示例 Webhook 终结点
以下代码是 realtime.call.incoming 处理程序的 python 示例。 它接受调用,然后记录来自实时 API 的所有事件。
from flask import Flask, request, Response, jsonify, make_response
from openai import OpenAI, InvalidWebhookSignatureError
import asyncio
import json
import os
import requests
import time
import threading
import websockets
app = Flask(__name__)
client = OpenAI(
webhook_secret=os.environ["OPENAI_WEBHOOK_SECRET"]
)
AUTH_HEADER = {
"api-key": os.getenv("OPENAI_API_KEY")
}
call_accept = {
"type": "realtime",
"instructions": "You are a support agent.",
"model": "gpt-realtime",
}
response_create = {
"type": "response.create",
"response": {
"instructions": (
"Say to the user 'Thank you for calling, how can I help you'"
)
},
}
async def websocket_task(call_id):
try:
async with websockets.connect(
"wss://<your azure resource>.openai.azure.com/openai/v1/realtime?call_id=" + call_id,
additional_headers=AUTH_HEADER,
) as websocket:
await websocket.send(json.dumps(response_create))
while True:
response = await websocket.recv()
print(f"Received from WebSocket: {response}")
except Exception as e:
print(f"WebSocket error: {e}")
@app.route("/", methods=["POST"])
def webhook():
try:
event = client.webhooks.unwrap(request.data, request.headers)
if event.type == "realtime.call.incoming":
requests.post(
"https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/"
+ event.data.call_id
+ "/accept",
headers={**AUTH_HEADER, "Content-Type": "application/json"},
json=call_accept,
)
threading.Thread(
target=lambda: asyncio.run(
websocket_task(event.data.call_id)
),
daemon=True,
).start()
return Response(status=200)
except InvalidWebhookSignatureError as e:
print("Invalid signature", e)
return Response("Invalid signature", status=400)
if __name__ == "__main__":
app.run(port=8000)
后续步骤
现在,你已了解如何通过 SIP 连接呼叫。 下一步是构建您的实时应用程序提示来服务您的客户。