qwen-audio-3.0-realtime-plus
מודל לשיחה קולית בזמן אמת שמקבל דיבור וטקסט ומשיב בקול או בטקסט. מיועד לקצב שיחה טבעי ולעבודה עם כלים.
על המודל
התיאור הזה מציג את יכולות המודל. הקלט, הפלט והאפשרויות הזמינים ב-Ailoot מפורטים בהמשך לפי השיטה שנבחרה.
Qwen-Audio-3.0-Realtime-Plus הוא מודל של Alibaba לשיחה קולית בזמן אמת. הוא מקבל דיבור וטקסט, משיב באודיו ובטקסט ותומך בשיחה דו־כיוונית עם חילופי דברים טבעיים. אפשר לשלוח ולקבל צליל בחלקים, כך שהאינטראקציה מתפתחת תוך כדי השיחה.
כשהדובר סיים את דבריו
זמינות כמה דרכים לקבוע את גבולות התור בשיחה: לפי פעילות קולית, לפי השלמת המשמעות ובאמצעות שליטה מפורשת. אצל היצרן בוחרים את המצב לפני שליחת האודיו הראשון; כדי לשנותו לאחר תחילת השיחה נדרש חיבור חדש. התמיכה בשליטה זו נקבעת לפי השיטה שנבחרה. המצב הסמנטי מביא בחשבון הפסקות ומילות מילוי: היסוס קצר אינו בהכרח אומר שהמשתמש סיים את דבריו. דיבור חדש של המשתמש יכול לקטוע את התשובה שמתגבשת, כדי שהשיחה תמשיך תוך התחשבות בדברים החדשים. במצב הסמנטי אפשר לכוון את הזיהוי לדוגמת דיבור של הדובר שנבחר, כדי לצמצם הפרעות מקולות אחרים ומרעש רקע.
ההוראות קובעות את תפקיד העוזר ואת סגנון השיחה. ההגשה הקולית יכולה להביא בחשבון טון, קצב ורגש; לגרסה 3.0 זמינים חמישה קולות מערכת וקולות המבוססים על דוגמת דיבור. המודל תומך ב־11 שפות, כולל רוסית, וכן בגרסאות הניבים הסיניים שהיצרן ציין. אצל היצרן הקול נקבע בעדכון הראשון של הגדרות ההפעלה; שליחת קול חדש בהמשך אותה שיחה אינה נלקחת בחשבון. הגדרות אלה דורשות תמיכה מצד דרך הפנייה שנבחרה.
כלים והיסטוריית השיחה
נתמכת קריאה לפונקציות. המודל מנסח את הפעולה הנדרשת, היישום המחובר מבצע אותה ומחזיר את התוצאה לשיחה. כך אפשר לבסס את השיחה על נתונים בפועל ולהמשיך אותה לאחר הפעולה שבוצעה. העוזר הקולי יכול להסתמך על תוצאות הכלים תוך שמירה על הקשר השיחה. יכולות היצרן כוללות גם חיפוש מובנה ברשת, אם השיטה שנבחרה מספקת אותו. אי אפשר להפעיל חיפוש ברשת וקריאות לפונקציות במקביל באותה הפעלה.
כברירת מחדל ההיסטוריה כוללת 20 תורים בשיחה, והטווח המותר הוא מתור אחד עד 50. לאודיו המצטבר נקבעה מגבלה של 300 שניות; חלקים ישנים מההיסטוריה נמחקים כאשר עוברים את המגבלות. זה שונה מהמשך של אמירה בודדת: ההיסטוריה קובעת אילו חומרים קודמים נשארים זמינים להמשך השיחה.
הקשר טקסטואלי וצליל
ההקשר הפורמלי הוא 40 960 טוקנים. אורך הקלט המרבי הוא 16 384 טוקנים, והפלט 8192; אותן מגבלות קלט ופלט מצוינות גם למצב ההסקה, עם מגבלה נפרדת של 1024 טוקנים לשרשרת ההסקה.
לאודיו זורם זמין PCM חד־ערוצי בייצוג של 16 סיביות: בקלט 16 קילו־הרץ, ובפלט 24 קילו־הרץ. הטקסט ונתוני האודיו שייכים לאותה שיחה. לא הוצהרו קלט חזותי או פלט תמונות למודל מסוים זה; ההתמחות שלו היא דיבור, טקסט ואינטראקציה קולית.
Ailoot · קול בזמן אמת GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusהתחלה
מודל לשיחה קולית בזמן אמת שמקבל דיבור וטקסט ומשיב בקול או בטקסט. מיועד לקצב שיחה טבעי ולעבודה עם כלים.
- סוגי קלט נתמכים
- טקסט · שמע
- תוצאות
- טקסט · שמע
זמין ב-Ailoot · קלט ושיטות
Ailoot · קול בזמן אמת GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- סוגי קלט
text,audio- סוגי פלט
text,audio- פורמט פלט
- אירועי סשן
| שדה | סוג | דרישה | ערכים ומגבלות | ברירת מחדל |
|---|---|---|---|---|
שדהquery.model | סוגstring | דרישהחובה | ערכים ומגבלות qwen-audio-3.0-realtime-plus | ברירת מחדל— |
שדהsession.input_audio_format | סוגstring | דרישהרשות | ערכים ומגבלות pcm16, pcm | ברירת מחדל— |
שדהsession.output_audio_format | סוגstring | דרישהרשות | ערכים ומגבלות pcm16, pcm | ברירת מחדל— |
שדהsession.instructions | סוגstring | דרישהרשות | ערכים ומגבלות המגבלה חלה על: מדיניות הסשן שנבחרה | ברירת מחדל— |
שדהsession.max_history_turns | סוגinteger | דרישהרשות | ערכים ומגבלות מינימום: 1 המגבלה חלה על: מדיניות הסשן שנבחרה | ברירת מחדל— |
שדהinput_audio_buffer.append.audio | סוגbase64_string | דרישהחובה | ערכים ומגבלות תוכן הקלט: PCM16 בערוץ יחיד; קלט 16 kHz, פלט 24 kHz; אורך לא ריק וזוגי בבתים | ברירת מחדל— |
שילובים של חומרי קלט
realtime_text_audio
פרמטרים ומחזור חיים של השיטה
| פרמטר | מפרט |
|---|---|
פרמטרmaterial_types | מפרטtext, audio |
פרמטרrequired | מפרטnull |
פרמטרoptional_controls | מפרטnull |
פרמטרcontent_type | מפרטWebSocket |
מחזור חיים: exact retained published method
מבני המתודות והמזהים מדויקים; יכולת הספק נפרדת מקבלת הבקשה לביצוע.
תעריפים
תעריפי שיטות Ailoot
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- קלט
- 0.0008 $ / 1K
- פלט
- 0.0064 $ / 1K
- קלט
- 0.0048 $ לכל דקת שמע
- פלט
- 0.018 $ לכל דקת שמע בפלט
לפני הבקשה Ailoot משריינת סכום משוער. לאחר קבלת התוצאה היא מסדירה את החיוב הסופי לפי השימוש המדוד. הסדרת חיוב בהזרמה משתמשת ברשומת השימוש הסופית. איך פועלים שריון הסכום והסדרת החיוב →
דוגמאות לבקשות
Ailoot · קול בזמן אמת
# Install the documented client once: python3 -m pip install websockets
import base64, json, os, time, wave
from pathlib import Path
from websockets.sync.client import connect
key = os.environ.get("AILOOT_API_KEY", "")
if not key.strip():
raise SystemExit("Set your AILOOT_API_KEY before connecting")
file = Path(os.environ.get("AILOOT_TEXT_FILE", ""))
if not file.is_file(): raise SystemExit("Set AILOOT_TEXT_FILE to your actual UTF-8 material")
material = file.read_text(encoding="utf-8")
if not material.strip(): raise SystemExit("Text material must not be empty")
out = Path("realtime-results")
out.mkdir(exist_ok=True)
audio, texts, complete = {}, {}, []
current_response = None
pending = False
deadline = time.monotonic() + 570 # Local client bound; lower server/session limits still apply.
def receive(ws, log):
global current_response, pending
left = deadline - time.monotonic()
if left <= 0:
raise TimeoutError("Client session limit; preserve IDs and partial results, do not replay")
event = json.loads(ws.recv(timeout=min(60, left)))
log.write(json.dumps(event, ensure_ascii=False) + "\n")
log.flush()
kind = event.get("type")
if kind == "error":
raise RuntimeError(json.dumps(event, ensure_ascii=False))
if kind == "response.created":
current_response = event["response"]["id"]
if kind in {"response.audio.delta", "response.output_audio.delta", "response.text.delta", "response.output_text.delta", "response.audio_transcript.delta", "response.output_audio_transcript.delta", "response.text.done", "response.audio_transcript.done"}:
identity = (event["response_id"], event["item_id"], event["output_index"], event["content_index"])
if kind in {"response.audio.delta", "response.output_audio.delta"}:
raw = base64.b64decode(event["delta"], validate=True)
if len(raw) % 2: raise ValueError("Output PCM16 chunk must have an even byte length")
audio.setdefault(identity, bytearray()).extend(raw)
elif kind.endswith(".done"):
texts[identity] = event.get("text", event.get("transcript", ""))
else:
texts[identity] = texts.get(identity, "") + event["delta"]
print(event["delta"], end="", flush=True)
if kind == "response.done":
response = event["response"]
complete.append(response)
if current_response is None: current_response = response["id"]
if response["id"] == current_response: pending = False
return event
def wait_for(ws, log, kind):
while True:
event = receive(ws, log)
if event.get("type") == kind: return event
def send(ws, event):
ws.send(json.dumps(event, ensure_ascii=False))
try:
# One exact model query; no reconnect/retry loop and no provider credentials.
with connect("wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus", additional_headers={"Authorization": "Bearer " + key}) as ws:
with (out / "events.jsonl").open("w", encoding="utf-8") as log:
wait_for(ws, log, "session.created")
send(ws, {"type":"session.update", "session":{"modalities":["audio","text"], "input_audio_format":"pcm", "output_audio_format":"pcm", "turn_detection":None}})
wait_for(ws, log, "session.updated")
send(ws, {"type":"conversation.item.create", "item":{"type":"message", "role":"user", "content":[{"type":"input_text", "text":material}]}})
send(ws, {"type":"response.create"})
pending = True
try:
while pending: receive(ws, log)
except KeyboardInterrupt:
# Cancel the actual current inference, then preserve its returned status.
send(ws, {"type":"response.cancel"})
while pending: receive(ws, log)
if not complete or complete[-1].get("status") != "completed":
raise RuntimeError("Response did not complete normally; inspect saved events and status")
finally:
manifest = {"responses":complete, "parts":[]}
for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):
record = {"response_id":identity[0], "item_id":identity[1], "output_index":identity[2], "content_index":identity[3]}
if identity in audio:
raw = bytes(audio[identity])
pcm_file = out / ("audio-" + str(number) + ".pcm")
wav_file = out / ("audio-" + str(number) + ".wav")
pcm_file.write_bytes(raw)
with wave.open(str(wav_file), "wb") as wav:
wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)
record.update({"pcm":str(pcm_file), "wav":str(wav_file), "sample_rate_hz":24000})
if identity in texts:
text_file = out / ("text-" + str(number) + ".txt")
text_file.write_text(texts[identity], encoding="utf-8")
record["text"] = str(text_file)
manifest["parts"].append(record)
(out / "results.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8")
print("\nSaved every received event and result in", out)
# Install the documented client once: python3 -m pip install websockets
import base64, json, os, time, wave
from pathlib import Path
from websockets.sync.client import connect
key = os.environ.get("AILOOT_API_KEY", "")
if not key.strip():
raise SystemExit("Set your AILOOT_API_KEY before connecting")
file = Path(os.environ.get("AILOOT_AUDIO_FILE", ""))
if not file.is_file(): raise SystemExit("Set AILOOT_AUDIO_FILE to your raw PCM16 mono 16-kHz recording")
material = file.read_bytes()
if not material or len(material) % 2 or material.startswith(b"RIFF"):
raise SystemExit("Use nonempty signed little-endian PCM16 mono 16-kHz bytes, not a WAV header")
out = Path("realtime-results")
out.mkdir(exist_ok=True)
audio, texts, complete = {}, {}, []
current_response = None
pending = False
deadline = time.monotonic() + 570 # Local client bound; lower server/session limits still apply.
def receive(ws, log):
global current_response, pending
left = deadline - time.monotonic()
if left <= 0:
raise TimeoutError("Client session limit; preserve IDs and partial results, do not replay")
event = json.loads(ws.recv(timeout=min(60, left)))
log.write(json.dumps(event, ensure_ascii=False) + "\n")
log.flush()
kind = event.get("type")
if kind == "error":
raise RuntimeError(json.dumps(event, ensure_ascii=False))
if kind == "response.created":
current_response = event["response"]["id"]
if kind in {"response.audio.delta", "response.output_audio.delta", "response.text.delta", "response.output_text.delta", "response.audio_transcript.delta", "response.output_audio_transcript.delta", "response.text.done", "response.audio_transcript.done"}:
identity = (event["response_id"], event["item_id"], event["output_index"], event["content_index"])
if kind in {"response.audio.delta", "response.output_audio.delta"}:
raw = base64.b64decode(event["delta"], validate=True)
if len(raw) % 2: raise ValueError("Output PCM16 chunk must have an even byte length")
audio.setdefault(identity, bytearray()).extend(raw)
elif kind.endswith(".done"):
texts[identity] = event.get("text", event.get("transcript", ""))
else:
texts[identity] = texts.get(identity, "") + event["delta"]
print(event["delta"], end="", flush=True)
if kind == "response.done":
response = event["response"]
complete.append(response)
if current_response is None: current_response = response["id"]
if response["id"] == current_response: pending = False
return event
def wait_for(ws, log, kind):
while True:
event = receive(ws, log)
if event.get("type") == kind: return event
def send(ws, event):
ws.send(json.dumps(event, ensure_ascii=False))
try:
# One exact model query; no reconnect/retry loop and no provider credentials.
with connect("wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus", additional_headers={"Authorization": "Bearer " + key}) as ws:
with (out / "events.jsonl").open("w", encoding="utf-8") as log:
wait_for(ws, log, "session.created")
send(ws, {"type":"session.update", "session":{"modalities":["audio","text"], "input_audio_format":"pcm", "output_audio_format":"pcm", "turn_detection":None}})
wait_for(ws, log, "session.updated")
for offset in range(0, len(material), 640):
send(ws, {"type":"input_audio_buffer.append", "audio":base64.b64encode(material[offset:offset+640]).decode("ascii")})
time.sleep(0.02)
send(ws, {"type":"input_audio_buffer.commit"})
wait_for(ws, log, "input_audio_buffer.committed")
send(ws, {"type":"response.create"})
pending = True
try:
while pending: receive(ws, log)
except KeyboardInterrupt:
# Cancel the actual current inference, then preserve its returned status.
send(ws, {"type":"response.cancel"})
while pending: receive(ws, log)
if not complete or complete[-1].get("status") != "completed":
raise RuntimeError("Response did not complete normally; inspect saved events and status")
finally:
manifest = {"responses":complete, "parts":[]}
for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):
record = {"response_id":identity[0], "item_id":identity[1], "output_index":identity[2], "content_index":identity[3]}
if identity in audio:
raw = bytes(audio[identity])
pcm_file = out / ("audio-" + str(number) + ".pcm")
wav_file = out / ("audio-" + str(number) + ".wav")
pcm_file.write_bytes(raw)
with wave.open(str(wav_file), "wb") as wav:
wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)
record.update({"pcm":str(pcm_file), "wav":str(wav_file), "sample_rate_hz":24000})
if identity in texts:
text_file = out / ("text-" + str(number) + ".txt")
text_file.write_text(texts[identity], encoding="utf-8")
record["text"] = str(text_file)
manifest["parts"].append(record)
(out / "results.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8")
print("\nSaved every received event and result in", out)
קבלה ושמירה של תוצאות
Ailoot · קול בזמן אמת
אירועי סשן
שמירת כל התוצאות שהושלמו
שמרו כל תגובה מלאה, קובץ ומקטע תוכן שהוחזרו.
יש להרכיב כל מקטע אודיו וכל תוצאת טקסט או אירוע שהוחזרו עבור כל מזהה תגובה ממשי.
כשצריך לבדוק את התגובה המקורית
יש לשמור את מזהי הסשן, התגובה והאירועים הממשיים ואת האסמכתאות.
שגיאות והשלבים הבאים
| תגובה | תנאי | השלב הבא |
|---|---|---|
תגובה426 · invalid_request_error | תנאיאין שדרוג חיבור ל־WebSocket | השלב הבאיש להשתמש בלקוח WebSocket עם Upgrade: websocket. |
כינויים
כינויים למודל
Ailoot qwen-audio-3.0-realtime-plus
כינויים לנתיבי שיטות
השתמשו בנתיבי השיטות המוצגים למעלה.
מזהי מודלים קשורים IDs
FAQ · qwen-audio-3.0-realtime-plus
- אילו קלטים ותוצאות זמינים?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- אילו מגבלות חלות?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1