全部產品
Search
文件中心

Alibaba Cloud Model Studio:文本產生

更新時間:Dec 28, 2024

文本產生是一種人工智慧技術,它基於深度學習演算法,根據給定的提示資訊創作出有邏輯、連貫的常值內容。

文本產生所需的輸入(提示或Prompt)可以是簡單的關鍵詞、一句話概述或是更複雜的指令和上下文資訊。文本產生模型通過分析大量現有資料,學習語言模式,廣泛應用於以下領域:

  • 內容創作:自動產生新聞報道、商品介紹、短視頻指令碼等。

  • 客戶服務:在聊天機器人中應用,提供24小時客服支援,解答常見問題。

  • 文本翻譯:快速準確地將文本從一種語言翻譯成另一種語言。

  • 摘要產生:為長篇文章、報告、客戶郵件自動產生摘要。

  • 法律文檔編寫:自動化產生合約範本、法律意見書的基礎架構。

文本產生樣本:根據需求提取客戶郵件中的關鍵資訊

Prompt

請從這封客戶回函郵件中提取以下資訊:1.客戶資訊 2.軟體版本 3.錯誤碼 4.問題描述 5.作業系統 6.其他相關細節
------------
郵件內文:
主題:【報障求助】智能百鍊助手啟動故障
尊敬的百鍊客服和支援人員團隊,
我是來自通義科技的張偉,我的使用者ID是12345。我正在使用的智能百鍊助手軟體版本為V3.1.8,在此向您報告一個嚴重影響工作進度的技術問題,望儘快協助解決。
自昨日下午起,我在啟動智能百鍊助手時遇到嚴重障礙,軟體啟動過程卡在初始化介面,錯誤碼為ERR-2007,並彈出錯誤提示“資料庫連接失敗”,導致所有功能模組無法正常使用。這一情況已經持續至今,嚴重影響了我司的辦公效率。
我目前使用的伺服器作業系統是Windows 10版本1909,針對64位架構進行最佳化。在遇到問題後,我已經採取了若干初步故障排除措施,其中包括完全關閉並重新啟動系統以試圖清除可能的臨時軟體衝突或系統掛起狀態,以及徹底卸載並重新安裝相關軟體,旨在消除可能存在的軟體損壞或配置錯誤問題。然而,儘管進行了這些常規解決嘗試,問題仍然持續存在,未見任何改善。
為了便於更深入地診斷問題,我已將詳細的錯誤截圖和系統記錄檔作為附件一併提供。這些材料應當能精確展示錯誤發生時的軟體狀態、異常詳情以及任何相關的錯誤碼,為快速定位並解決當前遇到的技術障礙提供了關鍵資訊。
期待您的儘快回複!

模型輸出

1.客戶資訊:通義科技張偉(ID12345)
2.軟體版本:智能百鍊助手V3.1.8
3.錯誤碼:ERR-2007
4.問題描述:能百鍊助手在啟動過程中卡在初始化介面,出現“資料庫連接失敗”的錯誤提示,導致所有功能模組無法使用,問題自昨日下午開始持續存在。
5.作業系統:Win10 1909 64位
6.其他相關細節:已嘗試的解決措施包括重啟系統和重裝軟體,但問題未解決。附件包含錯誤截圖與記錄檔。

文本產生模型

百鍊大模型服務平台支援通義千問商業版、通義千問開源版與一些知名第三方模型,詳細的模型列表請參考文本產生模型列表

通義千問商業版

通義千問

通義new 通義千問-Max

通義new 通義千問-Plus

通義new 通義千問-Turbo

通義new 通義千問VL

特點

適合複雜任務,推理能力最強

效能均衡,介於Max和Turbo之間

適合簡單任務,速度快、成本低

可輸入超百萬像素和任意長寬比的映像

上下文長度

(Token數)

32,768

131,072

1,000,000

7,500

輸出長度

(Token數)

8,192

8,192

8,192

2,000

每千Token輸入成本

$0.0100

$0.0030

$0.0004

限時免費試用

每千Token輸出成本

$0.0300

$0.0090

$0.0012

限時免費試用

通義千問開源版

通義千問開源系列

通義new 通義千問2-開源版

通義new 通義千問1.5-開源版

上下文長度

(Token數)

65,536~131,072

8,000

輸出長度

(Token數)

6,144

2,000

參數規模

(B: Billion)

7B ~ 72B

7B ~ 110B

模型選型建議

  • 通義千問-Max、通義千問-Plus 和通義千問-Turbo 均適用於智能客服、文本創作(如撰寫文稿、文案創作)、文本潤色以及總結摘要等多種情境。如果您暫時不確定選擇哪個模型,建議優先嘗試使用通義千問-Plus,它在效果、速度和成本上相對均衡。

    推理能力:通義千問-Max > 通義千問-Plus > 通義千問-Turbo

    響應速度:通義千問-Turbo > 通義千問-Plus > 通義千問-Max

    三個模型都相容OpenAI 調用方式,相關細節請參考如何通過OpenAI介面調用通義千問模型

  • 如果您有明確的業務訴求,也可以選擇更適合該情境的模型,比如:

    • 希望實現超長文檔的總結分析,可以嘗試通義千問-Plus(最大131,072 Token)。

  • 您也可以結合具體任務充分體驗和評測,對比模型表現後再做決定:

    • 使用模型體驗功能,通過選擇多個文本產生模型,根據相同輸入對模型能力進行快速、直觀地橫向比較。

如何使用

文本產生模型將接收的資訊作為提示(Prompt),並返回一個根據提示資訊產生的輸出。百鍊支援 OpenAI SDK、DashScope SDK、HTTP 接入方式。

本文以調用通義千問模型為例,介紹如何使用文本產生模型。使用 OpenAI 介面進行模型調用的完整參數列表參考 OpenAI 相容 API 參考,DashScope 模型調用的完整參數列表參考DashScope API 參考

訊息類型

您通過API與大模型進行互動時的輸入和輸出也被稱為訊息(Message)。每條訊息都屬於一個角色(Role),角色包括系統(System)、使用者(User)和助手(Assistant)。

  • 系統訊息(System Message,也稱為System Prompt):用於告知模型要扮演的角色或行為。例如,您可以讓模型扮演一個嚴謹的科學家等。預設值是“You are a helpful assistant”。您也可以將此類指令放在使用者訊息中,但放在系統訊息中會更有效。

  • 使用者訊息(User Message):您輸入給模型的文本。

  • 助手訊息(Assistant Message):模型的回複。您也可以預先填寫助手訊息,作為後續助手訊息的樣本。

單輪對話

API 使用前提:已擷取API Key並完成配置API Key到環境變數

OpenAI相容

您可以通過OpenAI SDK或OpenAI相容的HTTP方式調用通義千問模型,體驗單輪對話的功能。

完整參數列表參考 OpenAI 相容 API 參考

Python

範例程式碼

import os
from openai import OpenAI

try:
    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",
    )

    completion = client.chat.completions.create(
        model="qwen-plus",
        messages=[
            {'role': 'system', 'content': 'You are a helpful assistant.'},
            {'role': 'user', 'content': '你是誰?'}
            ]
    )
    print(completion.choices[0].message.content)
except Exception as e:
    print(f"錯誤資訊:{e}")
    print("請參考文檔:https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code")

返回結果

我是來自阿里雲的超大規模語言模型,我叫通義千問。

curl

範例程式碼

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": "你是誰?"
        }
    ]
}'

返回結果

{
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "我是阿里雲開發的一款超大規模語言模型,我叫通義千問。"
            },
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null
        }
    ],
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 22,
        "completion_tokens": 17,
        "total_tokens": 39
    },
    "created": 1726127645,
    "system_fingerprint": null,
    "model": "qwen-plus",
    "id": "chatcmpl-81951b98-28b8-9659-ab07-cd30d25600e7"
}

Node.js

範例程式碼

import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 若沒有配置環境變數,請用百鍊API Key將下行替換為:apiKey: "sk-xxx",
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen-plus",  //模型列表:https://www.alibabacloud.com/help/zh/model-studio/getting-started/models
    messages: [
        { role: "system", content: "You are a helpful assistant." },
        { role: "user", content: "你是誰?" }
    ],
});
console.log(JSON.stringify(completion))

返回結果

{
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "我是來自阿里雲的超大規模語言模型,我叫通義千問。"
            },
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null
        }
    ],
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 22,
        "completion_tokens": 17,
        "total_tokens": 39
    },
    "created": 1728455191,
    "system_fingerprint": null,
    "model": "qwen-plus",
    "id": "chatcmpl-3a8c00cc-9c9f-9aba-b2d9-dc431e27d1b5"
}

DashScope

