پردازش صوت در Chat Completions
این مثال نشان میدهد چگونه از endpoint سازگار با OpenAI یعنی /v1/chat/completions در AvalAI همراه با مدلهای صوتی استفاده کنید. وقتی مدل باید input_audio بپذیرد یا message.audio را مستقیم برگرداند، Chat Completions را نگه دارید. وقتی به reasoning روی transcript، ابزارها، خروجی ساختاریافته یا state قبل از تولید گفتار نیاز دارید، از مسیر مهاجرت Responses استفاده کنید.
مستندات مرتبط: API صوتی، راهنمای پردازش صوت، Responses در برابر Chat Completions
مدلهای صوتی Chat
| مدل | مناسب برای |
|---|---|
gpt-audio-1.5 | گفتوگوهای صوتی با کیفیت بالاتر و زمینه طولانیتر. |
gpt-audio | گردشکارهای متعادل با ورودی/خروجی صوتی. |
gpt-audio-mini | توسعه کمهزینه، رباتهای پشتیبانی و قابلیتهای صوتی پرترافیک. |
قبل از استقرار، جزئیات مدلها را بررسی کنید؛ چون دسترسی endpoint میتواند به tier حساب و route ارائهدهنده وابسته باشد.
الگوی ۱: تولید پاسخ گفتاری از متن
وقتی کاربر متن میفرستد و میخواهید مدل هم متن و هم صدا برگرداند، از این الگو استفاده کنید.
curl https://api.avalai.ir/v1/chat/completions \
-H "Authorization: Bearer $AVALAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-audio-mini",
"modalities": ["text", "audio"],
"audio": { "voice": "alloy", "format": "wav" },
"messages": [
{
"role": "system",
"content": "تو یک دستیار صوتی دوستانه هستی. پاسخها را کوتاه نگه دار."
},
{
"role": "user",
"content": "در یک پاراگراف توضیح بده صورتحساب AvalAI چگونه کار میکند."
}
]
}'import base64
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
completion = client.chat.completions.create(
model="gpt-audio-mini",
modalities=["text", "audio"],
audio={"voice": "alloy", "format": "wav"},
messages=[
{
"role": "system",
"content": "تو یک دستیار صوتی دوستانه هستی. پاسخها را کوتاه نگه دار.",
},
{
"role": "user",
"content": "در یک پاراگراف توضیح بده صورتحساب AvalAI چگونه کار میکند.",
},
],
)
message = completion.choices[0].message
print(message.content)
if message.audio:
with open("answer.wav", "wb") as output:
output.write(base64.b64decode(message.audio.data))import fs from "node:fs/promises";
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AVALAI_API_KEY,
baseURL: "https://api.avalai.ir/v1",
});
const completion = await client.chat.completions.create({
model: "gpt-audio-mini",
modalities: ["text", "audio"],
audio: { voice: "alloy", format: "wav" },
messages: [
{
role: "system",
content: "تو یک دستیار صوتی دوستانه هستی. پاسخها را کوتاه نگه دار.",
},
{
role: "user",
content: "در یک پاراگراف توضیح بده صورتحساب AvalAI چگونه کار میکند.",
},
],
});
const message = completion.choices[0].message;
console.log(message.content);
if (message.audio?.data) {
await fs.writeFile("answer.wav", Buffer.from(message.audio.data, "base64"));
}الگوی ۲: ارسال ورودی صوتی به مدل
وقتی مدل باید مستقیم روی صوت reasoning انجام دهد، از input_audio استفاده کنید. فایل صوتی را متناسب با محدودیت مدل و request کوتاه نگه دارید.
import base64
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
with open("customer_question.wav", "rb") as audio_file:
audio_b64 = base64.b64encode(audio_file.read()).decode("utf-8")
completion = client.chat.completions.create(
model="gpt-audio-mini",
modalities=["text", "audio"],
audio={"voice": "coral", "format": "wav"},
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "مشتری چه سوالی میپرسد؟ کوتاه پاسخ بده."},
{
"type": "input_audio",
"input_audio": {"data": audio_b64, "format": "wav"},
},
],
}
],
)
print(completion.choices[0].message.content)import fs from "node:fs/promises";
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AVALAI_API_KEY,
baseURL: "https://api.avalai.ir/v1",
});
const audioB64 = (await fs.readFile("customer_question.wav")).toString("base64");
const completion = await client.chat.completions.create({
model: "gpt-audio-mini",
modalities: ["text", "audio"],
audio: { voice: "coral", format: "wav" },
messages: [
{
role: "user",
content: [
{ type: "text", text: "مشتری چه سوالی میپرسد؟ کوتاه پاسخ بده." },
{
type: "input_audio",
input_audio: { data: audioB64, format: "wav" },
},
],
},
],
});
console.log(completion.choices[0].message.content);الگوی ۳: ادامه گفتوگوی صوتی
برای گفتوگوهای کوتاه، transcript متنی را در برنامه خود نگه دارید و turnهای قبلی کاربر/دستیار را در messages بفرستید. بایتهای صوتی را جداگانه ذخیره کنید؛ فقط وقتی مدل باید دوباره خود صوت را بررسی کند، صوت را دوباره ارسال کنید.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
messages = [
{"role": "system", "content": "تو یک دستیار پشتیبانی صوتی و مختصر هستی."},
{"role": "user", "content": "آیا میتوانم SDKهای OpenAI را با AvalAI استفاده کنم؟"},
]
first = client.chat.completions.create(
model="gpt-audio-mini",
modalities=["text", "audio"],
audio={"voice": "alloy", "format": "mp3"},
messages=messages,
)
messages.append({"role": "assistant", "content": first.choices[0].message.content})
messages.append({"role": "user", "content": "base URL را هم نشان بده."})
second = client.chat.completions.create(
model="gpt-audio-mini",
modalities=["text", "audio"],
audio={"voice": "alloy", "format": "mp3"},
messages=messages,
)
print(second.choices[0].message.content)مسیر مهاجرت به Responses API
برای صوت مستقیم، input_audio و message.audio فعلا به Chat Completions تعلق دارند. وقتی workflow از Responses سود میبرد، آن را به چند مرحله request-based تقسیم کنید:
- صوت کاربر را با
/v1/audio/transcriptionsبه متن تبدیل کنید. - transcript را به
/v1/responsesبفرستید. - متن نهایی را از
response.output_textبخوانید. - صدا را با
/v1/audio/speechبسازید.
import os
from pathlib import Path
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
with open("customer_question.wav", "rb") as audio_file:
transcript = client.audio.transcriptions.create(
model="gpt-4o-transcribe",
file=audio_file,
response_format="text",
)
response = client.responses.create(
model="gpt-5.5",
instructions="تو یک دستیار پشتیبانی مختصر هستی. برای پخش صوتی پاسخ بده.",
input=transcript,
)
with client.audio.speech.with_streaming_response.create(
model="gpt-4o-mini-tts",
voice="coral",
input=response.output_text,
) as speech:
speech.stream_to_file(Path("response.mp3"))import fs from "node:fs";
import fsp from "node:fs/promises";
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AVALAI_API_KEY,
baseURL: "https://api.avalai.ir/v1",
});
const transcript = await client.audio.transcriptions.create({
model: "gpt-4o-transcribe",
file: fs.createReadStream("customer_question.wav"),
response_format: "text",
});
const response = await client.responses.create({
model: "gpt-5.5",
instructions: "تو یک دستیار پشتیبانی مختصر هستی. برای پخش صوتی پاسخ بده.",
input: transcript,
});
const speech = await client.audio.speech.create({
model: "gpt-4o-mini-tts",
voice: "coral",
input: response.output_text,
});
await fsp.writeFile("response.mp3", Buffer.from(await speech.arrayBuffer()));وقتی به قابلیتهایی مثل tool call، structured outputs، previous_response_id یا manual Item replay نیاز دارید، از این مسیر مهاجرت استفاده کنید. وقتی خروجی صوتی مستقیم مدل قابلیت اصلی است، Chat Completions را نگه دارید.
نکتههای فرمت و تأخیر
- وقتی تأخیر پخش مهم است از
wavیاpcmاستفاده کنید. - برای فایلهای کمحجم و سازگاری گسترده،
mp3مناسب است. - هنگام توسعه
gpt-audio-miniرا ترجیح دهید؛ وقتی کیفیت یا context مهمتر است بهgpt-audioیاgpt-audio-1.5بروید. - در گفتوگوهای چندمرحلهای، همان audio bytes را مدام نفرستید؛ transcript را نگه دارید و فقط وقتی مدل باید دوباره صوت را بررسی کند، صوت را ارسال کنید.
- برای ضبطهای طولانی، به جای base64 کردن صوت داخل Chat Completions از
/v1/audio/transcriptionsو chunking استفاده کنید.
عیبیابی
| نشانه | راهحل |
|---|---|
| پاسخ صوتی برنگشت | "audio" را در modalities بگذارید و object audio را با voice و format تنظیم کنید. |
input_audio رد شد | مطمئن شوید مدل انتخابی ورودی صوتی را پشتیبانی میکند و format با بایتهای encode شده سازگار است. |
| payload خیلی بزرگ است | برای فایلها از /v1/audio/transcriptions استفاده کنید، صوت را فشرده کنید یا ضبطهای طولانی را تقسیم کنید. |
| مدل صوت قبلی را به یاد نمیآورد | transcript متنی را ذخیره و ارسال کنید؛ فرض نکنید صوت خام بین requestها باقی میماند. |
| ابزارها یا خروجی ساختاریافته نیاز دارید | از مسیر مهاجرت Responses استفاده کنید و متن نهایی را با /v1/audio/speech به صدا تبدیل کنید. |