All Products
Search
Document Center

Alibaba Cloud Model Studio:Pemanggilan fungsi

Last Updated:Mar 18, 2026

Model Bahasa Besar (Large Language Models/LLMs) kerap kesulitan menangani informasi real-time dan perhitungan matematis. Pemanggilan fungsi memungkinkan LLMs menggunakan alat eksternal untuk menjawab pertanyaan yang tidak dapat dijawab secara langsung.

Cara kerja

Pemanggilan fungsi memungkinkan LLMs menggunakan alat eksternal melalui interaksi multi-langkah antara aplikasi Anda dan model.

  1. Lakukan panggilan model pertama

    Kirim permintaan ke LLM berisi pertanyaan pengguna dan daftar alat yang tersedia.

  2. Terima instruksi pemanggilan alat dari model (nama alat dan parameter input)

    Jika model menentukan bahwa diperlukan alat eksternal, model akan mengembalikan instruksi JSON yang menentukan fungsi yang akan dieksekusi beserta parameter inputnya.

    Jika model menentukan bahwa tidak diperlukan alat, model akan mengembalikan respons dalam bahasa alami.
  3. Jalankan alat dalam aplikasi Anda

    Setelah aplikasi Anda menerima instruksi alat, jalankan alat tersebut untuk mendapatkan output-nya.

  4. Lakukan panggilan model kedua

    Tambahkan output alat ke konteks model (messages) dan lakukan panggilan model berikutnya.

  5. Terima respons akhir dari model

    Model menggabungkan output alat dengan pertanyaan pengguna untuk menghasilkan respons dalam bahasa alami.

Diagram berikut menunjukkan alur kerja:

image

Model yang didukung

Qwen

DeepSeek

  • deepseek-v3.2

  • deepseek-v3.2-exp (mode non-thinking)

  • deepseek-v3.1 (mode non-thinking)

  • deepseek-r1

  • deepseek-r1-0528

  • deepseek-v3

GLM

  • glm-4.7

  • glm-4.6

Kimi

  • kimi-k2.5

  • kimi-k2-thinking

  • Moonshot-Kimi-K2-Instruct

Memulai

Anda harus mendapatkan Kunci API dan menyetel Kunci API sebagai variabel lingkungan. Jika Anda memanggil model menggunakan SDK OpenAI atau SDK DashScope, Anda harus menginstal SDK.

Bagian ini menggunakan skenario kueri cuaca sebagai contoh untuk menunjukkan cara memulai pemanggilan fungsi.

Kompatibel dengan OpenAI

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

client = OpenAI(
    # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti base_url dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",  
)
# Simulasikan pertanyaan pengguna.
USER_QUESTION = "What's the weather like in Singapore?"
# Definisikan daftar alat.
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or county, such as Singapore or New York.",
                    }
                },
                "required": ["location"],
            },
        },
    },
]


# Simulasikan alat kueri cuaca.
def get_current_weather(arguments):
    weather_conditions = ["sunny", "cloudy", "rainy"]
    random_weather = random.choice(weather_conditions)
    location = arguments["location"]
    return f"{location} is {random_weather} today."


# Enkapsulasi fungsi respons model.
def get_response(messages):
    completion = client.chat.completions.create(
        model="qwen-plus",
        messages=messages,
        tools=tools,
    )
    return completion


messages = [{"role": "user", "content": USER_QUESTION}]
response = get_response(messages)
assistant_output = response.choices[0].message
if assistant_output.content is None:
    assistant_output.content = ""
messages.append(assistant_output)
# Jika tidak diperlukan alat, langsung keluarkan kontennya.
if assistant_output.tool_calls is None:
    print(f"No weather query tool is required. Direct reply: {assistant_output.content}")
else:
    # Masuk ke loop pemanggilan alat.
    while assistant_output.tool_calls is not None:
        tool_call = assistant_output.tool_calls[0]
        tool_call_id = tool_call.id
        func_name = tool_call.function.name
        arguments = json.loads(tool_call.function.arguments)
        print(f"Calling tool [{func_name}], parameters: {arguments}")
        # Jalankan alat.
        tool_result = get_current_weather(arguments)
        # Buat pesan balasan alat.
        tool_message = {
            "role": "tool",
            "tool_call_id": tool_call_id,
            "content": tool_result,  # Pertahankan output asli alat.
        }
        print(f"Tool returned: {tool_message['content']}")
        messages.append(tool_message)
        # Panggil model lagi untuk mendapatkan balasan ringkas dalam bahasa alami.
        response = get_response(messages)
        assistant_output = response.choices[0].message
        if assistant_output.content is None:
            assistant_output.content = ""
        messages.append(assistant_output)
    print(f"Final assistant reply: {assistant_output.content}")
import OpenAI from 'openai';  
  
// Menginisialisasi klien  
const openai = new OpenAI({  
  apiKey: process.env.DASHSCOPE_API_KEY,  
  // Jika Anda menggunakan model di wilayah Beijing, ganti baseURL dengan: https://dashscope.aliyuncs.com/compatible-mode/v1
  baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",  
});  
  
// Mendefinisikan daftar alat  
const tools = [  
  {  
    type: "function",  
    function: {  
      name: "get_current_weather",  
      description: "Berguna saat Anda ingin mengkueri cuaca untuk kota tertentu.",  
      parameters: {  
        type: "object",  
        properties: {  
          location: {  
            type: "string",  
            description: "Kota atau kabupaten, seperti Singapura atau New York.",  
          },  
        },  
        required: ["location"],  
      },  
    },  
  },  
];  
  
// Menyimulasikan alat kueri cuaca  
const getCurrentWeather = (args) => {  
  const weatherConditions = ["sunny", "cloudy", "rainy"];  
  const randomWeather = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];  
  const location = args.location;  
  return `${location} adalah ${randomWeather} hari ini.`;  
};  
  
// Membungkus fungsi tanggapan model  
const getResponse = async (messages) => {  
  const response = await openai.chat.completions.create({  
    model: "qwen-plus",  
    messages: messages,  
    tools: tools,  
  });  
  return response;  
};  

const main = async () => {  
  const input = "Bagaimana kondisi cuaca di Singapura?";

  let messages = [  
    {  
      role: "user",  
      content: input,  
    }  
  ];  
  let response = await getResponse(messages);  
  let assistantOutput = response.choices[0].message;  
  // Memastikan bahwa konten tidak bernilai null  
  if (!assistantOutput.content) assistantOutput.content = "";  
  messages.push(assistantOutput);  
  // Menentukan apakah akan memanggil alat  
  if (!assistantOutput.tool_calls) {  
    console.log(`Tidak perlu memanggil alat kueri cuaca. Balasan langsung: ${assistantOutput.content}`);  
  } else {  
    // Masuk ke loop pemanggilan alat  
    while (assistantOutput.tool_calls) {  
      const toolCall = assistantOutput.tool_calls[0];  
      const toolCallId = toolCall.id;  
      const funcName = toolCall.function.name;  
      const funcArgs = JSON.parse(toolCall.function.arguments);  
      console.log(`Memanggil alat [${funcName}] dengan argumen:`, funcArgs);  
      // Menjalankan alat  
      const toolResult = getCurrentWeather(funcArgs);  
      // Membuat tanggapan alat  
      const toolMessage = {  
        role: "tool",  
        tool_call_id: toolCallId,  
        content: toolResult,  
      };  
      console.log(`Tanggapan alat: ${toolMessage.content}`);  
      messages.push(toolMessage);  
      // Memanggil model lagi untuk mendapatkan ringkasan dalam bahasa alami  
      response = await getResponse(messages);  
      assistantOutput = response.choices[0].message;  
      if (!assistantOutput.content) assistantOutput.content = "";  
      messages.push(assistantOutput);  
    }  
    console.log(`Tanggapan akhir asisten: ${assistantOutput.content}`);  
  }  
};  
  
// Memulai program  
main().catch(console.error);

DashScope

import os
from dashscope import Generation
import dashscope
import json
import random

# Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti base_http_api_url dengan https://dashscope.aliyuncs.com/api/v1.
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

# 1. Definisikan daftar alat.
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or county, such as Singapore or New York.",
                    }
                },
                "required": ["location"],
            },
        },
    }
]

# 2. Simulasikan alat kueri cuaca.
def get_current_weather(arguments):
    weather_conditions = ["sunny", "cloudy", "rainy"]
    random_weather = random.choice(weather_conditions)
    location = arguments["location"]
    return f"{location} is {random_weather} today."

# 3. Enkapsulasi fungsi respons model.
def get_response(messages):
    response = Generation.call(
        # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
        # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan api_key="sk-xxx".
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        model="qwen-plus",
        messages=messages,
        tools=tools,
        result_format="message",
    )
    return response

# 4. Inisialisasi riwayat percakapan.
messages = [
    {
        "role": "user",
        "content": "What's the weather like in Singapore?"
    }
]

# 5. Lakukan panggilan model pertama.
response = get_response(messages)
assistant_output = response.output.choices[0].message
messages.append(assistant_output)

# 6. Tentukan apakah perlu memanggil alat.
if "tool_calls" not in assistant_output or not assistant_output["tool_calls"]:
    print(f"No tool is required. Direct reply: {assistant_output['content']}")
