Model bahasa besar (LLM) sering kurang optimal dalam menangani tugas yang sensitif terhadap waktu atau perhitungan matematis. Function Calling mengatasi keterbatasan ini dengan mengintegrasikan alat eksternal, sehingga memungkinkan LLM menjawab pertanyaan yang tidak dapat ditangani sendiri.
Cara kerja
Function Calling memungkinkan interaksi multi-langkah antara aplikasi Anda dan LLM, sehingga LLM dapat merujuk informasi dari alat eksternal saat menghasilkan respons.
Lakukan panggilan model pertama
Aplikasi Anda mengirim permintaan ke LLM yang mencakup pertanyaan pengguna dan daftar alat yang dapat dipanggil oleh model.
Terima instruksi pemanggilan alat dari model (nama alat dan parameter input)
Jika model menentukan bahwa diperlukan alat eksternal, model akan mengembalikan instruksi berformat JSON yang menentukan fungsi mana yang harus dijalankan dan parameter apa yang harus diteruskan.
Jika model menentukan tidak diperlukan alat, model akan mengembalikan respons dalam bahasa alami.
Jalankan alat dalam aplikasi Anda
Setelah menerima instruksi alat, aplikasi Anda menjalankan alat tersebut dan mengambil output-nya.
Lakukan panggilan model kedua
Setelah mengambil output alat, tambahkan ke konteks model (messages), lalu lakukan panggilan model lagi.
Terima respons akhir dari model
Model menggabungkan output alat dan pertanyaan pengguna untuk menghasilkan respons dalam bahasa alami.
Diagram alur kerja ditunjukkan di bawah ini:
Model yang didukung
Qwen
DeepSeek
deepseek-v3.2
deepseek-v3.2-exp (non-thinking mode)
deepseek-v3.1 (non-thinking mode)
deepseek-r1
deepseek-r1-0528
deepseek-v3
GLM
glm-5
glm-4.7
glm-4.6
Kimi
kimi-k2.5
kimi-k2-thinking
Moonshot-Kimi-K2-Instruct
MiniMax
MiniMax-M2.5
Memulai
Anda harus telah mendapatkan Kunci API dan mengonfigurasikannya sebagai variabel lingkungan (metode ini sedang ditinggalkan dan diintegrasikan ke dalam Configure API Key). Jika Anda melakukan panggilan melalui SDK OpenAI atau SDK DashScope, Anda harus menginstal SDK.
Contoh ini menunjukkan cara menggunakan Function Calling untuk pencarian cuaca.
Kompatibel dengan OpenAI
from openai import OpenAI
from datetime import datetime
import json
import os
import random
client = OpenAI(
# Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Untuk wilayah Beijing, gunakan: 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 in Singapore?"
# Definisikan daftar alat
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Useful when you want to check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, such as Singapore or New York.",
}
},
"required": ["location"],
},
},
},
]
# Simulasikan alat pencarian 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."
# Bungkus 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 pemanggilan alat, keluarkan konten secara langsung
if assistant_output.tool_calls is None:
print(f"No weather tool call needed. 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}] with arguments: {arguments}")
# Jalankan alat
tool_result = get_current_weather(arguments)
# Bangun respons 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';
// Inisialisasi klien
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
// Untuk wilayah Beijing, gunakan: https://dashscope.aliyuncs.com/compatible-mode/v1
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
});
// Tentukan daftar tool
const tools = [
{
type: "function",
function: {
name: "get_current_weather",
description: "Useful when you want to check the weather in a specific city.",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City or county, such as Singapore or New York.",
},
},
required: ["location"],
},
},
},
];
// Simulasikan tool pencarian 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 (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 in Singapore?";
let messages = [
{
role: "user",
content: input,
}
];
let response = await getResponse(messages);
let assistantOutput = response.choices[0].message;
// Pastikan konten tidak null
if (!assistantOutput.content) assistantOutput.content = "";
messages.push(assistantOutput);
// Periksa apakah pemanggilan tool diperlukan
if (!assistantOutput.tool_calls) {
console.log(`No weather tool call needed. Direct reply: ${assistantOutput.content}`);
} else {
// Masuk ke loop pemanggilan tool
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);
// Jalankan tool
const toolResult = getCurrentWeather(funcArgs);
// Buat tanggapan tool
const toolMessage = {
role: "tool",
tool_call_id: toolCallId,
content: toolResult,
};
console.log(`Tool returned: ${toolMessage.content}`);
messages.push(toolMessage);
// Panggil model lagi untuk mendapatkan ringkasan bahasa alami
response = await getResponse(messages);
assistantOutput = response.choices[0].message;
if (!assistantOutput.content) assistantOutput.content = "";
messages.push(assistantOutput);
}
console.log(`Final assistant reply: ${assistantOutput.content}`);
}
};
// Jalankan program
main().catch(console.error);DashScope
import os
from dashscope import Generation
import dashscope
import json
import random
# Untuk wilayah Beijing, gunakan: 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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, such as Singapore or New York.",
}
},
"required": ["location"],
},
},
}
]
# 2. Simulasikan alat pencarian 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. Bungkus fungsi respons model
def get_response(messages):
response = Generation.call(
# Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Jika Anda belum mengatur 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 in Singapore?"
}
]
# 5. Panggilan model pertama
response = get_response(messages)
assistant_output = response.output.choices[0].message
messages.append(assistant_output)
# 6. Periksa apakah diperlukan pemanggilan alat
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. Masuk ke loop pemanggilan alat
# Kondisi loop: lanjutkan 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 info 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}] with arguments: {arguments}")
# Jalankan fungsi alat yang sesuai
tool_result = get_current_weather(arguments)
# Bangun respons 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 untuk 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 {
/**
* Implementasi lokal alat.
* @param arguments String JSON berisi parameter alat yang diteruskan oleh model.
* @return String hasil setelah eksekusi alat.
*/
public static String getCurrentWeather(String arguments) {
try {
// Parameter dari model dalam format JSON dan harus 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) {
// Penanganan pengecualian untuk memastikan ketahanan.
return "Failed to parse location parameter.";
}
}
public static void main(String[] args) {
try {
// Daftarkan alat kami ke model.
String weatherParamsSchema =
"{\"type\":\"object\",\"properties\":{\"location\":{\"type\":\"string\",\"description\":\"City or county, such as Singapore or New York. \"}},\"required\":[\"location\"]}";
FunctionDefinition weatherFunction = FunctionDefinition.builder()
.name("get_current_weather") // Pengenal unik untuk alat. Harus sesuai dengan implementasi lokal.
.description("Useful when you want to check the weather in a specific city.") // Deskripsi jelas membantu model memutuskan kapan menggunakan alat.
.parameters(JsonUtils.parseString(weatherParamsSchema).getAsJsonObject())
.build();
// Untuk wilayah Beijing, gunakan: 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 in Singapore?";
List<Message> messages = new ArrayList<>();
messages.add(Message.builder().role(Role.USER.getValue()).content(userInput).build());
// Panggilan model pertama. Kirim permintaan pengguna dan daftar alat 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 berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
.messages(messages) // Teruskan riwayat percakapan saat ini.
.tools(Arrays.asList(ToolFunction.builder().function(weatherFunction).build())) // Teruskan 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 model pertama ke riwayat percakapan.
// Periksa balasan model untuk melihat apakah meminta pemanggilan alat.
if (assistantOutput.getToolCalls() == null || assistantOutput.getToolCalls().isEmpty()) {
// Kasus A: Model membalas langsung tanpa memanggil alat.
System.out.println("No weather tool call needed. Direct reply: " + assistantOutput.getContent());
} else {
// Kasus B: Model memutuskan untuk memanggil alat.
// Gunakan loop while untuk menangani beberapa pemanggilan alat.
while (assistantOutput.getToolCalls() != null && !assistantOutput.getToolCalls().isEmpty()) {
ToolCallBase toolCall = assistantOutput.getToolCalls().get(0);
// Uraikan detail pemanggilan alat (nama fungsi 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 + "] with arguments: " + arguments);
// Jalankan metode Java yang sesuai secara lokal.
String toolResult = getCurrentWeather(arguments);
// Bangun pesan dengan role "tool" 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 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 oleh model.
System.out.println("Final assistant reply: " + assistantOutput.getContent());
}
} catch (NoApiKeyException | InputRequiredException e) {
System.err.println("Error: " + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}Output setelah dijalankan:
Calling tool [get_current_weather] with arguments: {'location': 'Singapore'}
Tool returned: Singapore is cloudy today.
Final assistant reply: Today's weather in Singapore is cloudy.Cara menggunakan
Function Calling mendukung dua cara untuk meneruskan informasi alat:
Metode 1: Teruskan melalui parameter tools (direkomendasikan)
Lihat Cara menggunakan. Ikuti langkah-langkah berikut: Definisikan alat, Buat array messages, Mulai Function Calling, Jalankan fungsi alat, dan Rangkum output alat dengan LLM.
Metode 2: Teruskan melalui pesan sistem
Saat Anda meneruskan informasi alat melalui parameter tools, server secara otomatis memilih templat prompt terbaik dan menyusunnya. Oleh karena itu, kami merekomendasikan menggunakan parameter tools. Jika Anda tidak ingin menggunakan parameter tools dengan model Qwen, lihat Teruskan informasi alat melalui pesan sistem.
Contoh berikut menggunakan metode yang kompatibel dengan OpenAI dan menunjukkan cara menggunakan parameter tools untuk meneruskan informasi alat. Setiap langkah menjelaskan cara menggunakan Function Calling.
Asumsikan aplikasi Anda menangani dua jenis pertanyaan: pencarian cuaca dan pencarian waktu.
1. Definisikan alat
Alat menghubungkan LLM ke dunia luar. Mulailah dengan mendefinisikannya.
1.1. Buat fungsi alat
Buat dua fungsi alat: satu untuk pencarian cuaca dan satu untuk pencarian waktu.
Alat pencarian cuaca
Menerima parameter
arguments, di manaargumentsdalam format{"location": "lokasi yang ditanyakan"}. Alat ini menghasilkan string dalam format:"{lokasi} hari ini {cuaca}".Untuk menyederhanakan demo ini, alat cuaca tidak mengambil data cuaca nyata. Alat ini memilih secara acak dari cerah, berawan, atau hujan. Di produksi, gantilah dengan layanan nyata seperti Amap Weather API.
Alat pencarian waktu
Tidak memerlukan parameter input. Mengembalikan string seperti
“Waktu saat ini: {waktu}.”.Jika Anda menggunakan Node.js, jalankan
npm install date-fnsuntuk menginstal paket date-fns:
## Langkah 1: Definisikan fungsi alat
# Impor modul random
import random
from datetime import datetime
# Simulasikan alat pencarian cuaca. Contoh output: “Beijing hujan hari ini.”
def get_current_weather(arguments):
# Daftar kondisi cuaca yang mungkin
weather_conditions = ["sunny", "cloudy", "rainy"]
# Pilih kondisi cuaca secara acak
random_weather = random.choice(weather_conditions)
# Ekstrak lokasi dari JSON
location = arguments["location"]
# Kembalikan info cuaca yang diformat
return f"{location} is {random_weather} today."
# Cari waktu saat ini. Contoh output: “Waktu saat ini: 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 diformat
return f"Current time: {formatted_time}."
# Uji fungsi alat dan cetak hasilnya. Hapus empat baris ini sebelum menjalankan langkah selanjutnya.
print("Test tool output:")
print(get_current_weather({"location": "Shanghai"}))
print(get_current_time())
print("\n")// Langkah 1: Definisikan fungsi alat
// Impor alat pencarian waktu
import { format } from 'date-fns';
function getCurrentWeather(args) {
// Daftar kondisi cuaca yang mungkin
const weatherConditions = ["sunny", "cloudy", "rainy"];
// Pilih kondisi cuaca acak
const randomWeather = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];
// Ekstrak lokasi dari JSON
const location = args.location;
// Kembalikan informasi cuaca yang diformat
return `${location} is ${randomWeather} today.`;
}
function getCurrentTime() {
// Dapatkan tanggal dan waktu saat ini
const currentDatetime = new Date();
// Format tanggal dan waktu saat ini
const formattedTime = format(currentDatetime, 'yyyy-MM-dd HH:mm:ss');
// Kembalikan waktu saat ini yang diformat
return `Current time: ${formattedTime}.`;
}
// Uji fungsi alat dan cetak hasilnya. Hapus keempat baris ini sebelum menjalankan langkah-langkah berikutnya.
console.log("Test tool output:")
console.log(getCurrentWeather({location:"Shanghai"}));
console.log(getCurrentTime());
console.log("\n")Menjalankan alat memberikan output berikut:
Test 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 pengetahuan lengkap tentang alat tersebut: apa fungsinya, kapan menggunakannya, dan input apa yang dibutuhkan. LLM juga membutuhkan informasi yang sama untuk memilih alat secara akurat. Berikan informasi alat dalam format JSON di bawah ini.
| Untuk alat pencarian cuaca, informasinya tampak seperti ini: |
Sebelum memulai Function Calling, definisikan array tools dalam kode Anda. Sertakan nama, deskripsi, dan definisi parameter setiap alat. Anda akan meneruskan array ini sebagai parameter dalam permintaan Function Calling Anda.
# Tempelkan kode ini setelah 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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, 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 ini setelah 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 check the weather in a specific city.",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City or county, 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
Function Calling menggunakan array messages untuk mengirim instruksi dan konteks ke LLM. Sebelum memulai Function Calling, array messages harus mencakup pesan sistem dan pesan pengguna.
Pesan sistem
Meskipun Anda telah menjelaskan tujuan dan penggunaan alat pada langkah Buat array tools, menambahkan panduan yang jelas dalam pesan sistem sering kali meningkatkan akurasi pemilihan alat. Untuk skenario ini, atur prompt sistem menjadi:
You are a helpful assistant. If the user asks about weather, call the ‘get_current_weather’ function. If the user asks about time, call the ‘get_current_time’ function. Answer in a friendly tone.Pesan pengguna
Pesan pengguna meneruskan pertanyaan pengguna. Jika pengguna bertanya “Shanghai weather”, array messages tampak seperti ini:
# Langkah 3: Buat array messages
# Tempelkan kode ini setelah Langkah 2
# Pesan pengguna untuk model generasi teks
messages = [
{
"role": "system",
"content": """You are a helpful assistant. If the user asks about weather, call the ‘get_current_weather’ function. If the user asks about time, call the ‘get_current_time’ function. Answer in a friendly tone.""",
},
{
"role": "user",
"content": "Shanghai weather"
}
]
# Pesan pengguna untuk model multimodal
# messages=[
# {
# "role": "system",
# "content": """You are a helpful assistant. If the user asks about weather, call the ‘get_current_weather’ function. If the user asks about time, call the ‘get_current_time’ function. 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": "Check current weather for the location in the image"}]},
# ]
print("messages array created\n") // Langkah 3: Buat array messages
// Tempelkan kode ini setelah Langkah 2
const messages = [
{
role: "system",
content: "You are a helpful assistant. If the user asks about weather, call the ‘get_current_weather’ function. If the user asks about time, call the ‘get_current_time’ function. Answer in a friendly tone.",
},
{
role: "user",
content: "Shanghai weather"
}
];
// Pesan pengguna 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 pencarian cuaca dan waktu, Anda juga dapat menanyakan waktu saat ini.
3. Memulai Function Calling
Teruskan array tools dan messages ke LLM untuk memulai Function Calling. LLM memutuskan apakah akan memanggil alat. Jika ya, LLM mengembalikan nama alat dan parameter.
Untuk model yang didukung, lihat Model yang didukung.
# Langkah 4: Mulai pemanggilan fungsi
# Tempelkan kode ini setelah Langkah 3
from openai import OpenAI
import os
client = OpenAI(
# Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Untuk wilayah Beijing, gunakan: 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 model. Ganti sesuai kebutuhan. Daftar model: https://www.alibabacloud.com/help/zh/model-studio/getting-started/models
model="qwen-plus",
messages=messages,
tools=tools
)
print("Response object:")
print(completion.choices[0].message.model_dump_json())
print("\n")
return completion
print("Initiating function calling...")
completion = function_calling()// Langkah 4: Mulai pemanggilan fungsi
// Tempelkan kode ini setelah Langkah 3
import OpenAI from "openai";
const openai = new OpenAI(
{
// Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: apiKey: "sk-xxx"
apiKey: process.env.DASHSCOPE_API_KEY,
// Untuk wilayah Beijing, gunakan: 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 model. Ganti sesuai kebutuhan. Daftar model: https://www.alibabacloud.com/help/zh/model-studio/getting-started/models
messages: messages,
tools: tools
});
console.log("Response object:");
console.log(JSON.stringify(completion.choices[0].message));
console.log("\n");
return completion;
}
const completion = await functionCalling();Karena pengguna menanyakan tentang cuaca Shanghai, LLM menentukan nama fungsi alat sebagai "get_current_weather" dan parameter input sebagai {"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 LLM memutuskan tidak diperlukan alat, LLM akan membalas langsung melalui parameter content. Saat Anda memasukkan “Hello”, parameter tool_calls kosong. Objek respons tampak seperti ini:
{
"content": "Hello! How can I help you? I am especially 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 mengembalikan nilaicontentsecara langsung. Lewati langkah-langkah berikutnya.
Untuk memaksa LLM memanggil alat tertentu setiap kali, lihat Paksa pemanggilan alat.
4. Jalankan fungsi alat
Menjalankan fungsi alat mengubah keputusan LLM menjadi tindakan.
Aplikasi Anda—bukan LLM—yang menjalankan fungsi alat.
Karena LLM hanya menghasilkan string, Anda harus mengurai nama alat dan parameter input sebelum menjalankan alat.
fungsi alat
Buat pemetaan dari nama fungsi alat ke entitas fungsi alat,
function_mapper, yang memetakan string fungsi alat yang dikembalikan ke entitas fungsi alat.Parameter input
Function Calling mengembalikan parameter input sebagai string JSON. Uraikan menjadi objek JSON untuk mengekstrak nilainya.
Setelah diurai, teruskan parameter ke fungsi alat dan jalankannya untuk mengambil hasilnya.
# Langkah 5: Jalankan fungsi alat
# Tempelkan kode ini setelah Langkah 4
import json
print("Running tool function...")
# Dapatkan nama fungsi dan parameter input dari respons
function_name = completion.choices[0].message.tool_calls[0].function.name
arguments_string = completion.choices[0].message.tool_calls[0].function.arguments
# Uraikan string parameter menggunakan modul json
arguments = json.loads(arguments_string)
# Buat tabel pemetaan fungsi
function_mapper = {
"get_current_weather": get_current_weather,
"get_current_time": get_current_time
}
# Dapatkan objek fungsi
function = function_mapper[function_name]
# Panggil fungsi tanpa parameter
if arguments == {}:
function_output = function()
# Jika tidak, panggil fungsi dengan parameter
else:
function_output = function(arguments)
# Cetak output alat
print(f"Tool function output: {function_output}\n")// Langkah 5: Jalankan fungsi alat
// Tempelkan kode ini setelah Langkah 4
console.log("Running 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;
// Uraikan string parameter menggunakan modul JSON
const args = JSON.parse(arguments_string);
// Buat tabel pemetaan fungsi
const functionMapper = {
"get_current_weather": getCurrentWeather,
"get_current_time": getCurrentTime
};
// Dapatkan objek fungsi
const func = functionMapper[function_name];
// Panggil fungsi tanpa parameter
let functionOutput;
if (Object.keys(args).length === 0) {
functionOutput = func();
} else {
// Jika tidak, panggil fungsi dengan parameter
functionOutput = func(args);
}
// Cetak output alat
console.log(`Tool function output: ${functionOutput}\n`);Output setelah dijalankan:
Shanghai is cloudy today.Dalam aplikasi nyata, banyak alat melakukan tindakan (seperti mengirim email atau mengunggah file), bukan hanya pencarian data. Alat-alat ini mungkin tidak mengembalikan string. Untuk membantu LLM memahami statusnya, tambahkan pesan status seperti “Email sent” atau “Operation failed” ke desain alat Anda.
5. Rangkum output alat dengan LLM
Output alat mengikuti format tetap. Mengembalikannya langsung kepada pengguna mungkin terdengar kaku atau tidak fleksibel. Untuk mendapatkan balasan dalam bahasa alami yang menggabungkan input pengguna dan output alat, kirimkan output alat ke konteks model dan panggil model lagi.
Tambahkan pesan asisten
Mulai Function Calling Setelah Anda memulai Function Calling, ambil Pesan Asisten menggunakan
completion.choices[0].message, dan tambahkan ke array messages terlebih dahulu.Tambahkan pesan alat
Tambahkan output alat ke array messages dalam format ini:
{"role": "tool", "content": "output alat","tool_call_id": completion.choices[0].message.tool_calls[0].id}.CatatanPastikan output alat adalah string.
tool_call_idadalah ID unik yang dihasilkan sistem untuk setiap pemanggilan alat. Model mungkin meminta beberapa alat sekaligus. Menggunakantool_call_idmemastikan setiap output alat sesuai dengan maksud pemanggilannya.
# Langkah 6: Kirim output alat ke LLM
# Tempelkan kode ini setelah Langkah 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")// Langkah 6: Kirim output alat ke LLM
// Tempelkan kode ini setelah Langkah 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");Array messages sekarang tampak seperti ini:
[
Pesan sistem -- Strategi untuk memandu pemanggilan alat
Pesan pengguna -- Pertanyaan pengguna
Pesan asisten -- Info pemanggilan alat dari model
Pesan alat -- Output alat (Jika menggunakan pemanggilan alat paralel, mungkin ada beberapa pesan alat)
]Setelah memperbarui array messages, jalankan kode berikut.
# Langkah 7: LLM merangkum output alat
# Tempelkan kode ini setelah Langkah 6
print("Summarizing tool output...")
completion = function_calling()// Langkah 7: LLM merangkum output alat
// Tempelkan kode ini setelah Langkah 6
console.log("Summarizing tool output...");
const completion_1 = await functionCalling();Anda mengambil balasan di bidang content: “Today’s weather in Shanghai is cloudy. Let me know if you have other questions.”
{
"content": "Today's weather in Shanghai is cloudy. Let me know if you have other questions.",
"refusal": null,
"role": "assistant",
"audio": null,
"function_call": null,
"tool_calls": null
}Anda telah menyelesaikan alur Function Calling secara lengkap.
Penggunaan lanjutan
Tentukan metode pemanggilan alat
Pemanggilan alat paralel
Pencarian cuaca untuk satu kota memerlukan satu pemanggilan alat. Tetapi beberapa pertanyaan memerlukan beberapa pemanggilan alat. Misalnya, “What is the weather in Beijing and Shanghai?” atau “What is the weather in Hangzhou and what time is it?” Setelah memulai Function Calling, hanya satu pemanggilan alat yang muncul dalam respons. Untuk “What is the weather in Beijing and Shanghai?”, respons tampak seperti ini:
{
"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
}
]
}Respons hanya berisi parameter input untuk Beijing. Untuk mengatasi masalah ini, saat Anda memulai Function Calling, atur parameter permintaan parallel_tool_calls ke true. Dengan cara ini, objek respons mencakup parameter input untuk semua fungsi alat yang perlu dipanggil.
Gunakan pemanggilan alat paralel saat tugas tidak memiliki dependensi. Jika tugas saling bergantung (misalnya, input alat A bergantung pada output alat B), lihat Memulai. Gunakan loop while untuk pemanggilan alat serial (satu per satu).
def function_calling():
completion = client.chat.completions.create(
model="qwen-plus", # Contoh model. Ganti sesuai kebutuhan
messages=messages,
tools=tools,
# Parameter baru
parallel_tool_calls=True
)
print("Response 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 model. Ganti sesuai kebutuhan
messages: messages,
tools: tools,
parallel_tool_calls: true
});
console.log("Response object:");
console.log(JSON.stringify(completion.choices[0].message));
console.log("\n");
return completion;
}
const completion = await functionCalling();Array tool_calls dalam objek respons 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"
}
]
}Paksa pemanggilan alat
Konten yang dihasilkan LLM tidak pasti, dan LLM kadang-kadang memilih alat yang salah untuk pemanggilan alat. Jika Anda ingin LLM mengikuti strategi yang ditentukan manusia untuk jenis pertanyaan tertentu—seperti memaksa penggunaan alat tertentu atau melarang penggunaan alat—Anda dapat memodifikasi parameter tool_choice. Nilai default parameter tool_choice adalah "auto", yang berarti LLM secara otonom memutuskan apakah dan bagaimana memanggil alat.
Hapus parameter tool_choice saat merangkum output alat. Jika tidak, API tetap mengembalikan info pemanggilan alat.Paksa alat tertentu
Untuk memaksa Function Calling menggunakan alat tertentu untuk pertanyaan tertentu, atur
tool_choiceke{"type": "function", "function": {"name": "the_function_to_call"}}. LLM melewati pemilihan alat dan hanya mengeluarkan parameter.Misalnya, jika aplikasi Anda hanya menangani pertanyaan cuaca, perbarui kode function_calling seperti ini:
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("Response object:"); console.log(JSON.stringify(response.choices[0].message)); console.log("\n"); return response; } const response = await functionCalling();Tidak peduli pertanyaan apa yang Anda ajukan, respons selalu menggunakan
get_current_weather.Sebelum menggunakan strategi ini, pastikan pertanyaan sesuai dengan alat yang dipilih. Jika tidak, hasilnya mungkin tidak sesuai harapan.
Blokir semua alat
Untuk memblokir pemanggilan alat untuk pertanyaan apa pun (sehingga respons mencakup
contenttetapi parametertool_callskosong), aturtool_choiceke"none"atau abaikan parametertools. Parametertool_callsselalu kosong.Misalnya, jika tidak ada pertanyaan yang memerlukan alat, perbarui kode function_calling seperti ini:
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("Response object:"); console.log(JSON.stringify(completion.choices[0].message)); console.log("\n"); return completion; } const completion = await functionCalling();
Percakapan multiputar
Pengguna mungkin bertanya “What is the weather in Beijing?” di putaran pertama dan “What about Shanghai?” di putaran kedua. Tanpa konteks putaran pertama, LLM tidak dapat menentukan alat mana yang harus dipanggil. Untuk percakapan multiputar, simpan array messages setelah setiap putaran. Kemudian tambahkan pesan pengguna dan mulai Function Calling serta langkah-langkah selanjutnya. Struktur messages tampak seperti ini:
[
Pesan sistem -- Strategi untuk memandu pemanggilan alat
Pesan pengguna -- Pertanyaan pengguna
Pesan asisten -- Info pemanggilan alat dari model
Pesan alat -- Output alat
Pesan asisten -- Ringkasan model atas pemanggilan alat
Pesan pengguna -- Pertanyaan putaran kedua
]Keluaran streaming
Untuk meningkatkan pengalaman pengguna dan mengurangi waktu tunggu, gunakan keluaran streaming untuk mengambil nama dan parameter alat secara real time. Begini caranya:
Parameter pemanggilan alat tiba dalam potongan.
Nama fungsi alat tiba di potongan pertama.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Untuk wilayah Beijing, gunakan: 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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, 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(
{
// Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: apiKey: "sk-xxx"
apiKey: process.env.DASHSCOPE_API_KEY,
// Untuk wilayah Beijing, gunakan: https://dashscope.aliyuncs.com/compatible-mode/v1
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
}
);
const tools = [
{
"type": "function",
"function": {
"name": "getCurrentWeather",
"description": "Useful when you want to check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"]
}
}
}
];
const stream = await openai.chat.completions.create({
model: "qwen-plus",
messages: [{ role: "user", content: "What's the weather in Beijing?" }],
tools: tools,
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0].delta;
console.log(delta.tool_calls);
}Output setelah dijalankan:
[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 ini untuk menggabungkan potongan parameter (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:
{"index":0,"id":"call_16c72bef988a4c6c8cc662","function":{"arguments":"{\"location\": \"Hangzhou\"}","name":"get_current_weather"},"type":"function"}Saat Anda merangkum output alat, pesan asisten harus sesuai dengan format di bawah ini. Cukup ganti elemen tool_calls dengan konten di atas.
{
"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 di atas menggunakan API Chat Completions dan DashScope OpenAI untuk pemanggilan alat. Jika Anda menggunakan Responses API OpenAI, alur keseluruhan sama. Namun, format antarmuka berbeda:
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 | | |
Output pemanggilan alat | response.choices[0].message.tool_calls | Item dalam response.output di mana tipe adalah function_call |
Kembalikan hasil alat | | |
Balasan 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 Model Studio Anda: api_key="sk-xxx"
# Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
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 is the weather like in Singapore?"
# Definisikan 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": "City or county, such as Singapore or London.",
}
},
"required": ["location"],
},
}
]
# Simulasikan alat pencarian 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."
# Bungkus 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 perlu memanggil alat, keluarkan konten secara langsung
if not function_calls:
print(f"Final assistant response: {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}] with arguments: {arguments}")
# Jalankan alat
tool_result = get_current_weather(arguments)
print(f"Tool result: {tool_result}")
# Tambahkan pasangan pemanggilan dan hasil alat ke konteks
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 response: {response.output_text}")
import OpenAI from "openai";
// Inisialisasi klien
const openai = new OpenAI({
// Kunci API berbeda-beda berdasarkan wilayah. Dapatkan kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan kunci API 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",
});
// Mendefinisikan daftar alat
const tools = [
{
type: "function",
name: "get_current_weather",
description: "Berguna ketika Anda ingin memeriksa cuaca di kota tertentu.",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "Kota atau kabupaten, seperti Singapura atau London.",
},
},
required: ["location"],
},
},
];
// Mensimulasikan alat pencarian 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.`;
};
// Membungkus fungsi tanggapan model
const getResponse = async (inputData) => {
const response = await openai.responses.create({
model: "qwen3.5-plus", // Pilihan: qwen3.5-flash, qwen3.5-flash-2026-02-23
input: inputData,
tools: tools,
});
return response;
};
const main = async () => {
const userQuestion = "What's the weather in Singapore?";
// Mempertahankan 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 diperlukan pemanggilan alat, keluarkan konten secara langsung
if (functionCalls.length === 0) {
console.log(`Tanggapan akhir asisten: ${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(`Memanggil alat [${funcName}] dengan argumen:`, args);
// Menjalankan alat
const toolResult = getCurrentWeather(args);
console.log(`Alat mengembalikan: ${toolResult}`);
// Menambahkan pemanggilan alat dan hasilnya ke konteks
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,
});
}
// Memanggil model lagi dengan konteks lengkap
response = await getResponse(conversation);
functionCalls = response.output.filter(
(item) => item.type === "function_call"
);
}
console.log(`Tanggapan akhir asisten: ${response.output_text}`);
}
};
// Menjalankan program
main().catch(console.error);
Pemanggilan alat dengan Qwen3-Omni-Flash
Selama tahap pengambilan informasi alat, Qwen3-Omni-Flash berbeda dari model lain dalam dua hal:
Keluaran streaming wajib:
Qwen3-Omni-Flashhanya mendukung keluaran streaming. Aturstream=Truesaat mengambil informasi alat.Keluaran hanya teks direkomendasikan: Saat mengambil informasi alat (nama fungsi dan parameter), hanya teks yang penting. Untuk menghindari audio yang tidak perlu, atur
modalities=["text"]. Jika output mencakup teks dan audio, lewati potongan audio saat mengambil informasi alat.
Untuk informasi lebih lanjut tentang Qwen3-Omni-Flash, lihat Non-real-time (Qwen-Omni).
from openai import OpenAI
import os
client = OpenAI(
# Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Untuk wilayah Beijing, gunakan: 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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, 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?"}],
# Atur modalitas output. Opsi: ["text"], ["text","audio"]. Direkomendasikan: ["text"]
modalities=["text"],
# stream harus True, atau gagal
stream=True,
tools=tools
)
for chunk in completion:
# Jika output mencakup audio, ubah kondisi 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. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan Kunci API Model Studio Anda: apiKey: "sk-xxx"
apiKey: process.env.DASHSCOPE_API_KEY,
// Untuk wilayah Beijing, gunakan: 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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"]
}
}
}
];
const stream = await openai.chat.completions.create({
model: "qwen3-omni-flash",
messages: [
{
"role": "user",
"content": "What's the weather in Hangzhou?"
}],
stream: true,
// Atur modalitas output. Opsi: ["text"], ["text","audio"]. Direkomendasikan: ["text"]
modalities: ["text"],
tools:tools
});
for await (const chunk of stream) {
// Jika output mencakup audio, ubah kondisi menjadi: 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 setelah dijalankan:
[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 menggabungkan potongan parameter (arguments), lihat Keluaran streaming.
Pemanggilan alat dengan model deep thinking
Model deep thinking melakukan penalaran sebelum mengeluarkan pemanggilan alat. Hal ini meningkatkan kemampuan menjelaskan keputusan dan keandalan.
Proses penalaran
Model menganalisis maksud pengguna, mengidentifikasi alat yang dibutuhkan, memvalidasi legalitas parameter, dan merencanakan strategi pemanggilan.
Pemanggilan alat
Model mengeluarkan satu atau beberapa pemanggilan fungsi dalam format terstruktur.
Mendukung pemanggilan alat paralel.
Berikut ini contoh streaming untuk model deep thinking.
Untuk model deep thinking generasi teks, lihat Deep thinking. Untuk model deep thinking multimodal, lihat Pemahaman gambar dan video dan Non-real-time (Qwen-Omni).
tool_choicehanya mendukung"auto"(default, model memilih alat) atau"none"(memblokir pemilihan alat).
Kompatibel dengan OpenAI
Python
Contoh kode
import os
from openai import OpenAI
# Inisialisasi klien OpenAI dengan layanan Alibaba Cloud DashScope
client = OpenAI(
# Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan Kunci API 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 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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"] # Parameter wajib
}
}
}
]
messages = [{"role": "user", "content": input("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?"}]
# }]
completion = client.chat.completions.create(
# Contoh model. Ganti dengan model deep thinking lainnya.
model="qwen-plus",
messages=messages,
extra_body={
# Aktifkan deep thinking. Ini tidak berpengaruh pada model qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, atau QwQ.
"enable_thinking": True
},
tools=tools,
parallel_tool_calls=True,
stream=True,
# Hapus komentar untuk mendapatkan info penggunaan token
# stream_options={
# "include_usage": True
# }
)
reasoning_content = "" # Proses penalaran lengkap
answer_content = "" # Balasan lengkap
tool_info = [] # Simpan info pemanggilan alat
is_answering = False # Bendera untuk melacak apakah penalaran berakhir dan balasan dimulai
print("="*20+"Reasoning process"+"="*20)
for chunk in completion:
if not chunk.choices:
# Tangani info penggunaan
print("\n"+"="*20+"Usage"+"="*20)
print(chunk.usage)
else:
delta = chunk.choices[0].delta
# Proses penalaran AI (rantai-pikiran)
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
# Proses konten balasan akhir
else:
if not is_answering: # Cetak judul hanya pada entri balasan pertama
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 info pemanggilan alat (mendukung pemanggilan 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 info alat secara dinamis
while len(tool_info) <= index:
tool_info.append({})
# Kumpulkan ID pemanggilan alat (untuk pemanggilan fungsi nanti)
if tool_call.id:
tool_info[index]['id'] = tool_info[index].get('id', '') + tool_call.id
# Kumpulkan nama fungsi (untuk mengarahkan ke fungsi yang benar)
if tool_call.function and tool_call.function.name:
tool_info[index]['name'] = tool_info[index].get('name', '') + tool_call.function.name
# Kumpulkan argumen fungsi (string JSON, perlu diurai nanti)
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 info"+"="*19)
if not tool_info:
print("No tool calls")
else:
print(tool_info)Respons
Masukkan “Weather in the four municipalities”, output:
====================Reasoning process====================
Okay, the user asked for “weather in the four municipalities.” First, I need to identify which cities are the four municipalities. According to China’s administrative divisions, they are Beijing, Shanghai, Tianjin, and Chongqing. So the user wants the weather for these four cities.
Next, I check the available tools. The tool provided is get_current_weather, with a location parameter of type string. Each city must be queried separately because the function can only handle one location at a time. Therefore, I need to make one call for each municipality.
Then, I consider how to generate the correct tool calls. Each call should include the city name as the parameter. For example, the first call is for Beijing, the second for Shanghai, and so on. Ensure the parameter name is location and the value is the correct city name.
Also, the user likely wants the weather for each city, so I need to ensure each function call is correct. Maybe I need to make four separate calls, one for each city. But based on the examples, it may involve making multiple calls step-by-step.
Finally, confirm if there are any other factors to consider, such as parameter correctness, city name accuracy, or error handling like city not found or API unavailable. But for now, the four municipalities are clear, so it should be fine.
====================Reply content====================
===================Tool call info===================
[{'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
Contoh kode
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. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
});
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 check the weather in a specific city.",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City or county, such as Beijing, Hangzhou, or Yuhang District."
}
},
required: ["location"]
}
}
}
];
async function main() {
const rl = readline.createInterface({ input, output });
const question = await rl.question("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 is 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 model. Ganti dengan model deep thinking lainnya.
model: "qwen-plus",
messages,
// Aktifkan deep thinking. Ini tidak berpengaruh pada model qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, atau 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 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 info" + "=".repeat(19));
console.log(toolInfo.length ? toolInfo : "No tool calls");
} catch (error) {
console.error("Error:", error);
}
}
main(); Respons
Masukkan “Weather in the four municipalities”, output:
Enter your question: Weather in the four municipalities
====================Reasoning process====================
Okay, the user asked for the weather in the four municipalities. First, I need to identify which cities are the four municipalities. Beijing, Shanghai, Tianjin, and Chongqing, right? Next, I need to call the weather lookup function for each city.
But the user’s question might require me to get the weather for each of these cities. Each city needs a separate call to get_current_weather, with its name as the parameter. I need to ensure the parameter is correct, such as “Beijing”, “Shanghai”, “Tianjin”, and “Chongqing”.
Then, I need to generate four tool calls, each for one municipality. Check each parameter to ensure it’s correct, then arrange them in order. This way, the user gets the weather data for all four municipalities.
====================Reply content====================
===================Tool call info===================
[
{
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
Contoh kode
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": "How is the weather 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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location":{
"type": "string",
"description": "City or county, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"]
}
}
}
],
"enable_thinking": true,
"stream": true
}'DashScope
Python
Contoh kode
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": {} # Tidak memerlukan parameter input, jadi dict kosong
}
},
# Alat 2: Dapatkan cuaca untuk kota tertentu
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Useful when you want to check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
# Lokasi diperlukan untuk pencarian cuaca, jadi parameternya adalah lokasi
"location": {
"type": "string",
"description": "City or county, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"]
}
}
}
]
# Definisikan pertanyaan
messages = [{"role": "user", "content": input("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 is the weather at the location in the image?"}]
# }]
# Gunakan antarmuka MultiModalConversation untuk model multimodal, bukan Generation
completion = dashscope.Generation.call(
# Contoh model. Ganti dengan model deep thinking 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 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 info 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 info"+"="*19)
if not tool_info:
print("No tool calls")
else:
print(tool_info)Respons
Masukkan “Weather in the four municipalities”, output:
Enter your question: Weather in the four municipalities
====================Reasoning process====================
Okay, the user asked for the weather in the four municipalities. First, I need to confirm which cities are the four municipalities. Beijing, Shanghai, Tianjin, and Chongqing, right? Next, the user needs the weather for each city, so I need to call the weather lookup function.
However, the question does not specify exact city names, just says “four municipalities.” I need to clarify each municipality’s name and then query their weather. For example, Beijing, Shanghai, Tianjin, and Chongqing. I need to call the get_current_weather function for each, passing the corresponding city name as the parameter. For instance, first call location is “Beijing”, second is “Shanghai”, third is “Tianjin”, fourth is “Chongqing”.
But I need to ensure each call’s parameters are correct and no omissions occur. This way, the user gets complete weather information for all four municipalities.
===================Tool call info===================
[{'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
Contoh kode
// DashScope SDK versi >= 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 dengan dukungan pemanggilan alat
private static GenerationParam buildGenerationParam(Message userMsg) {
FunctionDefinition fdWeather = buildFunctionDefinition(
"get_current_weather", "Get weather for a specified location", jsonSchemaWeather);
FunctionDefinition fdTime = buildFunctionDefinition(
"get_current_time", "Get 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 dengan dukungan pemanggilan alat
private static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage userMsg) {
FunctionDefinition fdWeather = buildFunctionDefinition(
"get_current_weather", "Get weather for a specified location", jsonSchemaWeather);
FunctionDefinition fdTime = buildFunctionDefinition(
"get_current_time", "Get 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( // Konfigurasi 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("Tell me the weather in Hangzhou")
.build();
try {
streamCallWithMessage(gen, userMsg);
} catch (InputRequiredException e) {
throw new RuntimeException(e);
}
// Hapus komentar untuk menggunakan model multimodal untuk pemanggilan alat
// 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 is 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);
}
}
Respons
{"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"}}]}}
{"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 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 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 parameter location"}}]}}
{"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 tools are needed"}}]}}
{"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":"because the user only asked about"}}]}}
{"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":"weather. Next, construct"}}]}}
{"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 tool_call, filling in the"}}]}}
{"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":"name and parameters. Make sure the parameters are"}}]}}
{"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":"in JSON format, with location as a string. Check for"}}]}}
{"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":"errors and proceed."}}]}}
{"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":"","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":106,"total_tokens":344},"output":{"choices":[{"finish_reason":"tool_calls","message":{"role":"assistant","content":"","reasoning_content":"","tool_calls":[{"type":"function","id":"","function":{"arguments":"\"}"}}]}}]}}HTTP
Contoh kode
curl
# ======= Catatan penting =======
# Untuk model multimodal, modifikasi parameter pesan dan ubah URL ke https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation
# Kunci API berbeda berdasarkan wilayah. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Untuk wilayah Beijing, ubah URL ke: 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": "What is the weather in Hangzhou?"
}
]
},
"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 check the weather in a specific city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or county, such as Beijing, Hangzhou, or Yuhang District."
}
},
"required": ["location"]
}
}
}]
}
}'Mulai Beroperasi
Uji akurasi pemanggilan alat
Bangun sistem evaluasi:
Buat set data uji yang mencerminkan skenario bisnis nyata. Definisikan metrik yang jelas, seperti akurasi pemilihan alat, akurasi ekstraksi parameter, dan tingkat keberhasilan end-to-end.
Optimalkan prompt
Berdasarkan masalah yang ditemukan dalam pengujian (pemilihan alat salah, parameter salah), sempurnakan prompt sistem, deskripsi alat, dan deskripsi parameter. Ini adalah metode penyetelan utama.
Tingkatkan model
Saat rekayasa prompt tidak dapat meningkatkan kinerja, meningkatkan ke model yang lebih canggih (seperti
qwen3-max-preview) adalah cara paling langsung dan efektif untuk meningkatkan metrik.
Kontrol jumlah alat secara dinamis
Saat aplikasi Anda mengintegrasikan puluhan atau ratusan alat, menyediakan pustaka alat lengkap ke model menyebabkan masalah:
Penurunan kinerja: Model kesulitan memilih alat yang tepat dari pustaka besar.
Biaya dan latensi: Deskripsi alat yang panjang menghabiskan banyak token input, meningkatkan biaya dan memperlambat respons.
Solusi: Tambahkan lapisan perutean atau pengambilan alat sebelum memanggil model. Berdasarkan kueri pengguna, saring dengan cepat dan akurat subset kecil alat yang relevan dari pustaka lengkap, lalu berikan subset tersebut ke model.
Metode populer untuk perutean alat:
Pencarian semantik
Pra-proses semua deskripsi alat (
description) menggunakan model penyematan untuk membuat vektor. Simpan vektor dalam database vektor. Saat kueri, konversi kueri pengguna menjadi vektor dan gunakan pencarian kemiripan vektor untuk mengambil K alat teratas yang paling relevan.Pencarian hibrid
Gabungkan “pencocokan kabur” pencarian semantik dengan “pencocokan eksak” kata kunci tradisional atau tag metadata. Tambahkan
tagsataukeywordske alat. Selama pencarian, jalankan pencarian vektor dan penyaringan kata kunci untuk meningkatkan presisi recall untuk skenario frekuensi tinggi atau spesifik.Router LLM ringan
Untuk logika perutean kompleks, gunakan model yang lebih kecil, lebih cepat, dan lebih murah (seperti Qwen-Flash) sebagai “model router”. Tugasnya adalah mengeluarkan daftar nama alat yang relevan berdasarkan pertanyaan pengguna.
Praktik terbaik
Pertahankan set kandidat kecil: Apa pun metodenya, batasi jumlah alat yang diteruskan ke model utama hingga paling banyak 20. Ini menyeimbangkan beban kognitif model, biaya, latensi, dan akurasi.
Strategi penyaringan berlapis: Bangun strategi perutean bergaya corong. Misalnya, pertama gunakan pencocokan aturan atau kata kunci berbiaya rendah untuk menyaring alat yang jelas tidak relevan, lalu jalankan pencarian semantik pada alat yang tersisa untuk meningkatkan efisiensi dan kualitas.
Prinsip keamanan alat
Saat memberikan kemampuan eksekusi alat ke LLM, keamanan harus diutamakan. 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 pencarian cuaca atau pencarian dokumen). Hindari memberikan akses langsung ke izin “write” apa pun yang mengubah status atau sumber daya.
Isolasi alat berbahaya: Jangan berikan alat berbahaya langsung ke LLM. Contohnya termasuk eksekusi kode arbitrer (
code interpreter), operasi sistem file (fs.delete), operasi hapus atau perbarui database (db.drop_table), atau alat transfer keuangan (payment.transfer).Keterlibatan manusia: Untuk semua tindakan berhak tinggi atau tidak dapat diubah, tambahkan tinjauan dan konfirmasi manual. Model dapat menghasilkan permintaan tindakan, tetapi tombol “execute” akhir harus diklik oleh pengguna manusia. Misalnya, model dapat menyusun email, tetapi pengiriman memerlukan konfirmasi pengguna.
Optimasi pengalaman pengguna
Function Calling melibatkan banyak langkah. Kegagalan pada langkah apa pun menurunkan pengalaman pengguna.
Tangani kegagalan eksekusi alat
Kegagalan eksekusi alat umum terjadi. Gunakan strategi ini:
Jumlah maksimum percobaan ulang: Tetapkan batas percobaan ulang yang wajar (seperti tiga kali) untuk menghindari waktu tunggu lama atau pemborosan sumber daya sistem akibat kegagalan berulang.
Pesan fallback: Saat percobaan ulang habis atau kesalahan tidak dapat diselesaikan, kembalikan pesan yang jelas dan ramah kepada pengguna. Misalnya: “Maaf, saya tidak dapat mengambil informasi tersebut saat ini. Layanan mungkin sedang sibuk. Silakan coba lagi nanti.”
Tangani penundaan pemrosesan
Latensi tinggi mengurangi kepuasan pengguna. Tingkatkan melalui interaksi frontend dan optimasi backend.
Tetapkan nilai timeout: Tetapkan timeout independen dan wajar untuk setiap langkah Function Calling. Saat timeout, hentikan segera dan berikan umpan balik.
Berikan umpan balik segera: Saat memulai Function Calling, tampilkan petunjuk di UI, seperti “Mencari cuaca untuk Anda…” atau “Mencari informasi terkait…”. Berikan pembaruan progres secara real time kepada pengguna.
Detail penagihan
Selain token dalam array messages, deskripsi alat juga dihitung sebagai token input dalam prompt untuk penagihan.
Teruskan informasi alat melalui pesan sistem
Kode kesalahan
Jika panggilan model gagal dan mengembalikan pesan kesalahan, lihat Pesan kesalahan untuk resolusi.