使用 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_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分片。 - 保持服务提供方协议兼容。
openai和azure-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。