else:
    # 7. Masuk ke loop pemanggilan alat.
    # Kondisi loop: Selama balasan model terbaru berisi permintaan pemanggilan alat.
    while "tool_calls" in assistant_output and assistant_output["tool_calls"]:
        tool_call = assistant_output["tool_calls"][0]
        # Uraikan informasi pemanggilan alat.
        func_name = tool_call["function"]["name"]
        arguments = json.loads(tool_call["function"]["arguments"])
        tool_call_id = tool_call.get("id")  # Dapatkan tool_call_id.
        print(f"Calling tool [{func_name}], parameters: {arguments}")
        # Jalankan fungsi alat yang sesuai.
        tool_result = get_current_weather(arguments)
        # Buat pesan balasan alat.
        tool_message = {
            "role": "tool",
            "content": tool_result,
            "tool_call_id": tool_call_id
        }
        print(f"Tool returned: {tool_message['content']}")
        messages.append(tool_message)
        # Panggil model lagi agar model dapat membalas berdasarkan hasil alat.
        response = get_response(messages)
        assistant_output = response.output.choices[0].message
        messages.append(assistant_output)
    # 8. Keluarkan balasan akhir dalam bahasa alami.
    print(f"Final assistant reply: {assistant_output['content']}")
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.protocol.Protocol;
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.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * Definisikan implementasi lokal alat.
     * @param arguments String JSON yang berisi parameter alat yang diberikan oleh model.
     * @return Hasil string setelah alat dijalankan.
     */
    public static String getCurrentWeather(String arguments) {
        try {
            // Parameter yang diberikan oleh model dalam format JSON dan perlu diurai secara manual.
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode argsNode = objectMapper.readTree(arguments);
            String location = argsNode.get("location").asText();

            // Gunakan hasil acak untuk mensimulasikan panggilan API nyata atau logika bisnis.
            List<String> weatherConditions = Arrays.asList("sunny", "cloudy", "rainy");
            String randomWeather = weatherConditions.get(new Random().nextInt(weatherConditions.size()));

            return location + " is " + randomWeather + " today.";
        } catch (Exception e) {
            // Tangani pengecualian untuk memastikan ketahanan program.
            return "Failed to parse the location parameter.";
        }
    }

    public static void main(String[] args) {
        try {
            // Deskripsikan (daftarkan) alat kami ke model.
            String weatherParamsSchema =
                    "{\"type\":\"object\",\"properties\":{\"location\":{\"type\":\"string\",\"description\":\"A city or county, such as Singapore or New York.\"}},\"required\":[\"location\"]}";

            FunctionDefinition weatherFunction = FunctionDefinition.builder()
                    .name("get_current_weather") // Pengidentifikasi unik alat, harus sesuai dengan implementasi lokal.
                    .description("Useful when you want to query the weather for a specified city.") // Deskripsi yang jelas membantu model menentukan kapan menggunakan alat.
                    .parameters(JsonUtils.parseString(weatherParamsSchema).getAsJsonObject())
                    .build();
            // Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti url dengan https://dashscope.aliyuncs.com/api/v1.        
            Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
            String userInput = "What's the weather like in Singapore?";

            List<Message> messages = new ArrayList<>();
            messages.add(Message.builder().role(Role.USER.getValue()).content(userInput).build());

            // Lakukan panggilan model pertama. Kirim permintaan pengguna dan daftar alat yang ditentukan ke model.
            GenerationParam param = GenerationParam.builder()
                    .model("qwen-plus") // Tentukan model yang akan dipanggil.
                    .apiKey(System.getenv("DASHSCOPE_API_KEY")) // Dapatkan Kunci API dari variabel lingkungan. Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
                    .messages(messages) // Kirim riwayat percakapan saat ini.
                    .tools(Arrays.asList(ToolFunction.builder().function(weatherFunction).build())) // Kirim daftar alat yang tersedia.
                    .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                    .build();

            GenerationResult result = gen.call(param);
            Message assistantOutput = result.getOutput().getChoices().get(0).getMessage();
            messages.add(assistantOutput); // Tambahkan balasan pertama model ke riwayat percakapan.

            // Periksa balasan model untuk menentukan apakah meminta pemanggilan alat.
            if (assistantOutput.getToolCalls() == null || assistantOutput.getToolCalls().isEmpty()) {
                // Kasus A: Model tidak memanggil alat, tetapi memberikan jawaban langsung.
                System.out.println("No weather query tool is required. Direct reply: " + assistantOutput.getContent());
            } else {
                // Kasus B: Model memutuskan untuk memanggil alat.
                // Gunakan loop while untuk menangani skenario di mana model terus-menerus memanggil alat beberapa kali.
                while (assistantOutput.getToolCalls() != null && !assistantOutput.getToolCalls().isEmpty()) {
                    ToolCallBase toolCall = assistantOutput.getToolCalls().get(0);

                    // Uraikan informasi spesifik pemanggilan alat (nama fungsi yang akan dipanggil dan parameter) dari balasan model.
                    ToolCallFunction functionCall = (ToolCallFunction) toolCall;
                    String funcName = functionCall.getFunction().getName();
                    String arguments = functionCall.getFunction().getArguments();
                    System.out.println("Calling tool [" + funcName + "], parameters: " + arguments);

                    // Jalankan metode Java lokal yang sesuai berdasarkan nama alat.
                    String toolResult = getCurrentWeather(arguments);

                    // Buat pesan dengan peran "tool", yang berisi hasil eksekusi alat.
                    Message toolMessage = Message.builder()
                            .role("tool")
                            .toolCallId(toolCall.getId())
                            .content(toolResult)
                            .build();
                    System.out.println("Tool returned: " + toolMessage.getContent());
                    messages.add(toolMessage); // Tambahkan hasil balik alat ke riwayat percakapan.

                    // Panggil model lagi.
                    param.setMessages(messages);
                    result = gen.call(param);
                    assistantOutput = result.getOutput().getChoices().get(0).getMessage();
                    messages.add(assistantOutput);
                }

                // Cetak balasan akhir yang dihasilkan model setelah diringkas.
                System.out.println("Final assistant reply: " + assistantOutput.getContent());
            }

        } catch (NoApiKeyException | InputRequiredException e) {
            System.err.println("Error: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output berikut dikembalikan:

Calling tool [get_current_weather], parameters: {'location': 'Singapore'}
Tool returned: Singapore is cloudy today.
Final assistant reply: The weather in Singapore is cloudy today.

Cara menggunakan

Pemanggilan fungsi mendukung dua cara untuk mengirimkan informasi alat:

  • Metode 1: Mengirimkan informasi menggunakan parameter tools (disarankan)

    Untuk informasi lebih lanjut, lihat Cara menggunakan. Anda dapat memanggil model dengan mengikuti langkah-langkah berikut: Definisikan alat, Buat array messages, Initiasi pemanggilan fungsi, Jalankan fungsi alat, dan Gunakan LLM untuk merangkum output fungsi alat.

  • Metode 2: Mengirimkan informasi menggunakan System Message

    Saat Anda mengirimkan informasi menggunakan parameter `tools`, sisi server secara otomatis menyesuaikan dan menyusun templat prompt yang sesuai berdasarkan model. Oleh karena itu, kami menyarankan Anda menggunakan parameter `tools`. Jika Anda tidak ingin menggunakan parameter `tools` saat menggunakan model Qwen, lihat Kirimkan informasi alat menggunakan System Message.

Konten berikut menggunakan metode pemanggilan yang kompatibel dengan OpenAI sebagai contoh. Informasi alat dikirimkan menggunakan parameter `tools` untuk memberikan panduan langkah demi langkah tentang cara menggunakan pemanggilan fungsi.

Asumsikan skenario yang melibatkan dua jenis pertanyaan: kueri cuaca dan kueri waktu.

1. Definisikan alat

Alat adalah jembatan antara LLMs dan dunia luar. Pertama, Anda perlu mendefinisikan alat-alat tersebut.

1.1. Buat fungsi alat

Anda dapat membuat dua fungsi alat: alat kueri cuaca dan alat kueri waktu.

  • Alat kueri cuaca

    Alat ini menerima parameter arguments. Format arguments adalah {"location": "lokasi kueri"}. Output alat adalah string dalam format: "{lokasi} hari ini {cuaca}".

    Untuk tujuan demonstrasi, alat kueri cuaca yang didefinisikan di sini tidak benar-benar melakukan kueri cuaca. Alat ini memilih secara acak dari cerah, berawan, atau hujan. Dalam aplikasi dunia nyata, Anda dapat menggantinya dengan alat seperti Amap Weather Query.
  • Alat kueri waktu

    Alat kueri waktu tidak memerlukan parameter input. Output alat adalah string dalam format: "Waktu saat ini: {waktu yang dikueri}.".

    Jika Anda menggunakan Node.js, Anda dapat menjalankan npm install date-fns untuk menginstal paket alat date-fns guna mendapatkan waktu.
## Langkah 1: Definisikan fungsi alat

# Tambahkan impor untuk modul random
import random
from datetime import datetime

# Simulasikan alat kueri cuaca. Contoh output: "Beijing is rainy today."
def get_current_weather(arguments):
    # Definisikan daftar kondisi cuaca alternatif
    weather_conditions = ["sunny", "cloudy", "rainy"]
    # Pilih kondisi cuaca secara acak
    random_weather = random.choice(weather_conditions)
    # Ekstrak informasi lokasi dari JSON
    location = arguments["location"]
    # Kembalikan informasi cuaca yang diformat
    return f"{location} is {random_weather} today."

# Alat untuk menanyakan waktu saat ini. Contoh output: "Current time: 2024-04-15 17:15:18."
def get_current_time():
    # Dapatkan tanggal dan waktu saat ini
    current_datetime = datetime.now()
    # Format tanggal dan waktu saat ini
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # Kembalikan waktu saat ini yang telah diformat
    return f"Current time: {formatted_time}."

# Uji fungsi alat dan tampilkan hasilnya. Anda dapat menghapus empat baris kode uji berikut saat menjalankan langkah selanjutnya.
print("Testing tool output:")
print(get_current_weather({"location": "Shanghai"}))
print(get_current_time())
print("\n")
// Langkah 1: Mendefinisikan fungsi alat

// Impor alat kueri waktu
import { format } from 'date-fns';

function getCurrentWeather(args) {
    // Mendefinisikan daftar kondisi cuaca alternatif
    const weatherConditions = ["sunny", "cloudy", "rainy"];
    // Memilih secara acak kondisi cuaca
    const randomWeather = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];
    // Mengekstrak informasi lokasi dari JSON
    const location = args.location;
    // Mengembalikan informasi cuaca yang diformat
    return `${location} is ${randomWeather} today.`;
}

function getCurrentTime() {
    // Mendapatkan tanggal dan waktu saat ini
    const currentDatetime = new Date();
    // Memformat tanggal dan waktu saat ini
    const formattedTime = format(currentDatetime, 'yyyy-MM-dd HH:mm:ss');
    // Mengembalikan waktu saat ini yang diformat
    return `Current time: ${formattedTime}.`;
}

// Menguji fungsi alat dan menampilkan hasilnya. Anda dapat menghapus empat baris kode uji berikut saat menjalankan langkah-langkah selanjutnya.
console.log("Testing tool output:")
console.log(getCurrentWeather({location:"Shanghai"}));
console.log(getCurrentTime());
console.log("\n")

Setelah menjalankan alat, output berikut dikembalikan:

Testing tool output:
Shanghai is cloudy today.
Current time: 2025-01-08 20:21:45.

1.2 Buat array tools

Sebelum manusia memilih alat, mereka perlu memahami secara komprehensif, termasuk fungsinya, kapan menggunakannya, dan parameter inputnya. LLMs juga membutuhkan informasi ini untuk memilih alat dengan lebih akurat. Anda harus memberikan informasi ini kepada LLM dalam format JSON berikut.

  • Bidang type harus berupa "function".

  • Bidang function adalah objek.

    • Bidang name adalah nama fungsi alat kustom. Kami menyarankan Anda menggunakan nama yang sama dengan fungsi, seperti get_current_weather atau get_current_time.

    • Bidang description menjelaskan fungsi alat. LLM merujuk ke bidang ini untuk memutuskan apakah akan menggunakan fungsi alat.

    • Bidang parameters, yang merupakan objek, menjelaskan parameter input fungsi alat. LLM menggunakan bidang ini untuk mengekstrak parameter input. Jika fungsi alat tidak memerlukan parameter input, Anda dapat menghilangkan bidang parameters.

      • Bidang type harus berupa "object".

      • Bidang properties adalah objek yang menjelaskan nama, tipe data, dan deskripsi setiap parameter input. Kuncinya adalah nama parameter, dan nilainya adalah objek yang berisi tipe data dan deskripsi parameter.

      • Bidang required adalah array yang menentukan parameter mana yang wajib.

Untuk alat kueri cuaca, format informasi deskripsi alat adalah sebagai berikut:

{
    "type": "function",
    "function": {
        "name": "get_current_weather",
        "description": "Useful when you want to query the weather for a specified city.",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                }
            },
            "required": ["location"]
        }
    }
}

Sebelum memulai pemanggilan fungsi, Anda harus mendefinisikan array alat dalam kode Anda. Array ini mencakup nama fungsi, deskripsi, dan definisi parameter untuk setiap alat dan dikirimkan sebagai parameter dalam permintaan selanjutnya.

# Tempelkan kode berikut setelah kode di Langkah 1.

## Langkah 2: Buat array tools

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Useful when you want to know the current time.",
            "parameters": {}
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District.",
                    }
                },
                "required": ["location"]
            }
        }
    }
]
tool_name = [tool["function"]["name"] for tool in tools]
print(f"Created {len(tools)} tools: {tool_name}\n")
// Tempelkan kode berikut setelah kode di Langkah 1.

// Langkah 2: Buat array tools

const tools = [
    {
      type: "function",
      function: {
        name: "get_current_time",
        description: "Useful when you want to know the current time.",
        parameters: {}
      }
    },
    {
      type: "function",
      function: {
        name: "get_current_weather",
        description: "Useful when you want to query the weather for a specified city.",
        parameters: {
          type: "object",
          properties: {
            location: {
              type: "string",
              description: "A city or district, such as Beijing, Hangzhou, or Yuhang District.",
            }
          },
          required: ["location"]
        }
      }
    }
  ];
  
const toolNames = tools.map(tool => tool.function.name);
console.log(`Created ${tools.length} tools: ${toolNames.join(', ')}\n`);

2. Buat array messages

Pemanggilan fungsi menggunakan array `messages` untuk mengirimkan instruksi dan konteks ke LLM. Sebelum memulai pemanggilan fungsi, array `messages` harus mencakup System Message dan User Message.

System Message

Meskipun fungsi dan penggunaan alat telah dijelaskan di Buat array tools, menekankan kapan memanggil alat dalam System Message biasanya meningkatkan akurasi pemanggilan alat. Dalam skenario ini, Anda dapat mengatur System Prompt menjadi:

You are a helpful assistant. If the user asks about the weather, call the 'get_current_weather' function;
If the user asks about the time, call the 'get_current_time' function.
Please answer in a friendly tone.

User Message

User Message mengirimkan pertanyaan pengguna ke model. Misalnya, jika pengguna bertanya "Shanghai weather", array `messages` adalah sebagai berikut:

# Langkah 3: Buat array messages
# Tempelkan kode berikut setelah kode di Langkah 2.
# Contoh User Message untuk model generasi teks
messages = [
    {
        "role": "system",
        "content": """You are a helpful assistant. If the user asks about the weather, call the 'get_current_weather' function;
     If the user asks about the time, call the 'get_current_time' function.
     Please answer in a friendly tone.""",
    },
    {
        "role": "user",
        "content": "Shanghai weather"
    }
]

