全部產品
Search
文件中心

Alibaba Cloud Model Studio:流式輸出

更新時間:Feb 01, 2026

在即時聊天或長文本產生應用中,長時間的等待會損害使用者體驗並可能導致觸發服務端逾時,導致任務失敗。流式輸出通過持續返回模型產生的文本片段,解決了這兩個核心問題。

工作原理

流式輸出基於 Server-Sent Events (SSE) 協議。發起流式請求後,服務端與用戶端建立持久化 HTTP 串連。模型每產生一個文字區塊(稱為 chunk),立即通過串連推送。全部內容產生後,服務端發送結束訊號。

用戶端監聽事件流,即時接收並處理文字區塊,例如逐字渲染介面。這與非流式調用(一次性返回所有內容)形成對比。

⏱️ 等待時間:3 秒
已關閉流式輸出
以上組件僅供您參考,並未真實發送請求。

計費說明

流式輸出計費規則與非流式調用完全相同,根據請求的輸入Token數和輸出Token數計費。

請求中斷時,輸出 Token 僅計算服務端收到終止請求前已產生的部分。

如何使用

重要

Qwen3 開源版、QwQ 商業版與開源版、QVQ 、Qwen-Omni等模型僅支援流式輸出方式調用。

步驟一:配置 API Key 並選擇地區

需要已擷取API Key配置API Key到環境變數(準備下線,併入配置 API Key)

將API Key配置為環境變數(DASHSCOPE_API_KEY)比在代碼中寫入程式碼更安全。

步驟二:發起流式請求

OpenAI相容

  • 如何開啟

    設定 streamtrue 即可。

  • 查看 Token 消耗

    OpenAI 協議預設不返回 Token 消耗量,需設定stream_options={"include_usage": true},使最後一個返回的資料區塊包含Token消耗資訊。

Python

import os
from openai import OpenAI

# 1. 準備工作:初始化用戶端
client = OpenAI(
    # 建議通過環境變數配置API Key,避免寫入程式碼。
    api_key=os.environ["DASHSCOPE_API_KEY"],
    # API Key與地區強綁定,請確保base_url與API Key的地區一致。
    # 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

# 2. 發起流式請求
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "請介紹一下自己"}
    ],
    stream=True,
    stream_options={"include_usage": True}
)

# 3. 處理流式響應
# 用列表暫存響應片段,最後 join 比逐次 += 字串更高效
content_parts = []
print("AI: ", end="", flush=True)

for chunk in completion:
    if chunk.choices:
        content = chunk.choices[0].delta.content or ""
        print(content, end="", flush=True)
        content_parts.append(content)
    elif chunk.usage:
        print("\n--- 請求用量 ---")
        print(f"輸入 Tokens: {chunk.usage.prompt_tokens}")
        print(f"輸出 Tokens: {chunk.usage.completion_tokens}")
        print(f"總計 Tokens: {chunk.usage.total_tokens}")

full_response = "".join(content_parts)
# print(f"\n--- 完整回複 ---\n{full_response}")

返回結果

AI: 你好!我是Qwen,是阿里巴巴集團旗下的通義實驗室自主研發的超大規模語言模型。我能夠回答問題、創作文字,比如寫故事、寫公文、寫郵件、寫劇本、邏輯推理、編程等等,還能表達觀點,玩遊戲等。我支援多種語言,包括但不限於中文、英文、德語、法語、西班牙語等。如果你有任何問題或需要協助,歡迎隨時告訴我!
--- 請求用量 ---
輸入 Tokens: 26
輸出 Tokens: 87
總計 Tokens: 113

Node.js

import OpenAI from "openai";

async function main() {
    // 1. 準備工作:初始化用戶端
    // 建議通過環境變數配置API Key,避免寫入程式碼。
    if (!process.env.DASHSCOPE_API_KEY) {
        throw new Error("請設定環境變數 DASHSCOPE_API_KEY");
    }
    // API Key與地區強綁定,請確保baseURL與API Key的地區一致。
    // 若使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    const client = new OpenAI({
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
    });

    try {
        // 2. 發起流式請求
        const stream = await client.chat.completions.create({
            model: "qwen-plus",
            messages: [
                { role: "system", content: "You are a helpful assistant." },
                { role: "user", content: "請介紹一下自己" },
            ],
            stream: true,
            // 目的:在最後一個chunk中擷取本次請求的Token用量。
            stream_options: { include_usage: true },
        });

        // 3. 處理流式響應
        const contentParts = [];
        process.stdout.write("AI: ");
        
        for await (const chunk of stream) {
            // 最後一個chunk不包含choices,但包含usage資訊。
            if (chunk.choices && chunk.choices.length > 0) {
                const content = chunk.choices[0]?.delta?.content || "";
                process.stdout.write(content);
                contentParts.push(content);
            } else if (chunk.usage) {
                // 請求結束,列印Token用量。
                console.log("\n--- 請求用量 ---");
                console.log(`輸入 Tokens: ${chunk.usage.prompt_tokens}`);
                console.log(`輸出 Tokens: ${chunk.usage.completion_tokens}`);
                console.log(`總計 Tokens: ${chunk.usage.total_tokens}`);
            }
        }
        
        const fullResponse = contentParts.join("");
        // console.log(`\n--- 完整回複 ---\n${fullResponse}`);

    } catch (error) {
        console.error("請求失敗:", error);
    }
}

