全部產品
Search
文件中心

Alibaba Cloud Model Studio:多輪對話

更新時間:Feb 01, 2026

通義千問 API 是無狀態的,不會儲存對話歷史。要實現多輪對話,需在每次請求中顯式傳入歷史對話訊息,並可結合截斷、摘要、召回等策略,高效管理上下文,減少 Token 消耗。

本文介紹如何通過 OpenAI 相容的 Chat Completion 介面或 DashScope 介面實現多輪對話。 Responses API 可更便捷地實現多輪對話,參見:OpenAI相容-Responses

工作原理

實現多輪對話的核心是維護一個 messages 數組。每一輪對話都需要將使用者的最新提問和模型的回複追加到此數組中,並將其作為下一次請求的輸入。

以下樣本為多輪對話時 messages 的狀態變化:

  1. 第一輪對話

    messages 數組添加使用者問題。

    // 使用文本模型
    [
        {"role": "user", "content": "推薦一部關於太空探索的科幻電影。"}
    ]
    
    // 使用多模態模型,以 Qwen-VL 為例
    // {"role": "user",
    //       "content": [{"type": "image_url","image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"}},
    //                   {"type": "text", "text": "請問圖片展現了有哪些商品?"}]
    // }
  2. 第二輪對話

    messages數組添加大模型回複內容與使用者的最新提問。

    // 使用文本模型
    [
        {"role": "user", "content": "推薦一部關於太空探索的科幻電影。"},
        {"role": "assistant", "content": "我推薦《xxx》,這是一部經典的科幻作品。"},
        {"role": "user", "content": "這部電影的導演是誰?"}
    ]
    
    // 使用多模態模型,以 Qwen-VL 為例
    //[
    //    {"role": "user", "content": [
    //                    {"type": "image_url","image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"}},
    //                   {"type": "text", "text": "請問圖片展現了有哪些商品?"}]},
    //    {"role": "assistant", "content": "圖片展示了三件商品:一件淺藍色背帶褲、一件藍白條紋短袖襯衫和一雙白色運動鞋。"},
    //    {"role": "user", "content": "它們屬於什麼風格?"}
    //]

快速開始

OpenAI相容

Python

import os
from openai import OpenAI


def get_response(messages):
    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",
    )
    # 模型列表:https://www.alibabacloud.com/help/zh/model-studio/getting-started/models
    completion = client.chat.completions.create(model="qwen-plus", messages=messages)
    return completion

# 初始化一個 messages 數組
messages = [
    {
        "role": "system",
        "content": """你是一名阿里雲百鍊手機商店的店員,你負責給使用者推薦手機。手機有兩個參數:螢幕尺寸(包括6.1英寸、6.5英寸、6.7英寸)、解析度(包括2K、4K)。
        你一次只能向使用者提問一個參數。如果使用者提供的資訊不全,你需要反問他,讓他提供沒有提供的參數。如果參數收集完成,你要說:我已瞭解您的購買意向,請稍等。""",
    }
]
assistant_output = "歡迎光臨阿里雲百鍊手機商店,您需要購買什麼尺寸的手機呢?"
print(f"模型輸出:{assistant_output}\n")
while "我已瞭解您的購買意向" not in assistant_output:
    user_input = input("請輸入:")
    # 將使用者問題資訊添加到messages列表中
    messages.append({"role": "user", "content": user_input})
    assistant_output = get_response(messages).choices[0].message.content
    # 將大模型的回複資訊添加到messages列表中
    messages.append({"role": "assistant", "content": assistant_output})
    print(f"模型輸出:{assistant_output}")
    print("\n")

Node.js

import OpenAI from "openai";
import { createInterface } from 'readline/promises';

// 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
const BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
// 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
const openai = new OpenAI({
    apiKey: process.env.DASHSCOPE_API_KEY,
    baseURL: BASE_URL
});

async function getResponse(messages) {
    try {
        const completion = await openai.chat.completions.create({
            // 模型列表:https://www.alibabacloud.com/help/zh/model-studio/getting-started/models
            model: "qwen-plus",
            messages: messages,
        });
        return completion.choices[0].message.content;
    } catch (error) {
        console.error("Error fetching response:", error);
        throw error;  // 重新拋出異常以便上層處理
    }
}

