モデル

qwen-audio-3.0-realtime-plus

Markdown · JSON

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トークンの上限があります。

ストリーミング音声には、16ビットのモノラルPCMを使用し、入力は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

Alibaba /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のメソッド料金

Ailoot リアルタイム音声GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
入力
$0.0008 / 1K
出力
$0.0064 / 1K
入力
$0.0048 音声1分あたり
出力
$0.018 出力音声1分あたり

Ailootはリクエスト前に見積額を確保します。結果の取得後、実測使用量に基づいて最終料金を精算します。ストリーミング時の精算には最終の使用量記録を使用します。金額の確保と精算の仕組み →

リクエスト例

Ailoot · リアルタイム音声

Python WebSocket · テキストPython WebSocket · 音声
# 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へのアップグレードなし次の手順Upgrade: websocketを指定するWebSocketクライアントを使用してください。

エイリアス

モデルのエイリアス

Ailoot qwen-audio-3.0-realtime-plus

メソッドパスのエイリアス

上記に表示されたメソッドパスを使用してください。

関連する呼び出し用ID

qwen-audio-3.0-realtime-plus

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

詳細を見る

AilootをClaude Code、OpenCode、Hermes、自分のアプリに接続しましょう。

企業とそのプロジェクト群

企業とそのプロジェクト群:数百万の顧客、毎月数十億規模の売上。

トークンを割引価格で購入。

継続利用にサブスクリプション割引。プロモコードでトークン購入が最大50%割引。

サブスクリプション
定期的なリクエストに合う割引プランを選びましょう。
最大50%のプロモコード
購入時にコードを入力すると、実施中のキャンペーンに沿って価格を再計算します。
支出を履歴で確認
各リクエストのモデル、トークン、金額が保存されます。

サブスクリプションを選ぶ · モデルの価格を見る

販売する製品に、 APIを組み込みましょう。

SaaS、アプリ、ボットをAilootの公式サービス提供条件とライセンス契約に基づいて接続できます。再販にはリセラーライセンスを申請できます。

商用アプリ
サービスの有料機能に、文章、画像、動画、音声の生成を組み込めます。
リセラーライセンス
プロジェクトの説明とアクセスの仕組みをお送りください。利用・再販条件の書面を申請できます。
サイトで契約文書を確認
接続前にサービス提供条件、ライセンス契約、データ処理ポリシーを読めます。

リセラーライセンスを申請 · サービス提供条件とライセンス契約