您可以通過DashScope SDK或HTTP方式調用通義千問模型,體驗單輪對話的功能。

完整參數列表參考DashScope API 參考。SDK 安裝請參考DashScope SDK

Python

範例程式碼

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

messages = [
    {'role': 'system', 'content': 'You are a helpful assistant.'},
    {'role': 'user', 'content': '你是誰?'}
    ]
response = Generation.call(
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key = "sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"), 
    model="qwen-plus",
    messages=messages,
    result_format="message"
)

if response.status_code == 200:
    print(response.output.choices[0].message.content)
else:
    print(f"HTTP返回碼:{response.status_code}")
    print(f"錯誤碼:{response.code}")
    print(f"錯誤資訊:{response.message}")
    print("請參考文檔:https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code")

返回結果

我是通義千問,由阿里雲開發的AI助手。我被設計用來回答各種問題、提供資訊和與使用者進行對話。有什麼我可以協助你的嗎?

Java

範例程式碼

import java.util.Arrays;
import java.lang.System;
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 com.alibaba.dashscope.protocol.Protocol;
public class Main {
    public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException {
        Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .content("You are a helpful assistant.")
                .build();
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content("你是誰?")
                .build();
        GenerationParam param = GenerationParam.builder()
                // 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-plus")
                .messages(Arrays.asList(systemMsg, userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();
        return gen.call(param);
    }
    public static void main(String[] args) {
        try {
            GenerationResult result = callWithMessage();
            System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent());
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            System.err.println("錯誤資訊:"+e.getMessage());
            System.out.println("請參考文檔:https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code");
        }
        System.exit(0);
    }
}

返回結果

我是阿里雲開發的一款超大規模語言模型,我叫通義千問。

curl

範例程式碼

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": "你是誰?"
            }
        ]
    },
    "parameters": {
        "result_format": "message"
    }
}'

返回結果

{
    "output": {
        "choices": [
            {
                "finish_reason": "stop",
                "message": {
                    "role": "assistant",
                    "content": "我是來自阿里雲的大規模語言模型,我叫通義千問。"
                }
            }
        ]
    },
    "usage": {
        "total_tokens": 38,
        "output_tokens": 16,
        "input_tokens": 22
    },
    "request_id": "09dceb20-ae2e-999b-85f9-c5ab266198c0"
}

多輪對話

相比於單輪對話,多輪對話可以讓大模型參考歷史對話資訊,更符合日常交流的情境。實現多輪對話的關鍵在於維護一個存放歷史對話資訊的數組,並將更新後的數組作為大模型的輸入,從而使大模型可以參考歷史對話資訊進行回複。您可以將每一輪的對話歷史添加到messages數組中,實現多輪對話的功能。多輪對話樣本:

image

API 使用前提:已擷取API Key並完成配置API Key到環境變數

OpenAI相容

您可以通過OpenAI SDK或OpenAI相容的HTTP方式調用通義千問模型,體驗多輪對話的功能。

完整參數列表參考 OpenAI 相容 API 參考

Python

import os
from openai import OpenAI


def get_response(messages):
    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",
    )
    completion = client.chat.completions.create(model="qwen-plus", messages=messages)
    return completion


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")

curl

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": "你有哪些技能?"
        }
    ]
}'

Node.js

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

// 定義常量
const BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
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({
            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();
})();

DashScope

您可以通過DashScope SDK或HTTP方式調用通義千問模型,體驗多輪對話的功能。

完整參數列表參考DashScope API 參考。SDK 安裝請參考DashScope SDK

Python

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

def get_response(messages):
    response = Generation.call(
        # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        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將下行替換為:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-plus")
                .messages(messages)
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();
    }
    public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException {
        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

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": "你有哪些技能?"
            }
        ]
    }
}'

流式輸出

大模型收到輸入後並不是一次性產生最終結果,而是逐步地產生中間結果,最終結果由中間結果拼接而成。使用非流式輸出方式需要等待模型產生結束後再將產生的中間結果拼接後返回,而流式輸出可以即時地將中間結果返回,您可以在模型進行輸出的同時進行閱讀,減少等待模型回複的時間。

API 使用前提:已擷取API Key並完成配置API Key到環境變數

OpenAI相容

您可以通過OpenAI SDK或OpenAI相容的HTTP方式調用通義千問模型,體驗流式輸出的功能。

完整參數列表參考 OpenAI 相容 API 參考

Python

import os
from openai import 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",
)
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {'role': 'system', 'content': 'You are a helpful assistant.'},
        {'role': 'user', 'content': '你是誰?'}
        ],
    stream=True
    )
full_content = ""
print("流式輸出內容為:")
for chunk in completion:
    full_content += chunk.choices[0].delta.content
    print(chunk.choices[0].delta.content)
print(f"完整內容為:{full_content}")

返回結果

流式輸出內容為:

我是來自
阿里
雲
的大規模語言模型
,我叫通
義千問。

完整內容為:我是來自阿里雲的大規模語言模型,我叫通義千問。

curl

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": "你是誰?"
        }
    ],
    "stream":true,
    "stream_options":{
        "include_usage":true
    }
}'

返回結果

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-max","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-max","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-max","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-max","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-max","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-max","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-max","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-max","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-max","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}

data: [DONE]

Node.js

範例程式碼

import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 若沒有配置環境變數,請用百鍊API Key將下行替換為:apiKey: "sk-xxx",
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);

const completion = await openai.chat.completions.create({
    model: "qwen-plus",
    messages: [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "你是誰?"}
    ],
    stream: true,
});

let fullContent = "";
console.log("流式輸出內容為:")
for await (const chunk of completion) {
    fullContent = fullContent + chunk.choices[0].delta.content;
    console.log(chunk.choices[0].delta.content);
}
console.log("\n完整內容為:")
console.log(fullContent);

返回結果

流式輸出內容為:

我是
來自
阿里
雲
的大規模語言模型
,我叫通
義千問。


完整內容為:
我是來自阿里雲的大規模語言模型,我叫通義千問。

DashScope

您可以通過DashScope SDK或HTTP方式調用通義千問模型,體驗流式輸出的功能。

完整參數列表參考DashScope API 參考。SDK 安裝請參考DashScope SDK

Python

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

messages = [
    {'role':'system','content':'you are a helpful assistant'},
    {'role': 'user','content': '你是誰?'}]
responses = Generation.call(
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    model="qwen-plus",
    messages=messages,
    result_format='message',
    stream=True,
    # 增量式流式輸出
    incremental_output=True
    )
full_content = ""
print("流式輸出內容為:")
for response in responses:
    full_content += response.output.choices[0].message.content
    print(response.output.choices[0].message.content)
print(f"完整內容為:{full_content}")

返回結果

流式輸出內容為:
我是來自
阿里
雲
的大規模語言模型
,我叫通
義千問。

完整內容為:我是來自阿里雲的大規模語言模型,我叫通義千問。

Java

import java.util.Arrays;
import java.lang.System;
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 com.alibaba.dashscope.protocol.Protocol;

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    private static StringBuilder fullContent = new StringBuilder();
    private static void handleGenerationResult(GenerationResult message) {
        String content = message.getOutput().getChoices().get(0).getMessage().getContent();
        fullContent.append(content);
        System.out.println(content);
    }
    public static void streamCallWithMessage(Generation gen, Message userMsg)
            throws NoApiKeyException, ApiException, InputRequiredException {
        GenerationParam param = buildGenerationParam(userMsg);
        System.out.println("流式輸出內容為:");
        Flowable<GenerationResult> result = gen.streamCall(param);
        result.blockingForEach(message -> handleGenerationResult(message));
        System.out.println("完整內容為: " + fullContent.toString());
    }
    private static GenerationParam buildGenerationParam(Message userMsg) {
        return GenerationParam.builder()
                // 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-plus")
                .messages(Arrays.asList(userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .incrementalOutput(true)
                .build();
    }
    public static void main(String[] args) {
        try {
            Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
            Message userMsg = Message.builder().role(Role.USER.getValue()).content("你是誰?").build();
            streamCallWithMessage(gen, userMsg);
        } catch (ApiException | NoApiKeyException | InputRequiredException  e) {
            logger.error("An exception occurred: {}", e.getMessage());
        }
        System.exit(0);
    }
}

返回結果

流式輸出內容為:
我是通
義
千
問,由阿里
雲開發的人工
智能助手。我
被設計用來回答
各種問題、提供
資訊和與使用者
進行對話。有什麼
我可以協助你的嗎
?

完整內容為: 我是通義千問,由阿里雲開發的人工智慧助手。我被設計用來回答各種問題、提供資訊和與使用者進行對話。有什麼我可以協助你的嗎?

curl

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
    }
}'

返回結果