# Contoh User Message untuk model multimodal
# messages=[
#  {
#         "role": "system",
#         "content": """You are a helpful assistant. If the user asks about the weather, call the 'get_current_weather' function;
#      If the user asks about the time, call the 'get_current_time' function.
#      Please answer in a friendly tone.""",
#     },
#     {"role": "user",
#      "content": [{"type": "image_url","image_url": {"url": "https://img.alicdn.com/imgextra/i2/O1CN01FbTJon1ErXVGMRdsN_!!6000000000405-0-tps-1024-683.jpg"}},
#                  {"type": "text", "text": "Based on the location in the image, query the current weather for that location"}]},
# ]

print("messages array created\n") 
// Langkah 3: Buat array messages
// Tempelkan kode berikut setelah kode di Langkah 2.
const messages = [
    {
        role: "system",
        content: "You are a helpful assistant. If the user asks about the weather, call the 'get_current_weather' function; If the user asks about the time, call the 'get_current_time' function. Please answer in a friendly tone.",
    },
    {
        role: "user",
        content: "Shanghai weather"
    }
];
// Contoh User Message untuk model multimodal,
// const messages: [{
//     role: "user",
//     content: [{type: "image_url", image_url: {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"}},
//               {type: "text", text: "What scene is depicted in the image?"}]
//   }];

console.log("messages array created\n");
Karena alat yang tersedia mencakup kueri cuaca dan waktu, Anda juga dapat menanyakan waktu saat ini.

3. Initiasi pemanggilan fungsi

Kirimkan tools dan messages yang telah dibuat ke LLM untuk memulai pemanggilan fungsi. LLM kemudian akan menentukan apakah perlu memanggil alat. Jika alat dipanggil, LLM mengembalikan nama fungsinya dan parameter-parameternya.

Untuk informasi lebih lanjut tentang model yang didukung, lihat Model yang didukung.
# Langkah 4: Initiasi pemanggilan fungsi
# Tempelkan kode berikut setelah kode di Langkah 3.
from openai import OpenAI
import os

client = OpenAI(
    # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti base_url dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

def function_calling():
    completion = client.chat.completions.create(
        # Contoh ini menggunakan qwen-plus. Anda dapat menggantinya dengan nama model lain sesuai kebutuhan. Untuk daftar model, lihat https://www.alibabacloud.com/help/document_detail/2751232.html
        model="qwen-plus",
        messages=messages,
        tools=tools
    )
    print("Returned object:")
    print(completion.choices[0].message.model_dump_json())
    print("\n")
    return completion

print("Initiating function calling...")
completion = function_calling()
// Langkah 4: Initiasi pemanggilan fungsi
// Tempelkan kode berikut setelah kode di Langkah 3.
import OpenAI from "openai";
const openai = new OpenAI(
    {
        // Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
        // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: apiKey: "sk-xxx",
        apiKey: process.env.DASHSCOPE_API_KEY,
        // Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti baseURL dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);

async function functionCalling() {
    const completion = await openai.chat.completions.create({
        model: "qwen-plus",  // Contoh ini menggunakan qwen-plus. Anda dapat menggantinya dengan nama model lain sesuai kebutuhan. Untuk daftar model, lihat https://www.alibabacloud.com/help/document_detail/2751232.html
        messages: messages,
        tools: tools
    });
    console.log("Returned object:");
    console.log(JSON.stringify(completion.choices[0].message));
    console.log("\n");
    return completion;
}

const completion = await functionCalling();

Karena pengguna menanyakan tentang cuaca di Shanghai, LLM menentukan "get_current_weather" sebagai fungsi alat dan "{\"location\": \"Shanghai\"}" sebagai parameter input.

{
    "content": "",
    "refusal": null,
    "role": "assistant",
    "audio": null,
    "function_call": null,
    "tool_calls": [
        {
            "id": "call_6596dafa2a6a46f7a217da",
            "function": {
                "arguments": "{\"location\": \"Shanghai\"}",
                "name": "get_current_weather"
            },
            "type": "function",
            "index": 0
        }
    ]
}

Perhatikan bahwa jika LLM menentukan bahwa alat tidak diperlukan, LLM akan membalas langsung menggunakan parameter content. Misalnya, jika Anda menginput "Hello", parameter tool_calls kosong, dan objek yang dikembalikan memiliki format berikut:

{
    "content": "Hello! How can I help you? If you have questions about weather or time, I'm particularly good at answering them.",
    "refusal": null,
    "role": "assistant",
    "audio": null,
    "function_call": null,
    "tool_calls": null
}
Jika parameter tool_calls kosong, program Anda dapat langsung mengembalikan content dan melewati langkah-langkah berikutnya.
Jika Anda ingin LLM memilih alat tertentu untuk setiap pemanggilan fungsi, lihat Pemanggilan alat paksa.

4. Jalankan fungsi alat

Menjalankan fungsi alat adalah langkah kunci yang mengubah keputusan LLM menjadi operasi nyata.

Lingkungan komputasi Anda, bukan LLM, yang menjalankan fungsi alat.

Karena LLM hanya dapat mengeluarkan konten sebagai string, Anda perlu mengurai nama fungsi alat dan parameter input dari respons string sebelum dapat menjalankan fungsi alat.

  • Fungsi alat

    Buat pemetaan function_mapper dari nama fungsi alat ke entitas fungsi alat untuk menyelesaikan string fungsi alat yang dikembalikan ke entitas yang sesuai.

  • Parameter input

    Parameter input dikembalikan sebagai string JSON. Anda harus mengurai string ini menjadi objek JSON untuk mengekstrak informasi parameternya.

Setelah penguraian selesai, Anda dapat mengirimkan parameter ke fungsi alat dan mengeksekusinya untuk mendapatkan output.

# Langkah 5: Jalankan fungsi alat
# Tempelkan kode berikut setelah kode di Langkah 4.
import json

print("Running the tool function...")
# Dapatkan nama fungsi dan parameter input dari hasil yang dikembalikan
function_name = completion.choices[0].message.tool_calls[0].function.name
arguments_string = completion.choices[0].message.tool_calls[0].function.arguments

# Gunakan modul json untuk mengurai string parameter
arguments = json.loads(arguments_string)
# Buat tabel pemetaan fungsi
function_mapper = {
    "get_current_weather": get_current_weather,
    "get_current_time": get_current_time
}
# Dapatkan entitas fungsi
function = function_mapper[function_name]
# Jika parameter input kosong, panggil fungsi langsung
if arguments == {}:
    function_output = function()
# Jika tidak, panggil fungsi dengan parameter input
else:
    function_output = function(arguments)
# Cetak output alat
print(f"Tool function output: {function_output}\n")
// Langkah 5: Jalankan fungsi alat
// Tempelkan kode berikut setelah kode di Langkah 4.

console.log("Running the tool function...");
const function_name = completion.choices[0].message.tool_calls[0].function.name;
const arguments_string = completion.choices[0].message.tool_calls[0].function.arguments;

// Gunakan modul JSON untuk mengurai string parameter
const args = JSON.parse(arguments_string);

// Buat tabel pemetaan fungsi
const functionMapper = {
    "get_current_weather": getCurrentWeather,
    "get_current_time": getCurrentTime
};

// Dapatkan entitas fungsi
const func = functionMapper[function_name];

// Jika parameter input kosong, panggil fungsi langsung
let functionOutput;
if (Object.keys(args).length === 0) {
    functionOutput = func();
} else {
    // Jika tidak, panggil fungsi dengan parameter input
    functionOutput = func(args);
}

// Cetak output alat
console.log(`Tool function output: ${functionOutput}\n`);

Output berikut dikembalikan:

Shanghai is cloudy today.
Catatan

Dalam aplikasi dunia nyata, fungsi inti banyak alat adalah melakukan operasi spesifik, seperti mengirim email atau mengunggah file, daripada mengkueri data. Alat-alat ini mungkin tidak mengeluarkan string setelah eksekusi. Untuk membantu LLM memahami status eksekusi alat, kami menyarankan Anda merancang alat tersebut agar mengembalikan informasi status, seperti "Email sent" atau "Operation failed".

5. Minta LLM merangkum output fungsi alat

Output dari fungsi alat seringkali terstruktur dan tidak bersifat percakapan. Untuk menghasilkan respons dalam bahasa alami, Anda dapat mengirimkan output alat kembali ke model bersama dengan konteks sebelumnya. Model kemudian akan mensintesis informasi tersebut untuk membuat balasan yang ramah pengguna.

  1. Tambahkan Assistant Message

    Setelah Anda menginisiasi pemanggilan fungsi, Anda dapat mengambil Assistant Message dari completion.choices[0].message dan menambahkannya ke array `messages`.

  2. Tambahkan Tool Message

    Anda dapat menambahkan output alat ke array `messages` menggunakan format {"role": "tool", "content": "output alat","tool_call_id": completion.choices[0].message.tool_calls[0].id}.

    Catatan
    • Pastikan output alat berupa string.

    • tool_call_id adalah pengidentifikasi unik yang dihasilkan sistem untuk setiap permintaan pemanggilan alat. Model mungkin meminta untuk memanggil beberapa alat sekaligus. Saat Anda mengembalikan beberapa hasil alat ke model, tool_call_id memastikan bahwa setiap output alat dicocokkan dengan permintaannya yang sesuai.

# Langkah 6: Kirimkan output alat ke LLM
# Tempelkan kode berikut setelah kode di Langkah 5.

messages.append(completion.choices[0].message)
print("Added assistant message")
messages.append({"role": "tool", "content": function_output, "tool_call_id": completion.choices[0].message.tool_calls[0].id})
print("Added tool message\n")
// Langkah 6: Kirimkan output alat ke LLM
// Tempelkan kode berikut setelah kode di Langkah 5.

messages.push(completion.choices[0].message);
console.log("Added assistant message")
messages.push({
    "role": "tool",
    "content": functionOutput,
    "tool_call_id": completion.choices[0].message.tool_calls[0].id
});
console.log("Added tool message\n");

Array `messages` sekarang:

[
  System Message -- Memandu strategi pemanggilan alat model
  User Message -- Pertanyaan pengguna
  Assistant Message -- Informasi pemanggilan alat yang dikembalikan model
  Tool Message -- Informasi output alat (jika menggunakan pemanggilan alat paralel seperti dijelaskan di bawah, mungkin ada beberapa Tool Message)
]

Setelah memperbarui array `messages`, jalankan kode berikut.

# Langkah 7: Minta LLM merangkum output alat
# Tempelkan kode berikut setelah kode di Langkah 6.
print("Summarizing tool output...")
completion = function_calling()
// Langkah 7: Minta LLM merangkum output alat
// Tempelkan kode berikut setelah kode di Langkah 6.

console.log("Summarizing tool output...");
const completion_1 = await functionCalling();

Anda dapat mengambil balasan akhir dari bidang content: "Cuaca di Shanghai hari ini berawan. Jika Anda memiliki pertanyaan lain, jangan ragu untuk bertanya."

{
    "content": "The weather in Shanghai today is cloudy. If you have any other questions, feel free to ask.",
    "refusal": null,
    "role": "assistant",
    "audio": null,
    "function_call": null,
    "tool_calls": null
}

Ini menyelesaikan proses pemanggilan fungsi.

Penggunaan lanjutan

Tentukan perilaku pemanggilan alat

Pemanggilan alat paralel

Kueri cuaca untuk satu kota hanya memerlukan satu pemanggilan alat. Namun, jika pertanyaan memerlukan beberapa pemanggilan alat, seperti "Bagaimana cuaca di Beijing dan Shanghai?" atau "Bagaimana cuaca di Hangzhou, dan jam berapa sekarang?", model mungkin hanya mengembalikan satu pemanggilan alat setelah Anda menginisiasi pemanggilan fungsi. Misalnya, untuk pertanyaan "Bagaimana cuaca di Beijing dan Shanghai?", model mungkin mengembalikan hal berikut:

{
    "content": "",
    "refusal": null,
    "role": "assistant",
    "audio": null,
    "function_call": null,
    "tool_calls": [
        {
            "id": "call_61a2bbd82a8042289f1ff2",
            "function": {
                "arguments": "{\"location\": \"Beijing\"}",
                "name": "get_current_weather"
            },
            "type": "function",
            "index": 0
        }
    ]
}

Hasilnya hanya berisi informasi untuk Beijing. Untuk mengatasi hal ini, Anda dapat mengatur parameter permintaan parallel_tool_calls ke true saat Anda menginisiasi pemanggilan fungsi. Objek yang dikembalikan kemudian akan berisi semua fungsi alat yang diperlukan dan parameter inputnya.

Catatan

Pemanggilan alat paralel cocok untuk tugas-tugas yang saling independen. Jika tugas saling bergantung, misalnya input alat A bergantung pada output alat B, Anda harus mengimplementasikan pemanggilan alat serial. Untuk informasi lebih lanjut, lihat Memulai dan implementasikan pemanggilan alat serial menggunakan loop `while`.

def function_calling():
    completion = client.chat.completions.create(
        model="qwen-plus",  # Contoh ini menggunakan qwen-plus. Anda dapat menggantinya dengan nama model lain sesuai kebutuhan.
        messages=messages,
        tools=tools,
        # Parameter baru
        parallel_tool_calls=True
    )
    print("Returned object:")
    print(completion.choices[0].message.model_dump_json())
    print("\n")
    return completion

print("Initiating function calling...")
completion = function_calling()
async function functionCalling() {
    const completion = await openai.chat.completions.create({
        model: "qwen-plus",  // Contoh ini menggunakan qwen-plus. Anda dapat menggantinya dengan nama model lain sesuai kebutuhan.
        messages: messages,
        tools: tools,
        parallel_tool_calls: true
    });
    console.log("Returned object:");
    console.log(JSON.stringify(completion.choices[0].message));
    console.log("\n");
    return completion;
}

const completion = await functionCalling();

Array tool_calls dalam objek yang dikembalikan sekarang berisi parameter input untuk Beijing dan Shanghai:

{
    "content": "",
    "role": "assistant",
    "tool_calls": [
        {
            "function": {
                "name": "get_current_weather",
                "arguments": "{\"location\": \"Beijing\"}"
            },
            "index": 0,
            "id": "call_c2d8a3a24c4d4929b26ae2",
            "type": "function"
        },
        {
            "function": {
                "name": "get_current_weather",
                "arguments": "{\"location\": \"Shanghai\"}"
            },
            "index": 1,
            "id": "call_dc7f2f678f1944da9194cd",
            "type": "function"
        }
    ]
}

Pemanggilan alat paksa

Konten yang dihasilkan LLMs bersifat non-deterministik, dan terkadang mereka memilih alat yang salah. Jika Anda ingin LLM menggunakan strategi tertentu untuk jenis pertanyaan tertentu, seperti memaksanya menggunakan alat tertentu atau tidak menggunakan alat sama sekali, Anda dapat mengatur parameter tool_choice. Nilai default tool_choice adalah "auto", yang memungkinkan LLM memutuskan apakah akan memanggil alat dan alat mana yang akan dipanggil.

Saat Anda meminta LLM untuk merangkum output fungsi alat, hapus parameter tool_choice. Jika tidak, API akan mengembalikan informasi pemanggilan alat lagi.
  • Paksa penggunaan alat tertentu

    Jika Anda ingin memaksa model memanggil alat tertentu untuk jenis pertanyaan tertentu, Anda dapat mengatur parameter tool_choice ke {"type": "function", "function": {"name": "the_function_to_call"}}. LLM tidak akan memilih alat dan hanya akan mengeluarkan parameter input untuk fungsi yang ditentukan.

    Misalnya, jika skenario saat ini hanya melibatkan kueri cuaca, Anda dapat memodifikasi kode pemanggilan fungsi sebagai berikut:

    def function_calling():
        completion = client.chat.completions.create(
            model="qwen-plus",
            messages=messages,
            tools=tools,
            tool_choice={"type": "function", "function": {"name": "get_current_weather"}}
        )
        print(completion.model_dump_json())
    
    function_calling()
    async function functionCalling() {
        const response = await openai.chat.completions.create({
            model: "qwen-plus",
            messages: messages,
            tools: tools,
            tool_choice: {"type": "function", "function": {"name": "get_current_weather"}}
        });
        console.log("Returned object:");
        console.log(JSON.stringify(response.choices[0].message));
        console.log("\n");
        return response;
    }
    
    const response = await functionCalling();

    Tidak peduli pertanyaan apa yang diinput, fungsi alat dalam objek yang dikembalikan akan selalu menjadi get_current_weather.

    Sebelum menggunakan strategi ini, pastikan pertanyaan pengguna terkait dengan alat yang dipilih. Jika tidak, model mungkin mengembalikan hasil yang tidak terduga.
  • Paksa tidak menggunakan alat

    Jika Anda ingin pemanggilan fungsi tidak pernah melakukan pemanggilan alat untuk setiap pertanyaan input—artinya, objek yang dikembalikan berisi konten balasan di bidang content dan parameter tool_calls kosong—Anda dapat mengatur parameter tool_choice ke "none" atau menghilangkan parameter tools. Dalam kasus ini, parameter tool_calls yang dikembalikan oleh pemanggilan fungsi selalu kosong.

    Misalnya, jika tidak ada pertanyaan dalam skenario saat ini yang memerlukan pemanggilan alat, Anda dapat memodifikasi kode pemanggilan fungsi sebagai berikut:

    def function_calling():
        completion = client.chat.completions.create(
            model="qwen-plus",
            messages=messages,
            tools=tools,
            tool_choice="none"
        )
        print(completion.model_dump_json())
    
    function_calling()
    async function functionCalling() {
        const completion = await openai.chat.completions.create({
            model: "qwen-plus",
            messages: messages,
            tools: tools,
            tool_choice: "none"
        });
        console.log("Returned object:");
        console.log(JSON.stringify(completion.choices[0].message));
        console.log("\n");
        return completion;
    }
    
    const completion = await functionCalling();

Percakapan multi-putaran

Pengguna mungkin bertanya, "Bagaimana cuaca di Beijing?" lalu menindaklanjuti dengan, "Bagaimana dengan Shanghai?" Jika konteks model tidak mencakup pertanyaan pertama, model tidak dapat menentukan alat mana yang akan dipanggil untuk pertanyaan kedua. Untuk percakapan multi-putaran, kami menyarankan Anda mempertahankan array `messages` sepanjang percakapan. Anda dapat menambahkan User Message baru ke array yang ada sebelum Anda menginisiasi pemanggilan fungsi dan melakukan langkah-langkah selanjutnya. Struktur `messages` adalah sebagai berikut:

[
  System Message -- Memandu strategi pemanggilan alat model
  User Message -- Pertanyaan pengguna
  Assistant Message -- Informasi pemanggilan alat yang dikembalikan model
  Tool Message -- Informasi output alat
  Assistant Message -- Ringkasan model atas informasi pemanggilan alat
  User Message -- Pertanyaan putaran kedua pengguna
]

Keluaran streaming

Untuk meningkatkan pengalaman pengguna dan mengurangi waktu tunggu, Anda dapat menggunakan keluaran streaming untuk mengambil nama fungsi alat dan parameter input secara real time. Dalam kasus ini:

  • Parameter pemanggilan alat dikembalikan dalam potongan sebagai aliran data.

  • Nama fungsi alat dikembalikan di blok data pertama dari respons streaming.

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District.",
                    }
                },
                "required": ["location"],
            },
        },
    },
]