// 初始化 messages 數組
const messages = [
    {
        "role": "system",
        "content": `你是一名阿里雲百鍊手機商店的店員,你負責給使用者推薦手機。手機有兩個參數:螢幕尺寸(包括6.1英寸、6.5英寸、6.7英寸)、解析度(包括2K、4K)。
        你一次只能向使用者提問一個參數。如果使用者提供的資訊不全,你需要反問他,讓他提供沒有提供的參數。如果參數收集完成,你要說:我已瞭解您的購買意向,請稍等。`,
    }
];

let assistant_output = "歡迎光臨阿里雲百鍊手機商店,您需要購買什麼尺寸的手機呢?";
console.log(assistant_output);


const readline = createInterface({
    input: process.stdin,
    output: process.stdout
});

(async () => {
    while (!assistant_output.includes("我已瞭解您的購買意向")) {
        const user_input = await readline.question("請輸入:");
        messages.push({ role: "user", content: user_input});
        try {
            const response = await getResponse(messages);
            assistant_output = response;
            messages.push({ role: "assistant", content: assistant_output });
            console.log(assistant_output);
            console.log("\n");
        } catch (error) {
            console.error("擷取響應時發生錯誤:", error);
        }
    }
    readline.close();
})();

curl

# ======= 重要提示 =======
# 各地區的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" \
-d '{
    "model": "qwen-plus",
    "messages":[      
        {
            "role": "system",
            "content": "You are a helpful assistant."
        },
        {
            "role": "user",
            "content": "你好"
        },
        {
            "role": "assistant",
            "content": "你好啊,我是通義千問。"
        },
        {
            "role": "user",
            "content": "你有哪些技能?"
        }
    ]
}'

DashScope

Python

範例程式碼以手機商店導購為例,導購與顧客會進行多輪對話來採集購買意向,採集完成後會結束會話。

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

def get_response(messages):
    response = Generation.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"),
        # 模型列表:https://www.alibabacloud.com/help/zh/model-studio/getting-started/models
        model="qwen-plus",
        messages=messages,
        result_format="message",
    )
    return response


messages = [
    {
        "role": "system",
        "content": """你是一名阿里雲百鍊手機商店的店員,你負責給使用者推薦手機。手機有兩個參數:螢幕尺寸(包括6.1英寸、6.5英寸、6.7英寸)、解析度(包括2K、4K)。
        你一次只能向使用者提問一個參數。如果使用者提供的資訊不全,你需要反問他,讓他提供沒有提供的參數。如果參數收集完成,你要說:我已瞭解您的購買意向,請稍等。""",
    }
]

assistant_output = "歡迎光臨阿里雲百鍊手機商店,您需要購買什麼尺寸的手機呢?"
print(f"模型輸出:{assistant_output}\n")
while "我已瞭解您的購買意向" not in assistant_output:
    user_input = input("請輸入:")
    # 將使用者問題資訊添加到messages列表中
    messages.append({"role": "user", "content": user_input})
    assistant_output = get_response(messages).output.choices[0].message.content
    # 將大模型的回複資訊添加到messages列表中
    messages.append({"role": "assistant", "content": assistant_output})
    print(f"模型輸出:{assistant_output}")
    print("\n")

Java

import java.util.ArrayList;
import java.util.List;
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 java.util.Scanner;
import com.alibaba.dashscope.protocol.Protocol;