id:1
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"我是","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":23,"input_tokens":22,"output_tokens":1},"request_id":"xxx"}

id:2
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"通","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":24,"input_tokens":22,"output_tokens":2},"request_id":"xxx"}

id:3
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"義","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":25,"input_tokens":22,"output_tokens":3},"request_id":"xxx"}

id:4
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"千問,由阿里","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":30,"input_tokens":22,"output_tokens":8},"request_id":"xxx"}

id:5
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"雲開發的AI助手。我被","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":38,"input_tokens":22,"output_tokens":16},"request_id":"xxx"}

id:6
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"設計用來回答各種問題、提供資訊","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":46,"input_tokens":22,"output_tokens":24},"request_id":"xxx"}

id:7
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"和與使用者進行對話。有什麼我可以","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":54,"input_tokens":22,"output_tokens":32},"request_id":"xxx"}

id:8
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"協助你的嗎?","role":"assistant"},"finish_reason":"stop"}]},"usage":{"total_tokens":58,"input_tokens":22,"output_tokens":36},"request_id":"xxx"}

Function Call(工具調用)

大語言模型雖然在許多領域已經有廣泛運用,但仍然在某些具體任務上表現不佳,比如無法擷取最新資訊、存在幻覺傾向、不能進行精確計算等。

為瞭解決這些問題,‌模型需要藉助外部工具來輔助其功能。‌工具調用(‌Function Calling)‌便指的是,在必要時,模型會調用相應的外部函數或API,協助模型獲得更準確、‌更即時的資訊,‌提高模型表現和實用性。‌

Function Call 工作流程示意圖如下所示:

Function Call的使用涉及到參數解析功能,因此對大模型的響應品質要求較高,推薦您優先使用qwen-plus模型。

說明

Function Call資訊暫時不支援增量輸出。

OpenAI相容

您可以通過OpenAI SDK或OpenAI相容的HTTP方式調用通義千問模型,體驗Function Call的功能。

Python

範例程式碼

from openai import OpenAI
from datetime import datetime
import json
import os

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",  # 填寫DashScope SDK的base_url
)

# 定義工具列表,模型在選擇使用哪個工具時會參考工具的name和description
tools = [
    # 工具1 擷取當前時刻的時間
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "當你想知道現在的時間時非常有用。",
            # 因為擷取目前時間無需輸入參數,因此parameters為空白字典
            "parameters": {}
        }
    },  
    # 工具2 擷取指定城市的天氣
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "當你想查詢指定城市的天氣時非常有用。",
            "parameters": {  
                "type": "object",
                "properties": {
                    # 查詢天氣時需要提供位置,因此參數設定為location
                    "location": {
                        "type": "string",
                        "description": "城市或縣區,比如北京市、杭州市、餘杭區等。"
                    }
                }
            },
            "required": [
                "location"
            ]
        }
    }
]

# 類比天氣查詢工具。返回結果樣本:“北京今天是雨天。”
def get_current_weather(location):
    return f"{location}今天是雨天。 "

# 查詢目前時間的工具。返回結果樣本:“目前時間:2024-04-15 17:15:18。“
def get_current_time():
    # 擷取當前日期和時間
    current_datetime = datetime.now()
    # 格式化當前日期和時間
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化後的目前時間
    return f"目前時間:{formatted_time}。"

# 封裝模型響應函數
def get_response(messages):
    completion = client.chat.completions.create(
        model="qwen-plus",
        messages=messages,
        tools=tools
        )
    return completion.model_dump()

def call_with_messages():
    print('\n')
    messages = [
            {
                "content": input('請輸入:'),  # 提問樣本:"現在幾點了?" "一個小時後幾點" "北京天氣如何?"
                "role": "user"
            }
    ]
    print("-"*60)
    # 模型的第一輪調用
    i = 1
    first_response = get_response(messages)
    assistant_output = first_response['choices'][0]['message']
    print(f"\n第{i}輪大模型輸出資訊:{first_response}\n")
    if  assistant_output['content'] is None:
        assistant_output['content'] = ""
    messages.append(assistant_output)
    # 如果不需要調用工具,則直接返回最終答案
    if assistant_output['tool_calls'] == None:  # 如果模型判斷無需調用工具,則將assistant的回複直接列印出來,無需進行模型的第二輪調用
        print(f"無需調用工具,我可以直接回複:{assistant_output['content']}")
        return
    # 如果需要調用工具,則進行模型的多輪調用,直到模型判斷無需調用工具
    while assistant_output['tool_calls'] != None:
        # 如果判斷需要調用查詢天氣工具,則執行查詢天氣工具
        if assistant_output['tool_calls'][0]['function']['name'] == 'get_current_weather':
            tool_info = {"name": "get_current_weather", "role":"tool"}
            # 提取位置參數資訊
            location = json.loads(assistant_output['tool_calls'][0]['function']['arguments'])['location']
            tool_info['content'] = get_current_weather(location)
        # 如果判斷需要調用查詢時間工具,則執行查詢時間工具
        elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_time':
            tool_info = {"name": "get_current_time", "role":"tool"}
            tool_info['content'] = get_current_time()
        print(f"工具輸出資訊:{tool_info['content']}\n")
        print("-"*60)
        messages.append(tool_info)
        assistant_output = get_response(messages)['choices'][0]['message']
        if  assistant_output['content'] is None:
            assistant_output['content'] = ""
        messages.append(assistant_output)
        i += 1
        print(f"第{i}輪大模型輸出資訊:{assistant_output}\n")
    print(f"最終答案:{assistant_output['content']}")

if __name__ == '__main__':
    call_with_messages()

返回結果

當輸入:幾點了?時,程式會進行如下輸出:

2024-07-25_15-37-20 (1)

以下是發起Function Call流程(模型的第一輪調用)時模型的返回資訊。當輸入“杭州天氣”時,模型會返回tool_calls參數;當輸入“你好”時,模型判斷無需調用工具,模型不會返回tool_calls參數。

輸入:杭州天氣

{
    'id': 'chatcmpl-e2f045fd-2604-9cdb-bb61-37c805ecd15a',
    'choices': [
        {
            'finish_reason': 'tool_calls',
            'index': 0,
            'logprobs': None,
            'message': {
                'content': '',
                'role': 'assistant',
                'function_call': None,
                'tool_calls': [
                    {
                        'id': 'call_7a33ebc99d5342969f4868',
                        'function': {
                            'arguments': '{
                                "location": "杭州市"
                            }',
                            'name': 'get_current_weather'
                        },
                        'type': 'function',
                        'index': 0
                    }
                ]
            }
        }
    ],
    'created': 1726049697,
    'model': 'qwen-max',
    'object': 'chat.completion',
    'service_tier': None,
    'system_fingerprint': None,
    'usage': {
        'completion_tokens': 18,
        'prompt_tokens': 217,
        'total_tokens': 235
    }
}

輸入:你好

{
    'id': 'chatcmpl-5d890637-9211-9bda-b184-961acf3be38d',
    'choices': [
        {
            'finish_reason': 'stop',
            'index': 0,
            'logprobs': None,
            'message': {
                'content': '你好!有什麼可以協助你的嗎?',
                'role': 'assistant',
                'function_call': None,
                'tool_calls': None
            }
        }
    ],
    'created': 1726049765,
    'model': 'qwen-max',
    'object': 'chat.completion',
    'service_tier': None,
    'system_fingerprint': None,
    'usage': {
        'completion_tokens': 7,
        'prompt_tokens': 216,
        'total_tokens': 223
    }
}

HTTP

範例程式碼

import requests
import os
from datetime import datetime
import json

# 定義工具列表,模型在選擇使用哪個工具時會參考工具的name和description
tools = [
    # 工具1 擷取當前時刻的時間
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "當你想知道現在的時間時非常有用。",
            "parameters": {}  # 因為擷取目前時間無需輸入參數,因此parameters為空白字典
        }
    },  
    # 工具2 擷取指定城市的天氣
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "當你想查詢指定城市的天氣時非常有用。",
            "parameters": {  # 查詢天氣時需要提供位置,因此參數設定為location
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市或縣區,比如北京市、杭州市、餘杭區等。"
                    }
                }
            },
            "required": [
                "location"
            ]
        }
    }
]

# 類比天氣查詢工具。返回結果樣本:“北京今天是晴天。”
def get_current_weather(location):
    return f"{location}今天是晴天。 "

# 查詢目前時間的工具。返回結果樣本:“目前時間:2024-04-15 17:15:18。“
def get_current_time():
    # 擷取當前日期和時間
    current_datetime = datetime.now()
    # 格式化當前日期和時間
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化後的目前時間
    return f"目前時間:{formatted_time}。"