stream = client.chat.completions.create(
    model="qwen-plus",
    messages=[{"role": "user", "content": "Hangzhou weather?"}],
    tools=tools,
    stream=True
)

for chunk in stream:
    delta = chunk.choices[0].delta
    print(delta.tool_calls)
import { OpenAI } from "openai";

const openai = new OpenAI(
    {
        // Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
        // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: apiKey: "sk-xxx",
        apiKey: process.env.DASHSCOPE_API_KEY,
        // Jika Anda menggunakan model di wilayah Beijing, ganti baseURL dengan: https://dashscope.aliyuncs.com/compatible-mode/v1
        baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
    }
);
const tools = [
    {
        "type": "function",
        "function": {
            "name": "getCurrentWeather",
            "description": "This function is useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city or county-level district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]
            }
        }
    }
];

const stream = await openai.chat.completions.create({
    model: "qwen-plus",
    messages: [{ role: "user", content: "Beijing weather" }],
    tools: tools,
    stream: true,
});

for await (const chunk of stream) {
    const delta = chunk.choices[0].delta;
    console.log(delta.tool_calls);
}

Output berikut dikembalikan:

[ChoiceDeltaToolCall(index=0, id='call_8f08d2b0fc0c4d8fab7123', function=ChoiceDeltaToolCallFunction(arguments='{"location":', name='get_current_weather'), type='function')]
[ChoiceDeltaToolCall(index=0, id='', function=ChoiceDeltaToolCallFunction(arguments=' "Hangzhou"}', name=None), type='function')]
None

Anda dapat menjalankan kode berikut untuk merakit parameter input (arguments):

tool_calls = {}
for response_chunk in stream:
    delta_tool_calls = response_chunk.choices[0].delta.tool_calls
    if delta_tool_calls:
        for tool_call_chunk in delta_tool_calls:
            call_index = tool_call_chunk.index
            tool_call_chunk.function.arguments = tool_call_chunk.function.arguments or ""
            if call_index not in tool_calls:
                tool_calls[call_index] = tool_call_chunk
            else:
                tool_calls[call_index].function.arguments += tool_call_chunk.function.arguments
print(tool_calls[0].model_dump_json())
const toolCalls = {};
for await (const responseChunk of stream) {
  const deltaToolCalls = responseChunk.choices[0]?.delta?.tool_calls;
  if (deltaToolCalls) {
    for (const toolCallChunk of deltaToolCalls) {
      const index = toolCallChunk.index;
      toolCallChunk.function.arguments = toolCallChunk.function.arguments || "";
      if (!toolCalls[index]) {
        toolCalls[index] = { ...toolCallChunk };
        if (!toolCalls[index].function) {
            toolCalls[index].function = { name: '', arguments: '' };
        }
      } 
      else if (toolCallChunk.function?.arguments) {
        toolCalls[index].function.arguments += toolCallChunk.function.arguments;
      }
    }
  }
}
console.log(JSON.stringify(toolCalls[0]));

Output berikut dikembalikan:

{"index":0,"id":"call_16c72bef988a4c6c8cc662","function":{"arguments":"{\"location\": \"Hangzhou\"}","name":"get_current_weather"},"type":"function"}

Dalam langkah di mana LLM merangkum output fungsi alat, Assistant Message yang Anda tambahkan harus sesuai dengan format berikut. Anda hanya perlu mengganti elemen dalam tool_calls dengan konten dari langkah sebelumnya.

{
    "content": "",
    "refusal": None,
    "role": "assistant",
    "audio": None,
    "function_call": None,
    "tool_calls": [
        {
            "id": "call_xxx",
            "function": {
                "arguments": '{"location": "xx"}',
                "name": "get_current_weather",
            },
            "type": "function",
            "index": 0,
        }
    ],
}

Pemanggilan alat dengan Responses API

Contoh sebelumnya mengimplementasikan pemanggilan alat menggunakan API OpenAI Chat Completions dan DashScope. Jika Anda menggunakan OpenAI Responses API, proses keseluruhan sama, tetapi format antarmuka memiliki perbedaan berikut:

Dimensi

Chat Completions

Responses API

base_url

https://dashscope-intl.aliyuncs.com/compatible-mode/v1

https://dashscope-intl.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1

Format definisi alat

{
    "type": "function",
    "function": {
        "name":...,
        "parameters":...
    }
}
{
    "type": "function",
    "name":...,
    "parameters":...
}

Output pemanggilan alat

response.choices[0].message.tool_calls

Item dalam response.output dengan tipe function_call

Umpan balik hasil alat

{
    "role": "tool",
    "tool_call_id":...,
    "content":...
}
{
    "type": "function_call_output",
    "call_id":...,
    "output":...
}

Respons akhir

response.choices[0].message.content

response.output_text

from openai import OpenAI
import json
import os
import random

# Inisialisasi klien.
client = OpenAI(
    # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Alibaba Cloud Model Studio Anda: api_key="sk-xxx",
    # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1",
)
# Simulasikan pertanyaan pengguna.
USER_QUESTION = "What's the weather like in Singapore?"
# Definisikan daftar alat.
tools = [
    {
        "type": "function",
        "name": "get_current_weather",
        "description": "Useful when you want to query the weather for a specified city.",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "A city or county, such as Singapore or London.",
                }
            },
            "required": ["location"],
        },
    }
]