public class Main {
    public static GenerationParam createGenerationParam(List<Message> messages) {
        return GenerationParam.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"))
                // 模型列表:https://www.alibabacloud.com/help/zh/model-studio/getting-started/models
                .model("qwen-plus")
                .messages(messages)
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();
    }
    public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException {
        // 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/api/v1
        Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
        return gen.call(param);
    }
    public static void main(String[] args) {
        try {
            List<Message> messages = new ArrayList<>();
            messages.add(createMessage(Role.SYSTEM, "You are a helpful assistant."));
            for (int i = 0; i < 3;i++) {
                Scanner scanner = new Scanner(System.in);
                System.out.print("請輸入:");
                String userInput = scanner.nextLine();
                if ("exit".equalsIgnoreCase(userInput)) {
                    break;
                }
                messages.add(createMessage(Role.USER, userInput));
                GenerationParam param = createGenerationParam(messages);
                GenerationResult result = callGenerationWithMessages(param);
                System.out.println("模型輸出:"+result.getOutput().getChoices().get(0).getMessage().getContent());
                messages.add(result.getOutput().getChoices().get(0).getMessage());
            }
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }
    private static Message createMessage(Role role, String content) {
        return Message.builder().role(role.getValue()).content(content).build();
    }
}

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/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" \
-d '{
    "model": "qwen-plus",
    "input":{
        "messages":[      
            {
                "role": "system",
                "content": "You are a helpful assistant."
            },
            {
                "role": "user",
                "content": "你好"
            },
            {
                "role": "assistant",
                "content": "你好啊,我是通義千問。"
            },
            {
                "role": "user",
                "content": "你有哪些技能?"
            }
        ]
    }
}'

多模態模型的多輪對話

說明
  • 本章節適用於Qwen-VL、Kimi-K2.5模型,Qwen-Omni具體實現方法請參見全模態

  • Qwen-VL-OCR、Qwen3-Omni-Captioner是為特定單輪任務設計的模型,不支援多輪對話。

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

  • 使用者訊息(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"
)
messages = [
        {"role": "user",
         "content": [
            {
                "type": "image_url",
                "image_url": {
                    "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
                },
            },
            {"type": "text", "text": "請問圖片展現了有哪些商品?"},
        ],
    }
]
completion = client.chat.completions.create(
    model="qwen3-vl-plus",  #  可按需更換為其它多模態模型,並修改相應的 messages
    messages=messages,
    )
print(f"第一輪輸出: {completion.choices[0].message.content}")

assistant_message = completion.choices[0].message
messages.append(assistant_message.model_dump())
messages.append({
        "role": "user",
        "content": [
        {
            "type": "text",
            "text": "它們屬於什麼風格?"
        }
        ]
    })
completion = client.chat.completions.create(
    model="qwen3-vl-plus",
    messages=messages,
    )
    
print(f"第二輪輸出: {completion.choices[0].message.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"
    }
);

let messages = [
    {
    role: "user", content: [
        { type: "image_url", image_url: { "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png" } },
        { type: "text", text: "請問圖片展現了有哪些商品?" },
    ]
}]
async function main() {
    let response = await openai.chat.completions.create({
        model: "qwen3-vl-plus",   // 可按需更換為其它多模態模型,並修改相應的 messages
        messages: messages
    });
    console.log(`第一輪輸出: ${response.choices[0].message.content}`);
    messages.push(response.choices[0].message);
    messages.push({"role": "user", "content": "Write a poem describing this scene"});
    response = await openai.chat.completions.create({
        model: "qwen3-vl-plus",
        messages: messages
    });
    console.log(`第二輪輸出: ${response.choices[0].message.content}`);
}

main()

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 -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": "qwen3-vl-plus",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "image_url",
          "image_url": {
            "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
          }
        },
        {
          "type": "text",
          "text": "請問圖片展現了有哪些商品?"
        }
      ]
    },
    {
      "role": "assistant",
      "content": [
        {
          "type": "text",
          "text": "圖片展示了三件商品:一件淺藍色背帶褲、一件藍白條紋短袖襯衫和一雙白色運動鞋。"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "它們屬於什麼風格?"
        }
      ]
    }
  ]
}'

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://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
            },
            {"text": "請問圖片展現了有哪些商品?"},
        ],
    }
]
response = MultiModalConversation.call(
    # 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model='qwen3-vl-plus',  #  可按需更換為其它多模態模型,並修改相應的 messages
    messages=messages
    )
    
print(f"模型第一輪輸出 {response.output.choices[0].message.content[0]['text']}")
messages.append(response['output']['choices'][0]['message'])
user_msg = {"role": "user", "content": [{"text": "它們屬於什麼風格?"}]}
messages.append(user_msg)
response = MultiModalConversation.call(
    # If the environment variable is not configured, please replace the following line with: api_key="sk-xxx",
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model='qwen3-vl-plus',
    messages=messages
    )
    
print(f"模型第二輪輸出 {response.output.choices[0].message.content[0]['text']}")