def get_response(messages):
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
    api_key = os.getenv("DASHSCOPE_API_KEY")
    url = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions'
    headers = {'Content-Type': 'application/json',
            'Authorization':f'Bearer {api_key}'}
    body = {
        'model': 'qwen-plus',
        "messages": messages,
        "tools":tools
    }

    response = requests.post(url, headers=headers, json=body)
    return response.json()


def call_with_messages():
    messages = [
            {
                "content": input('請輸入:'),  # 提問樣本:"現在幾點了?" "一個小時後幾點" "北京天氣如何?"
                "role": "user"
            }
    ]
    
    # 模型的第一輪調用
    first_response = get_response(messages)
    print(f"\n第一輪調用結果:{first_response}")
    assistant_output = first_response['choices'][0]['message']
    if  assistant_output['content'] is None:
        assistant_output['content'] = ""
    messages.append(assistant_output)
    if 'tool_calls' not in assistant_output:  # 如果模型判斷無需調用工具,則將assistant的回複直接列印出來,無需進行模型的第二輪調用
        print(f"最終答案:{assistant_output['content']}")
        return
    # 如果模型選擇的工具是get_current_weather
    elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_weather':
        tool_info = {"name": "get_current_weather", "role":"tool"}
        location = json.loads(assistant_output['tool_calls'][0]['function']['arguments'])['location']
        tool_info['content'] = get_current_weather(location)
    # 如果模型選擇的工具是get_current_time
    elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_time':
        tool_info = {"name": "get_current_time", "role":"tool"}
        tool_info['content'] = get_current_time()
    print(f"工具輸出資訊:{tool_info['content']}")
    messages.append(tool_info)

    # 模型的第二輪調用,對工具的輸出進行總結
    second_response = get_response(messages)
    print(f"第二輪調用結果:{second_response}")
    print(f"最終答案:{second_response['choices'][0]['message']['content']}")

if __name__ == '__main__':
    call_with_messages()

返回結果

當輸入:杭州天氣時,程式會進行如下輸出:

2024-07-16_14-43-10 (1)

以下是發起Function Call流程(模型的第一輪調用)時模型的返回資訊。當輸入“杭州天氣”時,模型會返回tool_calls參數;當輸入“你好”時,模型判斷無需調用工具,模型不會返回tool_calls參數。

輸入:杭州天氣

{
    'choices': [
        {
            'message': {
                'content': '',
                'role': 'assistant',
                'tool_calls': [
                    {
                        'function': {
                            'name': 'get_current_weather',
                            'arguments': '{
                                "location": "杭州市"
                            }'
                        },
                        'index': 0,
                        'id': 'call_416cd81b8e7641edb654c4',
                        'type': 'function'
                    }
                ]
            },
            'finish_reason': 'tool_calls',
            'index': 0,
            'logprobs': None
        }
    ],
    'object': 'chat.completion',
    'usage': {
        'prompt_tokens': 217,
        'completion_tokens': 18,
        'total_tokens': 235
    },
    'created': 1726050222,
    'system_fingerprint': None,
    'model': 'qwen-max',
    'id': 'chatcmpl-61e30855-ee69-93ab-98d5-4194c51a9980'
}

輸入:你好

{
    'choices': [
        {
            'message': {
                'content': '你好!有什麼可以協助你的嗎?',
                'role': 'assistant'
            },
            'finish_reason': 'stop',
            'index': 0,
            'logprobs': None
        }
    ],
    'object': 'chat.completion',
    'usage': {
        'prompt_tokens': 216,
        'completion_tokens': 7,
        'total_tokens': 223
    },
    'created': 1726050238,
    'system_fingerprint': None,
    'model': 'qwen-max',
    'id': 'chatcmpl-2f2f86d1-bc4e-9494-baca-aac5b0555091'
}

Node.js

範例程式碼

import OpenAI from "openai";
import { format } from 'date-fns';
import readline from 'readline';

function getCurrentWeather(location) {
    return `${location}今天是雨天。`;
}
function getCurrentTime() {
    // 擷取當前日期和時間
    const currentDatetime = new Date();
    // 格式化當前日期和時間
    const formattedTime = format(currentDatetime, 'yyyy-MM-dd HH:mm:ss');
    // 返回格式化後的目前時間
    return `目前時間:${formattedTime}。`;
}
const openai = new OpenAI(
    {
        // 若沒有配置環境變數,請用百鍊API Key將下行替換為:apiKey: "sk-xxx",
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const tools = [
// 工具1 擷取當前時刻的時間
{
    "type": "function",
    "function": {
        "name": "getCurrentTime",
        "description": "當你想知道現在的時間時非常有用。",
        // 因為擷取目前時間無需輸入參數,因此parameters為空白
        "parameters": {}  
    }
},  
// 工具2 擷取指定城市的天氣
{
    "type": "function",
    "function": {
        "name": "getCurrentWeather",
        "description": "當你想查詢指定城市的天氣時非常有用。",
        "parameters": {  
            "type": "object",
            "properties": {
                // 查詢天氣時需要提供位置,因此參數設定為location
                "location": {
                    "type": "string",
                    "description": "城市或縣區,比如北京市、杭州市、餘杭區等。"
                }
            },
            "required": ["location"]
        }
    }
}
];
async function getResponse(messages) {
    const response = await openai.chat.completions.create({
        model: "qwen-plus",
        messages: messages,
        tools: tools,
    });
    return response;
}
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
rl.question("user: ", async (question) => {
    const messages = [{"role": "user","content": question}];
    let i = 1;
    const firstResponse = await getResponse(messages);
    let assistantOutput = firstResponse.choices[0].message;    
    console.log(`第${i}輪大模型輸出資訊:${JSON.stringify(assistantOutput)}`);
    if (Object.is(assistantOutput.content,null)){
        assistantOutput.content = "";
    }
    messages.push(assistantOutput);
    if (! ("tool_calls" in assistantOutput)) {
        console.log(`無需調用工具,我可以直接回複:${assistantOutput.content}`);
        rl.close();
    } else{
        while ("tool_calls" in assistantOutput) {
            let toolInfo = {};
            if (assistantOutput.tool_calls[0].function.name == "getCurrentWeather" ) {
                toolInfo = {"role": "tool"};
                let location = JSON.parse(assistantOutput.tool_calls[0].function.arguments)["location"];
                toolInfo["content"] = getCurrentWeather(location);
            } else if (assistantOutput.tool_calls[0].function.name == "getCurrentTime" ) {
                toolInfo = {"role":"tool"};
                toolInfo["content"] = getCurrentTime();
            }
            console.log(`工具輸出資訊:${JSON.stringify(toolInfo)}`);
            console.log("=".repeat(100));
            messages.push(toolInfo);
            assistantOutput = (await getResponse(messages)).choices[0].message;
            if (Object.is(assistantOutput.content,null)){
                assistantOutput.content = "";
            }
            messages.push(assistantOutput);
            i += 1;
            console.log(`第${i}輪大模型輸出資訊:${JSON.stringify(assistantOutput)}`)
    }
    console.log("=".repeat(100));
    console.log(`最終大模型輸出資訊:${JSON.stringify(assistantOutput.content)}`);
    rl.close();
    }});

返回結果

輸入四個直轄市的天氣如何?,輸出結果為:

第1輪大模型輸出資訊:{"content":"","role":"assistant","tool_calls":[{"function":{"name":"getCurrentWeather","arguments":"{\"location\": \"北京市\"}"},"index":0,"id":"call_d2aff21240b24c7291db6d","type":"function"}]}
工具輸出資訊:{"role":"tool","content":"北京市今天是雨天。"}
====================================================================================================
第2輪大模型輸出資訊:{"content":"","role":"assistant","tool_calls":[{"function":{"name":"getCurrentWeather","arguments":"{\"location\": \"天津市\"}"},"index":0,"id":"call_bdcfa937e69b4eae997b5e","type":"function"}]}
工具輸出資訊:{"role":"tool","content":"天津市今天是雨天。"}
====================================================================================================
第3輪大模型輸出資訊:{"content":"","role":"assistant","tool_calls":[{"function":{"name":"getCurrentWeather","arguments":"{\"location\": \"上海市\"}"},"index":0,"id":"call_bbf22d017e8e439e811974","type":"function"}]}
工具輸出資訊:{"role":"tool","content":"上海市今天是雨天。"}
====================================================================================================
第4輪大模型輸出資訊:{"content":"","role":"assistant","tool_calls":[{"function":{"name":"getCurrentWeather","arguments":"{\"location\": \"重慶市\"}"},"index":0,"id":"call_f4f8e149af01492fb60162","type":"function"}]}
工具輸出資訊:{"role":"tool","content":"重慶市今天是雨天。"}
====================================================================================================
第5輪大模型輸出資訊:{"content":"所有四個直轄市(北京市、天津市、上海市、重慶市)今天的天氣都是雨天。別忘了帶傘!","role":"assistant"}
====================================================================================================
最終大模型輸出資訊:"所有四個直轄市(北京市、天津市、上海市、重慶市)今天的天氣都是雨天。別忘了帶傘!"

DashScope

您可以通過DashScope SDK或HTTP方式調用通義千問模型,體驗Function Call的功能。

Python

範例程式碼

import os
from dashscope import Generation
from datetime import datetime
import random
import json
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

# 定義工具列表,模型在選擇使用哪個工具時會參考工具的name和description
tools = [
    # 工具1 擷取當前時刻的時間
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "當你想知道現在的時間時非常有用。",
            "parameters": {}  # 因為擷取目前時間無需輸入參數,因此parameters為空白字典
        }
    },
    # 工具2 擷取指定城市的天氣
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "當你想查詢指定城市的天氣時非常有用。",
            "parameters": {
                # 查詢天氣時需要提供位置,因此參數設定為location
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市或縣區,比如北京市、杭州市、餘杭區等。"
                    }
                }
            },
            "required": [
                "location"
            ]
        }
    }
]