# Simulasikan alat kueri cuaca.
def get_current_weather(arguments):
    weather_conditions = ["sunny", "cloudy", "rainy"]
    random_weather = random.choice(weather_conditions)
    location = arguments["location"]
    return f"{location} is {random_weather} today."


# Enkapsulasi fungsi respons model.
def get_response(input_data):
    response = client.responses.create(
        model="qwen3.5-plus",  # Opsi: qwen3.5-flash, qwen3.5-flash-2026-02-23
        input=input_data,
        tools=tools,
    )
    return response


# Pertahankan konteks percakapan.
conversation = [{"role": "user", "content": USER_QUESTION}]

response = get_response(conversation)
function_calls = [item for item in response.output if item.type == "function_call"]
# Jika tidak diperlukan alat, langsung keluarkan kontennya.
if not function_calls:
    print(f"Final assistant reply: {response.output_text}")
else:
    # Masuk ke loop pemanggilan alat.
    while function_calls:
        for fc in function_calls:
            func_name = fc.name
            arguments = json.loads(fc.arguments)
            print(f"Calling tool [{func_name}], parameters: {arguments}")
            # Jalankan alat.
            tool_result = get_current_weather(arguments)
            print(f"Tool returned: {tool_result}")
            # Tambahkan pemanggilan alat dan hasilnya ke konteks berpasangan.
            conversation.append(
                {
                    "type": "function_call",
                    "name": fc.name,
                    "arguments": fc.arguments,
                    "call_id": fc.call_id,
                }
            )
            conversation.append(
                {
                    "type": "function_call_output",
                    "call_id": fc.call_id,
                    "output": tool_result,
                }
            )
        # Panggil model lagi dengan konteks lengkap.
        response = get_response(conversation)
        function_calls = [
            item for item in response.output if item.type == "function_call"
        ]
    print(f"Final assistant reply: {response.output_text}")
import OpenAI from "openai";

// Inisialisasi klien
const openai = new OpenAI({
  // Kunci API bervariasi menurut wilayah. Dapatkan kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
  // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan kunci API Alibaba Cloud Model Studio Anda: apiKey: "sk-xxx",
  apiKey: process.env.DASHSCOPE_API_KEY,
  baseURL:
    "https://dashscope-intl.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1",
});

// Tentukan daftar alat
const tools = [
  {
    type: "function",
    name: "get_current_weather",
    description: "Berguna saat Anda ingin membuat kueri cuaca untuk kota tertentu.",
    parameters: {
      type: "object",
      properties: {
        location: {
          type: "string",
          description: "Kota atau wilayah, seperti Singapura atau London.",
        },
      },
      required: ["location"],
    },
  },
];

// Simulasikan alat kueri cuaca
const getCurrentWeather = (args) => {
  const weatherConditions = ["sunny", "cloudy", "rainy"];
  const randomWeather =
    weatherConditions[Math.floor(Math.random() * weatherConditions.length)];
  const location = args.location;
  return `${location} is ${randomWeather} today.`;
};

// Bungkus fungsi tanggapan model
const getResponse = async (inputData) => {
  const response = await openai.responses.create({
    model: "qwen3.5-plus",  // Opsi: qwen3.5-flash, qwen3.5-flash-2026-02-23
    input: inputData,
    tools: tools,
  });
  return response;
};

const main = async () => {
  const userQuestion = "Singapore weather";

  // Pertahankan konteks percakapan
  const conversation = [{ role: "user", content: userQuestion }];

  let response = await getResponse(conversation);
  let functionCalls = response.output.filter(
    (item) => item.type === "function_call"
  );
  // Jika tidak ada alat yang perlu dipanggil, langsung keluarkan kontennya
  if (functionCalls.length === 0) {
    console.log(`Final assistant response: ${response.output_text}`);
  } else {
    // Masuk ke loop pemanggilan alat
    while (functionCalls.length > 0) {
      for (const fc of functionCalls) {
        const funcName = fc.name;
        const args = JSON.parse(fc.arguments);
        console.log(`Calling the tool [${funcName}], parameters:`, args);
        // Jalankan alat
        const toolResult = getCurrentWeather(args);
        console.log(`Tool output: ${toolResult}`);
        // Tambahkan setiap panggilan alat dan hasilnya ke konteks percakapan sebagai pasangan
        conversation.push({
          type: "function_call",
          name: fc.name,
          arguments: fc.arguments,
          call_id: fc.call_id,
        });
        conversation.push({
          type: "function_call_output",
          call_id: fc.call_id,
          output: toolResult,
        });
      }
      // Panggil model lagi dengan konteks percakapan yang lengkap
      response = await getResponse(conversation);
      functionCalls = response.output.filter(
        (item) => item.type === "function_call"
      );
    }
    console.log(`Final assistant response: ${response.output_text}`);
  }
};

// Jalankan program
main().catch(console.error);

Pemanggilan alat untuk model Qwen3-Omni-Flash

Dalam fase pengambilan informasi alat, penggunaan model Qwen3-Omni-Flash berbeda dari model lain dalam hal-hal berikut:

  • Keluaran streaming wajib: Qwen3-Omni-Flash hanya mendukung keluaran streaming. Saat mengambil informasi alat, Anda harus mengatur stream=True.

  • Keluaran teks saja disarankan: Model hanya memerlukan informasi teks untuk mengambil nama dan parameter fungsi. Untuk menghindari pembuatan audio yang tidak perlu, kami menyarankan Anda mengatur modalities=["text"]. Jika keluaran mencakup modalitas teks dan audio, Anda harus melewatkan blok data audio saat mengambil informasi alat.

Untuk informasi lebih lanjut tentang Qwen3-Omni-Flash, lihat Asinkron (Qwen-Omni).
from openai import OpenAI
import os

client = OpenAI(
    # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District.",
                    }
                },
                "required": ["location"],
            },
        },
    },
]

completion = client.chat.completions.create(
    model="qwen3-omni-flash",
    messages=[{"role": "user", "content": "Hangzhou weather?"}],

    # Atur modalitas data keluaran. Nilai valid: ["text"], ["text","audio"]. Kami menyarankan mengatur ke ["text"].
    modalities=["text"],

    # stream harus diatur ke True, jika tidak akan terjadi error.
    stream=True,
    tools=tools
)

for chunk in completion:
    # Jika keluaran mencakup modalitas audio, ubah kondisi berikut menjadi: if chunk.choices and not hasattr(chunk.choices[0].delta, "audio"): 
    if chunk.choices:
        delta = chunk.choices[0].delta
        print(delta.tool_calls)
import { OpenAI } from "openai";

const openai = new OpenAI(
    {
        // Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
        // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: apiKey: "sk-xxx",
        apiKey: process.env.DASHSCOPE_API_KEY,
        // Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti baseURL dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const tools = [
    {
        "type": "function",
        "function": {
            "name": "getCurrentWeather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]
            }
        }
    }
];

const stream = await openai.chat.completions.create({
    model: "qwen3-omni-flash",
    messages: [
        {
            "role": "user",
            "content": "Hangzhou weather"
        }],
    stream: true,
    // Atur modalitas data keluaran. Nilai valid: ["text"], ["text","audio"]. Kami menyarankan mengatur ke ["text"].
    modalities: ["text"],
    tools:tools
});


for await (const chunk of stream) {
    // Jika keluaran mencakup audio, ganti pernyataan kondisional dengan: if (chunk.choices?.length && chunk.choices[0].delta && !('audio' in chunk.choices[0].delta)) 
    if (chunk.choices?.length){
    const delta = chunk.choices[0].delta;
    console.log(delta.tool_calls);
}}

Output berikut dikembalikan.

[ChoiceDeltaToolCall(index=0, id='call_391c8e5787bc4972a388aa', function=ChoiceDeltaToolCallFunction(arguments=None, name='get_current_weather'), type='function')]
[ChoiceDeltaToolCall(index=0, id='call_391c8e5787bc4972a388aa', function=ChoiceDeltaToolCallFunction(arguments=' {"location": "Hangzhou"}', name=None), type='function')]
None

Untuk kode yang merakit informasi parameter input (arguments, lihat Keluaran streaming.

Pemanggilan alat untuk model pemikiran mendalam

Model pemikiran mendalam melakukan penalaran sebelum mengeluarkan informasi pemanggilan alat, yang dapat meningkatkan interpretabilitas dan keandalan keputusannya.

  1. Proses penalaran

    Model secara progresif menganalisis maksud pengguna, mengidentifikasi alat yang diperlukan, memverifikasi validitas parameter, dan merencanakan strategi pemanggilan.

  2. Pemanggilan alat

    Model mengeluarkan satu atau beberapa permintaan pemanggilan fungsi dalam format terstruktur.

    Pemanggilan alat paralel didukung.

Contoh berikut menunjukkan pemanggilan alat streaming untuk model pemikiran mendalam.

Untuk model teks generasi pemikiran mendalam, lihat Pemikiran mendalam. Untuk model pemikiran mendalam multimodal, lihat Pemahaman gambar dan video dan Asinkron (Qwen-Omni).
tool_choice hanya mendukung "auto" (nilai default, yang memungkinkan model memilih alat) atau "none" (yang memaksa model tidak memilih alat).

Kompatibel dengan OpenAI

Python

Kode contoh

import os
from openai import OpenAI

# Inisialisasi klien OpenAI dan konfigurasikan layanan Alibaba Cloud DashScope.
client = OpenAI(
    # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Alibaba Cloud Model Studio Anda: api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),  # Baca Kunci API dari variabel lingkungan.
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

# Definisikan daftar alat yang tersedia.
tools = [
    # Alat 1: Dapatkan waktu saat ini.
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Useful when you want to know the current time.",
            "parameters": {}  # Tidak memerlukan parameter.
        }
    },  
    # Alat 2: Dapatkan cuaca untuk kota tertentu.
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {  
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]  # Parameter wajib.
            }
        }
    }
]

messages = [{"role": "user", "content": input("Please enter your question: ")}]

# contoh pesan untuk model multimodal
# messages = [{
#     "role": "user",
#     "content": [
#              {"type": "image_url","image_url": {"url": "https://img.alicdn.com/imgextra/i4/O1CN014CJhzi20NOzo7atOC_!!6000000006837-2-tps-2048-1365.png"}},
#              {"type": "text", "text": "Based on the location in the image, what is the current weather at that location?"}]
#     }]

completion = client.chat.completions.create(
    # Contoh ini menggunakan qwen-plus. Anda dapat menggantinya dengan model pemikiran mendalam lainnya.
    model="qwen-plus",
    messages=messages,
    extra_body={
        # Aktifkan pemikiran mendalam. Parameter ini tidak valid untuk model qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, dan QwQ.
        "enable_thinking": True
    },
    tools=tools,
    parallel_tool_calls=True,
    stream=True,
    # Hapus komentar untuk mendapatkan informasi konsumsi token.
    # stream_options={
    #     "include_usage": True
    # }
)

reasoning_content = ""  # Definisikan proses penalaran lengkap.
answer_content = ""     # Definisikan balasan lengkap.
tool_info = []          # Simpan informasi pemanggilan alat.
is_answering = False   # Tentukan apakah akan mengakhiri proses penalaran dan mulai membalas.
print("="*20+"Reasoning process"+"="*20)
for chunk in completion:
    if not chunk.choices:
        # Proses statistik penggunaan.
        print("\n"+"="*20+"Usage"+"="*20)
        print(chunk.usage)
    else:
        delta = chunk.choices[0].delta
        # Proses proses penalaran AI (rantai pemikiran).
        if hasattr(delta, 'reasoning_content') and delta.reasoning_content is not None:
            reasoning_content += delta.reasoning_content
            print(delta.reasoning_content,end="",flush=True)  # Streaming proses penalaran secara real time.
            
        # Proses konten balasan akhir.
        else:
            if not is_answering:  # Cetak judul saat pertama kali memasuki fase balasan.
                is_answering = True
                print("\n"+"="*20+"Reply content"+"="*20)
            if delta.content is not None:
                answer_content += delta.content
                print(delta.content,end="",flush=True)  # Streaming konten balasan.
            
            # Proses informasi pemanggilan alat (mendukung pemanggilan alat paralel).
            if delta.tool_calls is not None:
                for tool_call in delta.tool_calls:
                    index = tool_call.index  # Indeks pemanggilan alat untuk pemanggilan paralel.
                    
                    # Perluas daftar penyimpanan informasi alat secara dinamis.
                    while len(tool_info) <= index:
                        tool_info.append({})
                    
                    # Kumpulkan ID pemanggilan alat (untuk pemanggilan fungsi selanjutnya).
                    if tool_call.id:
                        tool_info[index]['id'] = tool_info[index].get('id', '') + tool_call.id
                    
                    # Kumpulkan nama fungsi (untuk routing ke fungsi tertentu).
                    if tool_call.function and tool_call.function.name:
                        tool_info[index]['name'] = tool_info[index].get('name', '') + tool_call.function.name
                    
                    # Kumpulkan parameter fungsi (dalam format string JSON, memerlukan penguraian selanjutnya).
                    if tool_call.function and tool_call.function.arguments:
                        tool_info[index]['arguments'] = tool_info[index].get('arguments', '') + tool_call.function.arguments
            
