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 kHz และเอาต์พุต 24 kHz ข้อความและข้อมูลเสียงอยู่ในบทสนทนาเดียวกัน สำหรับโมเดลนี้โดยเฉพาะ ยังไม่มีการระบุอินพุตภาพหรือเอาต์พุตภาพ ความเชี่ยวชาญของโมเดลคือเสียงพูด ข้อความ และการโต้ตอบด้วยเสียง
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
รูปแบบเมธอดและ ID ระบุอย่างแม่นยำ ความสามารถของผู้ให้บริการแยกจากการอนุญาตให้รับคำขอ
ราคา
อัตราค่าบริการเมธอด Ailoot
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- ขาเข้า
- US$0.0008 / 1K
- ขาออก
- US$0.0064 / 1K
- ขาเข้า
- US$0.0048 ต่อนาทีของเสียง
- ขาออก
- US$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 · เสียงแบบเรียลไทม์
เหตุการณ์ของเซสชัน
เก็บผลลัพธ์ที่เสร็จสมบูรณ์ทั้งหมด
เก็บทุกการตอบกลับ ไฟล์ และส่วนเนื้อหาที่ส่งกลับมาอย่างครบถ้วน
ประกอบข้อมูลเสียงส่วนเพิ่มและผลลัพธ์ข้อความ/เหตุการณ์ทั้งหมดที่ส่งกลับสำหรับ ID การตอบกลับจริงแต่ละรายการ
เมื่อต้องตรวจสอบการตอบกลับต้นฉบับ
เก็บ ID เซสชัน/การตอบกลับ/เหตุการณ์จริงและหลักฐานบันทึก
ข้อผิดพลาดและขั้นตอนถัดไป
| การตอบกลับ | เงื่อนไข | ขั้นตอนถัดไป |
|---|---|---|
การตอบกลับ426 · invalid_request_error | เงื่อนไขไม่มีการอัปเกรด WebSocket | ขั้นตอนถัดไปใช้ไคลเอนต์ WebSocket พร้อม Upgrade: websocket |
ชื่ออื่น
ชื่ออื่นของโมเดล
Ailoot qwen-audio-3.0-realtime-plus
ชื่อพาธเมธอดอื่น
ใช้พาธเมธอดที่แสดงด้านบน
ID ที่เกี่ยวข้องสำหรับเรียกใช้โมเดล
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