Tool call (atau function call) memungkinkan model AI untuk berinteraksi dengan alat atau layanan eksternal melalui aplikasi Anda. Perlu dipahami bahwa model tidak mengeksekusi tool tersebut secara langsung. Model hanya menyarankan tool mana yang perlu dipanggil beserta argumennya. Aplikasi Anda lah yang bertanggung jawab menjalankan tool tersebut, lalu mengirimkan hasilnya kembali ke model agar model bisa menyusun jawaban akhir.
Pola ini sangat cocok digunakan untuk:
Lunos kompatibel dengan format standar OpenAI. Jika model yang Anda pilih mendukung tool calling, Anda dapat langsung menggunakan alur standar tools + tool_calls pada endpoint POST /v1/chat/completions.
Tidak semua model memiliki kemampuan tool calling. Sebelum mengandalkan fitur ini, pastikan Anda sudah memverifikasi model yang akan digunakan melalui API GET /v1/models.
Proses tool calling pada umumnya mengikuti tiga langkah berikut.
toolsSaat Anda ingin memberikan izin kepada model untuk memanggil tool tertentu, sertakan array tools di dalam body request chat.
Contoh (request awal):
{
"model": "openai/gpt-4o",
"messages": [
{
"role": "user",
"content": "What are the titles of some James Joyce books?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "searchBooks",
"description": "Search for books based on provided keywords",
"parameters": {
"type": "object",
"properties": {
"search_terms": {
"type": "array",
"items": { "type": "string" },
"description": "List of keywords to search for books"
}
},
"required": ["search_terms"]
}
}
}
]
}
Jika model memutuskan bahwa sebuah tool perlu dipanggil, response akan berisi properti tool_calls. Aplikasi Anda kemudian perlu:
tool_calls.Setelah tool berhasil dijalankan, kirimkan request chat baru yang berisi: konteks percakapan sebelumnya, pesan assistant yang berisi tool_calls, dan satu pesan bertipe tool untuk setiap hasil tool call.
Contoh (langkah mengirim hasil tool):
{
"model": "openai/gpt-4o",
"messages": [
{
"role": "user",
"content": "What are the titles of some James Joyce books?"
},
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "searchBooks",
"arguments": "{\"search_terms\":[\"James\",\"Joyce\"]}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "[{\"id\":4300,\"title\":\"Ulysses\",\"authors\":[{\"name\":\"Joyce, James\"}]}]"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "searchBooks",
"description": "Search for books based on provided keywords",
"parameters": {
"type": "object",
"properties": {
"search_terms": {
"type": "array",
"items": { "type": "string" },
"description": "List of keywords to search for books"
}
},
"required": ["search_terms"]
}
}
}
]
}
Setelah hasil tool tersedia, model akan menggunakan informasi tersebut untuk menyusun jawaban akhir yang lengkap.
Peringatan:
@lunos/clientbisa tertinggal dari API; jika contoh ini gagal, gunakan SDK JavaScript OpenAI denganbaseURLLunos.
Contoh berikut menunjukkan implementasi loop minimal yang:
tools.tool_call yang diminta model.tool kembali ke model.import { LunosClient } from "@lunos/client";
const client = new LunosClient({
apiKey: process.env.LUNOS_API_KEY!,
baseURL: "https://api.lunos.tech/v1",
appId: "tool-function-calling-v1",
});
const MODEL = "openai/gpt-4o";
const MAX_TOOL_ITERATIONS = 5;
const tools = [
{
type: "function",
function: {
name: "searchBooks",
description: "Search for books based on provided keywords",
parameters: {
type: "object",
properties: {
search_terms: {
type: "array",
items: { type: "string" },
description: "List of keywords to search for books",
},
},
required: ["search_terms"],
},
},
},
];
async function searchBooks(search_terms: string[]) {
const url = "https://gutendex.com/books";
const searchQuery = encodeURIComponent(search_terms.join(" "));
const response = await fetch(`${url}?search=${searchQuery}`);
const data = await response.json();
return (data.results ?? []).map((book: any) => ({
id: book.id,
title: book.title,
authors: book.authors,
}));
}
const TOOL_MAPPING: Record<
string,
(args: any) => Promise<unknown>
> = {
searchBooks: ({ search_terms }) => searchBooks(search_terms),
};
async function run() {
const baseMessages = [
{
role: "system",
content: "You are a helpful assistant.",
},
{
role: "user",
content: "What are the titles of some James Joyce books?",
},
];
let messages = [...baseMessages];
let iterations = 0;
let finalContent = "";
while (iterations < MAX_TOOL_ITERATIONS) {
iterations += 1;
const result = await client.chat.completions.create({
model: MODEL,
tools,
messages,
});
const assistantMessage = result.choices[0]?.message;
if (!assistantMessage) break;
const toolCalls = assistantMessage.tool_calls ?? [];
if (toolCalls.length === 0) {
finalContent = assistantMessage.content ?? "";
break;
}
const nextMessages: any[] = [...messages, assistantMessage];
for (const toolCall of toolCalls) {
const toolName = toolCall.function.name;
const rawArgs = toolCall.function.arguments ?? "{}";
const args = JSON.parse(rawArgs);
const toolFn = TOOL_MAPPING[toolName];
if (!toolFn) {
throw new Error(`No local tool handler for ${toolName}`);
}
const toolResult = await toolFn(args);
nextMessages.push({
role: "tool",
tool_call_id: toolCall.id,
content: JSON.stringify(toolResult),
});
}
messages = nextMessages;
}
console.log(finalContent);
}
void run();
Saat mendefinisikan tool, fokus utama Anda adalah kejelasan:
Sebelum digunakan di lingkungan produksi, pastikan:
Beberapa implementasi yang kompatibel dengan OpenAI menawarkan parameter tambahan untuk mengontrol perilaku tool. Jika model atau proxy Anda mendukungnya, berikut beberapa opsi yang mungkin tersedia:
tool_choice — untuk meminta model menggunakan tool tertentu atau menonaktifkan tool calling sama sekali.parallel_tool_calls — untuk mengatur apakah beberapa tool bisa diminta secara bersamaan dalam satu turn.Pastikan Anda selalu memeriksa dokumentasi parameter untuk model atau proxy yang sedang digunakan.
Beberapa model dapat melakukan proses reasoning (berpikir logis) dengan memanfaatkan hasil tool sebelum meminta tool berikutnya. Kemampuan ini sangat bermanfaat untuk meningkatkan kualitas jawaban dalam workflow yang bersifat bertahap.
Detail implementasinya bergantung pada model spesifik yang digunakan. Sebelum mengandalkan fitur ini, periksa terlebih dahulu apakah model mendukung mode reasoning yang relevan (misalnya melalui metadata model pada GET /v1/models), lalu pastikan nama parameter yang tersedia pada dokumentasi model Anda.
Jika Anda mengaktifkan mode streaming (stream: true), response akan dikirimkan dalam bentuk chunk secara bertahap. Tool calls bisa muncul sebagai delta, dan nilai finish_reason di akhir stream akan menunjukkan apakah model meminta tool tambahan atau sudah mengakhiri jawabannya.
Di sisi client, kumpulkan data tool_calls sampai stream menandakan saatnya untuk mengeksekusi tool. Jalankan tool secara lokal, lalu kirim hasilnya kembali dalam request lanjutan (bisa non-streaming atau dilanjutkan dalam loop sesuai implementasi Anda).
Beberapa implementasi mengizinkan model untuk meminta beberapa tool sekaligus dalam satu turn percakapan.
Jika Anda mengharuskan eksekusi tool berjalan secara berurutan (satu per satu), nonaktifkan fitur ini:
{
"parallel_tool_calls": false
}
Anda bisa mendefinisikan beberapa tool sekaligus dan membiarkan model merangkainya secara natural sesuai kebutuhan. Pendekatan ini paling efektif jika setiap tool memiliki tujuan yang sempit dan terdefinisi dengan jelas.
Contoh:
{
"tools": [
{
"type": "function",
"function": {
"name": "searchProducts",
"description": "Search for products in your catalog",
"parameters": {
"type": "object",
"properties": {
"query": { "type": "string" }
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "getProductDetails",
"description": "Fetch detailed information for a product",
"parameters": {
"type": "object",
"properties": {
"productId": { "type": "string" }
},
"required": ["productId"]
}
}
},
{
"type": "function",
"function": {
"name": "checkInventory",
"description": "Check inventory levels for a product",
"parameters": {
"type": "object",
"properties": {
"productId": { "type": "string" }
},
"required": ["productId"]
}
}
}
]
}
Tidak ada judul di halaman ini.