print(f"\n"+"="*19+"Tool call information"+"="*19)
if not tool_info:
    print("No tool calls")
else:
    print(tool_info)

Hasil yang dikembalikan

Jika Anda memasukkan "Cuaca di empat kotamadya", hasil berikut dikembalikan:

====================Reasoning process====================
Okay, the user is asking for the weather in the four municipalities. First, I need to identify which four municipalities they are. According to China's administrative divisions, the municipalities include Beijing, Shanghai, Tianjin, and Chongqing. So the user wants to know the weather conditions in these four cities.

Next, I need to check the available tools. The provided tools include the get_current_weather function, with a 'location' parameter of type string. Each city needs to be queried separately because the function can only check one location at a time. Therefore, I need to call this function once for each municipality.

Then, I need to consider how to generate the correct tool calls. Each call should include the city name as a parameter. For example, the first call is for Beijing, the second for Shanghai, and so on. I need to ensure the parameter name is 'location' and the value is the correct city name.

Additionally, the user probably wants to get the weather information for each city, so I need to ensure that each function call is correct. It might be necessary to make four consecutive calls, one for each city. However, according to the tool usage rules, it might be necessary to handle them in multiple steps, or generate multiple calls at once. But based on the example, it seems only one function is called at a time, so I might need to proceed step by step.

Finally, I'll confirm if there are any other factors to consider, such as whether the parameters are correct, the city names are accurate, and whether I need to handle potential error situations, like a city not existing or the API being unavailable. But for now, the four municipalities are clear, so it should be fine.
====================Reply content====================

===================Tool call information===================
[{'id': 'call_767af2834c12488a8fe6e3', 'name': 'get_current_weather', 'arguments': '{"location": "Beijing"}'}, {'id': 'call_2cb05a349c89437a947ada', 'name': 'get_current_weather', 'arguments': '{"location": "Shanghai"}'}, {'id': 'call_988dd180b2ca4b0a864ea7', 'name': 'get_current_weather', 'arguments': '{"location": "Tianjin"}'}, {'id': 'call_4e98c57ea96a40dba26d12', 'name': 'get_current_weather', 'arguments': '{"location": "Chongqing"}'}]

Node.js

Kode contoh

import OpenAI from "openai";
import readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'node:process';

const openai = new OpenAI({
    // Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    apiKey: process.env.DASHSCOPE_API_KEY,
    baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
});

const tools = [
    {
        type: "function",
        function: {
            name: "get_current_time",
            description: "Useful when you want to know the current time.",
            parameters: {}
        }
    },
    {
        type: "function",
        function: {
            name: "get_current_weather",
            description: "Useful when you want to query the weather for a specified city.",
            parameters: {
                type: "object",
                properties: {
                    location: {
                        type: "string",
                        description: "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                required: ["location"]
            }
        }
    }
];

async function main() {
    const rl = readline.createInterface({ input, output });
    const question = await rl.question("Please enter your question: "); 
    rl.close();
    
    const messages = [{ role: "user", content: question }];
    // contoh pesan untuk model multimodal
    // const messages= [{
    //     role: "user",
    //     content: [{type: "image_url", image_url: {url: "https://img.alicdn.com/imgextra/i2/O1CN01FbTJon1ErXVGMRdsN_!!6000000000405-0-tps-1024-683.jpg"}},
    //               {type: "text", text: "What's the weather at the location in the image?"}]
    //   }];
    let reasoningContent = "";
    let answerContent = "";
    const toolInfo = [];
    let isAnswering = false;

    console.log("=".repeat(20) + "Reasoning process" + "=".repeat(20));
    
    try {
        const stream = await openai.chat.completions.create({
            // Contoh ini menggunakan qwen-plus. Anda dapat menggantinya dengan model pemikiran mendalam lainnya.
            model: "qwen-plus",
            messages,
            // Aktifkan pemikiran mendalam. Parameter ini tidak valid untuk model qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, dan QwQ.
            enable_thinking: true,
            tools,
            stream: true,
            parallel_tool_calls: true
        });

        for await (const chunk of stream) {
            if (!chunk.choices?.length) {
                console.log("\n" + "=".repeat(20) + "Usage" + "=".repeat(20));
                console.log(chunk.usage);
                continue;
            }

            const delta = chunk.choices[0]?.delta;
            if (!delta) continue;

            // Proses proses penalaran.
            if (delta.reasoning_content) {
                reasoningContent += delta.reasoning_content;
                process.stdout.write(delta.reasoning_content);
            }
            // Proses konten balasan.
            else {
                if (!isAnswering) {
                    isAnswering = true;
                    console.log("\n" + "=".repeat(20) + "Reply content" + "=".repeat(20));
                }
                if (delta.content) {
                    answerContent += delta.content;
                    process.stdout.write(delta.content);
                }
                // Proses pemanggilan alat.
                if (delta.tool_calls) {
                    for (const toolCall of delta.tool_calls) {
                        const index = toolCall.index;
                        
                        // Pastikan panjang array cukup.
                        while (toolInfo.length <= index) {
                            toolInfo.push({});
                        }
                        
                        // Perbarui ID alat.
                        if (toolCall.id) {
                            toolInfo[index].id = (toolInfo[index].id || "") + toolCall.id;
                        }
                        
                        // Perbarui nama fungsi.
                        if (toolCall.function?.name) {
                            toolInfo[index].name = (toolInfo[index].name || "") + toolCall.function.name;
                        }
                        
                        // Perbarui parameter.
                        if (toolCall.function?.arguments) {
                            toolInfo[index].arguments = (toolInfo[index].arguments || "") + toolCall.function.arguments;
                        }
                    }
                }
            }
        }

        console.log("\n" + "=".repeat(19) + "Tool call information" + "=".repeat(19));
        console.log(toolInfo.length ? toolInfo : "No tool calls");

    } catch (error) {
        console.error("An error occurred:", error);
    }
}

main(); 

Hasil yang dikembalikan

Jika Anda memasukkan "Cuaca di empat kotamadya", hasil berikut dikembalikan:

Please enter your question: Weather in the four municipalities
====================Reasoning process====================
Okay, the user is asking about the weather in the four municipalities. First, I need to clarify which four municipalities in China they are. Beijing, Shanghai, Tianjin, and Chongqing, right? Next, I need to call the weather query function for each city.

But the user's question might require me to get the weather conditions for these four cities separately. Each city needs a call to the get_current_weather function, with its respective city name as the parameter. I need to ensure the parameters are correct, for example, the full names of the municipalities, such as "Beijing", "Shanghai", "Tianjin", and "Chongqing".

Then, I need to call the weather interfaces for these four cities in sequence. Each call requires a separate tool_call. The user probably wants to get the current weather information for each city, so I need to ensure each call is correct. I might need to pay attention to the correct spelling and name of each city to avoid errors. For example, Chongqing is sometimes abbreviated, so the full name should be used in the parameter.

Now, I need to generate four tool_calls, each corresponding to a municipality. I'll check if each parameter is correct and then arrange them in order. This way, the user will get the weather data for the four municipalities.
====================Reply content====================

===================Tool call information===================
[
  {
    id: 'call_21dc802e717f491298d1b2',
    name: 'get_current_weather',
    arguments: '{"location": "Beijing"}'
  },
  {
    id: 'call_2cd3be1d2f694c4eafd4e5',
    name: 'get_current_weather',
    arguments: '{"location": "Shanghai"}'
  },
  {
    id: 'call_48cf3f78e02940bd9085e4',
    name: 'get_current_weather',
    arguments: '{"location": "Tianjin"}'
  },
  {
    id: 'call_e230a2b4c64f4e658d223e',
    name: 'get_current_weather',
    arguments: '{"location": "Chongqing"}'
  }
]

HTTP

Kode contoh

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": "What is the weather like in Hangzhou?"
        }
    ],
    "tools": [
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Useful when you want to know the current time.",
            "parameters": {}
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location":{
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]
            }
        }
    }
  ],
  "enable_thinking": true,
  "stream": true
}'

DashScope

Python

Kode contoh

import dashscope
dashscope.base_http_api_url = "https://dashscope-intl.aliyuncs.com/api/v1/"
tools = [
    # Alat 1: Dapatkan waktu saat ini.
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Useful when you want to know the current time.",
            "parameters": {}  # Karena tidak memerlukan parameter input untuk mendapatkan waktu saat ini, parameters adalah kamus kosong.
        }
    },  
    # Alat 2: Dapatkan cuaca untuk kota tertentu.
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {  
                "type": "object",
                "properties": {
                    # Lokasi diperlukan untuk mengkueri cuaca, jadi parameter diatur ke location.
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]
            }
        }
    }
]

# Definisikan pertanyaan.
messages = [{"role": "user", "content": input("Please enter your question: ")}]

# contoh pesan untuk model multimodal
# messages = [
# {
#     "role": "user",
#     "content": [
#     {"image": "https://img.alicdn.com/imgextra/i2/O1CN01FbTJon1ErXVGMRdsN_!!6000000000405-0-tps-1024-683.jpg"},
#     {"text": "What's the weather at the location in the image?"}]
# }]

# Jika Anda menggunakan model multimodal, ganti Generation dengan antarmuka MultiModalConversation.
completion = dashscope.Generation.call(
    # Contoh ini menggunakan qwen-plus. Anda dapat menggantinya dengan model pemikiran mendalam lainnya.
    model="qwen-plus", 
    messages=messages,
    enable_thinking=True,
    tools=tools,
    parallel_tool_calls=True,
    stream=True,
    incremental_output=True,
    result_format="message"
)

reasoning_content = ""
answer_content = ""
tool_info = []
is_answering = False
print("="*20+"Reasoning process"+"="*20)

for chunk in completion:
    if chunk.status_code == 200:
        msg = chunk.output.choices[0].message
        
        # Proses proses penalaran.
        if 'reasoning_content' in msg and msg.reasoning_content:
            reasoning_content += msg.reasoning_content
            print(msg.reasoning_content, end="", flush=True)
        
        # Proses konten balasan.
        if 'content' in msg and msg.content:
            if not is_answering:
                is_answering = True
                print("\n"+"="*20+"Reply content"+"="*20)
            answer_content += msg.content
            print(msg.content, end="", flush=True)
        
        # Proses pemanggilan alat.
        if 'tool_calls' in msg and msg.tool_calls:
            for tool_call in msg.tool_calls:
                index = tool_call['index']
                
                while len(tool_info) <= index:
                    tool_info.append({'id': '', 'name': '', 'arguments': ''})  # Inisialisasi semua bidang.
                
                # Perbarui ID alat secara inkremental.
                if 'id' in tool_call:
                    tool_info[index]['id'] += tool_call.get('id', '')
                
                # Perbarui informasi fungsi secara inkremental.
                if 'function' in tool_call:
                    func = tool_call['function']
                    # Perbarui nama fungsi secara inkremental.
                    if 'name' in func:
                        tool_info[index]['name'] += func.get('name', '')
                    # Perbarui parameter secara inkremental.
                    if 'arguments' in func:
                        tool_info[index]['arguments'] += func.get('arguments', '')

print(f"\n"+"="*19+"Tool call information"+"="*19)
if not tool_info:
    print("No tool calls")
else:
    print(tool_info)

Hasil yang dikembalikan

Saat Anda memasukkan "Cuaca di empat kotamadya", hasil berikut dikembalikan:

Please enter your question: Weather in the four municipalities
====================Reasoning process====================
Okay, the user is asking about the weather in the four municipalities. First, I need to confirm which four municipalities in China they are. Beijing, Shanghai, Tianjin, and Chongqing, right? Next, the user needs the weather conditions for each city, so I need to call the weather query function.

