Model dapat mengalami kesulitan dalam menangani tugas seperti menjawab pertanyaan real-time atau melakukan perhitungan matematis. Pemanggilan fungsi mengatasi masalah ini dengan memperkenalkan tool eksternal, sehingga memungkinkan model menjawab pertanyaan yang sebelumnya tidak dapat dijawab.
Cara kerja
Pemanggilan fungsi memungkinkan model merujuk informasi dari tool eksternal untuk menjawab melalui interaksi multi-langkah antara aplikasi Anda dan model.
Lakukan panggilan model pertama
Aplikasi Anda mengirim permintaan ke model yang mencakup pertanyaan pengguna dan daftar tool yang dapat dipanggil oleh model.
Terima instruksi pemanggilan tool dari model
Jika model memutuskan untuk memanggil tool eksternal, model akan mengembalikan instruksi dalam format JSON yang berisi fungsi yang harus dijalankan beserta parameter inputnya.
Jika model memutuskan untuk tidak memanggil tool, respons akan dikembalikan dalam bahasa alami.
Jalankan tool di aplikasi Anda
Setelah menerima instruksi tool, aplikasi Anda dapat menjalankan tool tersebut untuk mendapatkan output.
Lakukan panggilan model kedua
Setelah mendapatkan output tool, tambahkan output tersebut ke konteks model (messages) dan panggil kembali model.
Terima respons akhir dari model
Model menggabungkan output tool dengan pertanyaan pengguna untuk menghasilkan respons akhir dalam bahasa alami.
Gambar berikut menunjukkan alur kerja.
Ketersediaan model
Qwen
Model generasi teks
Model multimodal
DeepSeek
deepseek-v3.2
deepseek-v3.2-exp (non-thinking mode)
deepseek-v3.1 (non-thinking mode)
deepseek-r1
deepseek-r1-0528
deepseek-v3
Kimi
kimi-k2-thinking
Moonshot-Kimi-K2-Instruct
Memulai
Anda harus terlebih dahulu membuat Kunci API dan mengekspor Kunci API sebagai Variabel lingkungan. Jika Anda menggunakan SDK OpenAI atau SDK DashScope untuk melakukan panggilan, instal SDK.
Bagian ini menggunakan skenario kueri cuaca untuk menunjukkan cara cepat menggunakan pemanggilan fungsi.
Kompatibel dengan OpenAI
from openai import OpenAI
from datetime import datetime
import json
import os
import random
client = OpenAI(
# If you use a model in the China (Beijing) region, you need to use an API Key for the China (Beijing) region. Get the key from: https://bailian.console.alibabacloud.com/?tab=model#/api-key
# If you have not configured the environment variable, replace the following line with: api_key="sk-xxx", using your model Studio API key.
api_key=os.getenv("DASHSCOPE_API_KEY"),
# If you use a model in the China (Beijing) region, replace the base_url with: https://dashscope.aliyuncs.com/compatible-mode/v1
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
# Simulate a user question
USER_QUESTION = "What's the weather like in Singapore?"
# Define the tool list
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "This is useful when you want to query the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "A city or county, such as Singapore or New York.",
}
},
"required": ["location"],
},
},
},
]
# Simulate a weather query tool
def get_current_weather(arguments):
weather_conditions = ["Sunny", "Cloudy", "Rainy"]
random_weather = random.choice(weather_conditions)
location = arguments["location"]
return f"Today in {location} it is {random_weather}."
# Encapsulate the model response function
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)
# If no tool call is needed, output the content directly
if assistant_output.tool_calls is None:
print(f"No need to call the weather query tool. Direct reply: {assistant_output.content}")
else:
# Enter the tool calling loop
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}] with arguments: {arguments}")
# Run the tool
tool_result = get_current_weather(arguments)
# Construct the tool return message
tool_message = {
"role": "tool",
"tool_call_id": tool_call_id,
"content": tool_result, # Keep the original tool output
}
print(f"Tool returns: {tool_message['content']}")
messages.append(tool_message)
# Call the model again to get a summarized natural language reply
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"Assistant's final reply: {assistant_output.content}")import OpenAI from 'openai';
// Initialize the client
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
// If you use a model in the China (Beijing) region, replace the baseURL with: https://dashscope.aliyuncs.com/compatible-mode/v1
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
});
// Define the tool list
const tools = [
{
type: "function",
function: {
name: "get_current_weather",
description: "This is useful when you want to query the weather in a specific city.",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "A city or county, such as Singapore or New York.",
},
},
required: ["location"],
},
},
},
];
// Simulate a weather query tool
const getCurrentWeather = (args) => {
const weatherConditions = ["Sunny", "Cloudy", "Rainy"];
const randomWeather = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];
const location = args.location;
return `Today in ${location} it is ${randomWeather}.`;
};
// Encapsulate the model response function
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 = "What's the weather like in Singapore?";
let messages = [
{
role: "user",
content: input,
}
];
let response = await getResponse(messages);
let assistantOutput = response.choices[0].message;
// Make sure content is not null
if (!assistantOutput.content) assistantOutput.content = "";
messages.push(assistantOutput);
// Determine whether to call a tool
if (!assistantOutput.tool_calls) {
console.log(`No need to call the weather query tool. Direct reply: ${assistantOutput.content}`);
} else {
// Enter the tool calling loop
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(`Calling tool [${funcName}] with arguments:`, funcArgs);
// Run the tool
const toolResult = getCurrentWeather(funcArgs);
// Construct the tool return message
const toolMessage = {
role: "tool",
tool_call_id: toolCallId,
content: toolResult,
};
console.log(`Tool returns: ${toolMessage.content}`);
messages.push(toolMessage);
// Call the model again to get a natural language summary
response = await getResponse(messages);
assistantOutput = response.choices[0].message;
if (!assistantOutput.content) assistantOutput.content = "";
messages.push(assistantOutput);
}
console.log(`Assistant's final reply: ${assistantOutput.content}`);
}
};
// Start the program
main().catch(console.error);DashScope
import os
from dashscope import Generation
import dashscope
import json
import random
# If you use a model in the China (Beijing) region, replace base_http_api_url with: https://dashscope.aliyuncs.com/api/v1
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
# 1. Define the tool list
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "This is useful when you want to query the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "A city or county, such as Singapore or New York.",
}
},
"required": ["location"],
},
},
}
]
# 2. Simulate a weather query tool
def get_current_weather(arguments):
weather_conditions = ["Sunny", "Cloudy", "Rainy"]
random_weather = random.choice(weather_conditions)
location = arguments["location"]
return f"Today in {location} it is {random_weather}."
# 3. Encapsulate the model response function
def get_response(messages):
response = Generation.call(
# If you have not configured the environment variable, replace the following line with api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
model="qwen-plus",
messages=messages,
tools=tools,
result_format="message",
)
return response
# 4. Initialize the conversation history
messages = [
{
"role": "user",
"content": "What's the weather like in Singapore?"
}
]
# 5. Call the model for the first time
response = get_response(messages)
assistant_output = response.output.choices[0].message
messages.append(assistant_output)
# 6. Determine if a tool call is needed
if "tool_calls" not in assistant_output or not assistant_output["tool_calls"]:
print(f"No tool call needed. Direct reply: {assistant_output['content']}")
else:
# 7. Enter the tool calling loop
# Loop condition: As long as the latest model response includes a tool call request
while "tool_calls" in assistant_output and assistant_output["tool_calls"]:
tool_call = assistant_output["tool_calls"][0]
# Parse the tool call information
func_name = tool_call["function"]["name"]
arguments = json.loads(tool_call["function"]["arguments"])
tool_call_id = tool_call.get("id") # Get the tool_call_id
print(f"Calling tool [{func_name}] with arguments: {arguments}")
# Run the corresponding tool function
tool_result = get_current_weather(arguments)
# Construct the tool return message
tool_message = {
"role": "tool",
"content": tool_result,
"tool_call_id": tool_call_id
}
print(f"Tool returns: {tool_message['content']}")
messages.append(tool_message)
# Call the model again to get a response based on the tool result
response = get_response(messages)
assistant_output = response.output.choices[0].message
messages.append(assistant_output)
# 8. Output the final natural language reply
print(f"Assistant's final 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 {
/**
* Define the local implementation of the tool.
* @param arguments A JSON string from the model containing the required parameters for the tool.
* @return A string with the result of the tool's execution.
*/
public static String getCurrentWeather(String arguments) {
try {
// The parameters provided by the model are in JSON format and need to be parsed manually.
ObjectMapper objectMapper = new ObjectMapper();
JsonNode argsNode = objectMapper.readTree(arguments);
String location = argsNode.get("location").asText();
// Use a random result to simulate a real API call or business logic.
List<String> weatherConditions = Arrays.asList("Sunny", "Cloudy", "Rainy");
String randomWeather = weatherConditions.get(new Random().nextInt(weatherConditions.size()));
return "Today in " + location + " it is " + randomWeather + ".";
} catch (Exception e) {
// Exception handling to ensure program robustness.
return "Failed to parse location parameter.";
}
}
public static void main(String[] args) {
try {
// Describe (register) our tool to the 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") // The unique identifier of the tool, which must correspond to the local implementation.
.description("This is useful when you want to query the weather in a specific city.") // A clear description helps the model better decide when to use the tool.
.parameters(JsonUtils.parseString(weatherParamsSchema).getAsJsonObject())
.build();
// If you use a model in the China (Beijing) region, replace the URL with: 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());
// Call the model for the first time. Send the user's request and the defined tool list to the model.
GenerationParam param = GenerationParam.builder()
.model("qwen-plus") // Specify the model to call.
.apiKey(System.getenv("DASHSCOPE_API_KEY")) // Get the API key from the environment variable.
.messages(messages) // Pass in the current conversation history.
.tools(Arrays.asList(ToolFunction.builder().function(weatherFunction).build())) // Pass in the list of available tools.
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
.build();
GenerationResult result = gen.call(param);
Message assistantOutput = result.getOutput().getChoices().get(0).getMessage();
messages.add(assistantOutput); // Add the model's first reply to the conversation history as well.
// Check the model's reply to determine if it requests a tool call.
if (assistantOutput.getToolCalls() == null || assistantOutput.getToolCalls().isEmpty()) {
// Case A: The model does not call a tool, but provides a direct answer.
System.out.println("No need to call the weather query tool. Direct reply: " + assistantOutput.getContent());
} else {
// Case B: The model decides to call a tool.
// Use a while loop to handle scenarios where the model calls tools multiple times in a row.
while (assistantOutput.getToolCalls() != null && !assistantOutput.getToolCalls().isEmpty()) {
ToolCallBase toolCall = assistantOutput.getToolCalls().get(0);
// Parse the specific information of the tool call (function name, parameters) from the model's reply.
ToolCallFunction functionCall = (ToolCallFunction) toolCall;
String funcName = functionCall.getFunction().getName();
String arguments = functionCall.getFunction().getArguments();
System.out.println("Calling tool [" + funcName + "] with arguments: " + arguments);
// Run the corresponding Java method locally based on the tool name.
String toolResult = getCurrentWeather(arguments);
// Construct a message with role "tool" that contains the tool's execution result.
Message toolMessage = Message.builder()
.role("tool")
.toolCallId(toolCall.getId())
.content(toolResult)
.build();
System.out.println("Tool returns: " + toolMessage.getContent());
messages.add(toolMessage); // Add the tool's return result to the conversation history as well.
// Call the model again.
param.setMessages(messages);
result = gen.call(param);
assistantOutput = result.getOutput().getChoices().get(0).getMessage();
messages.add(assistantOutput);
}
// Print the final reply generated by the model after summarization.
System.out.println("Assistant's final 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] with arguments: {'location': 'Singapore'}
Tool returns: Today in Singapore it is Cloudy.
Assistant's final reply: Today in Singapore, the weather is cloudy.Panduan implementasi
Pemanggilan fungsi mendukung dua metode untuk meneruskan informasi tool:
Metode 1: Teruskan informasi melalui parameter tools (Direkomendasikan)
Untuk informasi selengkapnya, lihat Panduan implementasi. Anda dapat memanggil fungsi dengan mendefinisikan tool, membuat array messages, memulai pemanggilan fungsi, menjalankan fungsi tool, dan meminta model merangkum output fungsi tool.
Metode 2: Teruskan informasi melalui System Message
Saat Anda menggunakan parameter tools, server secara otomatis menyesuaikan dan menyusun templat prompt yang sesuai berdasarkan model. Oleh karena itu, kami merekomendasikan agar Anda menggunakan parameter tools. Jika Anda tidak ingin menggunakan parameter tools dengan model Qwen, lihat Teruskan informasi tool menggunakan system message.
Bagian berikut menggunakan metode pemanggilan yang kompatibel dengan OpenAI sebagai contoh. Bagian ini menunjukkan cara menggunakan pemanggilan fungsi langkah demi langkah dengan meneruskan informasi tool melalui parameter tools.
Asumsikan bahwa skenario bisnis Anda menerima dua jenis pertanyaan: kueri cuaca dan kueri waktu.
1. Definisikan tool
Tool adalah jembatan antara Model dan dunia luar. Pertama, Anda harus mendefinisikan tool.
1.1. Buat fungsi tool
Anda dapat membuat dua fungsi tool: tool kueri cuaca dan tool kueri waktu.
Tool kueri cuaca
Tool ini menerima parameter
arguments. Formatargumentsadalah{"location": "query_location"}. Output tool berupa string dengan format"Today in {location} it is {weather}".Untuk tujuan demonstrasi, tool kueri cuaca yang didefinisikan di sini tidak benar-benar melakukan kueri cuaca. Tool ini memilih secara acak dari Sunny, Cloudy, atau Rainy. Dalam skenario bisnis nyata, Anda dapat menggantinya dengan tool seperti AMap Weather Query.
Tool kueri waktu
Tool kueri waktu tidak memerlukan parameter input apa pun. Output tool berupa string dengan format
"Current time: {queried_time}.".Jika Anda menggunakan Node.js, Anda dapat menjalankan
npm install date-fnsuntuk menginstal paket date-fns guna mendapatkan waktu.
## Step 1: Define tool functions
# Add import for the random module
import random
from datetime import datetime
# Simulate a weather query tool. Example output: "Today in Beijing it is Rainy."
def get_current_weather(arguments):
# Define a list of alternative weather conditions
weather_conditions = ["Sunny", "Cloudy", "Rainy"]
# Randomly select a weather condition
random_weather = random.choice(weather_conditions)
# Extract location information from JSON
location = arguments["location"]
# Return formatted weather information
return f"Today in {location} it is {random_weather}."
# Tool to query the current time. Example output: "Current time: 2024-04-15 17:15:18."
def get_current_time():
# Get the current date and time
current_datetime = datetime.now()
# Format the current date and time
formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
# Return the formatted current time
return f"Current time: {formatted_time}."
# Test the tool functions and print the results. You can remove the following four lines of test code when running subsequent steps.
print("Testing tool output:")
print(get_current_weather({"location": "Shanghai"}))
print(get_current_time())
print("\n")// Step 1: Define tool functions
// Import the time query tool
import { format } from 'date-fns';
function getCurrentWeather(args) {
// Define a list of alternative weather conditions
const weatherConditions = ["Sunny", "Cloudy", "Rainy"];
// Randomly select a weather condition
const randomWeather = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];
// Extract location information from JSON
const location = args.location;
// Return formatted weather information
return `Today in ${location} it is ${randomWeather}.`;
}
function getCurrentTime() {
// Get the current date and time
const currentDatetime = new Date();
// Format the current date and time
const formattedTime = format(currentDatetime, 'yyyy-MM-dd HH:mm:ss');
// Return the formatted current time
return `Current time: ${formattedTime}.`;
}
// Test the tool functions and print the results. You can remove the following four lines of test code when running subsequent steps.
console.log("Testing tool output:")
console.log(getCurrentWeather({location:"Shanghai"}));
console.log(getCurrentTime());
console.log("\n")Setelah Anda menjalankan tool, Anda akan melihat output berikut:
Testing tool output:
Today in Shanghai it is Cloudy.
Current time: 2025-01-08 20:21:45.1.2 Buat array tools
Sebelum manusia memilih tool, mereka perlu memahami tool tersebut secara komprehensif, termasuk fungsinya, kapan harus menggunakannya, dan parameter inputnya. Model juga memerlukan informasi ini untuk memilih tool dengan lebih akurat. Anda dapat memberikan informasi tool dalam format JSON berikut.
| Untuk tool kueri cuaca, informasi deskripsi tool memiliki format berikut: |
Sebelum memulai pemanggilan fungsi, Anda harus mendefinisikan array informasi tool (tools) dalam kode Anda. Array ini berisi nama fungsi, deskripsi, dan definisi parameter untuk setiap tool. Array ini diteruskan sebagai parameter dalam permintaan pemanggilan fungsi selanjutnya.
# Paste the following code after the code from Step 1
## Step 2: Create the tools array
tools = [
{
"type": "function",
"function": {
"name": "get_current_time",
"description": "This is useful when you want to know the current time.",
"parameters": {}
}
},
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "This is useful when you want to query the weather in a specific 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")// Paste the following code after the code from Step 1
// Step 2: Create the tools array
const tools = [
{
type: "function",
function: {
name: "get_current_time",
description: "This is useful when you want to know the current time.",
parameters: {}
}
},
{
type: "function",
function: {
name: "get_current_weather",
description: "This is useful when you want to query the weather in a specific 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 meneruskan instruksi dan informasi konteks ke model. Sebelum memulai pemanggilan fungsi, array messages perlu mencakup system message dan user message.
System message
Meskipun tujuan tool dan kapan harus menggunakannya telah dijelaskan saat Anda membuat array tools, menekankan kapan harus memanggil tool dalam system message biasanya meningkatkan akurasi pemanggilan tool. Dalam skenario saat ini, Anda dapat mengatur prompt sistem sebagai berikut:
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 the questions in a friendly tone.User message
User message digunakan untuk meneruskan pertanyaan pengguna. Misalnya, jika pengguna bertanya "Shanghai weather", array messages akan menjadi sebagai berikut:
# Step 3: Create the messages array
# Paste the following code after the code from Step 2
# Example of a User Message for a text generation model
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 the questions in a friendly tone.""",
},
{
"role": "user",
"content": "Shanghai weather"
}
]
# Example of a User Message for the Qwen3-VL model
# 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 the questions 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": "Query the current weather for the location in the image"}]},
# ]
print("messages array created\n") // Step 3: Create the messages array
// Paste the following code after the code from Step 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 the questions in a friendly tone.",
},
{
role: "user",
content: "Shanghai weather"
}
];
// Example of a User Message for the Qwen3-VL model,
// 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 is depicted in the image?"}]
// }];
console.log("messages array created\n");Karena tool yang tersedia mencakup kueri cuaca dan waktu, Anda juga dapat menanyakan waktu saat ini.
3. Mulai pemanggilan fungsi
Anda dapat meneruskan tools dan messages yang telah dibuat ke model untuk memulai pemanggilan fungsi. Model menentukan apakah akan memanggil tool. Jika iya, model mengembalikan nama fungsi dan parameter tool tersebut.
Untuk daftar model yang didukung, lihat Ketersediaan model.
# Step 4: Initiate function calling
# Paste the following code after the code from Step 3
from openai import OpenAI
import os
client = OpenAI(
# If you use a model in the China (Beijing) region, you need to use an API Key for the China (Beijing) region. Get the key from: https://bailian.console.alibabacloud.com/?tab=model#/api-key
# If you have not configured the environment variable, replace the following line with: api_key="sk-xxx", using your model Studio API key.
api_key=os.getenv("DASHSCOPE_API_KEY"),
# If you use a model in the China (Beijing) region, replace the base_url with: 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(
# This example uses qwen-plus. You can change the model name as needed. For a list of models, see https://www.alibabacloud.com/help/en/model-studio/getting-started/models
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()// Step 4: Initiate function calling
// Paste the following code after the code from Step 3
import OpenAI from "openai";
const openai = new OpenAI(
{
// If you use a model in the China (Beijing) region, you need to use an API Key for the China (Beijing) region. Get the key from: https://bailian.console.alibabacloud.com/?tab=model#/api-key
// If you have not configured the environment variable, replace the following line with: apiKey: "sk-xxx", using your model Studio API key.
apiKey: process.env.DASHSCOPE_API_KEY,
// If you use a model in the China (Beijing) region, replace the baseURL with: 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", // This example uses qwen-plus. You can change the model name as needed. For a list of models, see https://www.alibabacloud.com/help/en/model-studio/getting-started/models
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, model menentukan bahwa fungsi tool yang akan digunakan bernama "get_current_weather", dan parameter input fungsi tersebut adalah "{\"location\": \"Shanghai\"}".
{
"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 model menentukan bahwa tidak ada tool yang diperlukan untuk pertanyaan tersebut, model akan langsung membalas melalui parameter content. Saat Anda memasukkan "Hello", parameter tool_calls kosong, dan objek yang dikembalikan memiliki format berikut:
{
"content": "Hello! How can I help you? I'm particularly good at answering questions about weather or time.",
"refusal": null,
"role": "assistant",
"audio": null,
"function_call": null,
"tool_calls": null
}Jika parametertool_callskosong, program Anda dapat langsung mengembalikancontenttanpa menjalankan langkah-langkah berikutnya.
Jika Anda ingin model selalu memilih tool tertentu setelah setiap pemanggilan fungsi, lihat Pemanggilan tool paksa.
4. Jalankan fungsi tool
Menjalankan fungsi tool adalah langkah kunci yang menerjemahkan keputusan model menjadi operasi aktual.
Proses menjalankan fungsi tool diselesaikan oleh lingkungan komputasi Anda, bukan oleh model.
Karena model hanya dapat menghasilkan konten dalam format string, Anda perlu mengurai string fungsi tool dan parameter input secara terpisah sebelum menjalankan fungsi tool.
Fungsi tool
Anda dapat membuat pemetaan
function_mapperdari nama fungsi tool ke entitas fungsi tool. Ini memetakan string fungsi tool yang dikembalikan ke entitas fungsi tool.Parameter input
Parameter input yang dikembalikan oleh pemanggilan fungsi berupa string JSON. Anda dapat menggunakan tool untuk menguraikannya menjadi objek JSON guna mengekstrak informasi parameter input.
Setelah penguraian, Anda dapat meneruskan parameter ke fungsi tool dan menjalankannya untuk mendapatkan hasil output.
# Step 5: Run the tool function
# Paste the following code after the code from Step 4
import json
print("Running the tool function...")
# Get the function name and input parameters from the returned result
function_name = completion.choices[0].message.tool_calls[0].function.name
arguments_string = completion.choices[0].message.tool_calls[0].function.arguments
# Use the json module to parse the parameter string
arguments = json.loads(arguments_string)
# Create a function mapping table
function_mapper = {
"get_current_weather": get_current_weather,
"get_current_time": get_current_time
}
# Get the function entity
function = function_mapper[function_name]
# If the input parameters are empty, call the function directly
if arguments == {}:
function_output = function()
# Otherwise, pass the parameters and then call the function
else:
function_output = function(arguments)
# Print the tool's output
print(f"Tool function output: {function_output}\n")// Step 5: Run the tool function
// Paste the following code after the code from Step 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;
// Use the JSON module to parse the parameter string
const args = JSON.parse(arguments_string);
// Create a function mapping table
const functionMapper = {
"get_current_weather": getCurrentWeather,
"get_current_time": getCurrentTime
};
// Get the function entity
const func = functionMapper[function_name];
// If the input parameters are empty, call the function directly
let functionOutput;
if (Object.keys(args).length === 0) {
functionOutput = func();
} else {
// Otherwise, pass the parameters and then call the function
functionOutput = func(args);
}
// Print the tool's output
console.log(`Tool function output: ${functionOutput}\n`);Output berikut dikembalikan:
Today in Shanghai it is Cloudy.Dalam skenario bisnis nyata, fungsi inti banyak tool adalah melakukan operasi spesifik, seperti mengirim email atau mengunggah file, bukan melakukan kueri data. Tool-tool ini tidak menghasilkan string setelah dieksekusi. Untuk membantu model memahami status eksekusi tool, kami merekomendasikan agar Anda menambahkan deskripsi status seperti "Email berhasil dikirim" atau "Operasi gagal" saat merancang tool semacam ini.
5. Model merangkum output fungsi tool
Format output fungsi tool relatif tetap. Jika dikembalikan langsung kepada pengguna, respons tersebut mungkin terdengar kaku dan tidak fleksibel. Jika Anda ingin model menghasilkan balasan dalam bahasa alami dengan menggabungkan input pengguna dan output tool, Anda dapat mengirimkan output tool ke konteks model dan mengirim permintaan lain ke model.
Tambahkan pesan asisten
Setelah Anda memulai pemanggilan fungsi, Anda dapat memperoleh Pesan Asisten melalui
completion.choices[0].message. Pertama, tambahkan pesan tersebut ke array `messages`.Tambahkan pesan tool
Anda dapat menambahkan output tool ke array messages sebagai
{"role": "tool", "content": "the tool's output","tool_call_id": completion.choices[0].message.tool_calls[0].id}.CatatanPastikan output tool dalam format string.
tool_call_idadalah pengidentifikasi unik yang dihasilkan sistem untuk setiap permintaan pemanggilan tool. Model mungkin meminta untuk memanggil beberapa tool sekaligus. Saat Anda mengembalikan beberapa hasil tool ke model,tool_call_idmemastikan bahwa output tool dapat dicocokkan dengan maksud pemanggilannya.
# Step 6: Submit the tool output to the Model
# Paste the following code after the code from Step 5
messages.append(completion.choices[0].message)
print("Assistant message added")
messages.append({"role": "tool", "content": function_output, "tool_call_id": completion.choices[0].message.tool_calls[0].id})
print("Tool message added\n")// Step 6: Submit the tool output to the Model
// Paste the following code after the code from Step 5
messages.push(completion.choices[0].message);
console.log("Assistant message added")
messages.push({
"role": "tool",
"content": functionOutput,
"tool_call_id": completion.choices[0].message.tool_calls[0].id
});
console.log("Tool message added\n");Pada titik ini, array messages adalah sebagai berikut:
[
System Message -- Guides the model's tool calling strategy
User Message -- The user's question
Assistant Message -- The tool call information returned by the model
Tool Message -- The tool's output information (there may be multiple Tool Messages if parallel tool calling, as described below, is used)
]Setelah memperbarui array messages, Anda dapat menjalankan kode berikut.
# Step 7: The model summarizes the tool output
# Paste the following code after the code from Step 6
print("Summarizing tool output...")
completion = function_calling()// Step 7: The model summarizes the tool output
// Paste the following code after the code from Step 6
console.log("Summarizing tool output...");
const completion_1 = await functionCalling();Anda dapat mengambil konten balasan dari content: "Today in Shanghai, the weather is cloudy. If you have any other questions, feel free to ask."
{
"content": "Today in Shanghai, the weather is cloudy. If you have any other questions, feel free to ask.",
"refusal": null,
"role": "assistant",
"audio": null,
"function_call": null,
"tool_calls": null
}Anda telah menyelesaikan proses pemanggilan fungsi secara lengkap.
Penggunaan lanjutan
Tentukan metode pemanggilan tool
Pemanggilan tool paralel
Pemanggilan tool tunggal sudah cukup untuk melakukan kueri cuaca di satu kota. Jika pertanyaan input memerlukan beberapa pemanggilan tool, seperti "What's the weather like in Beijing and Shanghai?" atau "What's the weather in Hangzhou, and what time is it now?", hanya satu instruksi pemanggilan tool yang dikembalikan setelah Anda memulai pemanggilan fungsi. Misalnya, jika Anda bertanya "What's the weather like in Beijing and Shanghai?", hasil berikut dikembalikan:
{
"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
}
]
}Hasil yang dikembalikan hanya berisi informasi parameter input untuk Beijing. Untuk mengatasi masalah ini, Anda dapat mengatur parameter permintaan parallel_tool_calls ke true saat Anda memulai pemanggilan fungsi. Dengan cara ini, objek yang dikembalikan berisi semua fungsi tool dan parameter input yang perlu dipanggil.
Pemanggilan tool paralel cocok untuk tugas-tugas yang tidak saling bergantung. Jika terdapat ketergantungan antar tugas, misalnya input untuk Tool A bergantung pada output dari Tool B, lihat Memulai dan gunakan while loop untuk mengimplementasikan pemanggilan tool serial (memanggil satu tool dalam satu waktu).
def function_calling():
completion = client.chat.completions.create(
model="qwen-plus", # This example uses qwen-plus. You can change the model name as needed.
messages=messages,
tools=tools,
# New parameter
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", // This example uses qwen-plus. You can change the model name as needed.
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 berisi informasi 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 tool paksa
Model menghasilkan konten dengan tingkat ketidakpastian tertentu dan terkadang memilih tool yang salah untuk dipanggil. Jika Anda ingin model menerapkan strategi yang ditentukan secara manual untuk jenis pertanyaan tertentu, seperti memaksa penggunaan tool tertentu atau memaksa tidak menggunakan tool, Anda dapat memodifikasi parameter tool_choice. Nilai default parameter tool_choice adalah "auto", yang berarti model secara mandiri memutuskan cara melakukan pemanggilan tool.
Saat model merangkum output fungsi tool, Anda harus menghapus parameter tool_choice. Jika tidak, API akan tetap mengembalikan informasi pemanggilan tool.Paksa tool tertentu
Jika Anda ingin pemanggilan fungsi secara paksa memanggil tool tertentu untuk jenis pertanyaan tertentu, Anda dapat mengatur parameter
tool_choiceke{"type": "function", "function": {"name": "the_function_to_call"}}. Model tidak berpartisipasi dalam pemilihan tool dan hanya menghasilkan informasi parameter input.Misalnya, jika skenario saat ini hanya melibatkan pertanyaan kueri cuaca, Anda dapat memodifikasi kode function_calling 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();Terlepas dari pertanyaan apa yang diajukan, fungsi tool dalam objek yang dikembalikan adalah
get_current_weather.Sebelum menggunakan strategi ini, pastikan pertanyaan relevan dengan tool yang dipilih. Jika tidak, Anda mungkin menerima hasil yang tidak diharapkan.
Paksa tanpa tool
Jika Anda ingin pemanggilan fungsi tidak pernah melakukan pemanggilan tool untuk pertanyaan apa pun, yang berarti objek yang dikembalikan berisi konten balasan dalam
contentdan parametertool_callskosong, Anda dapat mengatur parametertool_choiceke"none", atau tidak meneruskan parametertools. Parametertool_callsyang dikembalikan oleh pemanggilan fungsi selalu kosong.Misalnya, jika tidak ada pertanyaan dalam skenario saat ini yang memerlukan pemanggilan tool, Anda dapat memodifikasi kode function_calling 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 "What's the weather in Beijing?" pada putaran pertama, lalu "What about Shanghai?" pada putaran kedua. Jika konteks model tidak berisi informasi dari putaran pertama, model tidak dapat menentukan tool mana yang harus dipanggil. Kami merekomendasikan agar Anda mempertahankan array messages setelah setiap putaran dalam skenario percakapan multi-putaran. Anda dapat menambahkan User Message baru ke array ini dan kemudian memulai pemanggilan fungsi serta melakukan langkah-langkah selanjutnya. Struktur messages adalah sebagai berikut:
[
System Message -- Guides the model's tool calling strategy
User Message -- The user's question
Assistant Message -- The tool call information returned by the model
Tool Message -- The tool's output information
Assistant Message -- The model's summary of the tool call information
User Message -- The user's second-turn question
]Keluaran streaming
Untuk meningkatkan pengalaman pengguna dan mengurangi waktu tunggu, Anda dapat menggunakan keluaran streaming untuk mengambil nama fungsi tool dan informasi parameter input secara real-time. Dalam hal ini:
Informasi parameter pemanggilan tool: Ini dikembalikan dalam potongan-potongan sebagai aliran data.
Nama fungsi tool: Ini dikembalikan dalam potongan data pertama dari respons streaming.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# If you use a model in the China (Beijing) region, replace this with: 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": "This is useful when you want to query the weather in a specific 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": "What's the weather in Hangzhou?"}],
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(
{
// If you use a model in the China (Beijing) region, you must use an API key from the China (Beijing) region. Obtain the key at: https://bailian.console.alibabacloud.com/?tab=model#/api-key
// If the environment variable is not configured, replace the following line with your model Studio API key: apiKey: "sk-xxx",
apiKey: process.env.DASHSCOPE_API_KEY,
// If you use a model in the China (Beijing) region, replace the baseURL with: https://dashscope.aliyuncs.com/compatible-mode/v1
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
}
);
const tools = [
{
"type": "function",
"function": {
"name": "getCurrentWeather",
"description": "Useful for querying the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city or 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);
}Outputnya adalah sebagai berikut:
[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')]
NoneJalankan kode berikut untuk menyusun 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"}Saat model merangkum output fungsi tool, pesan asisten yang ditambahkan harus menggunakan format berikut. Ganti elemen dalam tool_calls dengan konten dari output 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,
}
],
}Untuk Qwen3-Omni-Flash
Pada tahap mendapatkan informasi tool, penggunaan model Qwen3-Omni-Flash berbeda dari model lain dalam hal-hal berikut:
Keluaran streaming bersifat wajib:
Qwen3-Omni-Flashhanya mendukung keluaran streaming. Anda juga harus mengaturstream=Truesaat mengambil informasi tool.Keluaran teks saja direkomendasikan: Model hanya memerlukan informasi teks untuk mengambil informasi tool, seperti nama fungsi dan parameter. Untuk menghindari pembuatan audio yang tidak perlu, kami merekomendasikan agar Anda mengatur
modalities=["text"]. Saat output mencakup modalitas teks dan audio, Anda perlu melewati potongan data audio saat mengambil informasi tool.
Untuk informasi selengkapnya tentang Qwen3-Omni-Flash, lihat omni-modal.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# If you use a model in the China (Beijing) region, replace this with: 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": "This is useful when you want to query the weather in a specific 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": "What's the weather in Hangzhou?"}],
# Set the modality of the output data. Valid values: ["text"], ["text","audio"]. We recommend setting this to ["text"].
modalities=["text"],
# stream must be set to True, otherwise an error will be reported.
stream=True,
tools=tools
)
for chunk in completion:
# If the output includes the audio modality, change the following condition to: 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(
{
// If you use a model in the China (Beijing) region, you need to use an API Key for the China (Beijing) region. Get the key from: https://bailian.console.alibabacloud.com/?tab=model#/api-key
// If you have not configured the environment variable, replace the following line with: apiKey: "sk-xxx", using your model Studio API key.
apiKey: process.env.DASHSCOPE_API_KEY,
// If you use a model in the China (Beijing) region, replace the baseURL with: https://dashscope.aliyuncs.com/compatible-mode/v1
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
}
);
const tools = [
{
"type": "function",
"function": {
"name": "getCurrentWeather",
"description": "This is useful when you want to query the weather in a specific 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,
// Set the modality of the output data. Valid values: ["text"], ["text","audio"]. We recommend setting this to ["text"].
modalities: ["text"],
tools:tools
});
for await (const chunk of stream) {
// If the output includes audio, replace the conditional statement with: 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')]
NoneUntuk kode yang menyusun parameter input (arguments), lihat Keluaran streaming.
Untuk model deep thinking
Model deep thinking berpikir sebelum menghasilkan informasi pemanggilan tool, yang dapat meningkatkan interpretabilitas dan keandalan keputusannya.
Proses berpikir
Model secara progresif menganalisis maksud pengguna, mengidentifikasi tool yang diperlukan, memvalidasi legalitas parameter, dan merencanakan strategi pemanggilan.
Pemanggilan tool
Model menghasilkan satu atau beberapa permintaan pemanggilan fungsi dalam format terstruktur.
Pemanggilan tool paralel didukung.
Bagian berikut menunjukkan contoh pemanggilan streaming ke model deep thinking untuk pemanggilan tool.
Untuk model thinking generasi teks, lihat Deep thinking. Untuk model thinking multimodal, lihat Visual understanding dan Omni-modal.
tool_choicehanya mendukung pengaturan ke"auto", yang merupakan nilai default dan berarti model memilih tool secara mandiri, atau"none", yang memaksa model tidak memilih tool.
Kompatibel dengan OpenAI
Python
Kode contoh
import os
from openai import OpenAI
# Initialize the OpenAI client and configure the Alibaba Cloud DashScope service
client = OpenAI(
# If you have not configured the environment variable, replace the following line with: api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"), # Read API key from environment variable
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
# Define the list of available tools
tools = [
# Tool 1: Get the current time
{
"type": "function",
"function": {
"name": "get_current_time",
"description": "This is useful when you want to know the current time.",
"parameters": {} # No parameters needed
}
},
# Tool 2: Get the weather for a specified city
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "This is useful when you want to query the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"] # Required parameter
}
}
}
]
messages = [{"role": "user", "content": input("Please enter your question: ")}]
# Example message for the Qwen3-VL model
# 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": "What is the current weather at the location in the image?"}]
# }]
completion = client.chat.completions.create(
# This example uses qwen-plus. It can be replaced with other deep thinking models.
model="qwen-plus",
messages=messages,
extra_body={
# Enable deep thinking. This parameter is invalid for qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, and QwQ models.
"enable_thinking": True
},
tools=tools,
parallel_tool_calls=True,
stream=True,
# Uncomment to get token consumption information
# stream_options={
# "include_usage": True
# }
)
reasoning_content = "" # Defines the complete thinking process
answer_content = "" # Defines the complete reply
tool_info = [] # Stores tool call information
is_answering = False # Determines if the thinking process has ended and the reply has begun
print("="*20+"Thinking Process"+"="*20)
for chunk in completion:
if not chunk.choices:
# Process usage statistics
print("\n"+"="*20+"Usage"+"="*20)
print(chunk.usage)
else:
delta = chunk.choices[0].delta
# Process the AI's thinking process (chain of thought)
if hasattr(delta, 'reasoning_content') and delta.reasoning_content is not None:
reasoning_content += delta.reasoning_content
print(delta.reasoning_content,end="",flush=True) # Output the thinking process in real time
# Process the final reply content
else:
if not is_answering: # Print the title when entering the reply phase for the first time
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) # Stream the reply content
# Process tool call information (supports parallel tool calls)
if delta.tool_calls is not None:
for tool_call in delta.tool_calls:
index = tool_call.index # Tool call index, for parallel calls
# Dynamically expand the tool information storage list
while len(tool_info) <= index:
tool_info.append({})
# Collect the tool call ID (for subsequent function calls)
if tool_call.id:
tool_info[index]['id'] = tool_info[index].get('id', '') + tool_call.id
# Collect the function name (for subsequent routing to a specific function)
if tool_call.function and tool_call.function.name:
tool_info[index]['name'] = tool_info[index].get('name', '') + tool_call.function.name
# Collect function arguments (in JSON string format, requires subsequent parsing)
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 "Weather in the four municipalities", hasil berikut dikembalikan:
====================Thinking Process====================
Okay, the user is asking for the "weather in the four municipalities". First, I need to identify which four municipalities are being referred to. 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, which takes a location of type string as a parameter. 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 make sure the parameter name is `location` and the value is the correct city name.
Also, the user probably wants the weather information for each city, so I need to ensure each function call is correct. It might require four consecutive calls, one for each city. However, based on the tool usage rules, it might need to be handled in multiple steps, or multiple calls might be generated at once. But based on the example, it seems only one function is called at a time, so it might need to be done step by step.
Finally, I need to confirm if there are any other factors to consider, such as whether the parameters are correct, the city names are accurate, and whether to handle possible error situations, like the 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({
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: "This is useful when you want to know the current time.",
parameters: {}
}
},
{
type: "function",
function: {
name: "get_current_weather",
description: "This is useful when you want to query the weather in a specific 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 }];
// Example message for the Qwen3-VL model
// 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) + "Thinking Process" + "=".repeat(20));
try {
const stream = await openai.chat.completions.create({
// This example uses qwen-plus. It can be replaced with other deep thinking models.
model: "qwen-plus",
messages,
// Enable deep thinking. This parameter is invalid for qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, and QwQ models.
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;
// Process thinking process
if (delta.reasoning_content) {
reasoningContent += delta.reasoning_content;
process.stdout.write(delta.reasoning_content);
}
// Process reply content
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);
}
// Process tool calls
if (delta.tool_calls) {
for (const toolCall of delta.tool_calls) {
const index = toolCall.index;
// Ensure array length is sufficient
while (toolInfo.length <= index) {
toolInfo.push({});
}
// Update tool ID
if (toolCall.id) {
toolInfo[index].id = (toolInfo[index].id || "") + toolCall.id;
}
// Update function name
if (toolCall.function?.name) {
toolInfo[index].name = (toolInfo[index].name || "") + toolCall.function.name;
}
// Update parameters
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 "Weather in the four municipalities", hasil berikut dikembalikan:
Please enter your question: Weather in the four municipalities
====================Thinking Process====================
Okay, the user is asking about the weather in the four municipalities. First, I need to clarify which four municipalities in China are being referred to. Beijing, Shanghai, Tianjin, and Chongqing, right? Next, I need to call the weather query function for each city.
However, the user's question may require me to get the weather conditions for these four cities separately. Each city requires a call to the get_current_weather function, with its respective city name as the parameter. I need to make sure the parameters are correct, such as the full names of the municipalities, for example, "Beijing Municipality", "Shanghai Municipality", "Tianjin Municipality", and "Chongqing Municipality".
Then, I need to call the weather API for these four cities in sequence. Each call requires a separate tool_call. The user probably wants 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, one for each municipality. I will check if each parameter is correct and then arrange them in order. This way, the user will get the weather data for all 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": "This is useful when you want to know the current time.",
"parameters": {}
}
},
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "This is useful when you want to query the weather in a specific 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 = [
# Tool 1: Get the current time
{
"type": "function",
"function": {
"name": "get_current_time",
"description": "This is useful when you want to know the current time.",
"parameters": {} # Since getting the current time requires no input parameters, parameters is an empty dictionary.
}
},
# Tool 2: Get the weather for a specified city
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "This is useful when you want to query the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
# A location is required to query the weather, so the parameter is set to location.
"location": {
"type": "string",
"description": "A city or district, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"]
}
}
}
]
# Define the question
messages = [{"role": "user", "content": input("Please enter your question: ")}]
# Example message for Qwen3-VL
# messages = [
# {
# "role": "user",
# "content": [
# {"image": "https://img.alicdn.com/imgextra/i2/O1CN01FbTJon1ErXVGMRdsN_!!6000000000405-0-tps-1024-683.jpg"},
# {"text": "Weather at the image location?"}]
# }]
# If you use the Qwen3-VL model, replace Generation with the MultiModalConversation interface.
completion = dashscope.Generation.call(
# This example uses qwen-plus. It can be replaced with other deep thinking models.
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+"Thinking Process"+"="*20)
for chunk in completion:
if chunk.status_code == 200:
msg = chunk.output.choices[0].message
# Process thinking process
if 'reasoning_content' in msg and msg.reasoning_content:
reasoning_content += msg.reasoning_content
print(msg.reasoning_content, end="", flush=True)
# Process reply content
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)
# Process tool calls
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': ''}) # Initialize all fields
# Incrementally update tool ID
if 'id' in tool_call:
tool_info[index]['id'] += tool_call.get('id', '')
# Incrementally update function information
if 'function' in tool_call:
func = tool_call['function']
# Incrementally update function name
if 'name' in func:
tool_info[index]['name'] += func.get('name', '')
# Incrementally update parameters
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
Memasukkan "Weather in the four municipalities" menghasilkan hasil berikut:
Please enter your question: Weather in the four municipalities
====================Thinking Process====================
Okay, the user is asking about the weather in the four municipalities. First, I need to confirm which four municipalities in China are being referred to. 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.
However, a problem arises: the user did not specify the city names, only "the 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 need to 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 a municipality like Chongqing, a more specific district might sometimes be needed, but the user probably only needs 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 conditions for all four cities.
Finally, I will ensure that the parameters for each call are correct and that none are missed. This will provide a complete answer to the user's question.
===================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 this.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));
}
// Create a tool calling method for text generation models
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));
}
// Build text generation model parameters that support tool calling
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();
}
// Create a tool calling method for the qwen3-vl-plus model
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)));
}
// Build Qwen3-vl model parameters that support tool calling
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") // Use the multimodal model Qwen3-vl
.enableThinking(true)
.messages(Arrays.asList(userMsg))
.tools(Arrays.asList( // Configure the tool list
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);
}
// If you use the Qwen3-VL model for tool calling, uncomment the following lines.
// 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", "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"}}]}}
{"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":" there are 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 there is 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"}}]}}
{"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":" other 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"}}]}}
{"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":" about the weather. Next, I will 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 will 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 will 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
# ======= Important Note =======
# If you use the Qwen3-VL model, modify the message parameter and replace the URL with https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation
# API keys for the Singapore and China (Beijing) regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
# The following is the URL for the Singapore region. If you use a model in the Beijing region, replace the URL with: https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
# === Please delete this comment before execution ===
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": "This is useful when you want to know the current time.",
"parameters": {}
}
},{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "This is useful when you want to query the weather in a specific 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 tool
Bangun sistem evaluasi:
Buat set data uji yang mencerminkan skenario bisnis nyata dan definisikan metrik evaluasi yang jelas, seperti akurasi pemilihan tool, akurasi ekstraksi parameter, dan tingkat keberhasilan end-to-end.
Optimalkan prompt
Jika pengujian mengungkapkan masalah seperti pemilihan tool yang salah atau parameter yang tidak tepat, Anda dapat melakukan optimasi yang ditargetkan pada prompt sistem, deskripsi tool, dan deskripsi parameter. Ini adalah metode penyetelan inti.
Tingkatkan model
Jika rekayasa prompt gagal meningkatkan kinerja, meningkatkan ke versi model yang lebih canggih, seperti
qwen3-max-preview, adalah cara paling langsung dan efektif untuk meningkatkan metrik.
Kontrol dinamis jumlah tool
Saat jumlah tool yang diintegrasikan ke dalam aplikasi besar, seperti puluhan atau bahkan ratusan, menyediakan seluruh pustaka tool ke model dapat menyebabkan masalah berikut:
Penurunan kinerja: Menjadi jauh lebih sulit bagi model untuk memilih tool yang tepat dari kumpulan tool yang sangat besar.
Biaya dan latensi: Banyak deskripsi tool mengonsumsi banyak token input, yang meningkatkan biaya dan memperlambat respons.
Solusinya adalah menambahkan lapisan perutean atau pengambilan tool sebelum memanggil model. Lapisan ini dengan cepat dan akurat menyaring subset tool yang kecil dan relevan dari pustaka tool lengkap berdasarkan kueri pengguna saat ini, lalu menyediakan subset ini ke model.
Berikut adalah beberapa metode utama untuk mengimplementasikan perutean tool:
Pengambilan semantik
Mengonversi informasi deskripsi (
description) semua tool menjadi vektor menggunakan model penyematan dan menyimpannya dalam database vektor. Saat pengguna memasukkan kueri, Anda dapat menggunakan pencarian kemiripan vektor pada vektor kueri untuk mengingat K tool teratas yang paling relevan.Pengambilan hibrid
Menggabungkan kemampuan "pencocokan fuzzy" dari pengambilan semantik dengan kemampuan "pencocokan eksak" dari kata kunci tradisional atau tag metadata. Menambahkan field
tagsataukeywordske tool dan melakukan pencarian vektor serta penyaringan kata kunci secara simultan selama pengambilan dapat secara signifikan meningkatkan presisi recall untuk skenario frekuensi tinggi atau spesifik.Router LLM ringan
Untuk logika perutean yang lebih kompleks, Anda dapat menggunakan model yang lebih kecil, lebih cepat, dan lebih murah, seperti Qwen-Flash, sebagai "model router" pra-perutean. Tugasnya adalah menghasilkan daftar nama tool yang relevan berdasarkan pertanyaan pengguna.
Saran praktis
Jaga agar set kandidat tetap ringkas: Terlepas dari metode yang digunakan, kami merekomendasikan untuk menyediakan tidak lebih dari 20 tool ke model utama. Angka ini mewakili keseimbangan optimal antara beban kognitif model, biaya, latensi, dan akurasi.
Strategi penyaringan berlapis: Anda dapat membangun kebijakan perutean berbentuk corong. Misalnya, Anda dapat terlebih dahulu menggunakan pencocokan kata kunci atau aturan berbiaya rendah untuk penyaringan awal guna menyaring tool yang tidak relevan, lalu melakukan pengambilan semantik pada tool yang tersisa untuk meningkatkan efisiensi dan kualitas.
Prinsip keamanan tool
Saat Anda mengaktifkan kemampuan eksekusi tool untuk model, keamanan harus menjadi prioritas utama Anda. Prinsip intinya adalah prinsip hak istimewa minimal dan konfirmasi manusia.
Prinsip hak istimewa minimal: Set tool yang disediakan ke model harus secara ketat mematuhi prinsip hak istimewa minimal. Secara default, tool harus read-only, seperti melakukan kueri cuaca atau mencari dokumen, dan hindari langsung menyediakan izin "write" apa pun yang melibatkan perubahan status atau operasi sumber daya.
Isolasi tool berbahaya: Jangan langsung menyediakan tool berbahaya ke model, seperti tool untuk mengeksekusi kode arbitrer (
code interpreter), mengoperasikan sistem file (fs.delete), melakukan operasi hapus atau perbarui database (db.drop_table), atau mentransfer dana (payment.transfer).Manusia dalam proses: Untuk semua operasi berhak tinggi atau tidak dapat diubah, Anda harus memperkenalkan langkah tinjauan dan konfirmasi manual. Model dapat menghasilkan permintaan operasi, tetapi pengguna manusia harus mengklik "tombol" eksekusi akhir. Misalnya, model dapat menyiapkan email, tetapi pengguna harus mengonfirmasi operasi pengiriman.
Optimasi pengalaman pengguna
Rantai pemanggilan fungsi panjang, dan masalah pada langkah apa pun dapat menurunkan pengalaman pengguna.
Atasi kegagalan eksekusi tool
Kegagalan eksekusi tool umum terjadi. Anda dapat mengadopsi strategi berikut:
Jumlah maksimum percobaan ulang: Tetapkan batas percobaan ulang yang wajar, misalnya 3, untuk menghindari waktu tunggu pengguna yang lama atau pemborosan sumber daya sistem akibat kegagalan berkelanjutan.
Berikan respons cadangan: Saat percobaan ulang habis atau terjadi kesalahan yang tidak dapat diselesaikan, Anda harus mengembalikan petunjuk yang jelas dan ramah kepada pengguna, misalnya: "Maaf, saya tidak dapat menemukan informasi yang relevan saat ini. Layanan mungkin sedang sibuk. Silakan coba lagi nanti."
Atasi penundaan pemrosesan
Latensi tinggi dapat mengurangi kepuasan pengguna dan harus diatasi melalui interaksi frontend dan optimasi backend.
Tetapkan batas waktu: Tetapkan batas waktu yang independen dan wajar untuk setiap langkah pemanggilan fungsi. Begitu terjadi timeout, operasi harus segera dihentikan dan umpan balik harus diberikan.
Berikan umpan balik instan: Saat Anda memulai proses pemanggilan fungsi, kami merekomendasikan agar Anda menampilkan petunjuk pada antarmuka, seperti "Mengkueri cuaca untuk Anda..." atau "Mencari informasi yang relevan...", untuk memberikan umpan balik real-time kepada pengguna mengenai kemajuan pemrosesan.
Deskripsi penagihan
Selain token dalam array messages, deskripsi tool ditambahkan ke prompt sebagai token input, yang juga dikenai biaya.
Teruskan informasi tool melalui system message
Kode error
Jika panggilan gagal, lihat Pesan error untuk troubleshooting.