Java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
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 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";
    }
    private static final String modelName = "qwen3-vl-plus";  //  可按需更換為其它多模態模型,並修改相應的 messages
    public static void MultiRoundConversationCall() throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(Collections.singletonMap("image", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"),
                        Collections.singletonMap("text", "請問圖片展現了有哪些商品?"))).build();
        List<MultiModalMessage> messages = new ArrayList<>();
        messages.add(userMessage);
        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(modelName)
                .messages(messages)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println("第一輪輸出: "+result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));        // add the result to conversation
        messages.add(result.getOutput().getChoices().get(0).getMessage());
        MultiModalMessage msg = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(Collections.singletonMap("text", "它們屬於什麼風格?"))).build();
        messages.add(msg);
        param.setMessages((List)messages);
        result = conv.call(param);
        System.out.println("第二輪輸出: "+result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));    }

    public static void main(String[] args) {
        try {
            MultiRoundConversationCall();
        } 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' \
-d '{
    "model": "qwen3-vl-plus",
    "input":{
        "messages":[
            {
                "role": "user",
                "content": [
                    {"image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"},
                    {"text": "請問圖片展現了有哪些商品?"}
                ]
            },
            {
                "role": "assistant",
                "content": [
                    {"text": "圖片展示了三件商品:一件淺藍色背帶褲、一件藍白條紋短袖襯衫和一雙白色運動鞋。"}
                ]
            },
            {
                "role": "user",
                "content": [
                    {"text": "它們屬於什麼風格?"}
                ]
            }
        ]
    }
}'

思考模型的多輪對話

思考模型返回reasoning_content(思考過程)與content(回複內容)兩個欄位。更新 messages 數組時,僅保留content欄位,忽略reasoning_content欄位。

[
    {"role": "user", "content": "推薦一部關於太空探索的科幻電影。"},
    {"role": "assistant", "content": "我推薦《xxx》,這是一部經典的科幻作品。"}, # 添加上下文時請勿添加reasoning_content欄位
    {"role": "user", "content": "這部電影的導演是誰?"}
]
思考模型詳情參見:深度思考視覺理解視覺推理
Qwen3-Omni-Flash(思考模式)實現多輪對話請參見全模態

OpenAI相容

Python

範例程式碼

from openai import OpenAI
import os

# 初始化OpenAI用戶端
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-intl.aliyuncs.com/compatible-mode/v1"
)


messages = []
conversation_idx = 1
while True:
    reasoning_content = ""  # 定義完整思考過程
    answer_content = ""     # 定義完整回複
    is_answering = False   # 判斷是否結束思考過程並開始回複
    print("="*20+f"第{conversation_idx}輪對話"+"="*20)
    conversation_idx += 1
    user_msg = {"role": "user", "content": input("請輸入你的訊息:")}
    messages.append(user_msg)
    # 建立聊天完成請求
    completion = client.chat.completions.create(
        # 您可以按需更換為其它深度思考模型
        model="qwen-plus",
        messages=messages,
        extra_body={"enable_thinking": True},
        stream=True,
        # stream_options={
        #     "include_usage": True
        # }
    )
    print("\n" + "=" * 20 + "思考過程" + "=" * 20 + "\n")
    for chunk in completion:
        # 如果chunk.choices為空白,則列印usage
        if not chunk.choices:
            print("\nUsage:")
            print(chunk.usage)
        else:
            delta = chunk.choices[0].delta
            # 列印思考過程
            if hasattr(delta, 'reasoning_content') and delta.reasoning_content != None:
                print(delta.reasoning_content, end='', flush=True)
                reasoning_content += delta.reasoning_content
            else:
                # 開始回複
                if delta.content != "" and is_answering is False:
                    print("\n" + "=" * 20 + "完整回複" + "=" * 20 + "\n")
                    is_answering = True
                # 列印回複過程
                print(delta.content, end='', flush=True)
                answer_content += delta.content
    # 將模型回複的content添加到上下文中
    messages.append({"role": "assistant", "content": answer_content})
    print("\n")

Node.js

範例程式碼

import OpenAI from "openai";
import process from 'process';
import readline from 'readline/promises';