# 類比天氣查詢工具。返回結果樣本:“北京今天是晴天。”
def get_current_weather(location):
    return f"{location}今天是晴天。 "


# 查詢目前時間的工具。返回結果樣本:“目前時間:2024-04-15 17:15:18。“
def get_current_time():
    # 擷取當前日期和時間
    current_datetime = datetime.now()
    # 格式化當前日期和時間
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化後的目前時間
    return f"目前時間:{formatted_time}。"


# 封裝模型響應函數
def get_response(messages):
    response = Generation.call(
        # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        model='qwen-plus',
        messages=messages,
        tools=tools,
        seed=random.randint(1, 10000),  # 設定隨機數種子seed,如果沒有設定,則隨機數種子預設為1234
        result_format='message'  # 將輸出設定為message形式
    )
    return response


def call_with_messages():
    print('\n')
    messages = [
            {
                "content": input('請輸入:'),  # 提問樣本:"現在幾點了?" "一個小時後幾點" "北京天氣如何?"
                "role": "user"
            }
    ]
   
    # 模型的第一輪調用
    first_response = get_response(messages)
    assistant_output = first_response.output.choices[0].message
    print(f"\n大模型第一輪輸出資訊:{first_response}\n")
    messages.append(assistant_output)
    if 'tool_calls' not in assistant_output:  # 如果模型判斷無需調用工具,則將assistant的回複直接列印出來,無需進行模型的第二輪調用
        print(f"最終答案:{assistant_output.content}")
        return
    # 如果模型選擇的工具是get_current_weather
    elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_weather':
        tool_info = {"name": "get_current_weather", "role":"tool"}
        location = json.loads(assistant_output.tool_calls[0]['function']['arguments'])['location']
        tool_info['content'] = get_current_weather(location)
    # 如果模型選擇的工具是get_current_time
    elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_time':
        tool_info = {"name": "get_current_time", "role":"tool"}
        tool_info['content'] = get_current_time()
    print(f"工具輸出資訊:{tool_info['content']}\n")
    messages.append(tool_info)

    # 模型的第二輪調用,對工具的輸出進行總結
    second_response = get_response(messages)
    print(f"大模型第二輪輸出資訊:{second_response}\n")
    print(f"最終答案:{second_response.output.choices[0].message['content']}")

if __name__ == '__main__':
    call_with_messages()

返回結果

通過運行以上代碼,您可以輸入問題,得到在工具輔助條件下模型的輸出結果。使用過程樣本如下圖所示:2024-04-29_11-22-10 (1).gif

以下是發起Function Call流程(模型的第一輪調用)時模型的返回資訊。當輸入“杭州天氣”時,模型會返回tool_calls參數;當輸入“你好”時,模型判斷無需調用工具,模型不會返回tool_calls參數。

輸入:杭州天氣

{
  "status_code": 200,
  "request_id": "33cf0a53-ea38-9f47-8fce-b93b55d86573",
  "code": "",
  "message": "",
  "output": {
    "text": null,
    "finish_reason": null,
    "choices": [
      {
        "finish_reason": "tool_calls",
        "message": {
          "role": "assistant",
          "content": "",
          "tool_calls": [
            {
              "function": {
                "name": "get_current_weather",
                "arguments": "{\"location\": \"杭州市\"}"
              },
              "index": 0,
              "id": "call_9f62f52f3a834a8194f634",
              "type": "function"
            }
          ]
        }
      }
    ]
  },
  "usage": {
    "input_tokens": 217,
    "output_tokens": 18,
    "total_tokens": 235
  }
}

輸入:你好

{
  "status_code": 200,
  "request_id": "4818ce03-e7c9-96de-a7bc-781649d98465",
  "code": "",
  "message": "",
  "output": {
    "text": null,
    "finish_reason": null,
    "choices": [
      {
        "finish_reason": "stop",
        "message": {
          "role": "assistant",
          "content": "你好!有什麼可以協助你的嗎?"
        }
      }
    ]
  },
  "usage": {
    "input_tokens": 216,
    "output_tokens": 7,
    "total_tokens": 223
  }
}

Java

範例程式碼

// Copyright (c) Alibaba, Inc. and its affiliates.
// version >= 2.12.0

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.alibaba.dashscope.aigc.conversation.ConversationParam.ResultFormat;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationOutput.Choice;
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 com.alibaba.dashscope.tools.FunctionDefinition;
import com.alibaba.dashscope.tools.ToolCallBase;
import com.alibaba.dashscope.tools.ToolCallFunction;
import com.alibaba.dashscope.tools.ToolFunction;
import com.alibaba.dashscope.utils.JsonUtils;
import com.alibaba.dashscope.protocol.Protocol;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.victools.jsonschema.generator.Option;
import com.github.victools.jsonschema.generator.OptionPreset;
import com.github.victools.jsonschema.generator.SchemaGenerator;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfig;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
import com.github.victools.jsonschema.generator.SchemaVersion;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {

    public static class GetWeatherTool {
        private String location;

        public GetWeatherTool(String location) {
            this.location = location;
        }

        public String callWeather() {
            // 假設location是一個JSON字串,例如{"location": "北京"}
            // 需要提取其中的"location"的值
            try {
                // 使用Jackson庫解析JSON
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode jsonNode = objectMapper.readTree(location);
                String locationName = jsonNode.get("location").asText();
                return locationName + "今天是晴天";
            } catch (Exception e) {
                // 如果解析失敗,返回原始字串
                return location + "今天是晴天";
            }
        }
    }
    public static class GetTimeTool {
        public String getCurrentTime() {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return "目前時間:" + now.format(formatter) + "。";
        }
    }
    private static ObjectNode generateSchema(Class<?> clazz) {
        SchemaGeneratorConfigBuilder configBuilder =
                new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON);
        SchemaGeneratorConfig config = configBuilder.with(Option.EXTRA_OPEN_API_FORMAT_VALUES)
                .without(Option.FLATTENED_ENUMS_FROM_TOSTRING).build();
        SchemaGenerator generator = new SchemaGenerator(config);
        return generator.generateSchema(clazz);
    }
    public static void selectTool()
            throws NoApiKeyException, ApiException, InputRequiredException {
        ObjectNode jsonSchemaWeather = generateSchema(GetWeatherTool.class);
        ObjectNode jsonSchemaTime = generateSchema(GetTimeTool.class);
        FunctionDefinition fdWeather = FunctionDefinition.builder().name("get_current_weather")
                .description("擷取指定地區的天氣")
                .parameters(JsonUtils.parseString(jsonSchemaWeather.toString()).getAsJsonObject()).build();
        FunctionDefinition fdTime = FunctionDefinition.builder().name("get_current_time")
                .description("擷取當前時刻的時間")
                .parameters(JsonUtils.parseString(jsonSchemaTime.toString()).getAsJsonObject()).build();
        Message systemMsg = Message.builder().role(Role.SYSTEM.getValue())
                .content("You are a helpful assistant. When asked a question, use tools wherever possible.")
                .build();
        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入:");
        String userInput = scanner.nextLine();
        Message userMsg = Message.builder().role(Role.USER.getValue()).content(userInput).build();
        List<Message> messages = new ArrayList<>(Arrays.asList(systemMsg, userMsg));
        GenerationParam param = GenerationParam.builder()
                .model("qwen-plus")
                // 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .messages(messages).resultFormat(ResultFormat.MESSAGE)
                .tools(Arrays.asList(
                        ToolFunction.builder().function(fdWeather).build(),
                        ToolFunction.builder().function(fdTime).build()
                )).build();
        Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
        GenerationResult result = gen.call(param);
        System.out.println("首輪輸出:" + JsonUtils.toJson(result));
        boolean needToolCall = true;
        while (needToolCall) {
            needToolCall = false;
            for (Choice choice : result.getOutput().getChoices()) {
                messages.add(choice.getMessage());
                if (choice.getMessage().getToolCalls() != null) {
                    for (ToolCallBase toolCall : choice.getMessage().getToolCalls()) {
                        if (toolCall.getType().equals("function")) {
                            String functionName = ((ToolCallFunction) toolCall).getFunction().getName();
                            String functionArgument = ((ToolCallFunction) toolCall).getFunction().getArguments();
                            if (functionName.equals("get_current_weather")) {
                                GetWeatherTool weatherTool = new GetWeatherTool(functionArgument);
                                String weather = weatherTool.callWeather();
                                Message toolResultMessage = Message.builder().role("tool")
                                        .content(weather).toolCallId(toolCall.getId()).build();
                                messages.add(toolResultMessage);
                                System.out.println("工具輸出資訊:" + weather);
                            } else if (functionName.equals("get_current_time")) {
                                GetTimeTool timeTool = new GetTimeTool();
                                String time = timeTool.getCurrentTime();
                                Message toolResultMessage = Message.builder().role("tool")
                                        .content(time).toolCallId(toolCall.getId()).build();
                                messages.add(toolResultMessage);
                                System.out.println("工具輸出資訊:" + time);
                            }
                            needToolCall = true;
                        }
                    }
                } else {
                    System.out.println("最終答案:" + choice.getMessage().getContent());
                    return;
                }
            }

            if (needToolCall) {
                param.setMessages(messages);
                result = gen.call(param);
                System.out.println("下一輪輸出:" + JsonUtils.toJson(result));
            }
        }

        System.out.println("最終答案:" + result.getOutput().getChoices().get(0).getMessage().getContent());
    }

    public static void main(String[] args) {
        try {
            selectTool();
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            System.out.println(String.format("Exception: %s", e.getMessage()));
        } catch (Exception e) {
            System.out.println(String.format("Exception: %s", e.getMessage()));
        }
        System.exit(0);
    }
}

