跳到主要内容

使用 Chat Completions 输入和输出音频

支持音频的聊天模型可以接收消息中的录制音频,并在同一个 Chat Completions 响应中返回生成的音频。这适合需要模型理解音频或以音频回答,同时保持兼容 OpenAI 的 POST /v1/chat/completions 请求形态的轮次式应用。

如需独立转录、翻译或语音生成,请使用语音与音频。如需交互式双向会话,请使用 Realtime API

当所选上游使用兼容的 OpenAI 形态 API 时,AISIX 会保留 OpenAI 聊天音频请求和响应字段。它不会将这些字段转换为其他服务提供方的原生音频协议。

准备工作

请先准备以下内容:

  • 一个可以处理代理请求的 AISIX 网关。
  • 一个可以访问该模型别名的调用方 API Key。
  • 一个由支持音频的 Chat Completions 模型支撑的模型别名。其服务提供方密钥必须使用 openaiazure-openai 适配器,且上游必须实现 OpenAI 聊天音频请求和响应形态。
  • 一个名为 question.wav 的本地 WAV 录音,用于音频输入示例。
  • 示例所需的 curljq、Python 3,以及 base64filetr 命令行工具。

如果尚未配置上游,请参阅 OpenAIAzure OpenAI自带端点。选择上游当前支持的音频模型,并为其创建 AISIX 别名。

对于路由别名,每个符合条件的目标都必须使用上述适配器之一,并支持相同的聊天音频字段。如果故障转移到仅支持文本或形态不同的服务提供方,音频内容可能丢失,或请求可能在上游失败。

导出网关连接和请求值:

# AISIX_PROXY 末尾不含斜杠,也不包含 /v1 等端点路径。
# 本地快速入门使用 http://127.0.0.1:3000。
export AISIX_PROXY="YOUR_AISIX_GATEWAY_ORIGIN"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export AISIX_MODEL="audio-chat-prod"

生成音频响应

同时请求文本和音频输出,然后保存完整响应:

curl -sS -X POST "${AISIX_PROXY}/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"modalities": ["text", "audio"],
"audio": {
"voice": "alloy",
"format": "wav"
},
"messages": [
{
"role": "user",
"content": "Say: Your AISIX audio route is working."
}
]
}' > chat-audio-response.json

AISIX 会在分发前将别名替换为上游模型 ID。上游决定接受哪些声音和输出格式。

检查返回的音频元数据,但不打印 base64 载荷:

jq '{
model,
audio: (.choices[0].message.audio | {
id,
transcript,
expires_at,
encoded_characters: (.data | length)
})
}' chat-audio-response.json

响应中的 model 会保持为 AISIX 别名。如果上游返回相应字段,audio 对象会包含服务提供方的音频标识、base64 数据、转录文本和过期时间戳。

使用 Python 标准库解码生成的 WAV 文件:

python3 - <<'PY'
import base64
import json

with open("chat-audio-response.json", encoding="utf-8") as response_file:
response = json.load(response_file)

audio = response["choices"][0]["message"]["audio"]
with open("aisix-chat-audio.wav", "wb") as audio_file:
audio_file.write(base64.b64decode(audio["data"]))

print(audio.get("transcript", ""))
PY

file aisix-chat-audio.wav

最后一条命令应将其识别为 WAV 文件。如果请求了其他格式,请使用匹配的文件名和媒体播放器。

在消息中发送音频

编码本地录音,并将其放入 input_audio 内容块。此示例要求模型以音频回答,以便使用与上一个请求相同的响应处理方式:

base64 < question.wav | tr -d '\n' | \
jq -Rs \
--arg model "$AISIX_MODEL" \
'{
model: $model,
modalities: ["text", "audio"],
audio: {
voice: "alloy",
format: "wav"
},
messages: [
{
role: "user",
content: [
{
type: "text",
text: "Answer the question in this recording."
},
{
type: "input_audio",
input_audio: {
data: .,
format: "wav"
}
}
]
}
]
}' > chat-audio-input.json

curl -sS -X POST "${AISIX_PROXY}/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
--data @chat-audio-input.json \
> chat-audio-response.json

AISIX 会通过兼容 OpenAI 的适配器原样转发带类型的内容块。它不会解码录音,也不会将其转换为其他服务提供方的音频输入形态。

了解当前行为

聊天音频使用普通 Chat Completions 的身份认证、模型访问、路由、重试和请求遥测路径。音频专属行为存在以下边界:

  • 使用非流式请求。 省略 stream 或将其设为 false。AISIX 会在完整响应中保留 message.audio,但目前不会返回流式 delta.audio 分片。
  • 保持服务提供方协议兼容。 openaiazure-openai 适配器会保留音频请求字段及非流式 message.audio 对象。其他适配器可能会将带类型的消息内容缩减为文本,且不会把音频字段转换为服务提供方原生语音 API。
  • 区分文本与音频的安全护栏行为。 输入安全护栏可以检查文本内容块,输出安全护栏可以检查普通的返回消息文本。它们不会检查 input_audio 中的字节、生成的音频数据,或嵌套在 message.audio 中的转录文本。
  • 将 Cloud 音频成本视为上游细节。 AISIX 会记录上游报告的标准化提示词和补全总量,但不会保留单独的音频 Token 数。因此,AISIX Cloud 定价无法对同一个 Chat Completions 请求分别应用文本 Token 和音频 Token 费率。

音频以 base64 编码在 JSON 中,因此请求体和响应体会大于底层二进制文件。设置客户端、代理或负载均衡器的请求体和响应体大小限制时,请计入这部分膨胀。

排查聊天音频问题

如果响应成功但没有 message.audio,请检查请求是否包含音频模态和 audio 对象,并确认上游模型支持通过 Chat Completions 输出音频。仅支持文本的模型可能接受 HTTP 请求,但会在上游拒绝或忽略不受支持的音频字段。

如果 AISIX 返回上游解码错误或服务提供方错误,请按照服务提供方文档中说明的请求格式直接调用同一个上游模型。更改网关策略前,请先确认模型 ID、声音、格式和音频输入编码。

如果请求在非流式模式下正常工作,但启用 stream 后不产生音频,请保持非流式请求。当应用需要增量双向音频时,请使用 Realtime API

下一步

你现在已经在兼容 OpenAI 的聊天请求中发送和接收音频。如需独立转录或语音合成,请继续阅读语音与音频;如需交互式语音会话,请阅读 Realtime API