// 初始化 readline 介面
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 初始化 openai 用戶端
const openai = new OpenAI({
    // 各地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
    apiKey: process.env.DASHSCOPE_API_KEY, // 從環境變數讀取
    baseURL: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
});

let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [];
let conversationIdx = 1;

async function main() {
    while (true) {
        console.log("=".repeat(20) + `第${conversationIdx}輪對話` + "=".repeat(20));
        conversationIdx++;
        
        // 讀取使用者輸入
        const userInput = await rl.question("請輸入你的訊息:");
        messages.push({ role: 'user', content: userInput });

        // 重設狀態
        reasoningContent = '';
        answerContent = '';
        isAnswering = false;

        try {
            const stream = await openai.chat.completions.create({
                // 您可以按需更換為其它深度思考模型
                model: 'qwen-plus',
                messages: messages,
                enable_thinking: true,
                stream: true,
                // stream_options:{
                //     include_usage: 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) {
                    process.stdout.write(delta.reasoning_content);
                    reasoningContent += delta.reasoning_content;
                }
                
                // 處理正式回複
                if (delta.content) {
                    if (!isAnswering) {
                        console.log('\n' + "=".repeat(20) + "完整回複" + "=".repeat(20) + "\n");
                        isAnswering = true;
                    }
                    process.stdout.write(delta.content);
                    answerContent += delta.content;
                }
            }
            
            // 將完整回複加入訊息歷史
            messages.push({ role: 'assistant', content: answerContent });
            console.log("\n");
            
        } catch (error) {
            console.error('Error:', error);
        }
    }
}

// 啟動程式
main().catch(console.error);

HTTP

範例程式碼

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 -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": "你好"
        },
        {
            "role": "assistant",
            "content": "你好!很高興見到你,有什麼我可以幫忙的嗎?"
        },
        {
            "role": "user",
            "content": "你是誰?"
        }
    ],
    "stream": true,
    "stream_options": {
        "include_usage": true
    },
    "enable_thinking": true
}'

DashScope

Python

範例程式碼

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

messages = []
conversation_idx = 1
while True:
    print("=" * 20 + f"第{conversation_idx}輪對話" + "=" * 20)
    conversation_idx += 1
    user_msg = {"role": "user", "content": input("請輸入你的訊息:")}
    messages.append(user_msg)
    response = dashscope.Generation.call(
        # 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx",
        api_key=os.getenv('DASHSCOPE_API_KEY'),
         # 此處以qwen-plus為例,可按需更換為其它深度思考模型
        model="qwen-plus", 
        messages=messages,
        enable_thinking=True,
        result_format="message",
        stream=True,
        incremental_output=True
    )
    # 定義完整思考過程
    reasoning_content = ""
    # 定義完整回複
    answer_content = ""
    # 判斷是否結束思考過程並開始回複
    is_answering = False
    print("=" * 20 + "思考過程" + "=" * 20)
    for chunk in response:
        # 如果思考過程與回複皆為空白,則忽略
        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
    # 將模型回複的content添加到上下文中
    messages.append({"role": "assistant", "content": answer_content})
    print("\n")
    # 如果您需要列印完整思考過程與完整回複,請將以下代碼解除注釋後運行
    # 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 java.util.List;
import com.alibaba.dashscope.protocol.Protocol;