返回結果

通過運行以上代碼,您可以輸入問題,得到在工具輔助條件下模型的輸出結果。使用過程樣本如下圖所示:2024-07-17_10-20-07 (1)

以下是發起Function Call流程(模型的第一輪調用)時模型的返回資訊。當輸入“杭州天氣”時,模型會返回tool_calls參數;當輸入“你好”時,模型判斷無需調用工具,模型不會返回tool_calls參數。

輸入:杭州天氣

{
    "requestId": "e2faa5cf-1707-973b-b216-36aa4ef52afc",
    "usage": {
        "input_tokens": 254,
        "output_tokens": 19,
        "total_tokens": 273
    },
    "output": {
        "choices": [
            {
                "finish_reason": "tool_calls",
                "message": {
                    "role": "assistant",
                    "content": "",
                    "tool_calls": [
                        {
                            "type": "function",
                            "id": "",
                            "function": {
                                "name": "get_current_whether",
                                "arguments": "{\"location\": \"杭州\"}"
                            }
                        }
                    ]
                }
            }
        ]
    }
}

輸入:你好

{
    "requestId": "f6ca3828-3b5f-99bf-8bae-90b4aa88923f",
    "usage": {
        "input_tokens": 253,
        "output_tokens": 7,
        "total_tokens": 260
    },
    "output": {
        "choices": [
            {
                "finish_reason": "stop",
                "message": {
                    "role": "assistant",
                    "content": "你好!有什麼可以協助你的嗎?"
                }
            }
        ]
    }
}

HTTP

範例程式碼

import requests
import os
from datetime import datetime
import json

# 定義工具列表,模型在選擇使用哪個工具時會參考工具的name和description
tools = [
    # 工具1 擷取當前時刻的時間
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "當你想知道現在的時間時非常有用。",
            "parameters": {}  # 因為擷取目前時間無需輸入參數,因此parameters為空白字典
        }
    },  
    # 工具2 擷取指定城市的天氣
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "當你想查詢指定城市的天氣時非常有用。",
            "parameters": {  # 查詢天氣時需要提供位置,因此參數設定為location
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市或縣區,比如北京市、杭州市、餘杭區等。"
                    }
                }
            },
            "required": [
                "location"
            ]
        }
    }
]

# 類比天氣查詢工具。返回結果樣本:“北京今天是晴天。”
def get_current_weather(location):
    return f"{location}今天是晴天。 "

# 查詢目前時間的工具。返回結果樣本:“目前時間:2024-04-15 17:15:18。“
def get_current_time():
    # 擷取當前日期和時間
    current_datetime = datetime.now()
    # 格式化當前日期和時間
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化後的目前時間
    return f"目前時間:{formatted_time}。"

def get_response(messages):
    api_key = os.getenv("DASHSCOPE_API_KEY")
    url = 'https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text-generation/generation'
    headers = {'Content-Type': 'application/json',
            'Authorization':f'Bearer {api_key}'}
    body = {
        'model': 'qwen-plus',
        "input": {

                        "messages": messages
        },
        "parameters": {
            "result_format": "message",
            "tools": tools
        }
    }

    response = requests.post(url, headers=headers, json=body)
    return response.json()

messages = [
    {
        "role": "user",
        "content": "今天天氣怎麼樣?"
    }
]

def call_with_messages():
    messages = [
            {
                "content": input('請輸入:'),  # 提問樣本:"現在幾點了?" "一個小時後幾點" "北京天氣如何?"
                "role": "user"
            }
    ]
    
    # 模型的第一輪調用
    first_response = get_response(messages)
    print(f"\n第一輪調用結果:{first_response}")
    assistant_output = first_response['output']['choices'][0]['message']
    messages.append(assistant_output)
    if 'tool_calls' not in assistant_output:  # 如果模型判斷無需調用工具,則將assistant的回複直接列印出來,無需進行模型的第二輪調用
        print(f"最終答案:{assistant_output['content']}")
        return
    # 如果模型選擇的工具是get_current_weather
    elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_weather':
        tool_info = {"name": "get_current_weather", "role":"tool"}
        location = json.loads(assistant_output['tool_calls'][0]['function']['arguments'])['location']
        tool_info['content'] = get_current_weather(location)
    # 如果模型選擇的工具是get_current_time
    elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_time':
        tool_info = {"name": "get_current_time", "role":"tool"}
        tool_info['content'] = get_current_time()
    print(f"工具輸出資訊:{tool_info['content']}")
    messages.append(tool_info)

    # 模型的第二輪調用,對工具的輸出進行總結
    second_response = get_response(messages)
    print(f"第二輪調用結果:{second_response}")
    print(f"最終答案:{second_response['output']['choices'][0]['message']['content']}")

if __name__ == '__main__':
    call_with_messages()
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.json.JSONArray;
import org.json.JSONObject;