But wait, the user didn't specify the city names, just "four municipalities". I might need to clarify the name of each municipality and then query them separately. For example, Beijing, Shanghai, Tianjin, and Chongqing. I need to make sure each city is correct.

Then, I'll check the available tools. The user has provided the get_current_weather function with a 'location' parameter. Therefore, I need to call this function for each municipality, passing the corresponding city name as the parameter. For example, the first call's location is Beijing, the second is Shanghai, the third is Tianjin, and the fourth is Chongqing.

However, I might need to be careful. For municipalities like Chongqing, sometimes a more specific district is needed, but the user probably just wants the city-level weather. So using the municipality name directly should be fine. Next, I need to generate four separate function calls, one for each municipality. This way, the user will get the weather information for all four cities.

Finally, I'll make sure the parameters for each call are correct and that none are missed. This will ensure the user's question is fully answered.
===================Tool call information===================
[{'id': 'call_2f774ed97b0e4b24ab10ec', 'name': 'get_current_weather', 'arguments': '{"location": "Beijing"}'}, {'id': 'call_dc3b05b88baa48c58bc33a', 'name': 'get_current_weather', 'arguments': '{"location": "Shanghai"}}'}, {'id': 'call_249b2de2f73340cdb46cbc', 'name': 'get_current_weather', 'arguments': '{"location": "Tianjin"}'}, {'id': 'call_833333634fda49d1b39e87', 'name': 'get_current_weather', 'arguments': '{"location": "Chongqing"}}'}]

Java

Kode contoh

// dashscope SDK version >= 2.19.4
import java.util.Arrays;

import com.alibaba.dashscope.exception.UploadFileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.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.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;
import com.alibaba.dashscope.tools.ToolFunction;
import com.alibaba.dashscope.tools.FunctionDefinition;
import io.reactivex.Flowable;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.lang.System;
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.Collections;

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    private static ObjectNode jsonSchemaWeather;
    private static ObjectNode jsonSchemaTime;
    
    static {Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";}

    static class TimeTool {
        public String call() {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return "Current time: " + now.format(formatter) + ".";
        }
    }

    static class WeatherTool {
        private String location;

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

        public String call() {
            return location + " is sunny today";
        }
    }

    static {
        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);
        jsonSchemaWeather = generator.generateSchema(WeatherTool.class);
        jsonSchemaTime = generator.generateSchema(TimeTool.class);
    }
    private static void handleGenerationResult(GenerationResult message) {
        System.out.println(JsonUtils.toJson(message));
    }
    
    // Buat metode pemanggilan alat untuk model generasi teks.
    public static void streamCallWithMessage(Generation gen, Message userMsg)
            throws NoApiKeyException, ApiException, InputRequiredException {
        GenerationParam param = buildGenerationParam(userMsg);
        Flowable<GenerationResult> result = gen.streamCall(param);
        result.blockingForEach(message -> handleGenerationResult(message));
    }
    // Bangun parameter model generasi teks yang mendukung pemanggilan alat.
    private static GenerationParam buildGenerationParam(Message userMsg) {
        FunctionDefinition fdWeather = buildFunctionDefinition(
                "get_current_weather", "Get the weather for a specified region", jsonSchemaWeather);
        FunctionDefinition fdTime = buildFunctionDefinition(
                "get_current_time", "Get the current time", jsonSchemaTime);

        return GenerationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-plus")
                .enableThinking(true)
                .messages(Arrays.asList(userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .incrementalOutput(true)
                .tools(Arrays.asList(
                        ToolFunction.builder().function(fdWeather).build(),
                        ToolFunction.builder().function(fdTime).build()))
                .build();
    }

    // Buat metode pemanggilan alat untuk model multimodal.
    public static void streamCallWithMultiModalMessage(MultiModalConversation conv, MultiModalMessage userMsg)
            throws NoApiKeyException, ApiException, UploadFileException {
        MultiModalConversationParam param = buildMultiModalConversationParam(userMsg);
        Flowable<MultiModalConversationResult> result = conv.streamCall(param);
        result.blockingForEach(message -> System.out.println(JsonUtils.toJson(message)));
    }

    // Bangun parameter model multimodal yang mendukung pemanggilan alat.
    private static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage userMsg) {
        FunctionDefinition fdWeather = buildFunctionDefinition(
                "get_current_weather", "Get the weather for a specified region", jsonSchemaWeather);
        FunctionDefinition fdTime = buildFunctionDefinition(
                "get_current_time", "Get the current time", jsonSchemaTime);

        return MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen3-vl-plus")  // Gunakan model multimodal Qwen3-VL.
                .enableThinking(true)
                .messages(Arrays.asList(userMsg))
                .tools(Arrays.asList(  // Konfigurasikan daftar alat.
                        ToolFunction.builder().function(fdWeather).build(),
                        ToolFunction.builder().function(fdTime).build()))
                .build();
    }

    private static FunctionDefinition buildFunctionDefinition(
            String name, String description, ObjectNode schema) {
        return FunctionDefinition.builder()
                .name(name)
                .description(description)
                .parameters(JsonUtils.parseString(schema.toString()).getAsJsonObject())
                .build();
    }

    public static void main(String[] args) {
        try {
            Generation gen = new Generation();
            Message userMsg = Message.builder()
                    .role(Role.USER.getValue())
                    .content("Please tell me the weather in Hangzhou")
                    .build();
            try {
                streamCallWithMessage(gen, userMsg);
            } catch (InputRequiredException e) {
                throw new RuntimeException(e);
            }
//             Jika Anda menggunakan model multimodal untuk pemanggilan alat, hapus komentar pada baris berikut.
//            MultiModalConversation conv = new MultiModalConversation();
//            MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
//                    .content(Arrays.asList(Collections.singletonMap("image", "https://img.alicdn.com/imgextra/i2/O1CN01FbTJon1ErXVGMRdsN_!!6000000000405-0-tps-1024-683.jpg"),
//                            Collections.singletonMap("text", "What's the weather at the location in the image?"))).build();
//            try {
//                streamCallWithMultiModalMessage(conv,userMessage);
//            } catch (UploadFileException e) {
//                throw new RuntimeException(e);
//            }
        } catch (ApiException | NoApiKeyException e) {
            logger.error("An exception occurred: {}", e.getMessage());
        }
        System.exit(0);
    }
}

Hasil yang dikembalikan

{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":6,"total_tokens":244},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"Okay, the user wants me"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":12,"total_tokens":250},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"to tell them the weather in Hangzhou. I"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":16,"total_tokens":254},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"need to first determine if there are"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":22,"total_tokens":260},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"any relevant tools available. Looking at the provided"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":28,"total_tokens":266},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"tools, I see a get_current"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":34,"total_tokens":272},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"_weather function with a location parameter"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":38,"total_tokens":276},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":". So I should call"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":43,"total_tokens":281},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"this function, with the parameter"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":48,"total_tokens":286},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"set to Hangzhou. No other"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":52,"total_tokens":290},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"tools are needed, because"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":56,"total_tokens":294},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"the user only asked about"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":60,"total_tokens":298},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"the weather. Next, I'll construct"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":64,"total_tokens":302},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"the tool_call, filling in"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":68,"total_tokens":306},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"the name and parameters"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":73,"total_tokens":311},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":". I'll make sure the parameter is a"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":78,"total_tokens":316},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"JSON object, and location is a"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":82,"total_tokens":320},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"string. After checking for errors"}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":88,"total_tokens":326},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":", I'll return."}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":106,"total_tokens":344},"output":{"choices":[{"finish_reason":"null","message":{"role":"assistant","content":"","reasoning_content":"","tool_calls":[{"type":"function","id":"call_ecc41296dccc47baa01567","function":{"name":"get_current_weather","arguments":"{\"location\": \"Hangzhou"}}]}}]}}
{"requestId":"4edb81cd-4647-9d5d-88f9-a4f30bc6d8dd","usage":{"input_tokens":238,"output_tokens":108,"total_tokens":346},"output":{"choices":[{"finish_reason":"tool_calls","message":{"role":"assistant","content":"","reasoning_content":"","tool_calls":[{"type":"function","id":"","function":{"arguments":"\"}"}}]}}]}}

HTTP

Kode contoh

curl

# ======= Catatan penting =======
# Jika Anda menggunakan model multimodal, modifikasi parameter pesan dan ganti url dengan https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation.
# Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
# Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti url dengan https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation.
# === Hapus komentar ini sebelum menjalankan ===

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": "Hangzhou weather"
            }
        ]
    },
    "parameters": {
        "enable_thinking": true,
        "incremental_output": true,
        "result_format": "message",
        "tools": [{
            "type": "function",
            "function": {
                "name": "get_current_time",
                "description": "Useful when you want to know the current time.",
                "parameters": {}
            }
        },{
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Useful when you want to query the weather for a specified city.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                        }
                    },
                    "required": ["location"]
                }
            }
        }]
    }
}'

Meluncurkan ke produksi

Uji akurasi pemanggilan alat

  • Bangun sistem evaluasi:

    Buat set data uji yang representatif terhadap skenario bisnis nyata dan definisikan metrik evaluasi yang jelas, seperti akurasi pemilihan alat, akurasi ekstraksi parameter, dan tingkat keberhasilan end-to-end.

  • Optimalkan prompt

    Berdasarkan masalah spesifik yang diidentifikasi selama pengujian (pemilihan alat salah atau kesalahan parameter), optimasi terarah terhadap prompt sistem, deskripsi alat, dan deskripsi parameter berfungsi sebagai metode penyetelan inti.

  • Tingkatkan model

    Saat penyetelan rekayasa prompt gagal meningkatkan kinerja, meningkatkan ke versi model yang lebih mumpuni (seperti qwen3-max-preview) adalah cara paling langsung dan efektif untuk meningkatkan metrik.

Kontrol dinamis jumlah alat

Saat jumlah alat yang diintegrasikan ke dalam aplikasi melebihi puluhan atau bahkan ratusan, menyediakan seluruh pustaka alat ke model dapat menyebabkan masalah berikut:

  • Penurunan kinerja: Kesulitan bagi model untuk memilih alat yang benar dari kumpulan alat yang sangat besar meningkat secara dramatis.

  • Biaya dan latensi: Banyak deskripsi alat akan mengonsumsi jumlah token input yang sangat besar, menyebabkan peningkatan biaya dan respons yang lebih lambat.

Solusinya melibatkan penambahan lapisan routing/pengambilan alat sebelum memanggil model. Berdasarkan kueri pengguna saat ini, cepat dan akurat saring subset kecil alat yang relevan dari pustaka alat lengkap, lalu berikan subset ini ke model.

Beberapa metode utama untuk mengimplementasikan routing alat:

  • Pengambilan semantik

    Pra-konversi informasi deskripsi (description) semua alat menjadi vektor menggunakan model Embedding dan simpan di database vektor. Saat pengguna mengajukan kueri, lakukan pencarian kemiripan vektor pada vektor kueri untuk mengingat kembali alat Top-K yang paling relevan.

  • Pengambilan hibrid

    Gabungkan kemampuan "pencocokan kabur" dari pengambilan semantik dengan kemampuan "pencocokan eksak" dari kata kunci tradisional atau tag metadata. Tambahkan bidang tags atau keywords ke alat. Melakukan pencarian vektor dan penyaringan kata kunci secara bersamaan selama pengambilan dapat sangat meningkatkan presisi pengingatan untuk skenario frekuensi tinggi atau spesifik.

  • Router LLM ringan

    Untuk logika routing yang lebih kompleks, Anda dapat menggunakan model yang lebih kecil, lebih cepat, dan lebih murah (seperti Qwen-Flash) sebagai model pra-routing. Tugasnya adalah mengeluarkan daftar nama alat yang relevan berdasarkan pertanyaan pengguna.

Saran praktis

  • Jaga agar set kandidat tetap ringkas: Terlepas dari metode yang digunakan, jumlah alat yang disediakan ke model utama idealnya harus tidak lebih dari 20. Ini adalah keseimbangan terbaik antara beban kognitif model, biaya, latensi, dan akurasi.

  • Strategi penyaringan berlapis: Anda dapat membangun kebijakan perutean berbentuk corong. Misalnya, pertama-tama gunakan pencocokan kata kunci/aturan berbiaya sangat rendah untuk putaran penyaringan awal guna menyaring alat yang jelas tidak relevan. Kemudian, lakukan pengambilan semantik pada alat yang tersisa untuk meningkatkan efisiensi dan kualitas.

Prinsip keamanan alat