public class Main {
    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) {
        if (message != null && message.getOutput() != null 
            && message.getOutput().getChoices() != null 
            && !message.getOutput().getChoices().isEmpty() 
            && message.getOutput().getChoices().get(0) != null
            && message.getOutput().getChoices().get(0).getMessage() != null) {
            
            String reasoning = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
            String content = message.getOutput().getChoices().get(0).getMessage().getContent();
            
            if (reasoning != null && !reasoning.isEmpty()) {
                reasoningContent.append(reasoning);
                if (isFirstPrint) {
                    System.out.println("====================思考過程====================");
                    isFirstPrint = false;
                }
                System.out.print(reasoning);
            }

            if (content != null && !content.isEmpty()) {
                finalContent.append(content);
                if (!isFirstPrint) {
                    System.out.println("\n====================完整回複====================");
                    isFirstPrint = true;
                }
                System.out.print(content);
            }
        }
    }
    
    private static GenerationParam buildGenerationParam(List<Message> messages) {
        return GenerationParam.builder()
                // 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                // 此處以 qwen-plus 為例,可按需更換模型名稱
                .model("qwen-plus")
                .enableThinking(true)
                .messages(messages)
                .incrementalOutput(true)
                .resultFormat("message")
                .build();
    }
    
    public static void streamCallWithMessage(Generation gen, List<Message> messages)
            throws NoApiKeyException, ApiException, InputRequiredException {
        GenerationParam param = buildGenerationParam(messages);
        Flowable<GenerationResult> result = gen.streamCall(param);
        result.doOnError(throwable -> logger.error("Error occurred in stream processing: {}", throwable.getMessage(), throwable))
              .blockingForEach(Main::handleGenerationResult);
    }

    public static void main(String[] args) {
        try {
            // 若使用北京地區的模型,需將base_url替換為:https://dashscope.aliyuncs.com/api/v1
            Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
            Message userMsg1 = Message.builder()
                    .role(Role.USER.getValue())
                    .content("你好")
                    .build();
            Message assistantMsg = Message.builder()
                    .role(Role.ASSISTANT.getValue())
                    .content("你好!很高興見到你,有什麼我可以幫忙的嗎?")
                    .build();
            Message userMsg2 = Message.builder()
                    .role(Role.USER.getValue())
                    .content("你是誰")
                    .build();
            List<Message> messages = Arrays.asList(userMsg1, assistantMsg, userMsg2);
            streamCallWithMessage(gen, messages);
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            logger.error("An exception occurred: {}", e.getMessage(), e);
        } catch (Exception e) {
            logger.error("Unexpected error occurred: {}", e.getMessage(), e);
        } finally {
            // 確保程式正常退出
            System.exit(0);
        }
    }
}

HTTP

範例程式碼

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/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": "你好"
            },
            {
                "role": "assistant",
                "content": "你好!很高興見到你,有什麼我可以幫忙的嗎?"
            },
            {
                "role": "user",
                "content": "你是誰?"
            }
        ]
    },
    "parameters":{
        "enable_thinking": true,
        "incremental_output": true,
        "result_format": "message"
    }
}'

應用於生產環境

多輪對話會帶來巨大的 Token 消耗,且容易超出大模型上下文最大長度導致報錯。以下策略可協助您有效管理上下文與控製成本。

1. 上下文管理

messages 數組會隨對話輪次增加而變長,最終可能超出模型的 Token 限制。建議參考以下內容,在對話過程中管理上下文長度。

1.1. 上下文截斷

當對話歷史過長時,保留最近的 N 輪對話歷史。該方式實現簡單,但會丟失較早的對話資訊。

1.2. 滾動摘要

為了在不丟失核心資訊的前提下動態壓縮對話歷史,控制上下文長度,可隨著對話的進行對上下文進行摘要:

a. 對話歷史達到一定長度(如上下文長度最大值的 70%)時,將對話歷史中較早的部分(如前一半)提取出來,發起獨立 API 呼叫使大模型對這部分內容產生“記憶摘要”;

b. 構建下一次請求時,用“記憶摘要”替換冗長的對話歷史,並拼接最近的幾輪對話。

1.3. 向量化召回

滾動摘要會丟失部分資訊,為了使模型可以從海量對話歷史中“回憶”起相關資訊,可將對話管理從“線性傳遞”轉變為“按需檢索”:

a. 每輪對話結束後,將該輪對話存入向量資料庫;

b. 使用者提問時,通過相似性檢索相關對話記錄;

c. 將檢索到的對話記錄與最近的使用者輸入拼接後輸入大模型。  

2. 成本控制

輸入 Token 數會隨著對話輪數增加,顯著增加使用成本,以下成本管理原則供您參考。

2.1. 減少輸入 Token

通過上文介紹的上下文管理原則減少輸入 Token,降低成本。

2.2. 使用支援上下文緩衝的模型

發起多輪對話請求時,messages 部分會重複計算並計費。阿里雲百鍊對qwen-maxqwen-plus等模型提供了上下文緩衝功能,可以降低使用成本並提升響應速度,建議優先使用支援上下文緩衝的模型。

上下文緩衝功能自動開啟,無需修改代碼。

錯誤碼

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