public class Main {
    private static final String userAGENT = "Java-HttpURLConnection/1.0";
    public static void main(String[] args) throws Exception {
        // 使用者輸入問題
        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入:");
        String UserInput = scanner.nextLine();
        // 初始化messages
        JSONArray messages = new JSONArray();
        // 定義系統資訊system_message
        JSONObject systemMessage = new JSONObject();
        systemMessage.put("role","system");
        systemMessage.put("content","You are a helpful assistant.");
        // 根據使用者的輸入構造user_message
        JSONObject userMessage = new JSONObject();
        userMessage.put("role","user");
        userMessage.put("content",UserInput);
        // 將system_message和user_message依次添加到messages中
        messages.put(systemMessage);
        messages.put(userMessage);
        // 進行模型的第一輪調用,並列印出結果
        JSONObject responseJson = getResponse(messages);
        System.out.println("第一輪調用結果:"+responseJson);
        // 擷取助手資訊assistant_message
        JSONObject assistantMessage = responseJson.getJSONObject("output").getJSONArray("choices").getJSONObject(0).getJSONObject("message");
        // 初始化工具資訊tool_message
        JSONObject toolMessage = new JSONObject();

        // 如果assistant_message沒有tool_calls參數,則直接列印出assistant_message中的響應資訊並返回
        if (! assistantMessage.has("tool_calls")){
            System.out.println("最終答案:"+assistantMessage.get("content"));
            return;
        }
        // 如果assistant_message有tool_calls參數,說明模型判斷需要調用工具
        else {
            // 將assistant_message添加到messages中
            messages.put(assistantMessage);
            // 如果模型判斷需要調用get_current_weather函數
            if (assistantMessage.getJSONArray("tool_calls").getJSONObject(0).getJSONObject("function").getString("name").equals("get_current_weather")) {
                // 擷取參數arguments資訊,並提取出location參數
                JSONObject argumentsJson = new JSONObject(assistantMessage.getJSONArray("tool_calls").getJSONObject(0).getJSONObject("function").getString("arguments"));
                String location = argumentsJson.getString("location");
                // 運行工具函數,得到工具的輸出,並列印
                String toolOutput = getCurrentWeather(location);
                System.out.println("工具輸出資訊:"+toolOutput);
                // 構造tool_message資訊
                toolMessage.put("name","get_current_weather");
                toolMessage.put("role","tool");
                toolMessage.put("content",toolOutput);
            }
            // 如果模型判斷需要調用get_current_time函數
            if (assistantMessage.getJSONArray("tool_calls").getJSONObject(0).getJSONObject("function").getString("name").equals("get_current_time")) {
                // 運行工具函數,得到工具的輸出,並列印
                String toolOutput = getCurrentTime();
                System.out.println("工具輸出資訊:"+toolOutput);
                // 構造tool_message資訊
                toolMessage.put("name","get_current_time");
                toolMessage.put("role","tool");
                toolMessage.put("content",toolOutput);
            }
        }
        // 將tool_message添加到messages中
        messages.put(toolMessage);
        // 進行模型的第二輪調用,並列印出結果
        JSONObject secondResponse = getResponse(messages);
        System.out.println("第二輪調用結果:"+secondResponse);
        System.out.println("最終答案:"+secondResponse.getJSONObject("output").getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content"));
    }
    // 定義擷取天氣的函數
    public static String getCurrentWeather(String location) {
        return location+"今天是晴天";
    }
    // 定義擷取目前時間的函數
    public static String getCurrentTime() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = "目前時間:" + now.format(formatter) + "。";
        return currentTime;
    }
    // 封裝模型響應函數,輸入:messages,輸出:json格式化後的http響應
    public static JSONObject getResponse(JSONArray messages) throws Exception{
        // 初始化工具庫
        JSONArray tools = new JSONArray();
        // 定義工具1:擷取目前時間
        String jsonStringTime = "{\"type\": \"function\", \"function\": {\"name\": \"get_current_time\", \"description\": \"當你想知道現在的時間時非常有用。\", \"parameters\": {}}}";
        JSONObject getCurrentTimeJson = new JSONObject(jsonStringTime);
        // 定義工具2:擷取指定地區天氣
        String jsonString_weather = "{\"type\": \"function\", \"function\": {\"name\": \"get_current_weather\", \"description\": \"當你想查詢指定城市的天氣時非常有用。\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"城市或縣區,比如北京市、杭州市、餘杭區等。\"}}}, \"required\": [\"location\"]}}";
        JSONObject getCurrentWeatherJson = new JSONObject(jsonString_weather);
        // 將兩個工具添加到工具庫中
        tools.put(getCurrentTimeJson);
        tools.put(getCurrentWeatherJson);
        String toolsString = tools.toString();
        // 介面調用URL
        String urlStr = "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text-generation/generation";
        // 通過環境變數擷取DASHSCOPE_API_KEY
        String apiKey = System.getenv("DASHSCOPE_API_KEY");

        URL url = new URL(urlStr);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        // 定義要求標頭資訊
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Authorization", "Bearer " + apiKey);
        connection.setDoOutput(true);
        // 定義請求體資訊
        String jsonInputString = String.format("{\"model\": \"qwen-max\", \"input\": {\"messages\":%s}, \"parameters\": {\"result_format\": \"message\",\"tools\":%s}}",messages.toString(),toolsString);

        // 擷取http響應response
        try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
            wr.write(jsonInputString.getBytes(StandardCharsets.UTF_8));
            wr.flush();
        }
        StringBuilder response = new StringBuilder();
        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()))) {
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
        }
        connection.disconnect();
        // 返回json格式化後的response
        return new JSONObject(response.toString());
    }
}

返回結果

當輸入:杭州天氣時,程式會進行如下輸出:

2024-07-16_14-07-04 (1)

以下是發起Function Call流程(模型的第一輪調用)時模型的返回資訊。當輸入“杭州天氣”時,模型會返回tool_calls參數;當輸入“你好”時,模型判斷無需調用工具,模型不會返回tool_calls參數。

輸入:杭州天氣

{
    'output': {
        'choices': [
            {
                'finish_reason': 'tool_calls',
                'message': {
                    'role': 'assistant',
                    'tool_calls': [
                        {
                            'function': {
                                'name': 'get_current_weather',
                                'arguments': '{
                                    "location": "杭州市"
                                }'
                            },
                            'index': 0,
                            'id': 'call_240d6341de4c484384849d',
                            'type': 'function'
                        }
                    ],
                    'content': ''
                }
            }
        ]
    },
    'usage': {
        'total_tokens': 235,
        'output_tokens': 18,
        'input_tokens': 217
    },
    'request_id': '235ed6a4-b6c0-9df0-aa0f-3c6dce89f3bd'
}

輸入:你好

{
    'output': {
        'choices': [
            {
                'finish_reason': 'stop',
                'message': {
                    'role': 'assistant',
                    'content': '你好!有什麼可以協助你的嗎?'
                }
            }
        ]
    },
    'usage': {
        'total_tokens': 223,
        'output_tokens': 7,
        'input_tokens': 216
    },
    'request_id': '42c42853-3caf-9815-96e8-9c950f4c26a0'
}

結構化輸出

如果您的業務需要輸出結構化資料,可以通過OpenAI相容的方式調用qwen模型,來確保產生的字串符合標準的JSON格式。在調用時,設定response_format{"type": "json_object"},並通過系統訊息或使用者訊息指引模型輸出JSON格式即可。

結構化輸出功能支援qwen-max、qwen-plus、qwen-turbo模型。

Python

範例程式碼

from openai import OpenAI
import os

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",  # 填寫DashScope服務的base_url
)
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {'role': 'system', 'content': 'You are a helpful assistant.'},
        {'role': 'user', 'content': '請用json格式輸出一個學生的資訊,姓名是張三,學號是12345678'}],
    response_format={
        "type": "json_object"
    }
    )
print(completion.choices[0].message.content)

返回結果

{
  "姓名": "張三",
  "學號": "12345678"
}

curl

樣本請求

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": "請用json格式輸出一個學生的資訊,姓名是張三,學號是12345678"
        }
    ],
    "response_format": {
        "type": "json_object"
    }
}'

返回結果

{
  "choices": [
    {
      "message": {
        "content": "{\"姓名\": \"張三\", \"學號\": \"12345678\"}",
        "role": "assistant"
      },
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null
    }
  ],
  "object": "chat.completion",
  "usage": {
    "prompt_tokens": 46,
    "completion_tokens": 21,
    "total_tokens": 67
  },
  "created": 1726110523,
  "system_fingerprint": null,
  "model": "qwen-plus",
  "id": "chatcmpl-f208fb06-9ef2-994e-af5e-8234b9e31d94"
}

Node.js

範例程式碼

import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 若沒有配置環境變數,請用百鍊API Key將下行替換為:apiKey: "sk-xxx",
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen-plus",  //模型列表:https://www.alibabacloud.com/help/en/model-studio/getting-started/models
    messages: [
        { role: "system", content: "You are a helpful assistant." },
        { role: "user", content: "請用json格式輸出一個學生的資訊,姓名是張三,學號是12345678" }
    ],
    response_format: {
        "type": "json_object"
    }
});
console.log(completion.choices[0].message.content)

返回結果

{
  "姓名": "張三",
  "學號": "12345678"
}

Partial Mode

如果您希望通義千問模型能夠嚴格地以指定首碼為基礎來產生文本,可以使用Partial Mode。您輸入的messages數組中最後一個message需要為assistant message,並且符合以下格式:

{
    "role": "assistant",
    "content": "您指定的首碼",
    "partial": true
}
Partial Mode功能支援qwen-max、qwen-plus、qwen-turbo模型。

OpenAI相容

Python

範例程式碼

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"), # 如果您沒有配置環境變數,請在此處用您的API Key進行替換
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",  # 填寫DashScope服務的base_url
)
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[{
        "role": "user",
        "content": "請對“春天來了,大地”這句話進行續寫,來表達春天的美好和作者的喜悅之情"
    },
    {
        "role": "assistant",
        "content": "春天來了,大地",
        "partial": True
    }]
    )
print(completion.choices[0].message.content)

返回結果

