使用 Chat Completions 输入和输出音频
支持音频的聊天模型可以接收消息中的录制音频,并在同一个 Chat Completions 响应中返回生成的音频。这适合需要模型理解音频或以音频回 答,同时保持兼容 OpenAI 的 POST /v1/chat/completions 请求形态的轮次式应用。
如需独立转录、翻译或语音生成,请使用语音与音频。如需交互式双向会话,请使用 Realtime API。
当所选上游使用兼容的 OpenAI 形态 API 时,AISIX 会保留 OpenAI 聊天音频请求和响应字段。它不会将这些字段转换为其他服务提供方的原生音频协议。
准备工作
请先准备以下内容:
- 一个可以处理代理请求的 AISIX 网关。
- 一个可以访问该模型别名的调用方 API Key。
- 一个由支持音频的 Chat Completions 模型支撑的模型别名。其服务提供方密钥必须使用
openai或azure-openai适配器,且上游必须实现 OpenAI 聊天音频请求和响应形态。 - 一个名为
question.wav的本地 WAV 录音,用于音频输入示例。 - 示例所需的
curl、jq、Python 3,以及base64、file和tr命令行工具。
如果尚未配置上游,请参阅 OpenAI、Azure OpenAI或自带端点。选择上游当前支持的音频模型,并为其创建 AISIX 别名。
对于路由别名,每个符合条件的目标都必须使用上述适配器之一,并支持相同的聊天音频字段。如果故障转移到仅支持文本或形态不同的服务 提供方,音频内容可能丢失,或请求可能在上游失败。
导出网关连接和请求值:
# AISIX_PROXY 不含尾部斜杠或 /v1 等端点路径
# 本地快速入门使用 http://127.0.0.1:3000。
export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
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
兼容 OpenAI 的适配器会原样转发 带类型的内容块,不会解码录音。
了解当前行为
聊天音频使用普通 Chat Completions 的身份认证、模型访问、路由、重试和请求遥测路径。音频专属行为存在以下边界:
- 流式和非流式均可。 完整响应会保留
message.audio。流式响应会按上游自己的形态转发delta.audio,包括其id、transcript、data以及末尾的expires_at分片;设置stream_options.include_usage时,最后的用量分片会带上音频 Token 数。这适用于 OpenAI 及兼容 OpenAI 的上游、Azure OpenAI,以及 Amazon Bedrock 和 Vertex AI 的兼容 OpenAI 路由。 - 保持服务提供方协议兼容。 兼容 OpenAI 的适配器会保留音频请求字段和
message.audio对象。原生协议的上游,例如 Anthropic、Vertex AI 或 Amazon Bedrock 上的 Claude、Vertex AI Gemini 以及 Bedrock Converse,在支持该类媒体时会以自己的媒体块接收input_audio部分;不支持时(例如向 Claude 发送音频),AISIX 返回400并以messages[i].content[j]指出该部分,而不是将其丢弃。AISIX 不会把音频输出字段转换为服务提供方原生语音 API。 - 区分文本与音频的安全护栏行为。 输入安全护栏可以检查文本内容块,输出安全护栏可以检查普通的返回消息文本。它们不会检查
input_audio中的字节、生成的音频数据,或嵌套在message.audio或流式delta.audio中的转录文本。