Saat mengekspos kemampuan eksekusi alat ke LLMs, keamanan harus menjadi prioritas utama. Prinsip intinya adalah "hak istimewa minimal" dan "konfirmasi manusia".

  • Prinsip hak istimewa minimal: Set alat yang disediakan ke model harus secara ketat mengikuti prinsip hak istimewa minimal. Secara default, alat harus read-only (seperti mengkueri cuaca, mencari dokumen), dan hindari langsung menyediakan izin "tulis" apa pun yang melibatkan perubahan status atau operasi sumber daya.

  • Isolasi alat berbahaya: Jangan langsung menyediakan alat berbahaya ke LLM, seperti mengeksekusi kode arbitrer (code interpreter), mengoperasikan sistem file (fs.delete), melakukan operasi penghapusan atau pembaruan database (db.drop_table), atau alat yang melibatkan transaksi keuangan (payment.transfer).

  • Keterlibatan manusia: Untuk semua operasi berhak tinggi atau tidak dapat diubah, proses tinjauan dan konfirmasi manual harus diperkenalkan. Model dapat menghasilkan permintaan operasi, tetapi "tombol" eksekusi akhir harus diklik oleh pengguna manusia. Misalnya, model dapat menyiapkan email, tetapi operasi pengiriman memerlukan konfirmasi pengguna.

Optimasi pengalaman pengguna

Proses pemanggilan fungsi panjang, dan masalah di bagian mana pun dari proses ini dapat menyebabkan penurunan pengalaman pengguna.

Atasi kegagalan eksekusi alat

Kegagalan eksekusi alat umum terjadi. Strategi berikut dapat diterapkan:

  • Jumlah percobaan ulang maksimum: Tetapkan batas percobaan ulang yang wajar (misalnya, 3 kali) untuk menghindari pengguna menunggu terlalu lama atau pemborosan sumber daya sistem akibat kegagalan berkelanjutan.

  • Berikan frasa cadangan: Saat percobaan ulang habis atau terjadi kesalahan yang tidak dapat diselesaikan, kembalikan prompt yang jelas dan ramah kepada pengguna, misalnya: "Maaf, saya sementara tidak dapat mengkueri informasi terkait. Layanan mungkin sedang sibuk. Silakan coba lagi nanti."

Atasi penundaan pemrosesan

Latensi tinggi akan mengurangi kepuasan pengguna dan memerlukan peningkatan melalui interaksi frontend dan optimasi backend.

  • Tetapkan batas waktu: Tetapkan batas waktu independen dan wajar untuk setiap langkah pemanggilan fungsi. Begitu terjadi timeout, operasi harus segera dihentikan dan umpan balik diberikan.

  • Berikan umpan balik segera: Saat memulai pemanggilan fungsi, disarankan untuk memberikan prompt pada antarmuka, seperti "Mencari cuaca untuk Anda..." atau "Mencari informasi terkait...", untuk memberikan umpan balik real-time kepada pengguna tentang progres pemrosesan.

Rincian penagihan

Selain token dalam array messages, deskripsi alat juga dihitung sebagai token input dan ditagih bersama prompt.

Kirimkan informasi alat menggunakan System Message

Anda dapat mengirimkan informasi alat ke model bahasa besar (LLM) menggunakan parameter tools. Untuk informasi lebih lanjut, lihat bagian Cara menggunakan. Untuk mengirimkan informasi alat menggunakan pesan sistem, gunakan templat prompt yang ditunjukkan dalam contoh kode berikut:

Kompatibel dengan OpenAI

Python

Kode contoh

import os
from openai import OpenAI
import json

client = OpenAI(
    # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti base_url dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

# Prompt Sistem kustom. Modifikasi sesuai kebutuhan.
custom_prompt = "You are an intelligent assistant specialized in calling various tools to help users solve problems. You can select and correctly call appropriate tools based on user needs."

tools = [
    # Alat 1: Dapatkan waktu saat ini.
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Useful when you want to know the current time.",
            "parameters": {}
        }
    },  
    # Alat 2: Dapatkan cuaca untuk kota tertentu.
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {  
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]
            }
        }
    }
]

# Iterasi daftar alat untuk membangun deskripsi setiap alat.
tools_descriptions = []
for tool in tools:
    tool_json = json.dumps(tool, ensure_ascii=False)
    tools_descriptions.append(tool_json)

# Gabungkan semua deskripsi alat menjadi satu string.
tools_content = "\n".join(tools_descriptions)

system_prompt = f"""{custom_prompt}

# Tools

You may call one or more functions to assist with the user query.

You are provided with function signatures within <tools></tools> XML tags:
<tools>
{tools_content}
</tools>

For each function call, return a JSON object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{{"name": <function-name>, "arguments": <args-json-object>}}
</tool_call>"""

messages = [
    {"role": "system", "content": system_prompt},
    {"role": "user", "content": "What time is it?"}
]

completion = client.chat.completions.create(
    model="qwen-plus",
    messages=messages,
)
print(completion.model_dump_json())

Node.js

Kode contoh

import OpenAI from "openai";

const client = new OpenAI({
    // Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: apiKey: "sk-xxx",
    apiKey: process.env.DASHSCOPE_API_KEY,
    // Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti baseURL dengan https://dashscope.aliyuncs.com/compatible-mode/v1.
    baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
});

// Prompt Sistem kustom.
const customPrompt = "You are an intelligent assistant specialized in calling various tools to help users solve problems. You can select and correctly call appropriate tools based on user needs.";

const tools = [
    // Alat 1: Dapatkan waktu saat ini.
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Useful when you want to know the current time.",
            "parameters": {}
        }
    },
    // Alat 2: Dapatkan cuaca untuk kota tertentu.
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]
            }
        }
    }
];

// Iterasi daftar alat untuk membangun deskripsi setiap alat.
const toolsDescriptions = [];
for (const tool of tools) {
    const toolJson = JSON.stringify(tool, null, 2);
    toolsDescriptions.push(toolJson);
}

// Gabungkan semua deskripsi alat menjadi satu string.
const toolsContent = toolsDescriptions.join("\n");

const systemPrompt = `${customPrompt}

# Tools

You may call one or more functions to assist with the user query.

You are provided with function signatures within <tools></tools> XML tags:
<tools>
${toolsContent}
</tools>

For each function call, return a JSON object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>`;

const messages = [
    {"role": "system", "content": systemPrompt},
    {"role": "user", "content": "What time is it?"}
];

async function main() {
    try {
        const completion = await client.chat.completions.create({
            model: "qwen-plus",
            messages: messages,
        });
        
        console.log(JSON.stringify(completion, null, 2));
    } catch (error) {
        console.error("Error:", error);
    }
}

main(); 

DashScope

Python

Kode contoh

import os
from dashscope import Generation
import json
# Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti base_http_api_url dengan https://dashscope.aliyuncs.com/api/v1.
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

# Prompt Sistem kustom.
custom_prompt = "You are an intelligent assistant specialized in calling various tools to help users solve problems. You can select and correctly call appropriate tools based on user needs."

tools = [
    # Alat 1: Dapatkan waktu saat ini.
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Useful when you want to know the current time.",
            "parameters": {}  # Karena tidak memerlukan parameter input untuk mendapatkan waktu saat ini, parameters adalah kamus kosong.
        }
    },  
    # Alat 2: Dapatkan cuaca untuk kota tertentu.
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Useful when you want to query the weather for a specified city.",
            "parameters": {  
                "type": "object",
                "properties": {
                    # Lokasi diperlukan untuk mengkueri cuaca, jadi atur parameter ke location.
                    "location": {
                        "type": "string",
                        "description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
                    }
                },
                "required": ["location"]
            }
        }
    }
]

# Iterasi daftar alat untuk membangun deskripsi setiap alat.
tools_descriptions = []
for tool in tools:
    tool_json = json.dumps(tool, ensure_ascii=False)
    tools_descriptions.append(tool_json)

# Gabungkan semua deskripsi alat menjadi satu string.
tools_content = "\n".join(tools_descriptions)

system_prompt = f"""{custom_prompt}

# Tools

You may call one or more functions to assist with the user query.

You are provided with function signatures within <tools></tools> XML tags:
<tools>
{tools_content}
</tools>

For each function call, return a JSON object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{{"name": <function-name>, "arguments": <args-json-object>}}
</tool_call>"""

messages = [
    {"role": "system", "content": system_prompt},
    {"role": "user", "content": "What time is it?"}
]

response = Generation.call(
    # Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
    # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    model="qwen-plus",
    messages=messages,
    result_format="message",  # Atur format keluaran ke message.
)

print(response)

Java

Kode contoh

// 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.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.utils.JsonUtils;
import com.alibaba.dashscope.protocol.Protocol;

public class Main {
    public static void main(String[] args) {
        try {
            callToolWithCustomPrompt();
        } 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);
    }

    public static void callToolWithCustomPrompt()
            throws NoApiKeyException, ApiException, InputRequiredException {

        // Prompt Sistem kustom.
        String customPrompt = "You are an intelligent assistant specialized in calling various tools to help users solve problems. You can select and correctly call appropriate tools based on user needs.";

        // Bangun deskripsi alat.
        String[] toolsDescriptions = {
                // Alat 1: Dapatkan waktu saat ini.
                "{\n" +
                        "    \"type\": \"function\",\n" +
                        "    \"function\": {\n" +
                        "        \"name\": \"get_current_time\",\n" +
                        "        \"description\": \"Useful when you want to know the current time.\",\n" +
                        "        \"parameters\": {}\n" +
                        "    }\n" +
                        "}",
                // Alat 2: Dapatkan cuaca untuk kota tertentu.
                "{\n" +
                        "    \"type\": \"function\",\n" +
                        "    \"function\": {\n" +
                        "        \"name\": \"get_current_weather\",\n" +
                        "        \"description\": \"Useful when you want to query the weather for a specified city.\",\n" +
                        "        \"parameters\": {\n" +
                        "            \"type\": \"object\",\n" +
                        "            \"properties\": {\n" +
                        "                \"location\": {\n" +
                        "                    \"type\": \"string\",\n" +
                        "                    \"description\": \"A city or district, such as Beijing, Hangzhou, or Yuhang District.\"\n" +
                        "                }\n" +
                        "            },\n" +
                        "            \"required\": [\"location\"]\n" +
                        "        }\n" +
                        "    }\n" +
                        "}"
        };

        // Gabungkan semua deskripsi alat menjadi satu string.
        String toolsContent = String.join("\n", toolsDescriptions);

        // Bangun prompt sistem.
        String systemPrompt = String.format("%s\n\n" +
                        "# Tools\n\n" +
                        "You may call one or more functions to assist with the user query.\n\n" +
                        "You are provided with function signatures within <tools></tools> XML tags:\n" +
                        "<tools>\n%s\n</tools>\n\n" +
                        "For each function call, return a JSON object with function name and arguments within <tool_call></tool_call> XML tags:\n"
                        +
                        "<tool_call>\n" +
                        "{\"name\": <function-name>, \"arguments\": <args-json-object>}\n" +
                        "</tool_call>",
                customPrompt, toolsContent);

        // Bangun daftar pesan.
        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .content(systemPrompt)
                .build();

        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content("What time is it?")
                .build();

        List<Message> messages = new ArrayList<>(Arrays.asList(systemMsg, userMsg));

        // Bangun parameter permintaan.
        GenerationParam param = GenerationParam.builder()
                .model("qwen-plus")
                // Kunci API berbeda berdasarkan wilayah. Untuk mendapatkan Kunci API, lihat https://www.alibabacloud.com/help/document_detail/2613999.html
                // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .messages(messages)
                .resultFormat(ResultFormat.MESSAGE)
                .build();

        // Panggil antarmuka generasi. Jika Anda menggunakan model di wilayah Tiongkok (Beijing), ganti url dengan https://dashscope.aliyuncs.com/api/v1.
        Generation gen = new Generation(Protocol.HTTP.getValue(), "https://dashscope-intl.aliyuncs.com/api/v1");
        GenerationResult result = gen.call(param);

        // Keluarkan hasilnya.
        System.out.println(JsonUtils.toJson(result));
    }
}
Setelah menjalankan kode di atas, gunakan parser XML untuk mengekstrak informasi pemanggilan alat—termasuk nama fungsi dan parameter input—dari konten antara tag <tool_call> dan </tool_call>.

Kode error

Jika panggilan model gagal dan mengembalikan pesan error, lihat Pesan error untuk resolusi.