披上了一襲翠綠的新裝,萬物複蘇,生機盎然。陽光溫柔地灑在每一寸土地上,彷彿是大自然最溫暖的擁抱。花兒爭先恐後地綻放,紅的、黃的、紫的……如同調色盤上最絢爛的顏色,點綴著這幅春日畫卷。微風輕拂,帶來陣陣花香與泥土的清新氣息,令人心曠神怡。小溪邊,柳樹抽出嫩芽,隨風搖曳生姿;田野裡,農民伯伯開始忙碌起來,播下希望的種子。在這充滿活力與美好的季節裡,我感受到了生命的力量,心中充滿了無限的喜悅與期待。

curl

範例程式碼

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": "春天來了,大地",
        "partial": true
    }]
}'

返回結果

{
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "換上了翠綠的新裝,萬物複蘇,生機勃勃。陽光透過輕柔的雲層,灑在剛剛探出頭的小草上,彷彿給它們披上了一層金色的紗衣。花兒們也不甘落後,爭先恐後地綻放著自己的美麗,紅的、黃的、紫的……五彩斑斕,像是大自然精心布置的一幅絢麗畫卷。微風中夾雜著泥土的芬芳與花香,讓人心曠神怡。漫步在這春意盎然的世界裡,我的心情也跟著明媚起來,感受到了生命的力量和希望的美好。"
            },
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null
        }
    ],
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 34,
        "completion_tokens": 125,
        "total_tokens": 159
    },
    "created": 1731898325,
    "system_fingerprint": null,
    "model": "qwen-plus",
    "id": "chatcmpl-244c5496-6a84-9380-951d-49d4691f252a"
}

DashScope

Python

範例程式碼

import os
import dashscope
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

messages = [{
    "role": "user",
    "content": "請對“春天來了,大地”這句話進行續寫,來表達春天的美好和作者的喜悅之情"
},
{
    "role": "assistant",
    "content": "春天來了,大地",
    "partial": True
}]
response = dashscope.Generation.call(
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    model='qwen-plus',
    messages=messages,
    result_format='message',  
)

print(response.output.choices[0].message.content)

返回結果

彷彿從漫長的冬眠中蘇醒,披上了一襲翠綠的新裝。萬物複蘇,生機勃勃,小草偷偷地探出了頭,花朵也爭先恐後地綻放著自己的美麗,散發出陣陣芳香。樹木抽出嫩芽,一片片葉子在陽光下閃爍著生命的光澤。河流解凍,潺潺流水聲如同大自然最美妙的樂章,喚醒了沉睡的山川。在這溫暖的季節裡,不僅自然界充滿了活力與希望,人們的心靈也隨之變得輕盈而愉悅,彷彿所有的煩惱都隨著春風飄散而去。我走在這樣的景色之中,心中滿是歡喜與感激,感謝這美好的春日時光,讓生活更加多彩多姿。

curl

範例程式碼

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": "user",
            "content": "請對“春天來了,大地”這句話進行續寫,來表達春天的美好和作者的喜悅之情"
        },
        {
            "role": "assistant",
            "content": "春天來了,大地",
            "partial": true
        }]
    },
    "parameters": {
        "result_format": "message"
    }
}'

返回結果

{
    "output": {
        "choices": [
            {
                "finish_reason": "stop",
                "message": {
                    "role": "assistant",
                    "content": "換上了嫩綠的新裝,萬物複蘇,生機盎然。陽光透過輕盈的雲層,溫柔地撫摸著每一寸土地,彷彿是大自然最溫暖的擁抱。花朵競相開放,散發出陣陣芬芳,吸引著蜜蜂與蝴蝶前來探訪,它們忙碌的身影在花間穿梭,構成了一幅生動活潑的畫面。小溪解凍,潺潺流水聲如同天籟之音,喚醒了沉睡一冬的小動物們,它們歡快地在林間跳躍、嬉戲。這一切美好景象,讓人心情愉悅,彷彿連空氣中都瀰漫著幸福的味道。我走在這樣的季節裡,心中充滿了對生活的熱愛和對未來無限美好的憧憬。"
                }
            }
        ]
    },
    "usage": {
        "total_tokens": 177,
        "output_tokens": 143,
        "input_tokens": 34
    },
    "request_id": "bb4dab4a-aba1-9786-9857-d0743bab11e8"
}

非同步呼叫

您可以使用Asyncio介面調用實現並發,提高程式的效率。範例程式碼如下:

OpenAI SDK

範例程式碼

import os
import asyncio
from openai import AsyncOpenAI
import platform

# 建立非同步用戶端執行個體
client = AsyncOpenAI(
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
)

# 定義非同步工作清單
async def task(question):
    print(f"Sending question: {question}")
    response = await client.chat.completions.create(
        messages=[
            {"role": "user", "content": question}
        ],
        model="qwen-plus",
    )
    print(f"Received answer: {response.choices[0].message.content}")

# 主非同步函數
async def main():
    questions = ["你是誰?", "你會什嗎?", "天氣怎麼樣?"]
    tasks = [task(q) for q in questions]
    await asyncio.gather(*tasks)

if __name__ == '__main__':
    # 設定事件迴圈策略
    if platform.system() == 'Windows':
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    # 運行主協程
    asyncio.run(main(), debug=False)
    

DashScope SDK

範例程式碼

您的DashScope Python SDK版本需要不低於 1.19.0。
import asyncio
import platform
from dashscope.aigc.generation import AioGeneration
import os
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

# 定義非同步工作清單
async def task(question):
    print(f"Sending question: {question}")
    response = await AioGeneration.call(
        # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key="sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        model="qwen-plus",
        prompt=question
        )
    print(f"Received answer: {response.output.text}")

# 主非同步函數
async def main():
    questions = ["你是誰?", "你會什嗎?", "天氣怎麼樣?"]
    tasks = [task(q) for q in questions]
    await asyncio.gather(*tasks)

if __name__ == '__main__':
    # 設定事件迴圈策略
    if platform.system() == 'Windows':
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    # 運行主協程
    asyncio.run(main(), debug=False)

控制產生的常用參數

Temperature 和 top_p

這兩個參數都用於控制模型產生文本的多樣性。temperature 或 top_p 越高,產生的文本更多樣,反之產生的文本更確定。

  • 具有多樣性的文本,適用於創意寫作(如小說、廣告文案)、頭腦風暴、聊天應用等情境。

  • 具有確定性文本,適用於有明確答案(如問題分析、選擇題、事實查詢)或要求用詞準確(如技術文檔、法律文本、新聞報導、學術論文)的情境。

原理介紹

temperature

  • temperature 越高,Token 機率分布變得更平坦(即高機率 Token 的機率降低,低機率 Token 的機率上升),使得模型在選擇下一個 Token 時更加隨機。

  • temperature 越低,Token 機率分布變得更陡峭(即高機率 Token 被選取的機率更高,低機率 Token 的機率更低),使得模型更傾向於選擇高機率的少數 Token。

top_p

top_p 採樣是指從最高機率(最核心)的 Token 集合中進行採樣。它將所有可能的下一個 Token 按機率從高到低排序,然後從機率最高的 Token 開始累加機率,直至機率總和達到閾值(例如80%,即 top_p=0.8),最後從這些機率最高、機率總和達到閾值的 Token 中隨機播放一個用於輸出。

  • top_p 越高,考慮的 Token 越多,因此產生的文本更多樣。

  • top_p 越低,考慮的 Token 越少,因此產生的文本更集中和確定。

API 參考

使用 OpenAI 介面進行模型調用的完整參數列表參考 OpenAI 相容 API 參考,DashScope 模型調用的完整參數列表參考DashScope API 參考

瞭解更多

提示(Prompt)工程

提示(Prompt)是輸入給大語言模型的文本資訊,用於明確地告訴模型想要解決的問題或完成的任務,也是模型理解需求並產生相關、準確內容的基礎。通過精心設計和最佳化 Prompt,向模型“明確”任務目的,使模型輸出的結果更符合預期,這一過程被稱之為"提示工程(Prompt Engineering)"這個過程包括以下關鍵步驟:

payukogjvzcwbvvabpvc.png

如果您對提示工程感興趣,請前往Prompt 最佳實務瞭解如何構建有效Prompt來提升模型表現。

也可以瀏覽百鍊服務平台的 Prompt工程頁面,從而快速瞭解如何利用模板來快速產生所需的常值內容。

多模態能力

多模態能力是指模型能夠處理和結合多種不同類型的資料模態(如文本、映像、音頻、視頻等)進行資訊的理解、處理和產生的能力。這種能力使得模型能夠更全面地理解和產生內容,增強上下文理解,提高模型表現。

當前百鍊支援的多模態模型有:

  • 通義千問VL(文+圖->文):具有映像理解能力的通義千問模型,能完成 OCR、視覺推理、本文理解等任務,支援超百萬像素解析度和任意寬高比的映像。