main();

返回結果

AI: 你好!我是Qwen,是阿里巴巴集團旗下的通義實驗室自主研發的超大規模語言模型。我能夠回答問題、創作文字,比如寫故事、寫公文、寫郵件、寫劇本、邏輯推理、編程等等,還能表達觀點,玩遊戲等。我支援多種語言,包括但不限於中文、英文、德語、法語、西班牙語等。如果你有任何問題或需要協助,歡迎隨時向我提問!
--- 請求用量 ---
輸入 Tokens: 26
輸出 Tokens: 89
總計 Tokens: 115

curl

請求

# ======= 重要提示 =======
# 確保已設定環境變數 DASHSCOPE_API_KEY
# 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions
# === 執行時請刪除該注釋 ===

curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
--no-buffer \
-d '{
    "model": "qwen-plus",
    "messages": [
        {"role": "user", "content": "你是誰?"}
    ],
    "stream": true,
    "stream_options": {"include_usage": true}
}'

響應

返回資料為符合 SSE 協議的流式響應。每一行 data: 都代表一個資料區塊。

data: {"choices":[{"delta":{"content":"","role":"assistant"},"index":0,"logprobs":null,"finish_reason":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[{"finish_reason":null,"delta":{"content":"我是"},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[{"delta":{"content":"來自"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[{"delta":{"content":"阿里"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[{"delta":{"content":"雲的超大規模語言"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[{"delta":{"content":"模型,我叫通義千問"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[{"delta":{"content":"。"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[{"finish_reason":"stop","delta":{"content":""},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: {"choices":[],"object":"chat.completion.chunk","usage":{"prompt_tokens":22,"completion_tokens":17,"total_tokens":39},"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: [DONE]
  • data:: 訊息的資料負載,通常是一個JSON字串。

  • [DONE]: 表示整個流式響應已結束。

DashScope

  • 如何開啟

    根據使用方式(Python SDK、Java SDK、cURL)不同,開啟流式輸出的方式不同:

    • Python SDK:設定 stream 參數為 True

    • Java SDK:通過streamCall介面調用;

    • cURL:設定 Header 參數X-DashScope-SSEenable

  • 是否啟動增量輸出

    DashScope 協議支援增量與非增量式流式輸出:

    • 增量(推薦):每個資料區塊僅包含新產生的內容,設定incremental_outputtrue啟動增量式流式輸出。

      樣本:["我愛","吃","蘋果"]
    • 非增量:每個資料區塊都包含之前已產生的內容,造成網路頻寬浪費和用戶端處理壓力。設定incremental_outputfalse啟動非增量式流式輸出。

      樣本:["我愛","我愛吃","我愛吃蘋果"]
  • 查看 Token 消耗

    每個資料區塊都包含即時的 Token 消耗資訊。

Python

import os
from http import HTTPStatus
import dashscope
from dashscope import Generation

# 1. 準備工作:配置API Key和地區
# 建議通過環境變數配置API Key,避免寫入程式碼。
try:
    dashscope.api_key = os.environ["DASHSCOPE_API_KEY"]
except KeyError:
    raise ValueError("請設定環境變數 DASHSCOPE_API_KEY")

# API Key與地區強綁定,請確保base_url與API Key的地區一致。
# 如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/api/v1
dashscope.base_http_api_url = "https://dashscope-intl.aliyuncs.com/api/v1"

# 2. 發起流式請求
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "請介紹一下自己"},
]

try:
    responses = Generation.call(
        model="qwen-plus",
        messages=messages,
        result_format="message",
        stream=True,
        # 關鍵:設定為True以擷取增量輸出,效能更佳。
        incremental_output=True,
    )

    # 3. 處理流式響應
    content_parts = []
    print("AI: ", end="", flush=True)

    for resp in responses:
        if resp.status_code == HTTPStatus.OK:
            content = resp.output.choices[0].message.content
            print(content, end="", flush=True)
            content_parts.append(content)

            # 檢查是否是最後一個包
            if resp.output.choices[0].finish_reason == "stop":
                usage = resp.usage
                print("\n--- 請求用量 ---")
                print(f"輸入 Tokens: {usage.input_tokens}")
                print(f"輸出 Tokens: {usage.output_tokens}")
                print(f"總計 Tokens: {usage.total_tokens}")
        else:
            # 處理錯誤情況
            print(
                f"\n請求失敗: request_id={resp.request_id}, code={resp.code}, message={resp.message}"
            )
            break

    full_response = "".join(content_parts)
    # print(f"\n--- 完整回複 ---\n{full_response}")

except Exception as e:
    print(f"發生未知錯誤: {e}")

返回結果

AI: 你好!我是Qwen,是阿里巴巴集團旗下的通義實驗室自主研發的超大規模語言模型。我能夠協助你回答問題、創作文字,比如寫故事、寫公文、寫郵件、寫劇本、邏輯推理、編程等等,還能表達觀點,玩遊戲等。我支援多種語言,包括但不限於中文、英文、德語、法語、西班牙語等。如果你有任何問題或需要協助,歡迎隨時向我提問!
--- 請求用量 ---
輸入 Tokens: 26
輸出 Tokens: 91
總計 Tokens: 117

Java

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;

import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import com.alibaba.dashscope.protocol.Protocol;

public class Main {
    public static void main(String[] args) {
        // 1. 擷取 API Key
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        if (apiKey == null || apiKey.isEmpty()) {
            System.err.println("請設定環境變數 DASHSCOPE_API_KEY");
            return;
        }

        // 2. 初始化 Generation 執行個體
        // API Key與地區強綁定,請確保baseUrl與API Key的地區一致。
        // 如果使用北京地區的模型,需將baseUrl替換為:https://dashscope.aliyuncs.com/api/v1
        Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
        CountDownLatch latch = new CountDownLatch(1);

        // 3. 構建請求參數
        GenerationParam param = GenerationParam.builder()
                .apiKey(apiKey)
                .model("qwen-plus")
                .messages(Arrays.asList(
                        Message.builder()
                                .role(Role.USER.getValue())
                                .content("介紹一下自己")
                                .build()
                ))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .incrementalOutput(true) // 開啟增量輸出,流式返回
                .build();
        // 4. 發起流式調用並處理響應
        try {
            Flowable<GenerationResult> result = gen.streamCall(param);
            StringBuilder fullContent = new StringBuilder();
            System.out.print("AI: ");
            result
                    .subscribeOn(Schedulers.io()) // IO線程執行請求
                    .observeOn(Schedulers.computation()) // 計算線程處理響應
                    .subscribe(
                            // onNext: 處理每個響應片段
                            message -> {
                                String content = message.getOutput().getChoices().get(0).getMessage().getContent();
                                String finishReason = message.getOutput().getChoices().get(0).getFinishReason();
                                // 輸出內容
                                System.out.print(content);
                                fullContent.append(content);
                                // 當 finishReason 不為 null 時,表示是最後一個 chunk,輸出用量資訊
                                if (finishReason != null && !"null".equals(finishReason)) {
                                    System.out.println("\n--- 請求用量 ---");
                                    System.out.println("輸入 Tokens:" + message.getUsage().getInputTokens());
                                    System.out.println("輸出 Tokens:" + message.getUsage().getOutputTokens());
                                    System.out.println("總 Tokens:" + message.getUsage().getTotalTokens());
                                }
                                System.out.flush(); // 立即重新整理輸出
                            },
                            // onError: 處理錯誤
                            error -> {
                                System.err.println("\n請求失敗: " + error.getMessage());
                                latch.countDown();
                            },
                            // onComplete: 完成回調
                            () -> {
                                System.out.println(); // 換行
                                // System.out.println("完整響應: " + fullContent.toString());
                                latch.countDown();
                            }
                    );
            // 主線程等待非同步任務完成
            latch.await();
            System.out.println("程式執行完成");
        } catch (Exception e) {
            System.err.println("請求異常: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

返回結果

AI: 你好!我是Qwen,是阿里巴巴集團旗下的通義實驗室自主研發的超大規模語言模型。我能夠協助你回答問題、創作文字,比如寫故事、寫公文、寫郵件、寫劇本、邏輯推理、編程等等,還能表達觀點,玩遊戲等。我支援多種語言,包括但不限於中文、英文、德語、法語、西班牙語等。如果你有任何問題或需要協助,歡迎隨時向我提問!
--- 請求用量 ---
輸入 Tokens: 26
輸出 Tokens: 91
總計 Tokens: 117

curl

請求

# ======= 重要提示 =======
# 確保已設定環境變數 DASHSCOPE_API_KEY
# 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若使用北京地區的模型,需將url替換為:https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
# === 執行時請刪除該注釋 ===
curl -X POST https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-SSE: enable" \
-d '{
    "model": "qwen-plus",
    "input":{
        "messages":[      
            {
                "role": "system",
                "content": "You are a helpful assistant."
            },
            {
                "role": "user",
                "content": "你是誰?"
            }
        ]
    },
    "parameters": {
        "result_format": "message",
        "incremental_output":true
    }
}'

響應

響應遵循 Server-Sent Events (SSE) 格式,每條訊息包含:

  • id: 資料區塊編號;

  • event: 事件類型,固定為result;

  • HTTP 狀態代碼資訊;

  • data:JSON 資料部分。

id:1
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"我是","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":27,"output_tokens":1,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}

id:2
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"通義千","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":30,"output_tokens":4,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}

id:3
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"問,阿里巴巴","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":33,"output_tokens":7,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}

...


id:13
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"或需要協助,歡迎隨時","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":90,"output_tokens":64,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}

id:14
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"告訴我!","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":92,"output_tokens":66,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}

id:15
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","role":"assistant"},"finish_reason":"stop"}]},"usage":{"total_tokens":92,"output_tokens":66,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}

多模態模型的流式輸出

說明
  • 本章節適用於Qwen-VL、Qwen-VL-OCR、Kimi-K2.5、Qwen3-Omni-Captioner模型。

  • Qwen-Omni 模型僅支援流式輸出,因其輸出可包含文本音頻等多模態內容,所以結果解析方式與其他模型不同,具體請參見全模態

多模態模型支援在對話中加入圖片、音頻等內容,其流式輸出的實現方式與文本模型主要有以下不同:

  • 使用者訊息(user message)的構造方式:多模態模型的輸入不僅包括文本,還包含圖片、音頻等多模態資訊。

  • DashScope SDK介面:使用 DashScope Python SDK 時,需調用 MultiModalConversation 介面;使用DashScope Java SDK 時,則調用 MultiModalConversation 類。

OpenAI相容

Python

from openai import OpenAI
import os

client = OpenAI(
    # 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3-vl-plus",  # 可按需更換為其它多模態模型,並修改相應的 messages
    messages=[
        {"role": "user",
        "content": [{"type": "image_url",
                    "image_url": {"url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},},
                    {"type": "text", "text": "圖中描繪的是什麼景象?"}]}],
    stream=True,
  # stream_options={"include_usage": True}
)
full_content = ""
print("流式輸出內容為:")
for chunk in completion:
    # 如果stream_options.include_usage為True,則最後一個chunk的choices欄位為空白列表,需要跳過(可以通過chunk.usage擷取 Token 使用量)
    if chunk.choices and chunk.choices[0].delta.content != "":
        full_content += chunk.choices[0].delta.content
        print(chunk.choices[0].delta.content)
print(f"完整內容為:{full_content}")

Node.js

import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
        // 若沒有配置環境變數,請用百鍊API Key將下行替換為:apiKey: "sk-xxx"
        apiKey: process.env.DASHSCOPE_API_KEY,
        // 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);

const completion = await openai.chat.completions.create({
    model: "qwen3-vl-plus",  //  可按需更換為其它多模態模型,並修改相應的 messages
    messages: [
        {role: "user",
        content: [{"type": "image_url",
                    "image_url": {"url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},},
                    {"type": "text", "text": "圖中描繪的是什麼景象?"}]}],
    stream: true,
    // stream_options: { include_usage: true },
});

let fullContent = ""
console.log("流式輸出內容為:")
for await (const chunk of completion) {
    // 如果stream_options.include_usage為true,則最後一個chunk的choices欄位為空白數組,需要跳過(可以通過chunk.usage擷取 Token 使用量)
    if (chunk.choices[0] && chunk.choices[0].delta.content != null) {
      fullContent += chunk.choices[0].delta.content;
      console.log(chunk.choices[0].delta.content);
    }
}
console.log(`完整輸出內容為:${fullContent}`)

curl

# ======= 重要提示 =======
# 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions
# 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# === 執行時請刪除該注釋 ===

curl --location 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "qwen3-vl-plus",
    "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "image_url",
          "image_url": {
            "url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"
          }
        },
        {
          "type": "text",
          "text": "圖中描繪的是什麼景象?"
        }
      ]
    }
  ],
    "stream":true,
    "stream_options":{"include_usage":true}
}'

DashScope

Python

import os
from dashscope import MultiModalConversation
import dashscope
# 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/api/v1
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

messages = [
    {
        "role": "user",
        "content": [
            {"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},
            {"text": "圖中描繪的是什麼景象?"}
        ]
    }
]

responses = MultiModalConversation.call(
    # 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    model='qwen3-vl-plus',  #  可按需更換為其它多模態模型,並修改相應的 messages
    messages=messages,
    stream=True,
    incremental_output=True)
    
full_content = ""
print("流式輸出內容為:")
for response in responses:
    if response["output"]["choices"][0]["message"].content:
        print(response.output.choices[0].message.content[0]['text'])
        full_content += response.output.choices[0].message.content[0]['text']
print(f"完整內容為:{full_content}")

Java

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import io.reactivex.Flowable;
import com.alibaba.dashscope.utils.Constants;

public class Main {
    static {
        // 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/api/v1
        Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
    }
    public static void streamCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        // must create mutable map.
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(Collections.singletonMap("image", "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"),
                        Collections.singletonMap("text", "圖中描繪的是什麼景象?"))).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                // 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen3-vl-plus")  //  可按需更換為其它多模態模型,並修改相應的 messages
                .messages(Arrays.asList(userMessage))
                .incrementalOutput(true)
                .build();
        Flowable<MultiModalConversationResult> result = conv.streamCall(param);
        result.blockingForEach(item -> {
            try {
                List<Map<String, Object>> content = item.getOutput().getChoices().get(0).getMessage().getContent();
                    // 判斷content是否存在且不為空白
                if (content != null &&  !content.isEmpty()) {
                    System.out.println(content.get(0).get("text"));
                    }
            } catch (Exception e){
                System.exit(0);
            }
        });
    }

    public static void main(String[] args) {
        try {
            streamCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}

curl

# ======= 重要提示 =======
# 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation
# === 執行時請刪除該注釋 ===

curl -X POST https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'X-DashScope-SSE: enable' \
-d '{
    "model": "qwen3-vl-plus",
    "input":{
        "messages":[
            {
                "role": "user",
                "content": [
                    {"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},
                    {"text": "圖中描繪的是什麼景象?"}
                ]
            }
        ]
    },
    "parameters": {
        "incremental_output": true
    }
}'

思考模型的流式輸出

思考模型會先返回reasoning_content(思考過程),再返回content(回複內容)。可根據資料包狀態判斷當前為思考或是回複階段。

思考模型詳情參見:深度思考視覺理解視覺推理
Qwen3-Omni-Flash(思考模式)實現流式輸出請參見全模態

OpenAI相容

以下是使用 OpenAI Python SDK 以流式方式調用思考模式 qwen-plus 模型時返回的資料格式:

# 思考階段
...
ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content='覆蓋所有要點,同時')
ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content='自然流暢。')
# 回複階段
ChoiceDelta(content='你好!我是**通', function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content=None)
ChoiceDelta(content='義千問**(', function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content=None)
...
  • reasoning_content不為 None,content 為 None,則當前處于思考階段;

  • reasoning_content為 None,content 不為 None,則當前處於回複階段;

  • 若兩者均為 None,則階段與前一包一致。

Python

範例程式碼

from openai import OpenAI
import os

# 初始化OpenAI用戶端
client = OpenAI(
    # 如果沒有配置環境變數,請用阿里雲百鍊API Key替換:api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

messages = [{"role": "user", "content": "你是誰"}]

completion = client.chat.completions.create(
    model="qwen-plus",  # 您可以按需更換為其它深度思考模型
    messages=messages,
    # enable_thinking 參數開啟思考過程,該參數對 qwen3-30b-a3b-thinking-2507、qwen3-235b-a22b-thinking-2507、QwQ 模型無效
    extra_body={"enable_thinking": True},
    stream=True,
    # stream_options={
    #     "include_usage": True
    # },
)

reasoning_content = ""  # 完整思考過程
answer_content = ""  # 完整回複
is_answering = False  # 是否進入回複階段
print("\n" + "=" * 20 + "思考過程" + "=" * 20 + "\n")

for chunk in completion:
    if not chunk.choices:
        print("\nUsage:")
        print(chunk.usage)
        continue

    delta = chunk.choices[0].delta

    # 只收集思考內容
    if hasattr(delta, "reasoning_content") and delta.reasoning_content is not None:
        if not is_answering:
            print(delta.reasoning_content, end="", flush=True)
        reasoning_content += delta.reasoning_content

    # 收到content,開始進行回複
    if hasattr(delta, "content") and delta.content:
        if not is_answering:
            print("\n" + "=" * 20 + "完整回複" + "=" * 20 + "\n")
            is_answering = True
        print(delta.content, end="", flush=True)
        answer_content += delta.content

返回結果

====================思考過程====================

好的,使用者問“你是誰”,我需要給出一個準確且友好的回答。首先,我要確認自己的身份,即通義千問,由阿里巴巴集團旗下的通義實驗室研發。接下來,應該說明我的主要功能,比如回答問題、創作文字、邏輯推理等。同時,要保持語氣親切,避免過於技術化,讓使用者感覺輕鬆。還要注意不要使用複雜術語,確保回答簡潔明了。另外,可能需要加入一些互動元素,邀請使用者提問,促進進一步交流。最後,檢查是否有遺漏的重要訊息,比如我的中文名稱“通義千問”和英文名稱“Qwen”,以及所屬公司和實驗室。確保回答全面且符合使用者期望。
====================完整回複====================

你好!我是通義千問,是阿里巴巴集團旗下的通義實驗室自主研發的超大規模語言模型。我可以回答問題、創作文字、進行邏輯推理、編程等,旨在為使用者提供高品質的資訊和服務。你可以叫我Qwen,或者直接叫我通義千問。有什麼我可以幫你的嗎?

Node.js

範例程式碼

import OpenAI from "openai";
import process from 'process';

// 初始化 openai 用戶端
const openai = new OpenAI({
    apiKey: process.env.DASHSCOPE_API_KEY, // 從環境變數讀取
    baseURL: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
});

let reasoningContent = '';
let answerContent = '';
let isAnswering = false;

async function main() {
    try {
        const messages = [{ role: 'user', content: '你是誰' }];
        const stream = await openai.chat.completions.create({
            // 您可以按需更換為其它 Qwen3 模型、QwQ模型
            model: 'qwen-plus',
            messages,
            stream: true,
            // enable_thinking 參數開啟思考過程,該參數對 qwen3-30b-a3b-thinking-2507、qwen3-235b-a22b-thinking-2507、QwQ 模型無效
            enable_thinking: true
        });
        console.log('\n' + '='.repeat(20) + '思考過程' + '='.repeat(20) + '\n');

        for await (const chunk of stream) {
            if (!chunk.choices?.length) {
                console.log('\nUsage:');
                console.log(chunk.usage);
                continue;
            }

            const delta = chunk.choices[0].delta;
            
            // 只收集思考內容
            if (delta.reasoning_content !== undefined && delta.reasoning_content !== null) {
                if (!isAnswering) {
                    process.stdout.write(delta.reasoning_content);
                }
                reasoningContent += delta.reasoning_content;
            }

            // 收到content,開始進行回複
            if (delta.content !== undefined && delta.content) {
                if (!isAnswering) {
                    console.log('\n' + '='.repeat(20) + '完整回複' + '='.repeat(20) + '\n');
                    isAnswering = true;
                }
                process.stdout.write(delta.content);
                answerContent += delta.content;
            }
        }
    } catch (error) {
        console.error('Error:', error);
    }
}

main();

返回結果

====================思考過程====================

好的,使用者問“你是誰”,我需要回答我的身份。首先,我應該明確說明我是通義千問,由阿里雲開發的超大規模語言模型。接下來,可以提到我的主要功能,比如回答問題、創作文字、邏輯推理等。還要強調我的多語言支援,包括中文和英文,這樣使用者知道我可以處理不同語言的請求。另外,可能需要解釋一下我的應用程式情境,比如學習、工作和生活中的協助。不過使用者的問題比較直接,可能不需要太詳細的資訊,保持簡潔明了。同時,要確保語氣友好,邀請使用者進一步提問。檢查有沒有遺漏的重要訊息,比如我的版本或最新更新,但可能使用者不需要那麼詳細。最後,確認回答準確無誤,沒有錯誤資訊。
====================完整回複====================

我是通義千問,是阿里巴巴集團旗下的通義實驗室自主研發的超大規模語言模型。我能夠回答問題、創作文字、邏輯推理、編程等多種任務,支援中英文等多種語言。如果你有任何問題或需要幫,歡迎隨時告訴我!

HTTP

範例程式碼

curl

Qwen3 開源版模型需要設定enable_thinkingtrue來開啟思考模式;enable_thinking對 qwen3-30b-a3b-thinking-2507、qwen3-235b-a22b-thinking-2507、QwQ 模型無效。

curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen-plus",
    "messages": [
        {
            "role": "user", 
            "content": "你是誰"
        }
    ],
    "stream": true,
    "stream_options": {
        "include_usage": true
    },
    "enable_thinking": true
}'

返回結果

data: {"choices":[{"delta":{"content":null,"role":"assistant","reasoning_content":""},"index":0,"logprobs":null,"finish_reason":null}],"object":"chat.completion.chunk","usage":null,"created":1745485391,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-e2edaf2c-8aaf-9e54-90e2-b21dd5045503"}

.....

data: {"choices":[{"finish_reason":"stop","delta":{"content":"","reasoning_content":null},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1745485391,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-e2edaf2c-8aaf-9e54-90e2-b21dd5045503"}

data: {"choices":[],"object":"chat.completion.chunk","usage":{"prompt_tokens":10,"completion_tokens":360,"total_tokens":370},"created":1745485391,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-e2edaf2c-8aaf-9e54-90e2-b21dd5045503"}

data: [DONE]

DashScope

以下為 DashScope Python SDK 調用思考模式的 qwen-plus 模型時,流式返回的資料包格式:

# 思考階段
...
{"role": "assistant", "content": "", "reasoning_content": "資訊量大,"}
{"role": "assistant", "content": "", "reasoning_content": "讓使用者覺得有協助。"}
# 回複階段
{"role": "assistant", "content": "我是通義千問", "reasoning_content": ""}
{"role": "assistant", "content": ",由通義實驗室研發", "reasoning_content": ""}
...
  • reasoning_content不為 "",content 為 "",則當前處于思考階段;

  • reasoning_content為 "",content 不為 "",則當前處於回複階段;

  • 若兩者均為 "",則階段與前一包一致。

Python

範例程式碼

import os
from dashscope import Generation
import dashscope
dashscope.base_http_api_url = "https://dashscope-intl.aliyuncs.com/api/v1/"

messages = [{"role": "user", "content": "你是誰?"}]

completion = Generation.call(
    # 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:api_key = "sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 可按需更換為其它深度思考模型
    model="qwen-plus",
    messages=messages,
    result_format="message", # Qwen3開源版模型只支援設定為"message";為了更好的體驗,其它模型也推薦您優先設定為"message"
    # 開啟深度思考,該參數對qwen3-30b-a3b-thinking-2507、qwen3-235b-a22b-thinking-2507、QwQ模型無效
    enable_thinking=True,
    stream=True,
    incremental_output=True, # Qwen3開源版模型只支援 true;為了更好的體驗,其它模型也推薦您優先設定為 true
)

# 定義完整思考過程
reasoning_content = ""
# 定義完整回複
answer_content = ""
# 判斷是否結束思考過程並開始回複
is_answering = False

print("=" * 20 + "思考過程" + "=" * 20)

for chunk in completion:
    # 如果思考過程與回複皆為空白,則忽略
    if (
        chunk.output.choices[0].message.content == ""
        and chunk.output.choices[0].message.reasoning_content == ""
    ):
        pass
    else:
        # 如果當前為思考過程
        if (
            chunk.output.choices[0].message.reasoning_content != ""
            and chunk.output.choices[0].message.content == ""
        ):
            print(chunk.output.choices[0].message.reasoning_content, end="", flush=True)
            reasoning_content += chunk.output.choices[0].message.reasoning_content
        # 如果當前為回複
        elif chunk.output.choices[0].message.content != "":
            if not is_answering:
                print("\n" + "=" * 20 + "完整回複" + "=" * 20)
                is_answering = True
            print(chunk.output.choices[0].message.content, end="", flush=True)
            answer_content += chunk.output.choices[0].message.content

# 如果您需要列印完整思考過程與完整回複,請將以下代碼解除注釋後運行
# print("=" * 20 + "完整思考過程" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "完整回複" + "=" * 20 + "\n")
# print(f"{answer_content}")

返回結果

====================思考過程====================
好的,使用者問:“你是誰?”我需要回答這個問題。首先,我要明確自己的身份,即通義千問,由阿里雲開發的超大規模語言模型。接下來,要說明我的功能和用途,比如回答問題、創作文字、邏輯推理等。同時,要強調我的目標是成為使用者的得力助手,提供協助和支援。

在表達時,要保持口語化,避免使用專業術語或複雜句式。可以加入一些親切的語氣詞,比如“你好呀~”,讓對話更自然。另外,要確保資訊準確,不遺漏關鍵點,比如我的開發人員、主要功能和使用情境。

還要考慮使用者可能的後續問題,比如具體的應用例子或技術細節,所以在回答中可以適當埋下伏筆,引導使用者進一步提問。例如,提到“無論是日常生活的疑問還是專業領域的問題,我都能儘力提供協助”,這樣既全面又開放。

最後,檢查回答是否流暢,有沒有重複或冗餘的資訊,確保簡潔明了。同時,保持友好和專業的平衡,讓使用者感受到既親切又可靠。
====================完整回複====================
你好呀~我是通義千問,是阿里雲開發的一款超大規模語言模型。我能夠回答問題、創作文字、進行邏輯推理、編程等等,旨在為使用者提供協助和支援。無論是日常生活的疑問還是專業領域的問題,我都能儘力提供協助。有什麼我可以幫你的嗎?

Java

範例程式碼

// dashscope SDK的版本 >= 2.19.4
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import java.lang.System;
import com.alibaba.dashscope.utils.Constants;

public class Main {
    static {
        Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
    }
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    private static StringBuilder reasoningContent = new StringBuilder();
    private static StringBuilder finalContent = new StringBuilder();
    private static boolean isFirstPrint = true;

    private static void handleGenerationResult(GenerationResult message) {
        String reasoning = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
        String content = message.getOutput().getChoices().get(0).getMessage().getContent();

        if (!reasoning.isEmpty()) {
            reasoningContent.append(reasoning);
            if (isFirstPrint) {
                System.out.println("====================思考過程====================");
                isFirstPrint = false;
            }
            System.out.print(reasoning);
        }

        if (!content.isEmpty()) {
            finalContent.append(content);
            if (!isFirstPrint) {
                System.out.println("\n====================完整回複====================");
                isFirstPrint = true;
            }
            System.out.print(content);
        }
    }
    private static GenerationParam buildGenerationParam(Message userMsg) {
        return GenerationParam.builder()
                // 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-plus")
                .enableThinking(true)
                .incrementalOutput(true)
                .resultFormat("message")
                .messages(Arrays.asList(userMsg))
                .build();
    }
    public static void streamCallWithMessage(Generation gen, Message userMsg)
            throws NoApiKeyException, ApiException, InputRequiredException {
        GenerationParam param = buildGenerationParam(userMsg);
        Flowable<GenerationResult> result = gen.streamCall(param);
        result.blockingForEach(message -> handleGenerationResult(message));
    }

    public static void main(String[] args) {
        try {
            Generation gen = new Generation();
            Message userMsg = Message.builder().role(Role.USER.getValue()).content("你是誰?").build();
            streamCallWithMessage(gen, userMsg);
//             列印最終結果
//            if (reasoningContent.length() > 0) {
//                System.out.println("\n====================完整回複====================");
//                System.out.println(finalContent.toString());
//            }
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            logger.error("An exception occurred: {}", e.getMessage());
        }
        System.exit(0);
    }
}

返回結果

====================思考過程====================
好的,使用者問“你是誰?”,我需要根據之前的設定來回答。首先,我的角色是通義千問,阿里巴巴集團旗下的超大規模語言模型。要保持口語化,簡潔易懂。

使用者可能剛接觸我,或者想確認我的身份。應該先直接回答我是誰,然後簡要說明我的功能和用途,比如回答問題、創作文字、編程等。還要提到支援多語言,這樣使用者知道我可以處理不同語言的需求。

另外,根據指導方針,要保持擬人性,所以語氣要友好,可能用Emoji增加親切感。同時,可能需要引導使用者進一步提問或使用我的功能,比如問他們需要什麼協助。

需要注意不要使用複雜術語,避免冗長。檢查是否有遺漏的關鍵點,比如多語言支援和具體能力。確保回答符合所有要求,包括口語化和簡潔。
====================完整回複====================
你好!我是通義千問,阿里巴巴集團旗下的超大規模語言模型。我能夠回答問題、創作文字,比如寫故事、寫公文、寫郵件、寫劇本、邏輯推理、編程等等,還能表達觀點,玩遊戲等。我熟練掌握多種語言,包括但不限於中文、英文、德語、法語、西班牙語等。有什麼需要我幫忙的嗎?

HTTP

範例程式碼

curl

混合思考模型需要設定enable_thinkingtrue來開啟思考模式;enable_thinking對qwen3-30b-a3b-thinking-2507、qwen3-235b-a22b-thinking-2507、 QwQ 模型無效。

# ======= 重要提示 =======
# 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若使用北京地區的模型,需將url替換為:https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
# === 執行時請刪除該注釋 ===
curl -X POST "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text-generation/generation" \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-SSE: enable" \
-d '{
    "model": "qwen-plus",
    "input":{
        "messages":[      
            {
                "role": "user",
                "content": "你是誰?"
            }
        ]
    },
    "parameters":{
        "enable_thinking": true,
        "incremental_output": true,
        "result_format": "message"
    }
}'

返回結果

id:1
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"嗯","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":14,"input_tokens":11,"output_tokens":3},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:2
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":",","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":15,"input_tokens":11,"output_tokens":4},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:3
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"使用者","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":16,"input_tokens":11,"output_tokens":5},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:4
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"問","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":17,"input_tokens":11,"output_tokens":6},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:5
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"“","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":18,"input_tokens":11,"output_tokens":7},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
......

id:358
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"協助","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":373,"input_tokens":11,"output_tokens":362},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:359
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":",","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":374,"input_tokens":11,"output_tokens":363},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:360
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"歡迎","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":375,"input_tokens":11,"output_tokens":364},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:361
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"隨時","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":376,"input_tokens":11,"output_tokens":365},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:362
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"告訴我","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":377,"input_tokens":11,"output_tokens":366},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:363
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"!","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":378,"input_tokens":11,"output_tokens":367},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

id:364
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"","role":"assistant"},"finish_reason":"stop"}]},"usage":{"total_tokens":378,"input_tokens":11,"output_tokens":367},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}

應用於生產環境

  • 效能與資源管理:在後端服務中,為每個流式請求維持一個HTTP長串連會消耗資源。確保您的服務配置了合理的串連池大小和逾時時間。在高並發情境下,監控服務的檔案描述符(file descriptors)使用方式,防止耗盡。

  • 用戶端渲染:在Web前端,使用 ReadableStream 和 TextDecoderStream API 可以平滑地處理和渲染SSE事件流,提供最佳的使用者體驗。

  • 模型監控

    • 關鍵計量:監控首Token延遲(Time to First Token, TTFT),該指標是衡量流式體驗的核心。同時監控請求錯誤率和平均響應時間長度。

    • 警示設定:為API錯誤率(特別是4xx和5xx錯誤)的異常設定警示。

  • Nginx代理配置:若使用 Nginx 作為反向 Proxy,其預設的輸出緩衝(proxy_buffering)會破壞流式響應的即時性。為確保資料能被即時推送到用戶端,務必在Nginx設定檔中設定proxy_buffering off以關閉此功能。

錯誤碼

如果模型調用失敗並返回報錯資訊,請參見錯誤資訊進行解決。

常見問題

Q:為什麼返回資料中沒有 usage 資訊?

A:OpenAI 協議預設不返回 usage 資訊,設定stream_options參數使得最後返回的包中包含 usage 資訊。

Q:開啟流式輸出對模型的回複效果是否有影響?

A:無影響,但部分模型僅支援流式輸出,且非流式輸出可能引發逾時錯誤。建議優先使用流式輸出。