Toolها (ابزارها) در هوش مصنوعی


مدل‌های زبانی بزرگ (LLMها) توانایی چشم‌گیری در تولید محتوا دارند، اما در انجام وظایف گسسته (مانند ریاضیات) و تعامل با دنیای بیرونی (مانند دریافت اطلاعات آب‌وهوا) با چالش‌هایی مواجه‌اند. Toolها یا ابزارها، توابعی هستند که یک مدل زبانی می‌تواند آن‌ها را فراخوانی کند. نتایج این توابع، می‌تواند به مدل بازگردانده شود تا در پاسخ بعدی مورد استفاده قرار گیرد.

به عنوان مثال، وقتی از یک مدل می‌پرسید: «هوای تهران چطور است؟» و ابزاری برای دریافت وضعیت آب‌وهوا در دسترس باشد، مدل می‌تواند این ابزار را با آرگومان «تهران» فراخوانی کند. ابزار، داده‌های مربوط به وضعیت آب‌وهوا را واکشی (fetch) کرده و به مدل بازمی‌گرداند. سپس مدل می‌تواند از این اطلاعات در پاسخ خود استفاده کند.

Tool در برنامه‌نویسی چیست؟

Tool، یک object قابل فراخوانی توسط مدل است که یک کار خاص را انجام می‌دهد. در حال حاضر، API لیارا، از دو نوع Tool زیر، پشتیبانی می‌کند:

  • Function calling
  • Web search

در ادامه، به توضیح هر یک از این Toolها پرداخته شده است.

فراخوانی تابع (Function calling)

با استفاده از قابلیت Function calling، شما می‌توانید به داده‌ها یا قابلیت‌هایی دسترسی پیدا کنید که به‌صورت مستقیم درون مدل در دسترس نیستند. در واقع، شما می‌توانید تابع مدنظر خودتان را در قالب یک Tool تعریف کنید و مدل می‌تواند این تابع را با پارامترهای مشخص شده فراخوانی کند.

وقتی که در برنامه خود، یک Function Calling تعریف می‌کنید؛ در حقیقت، به مدل این اجازه را می‌دهید که وقتی در دریافت ورودی (Prompt)، متوجه شود که سؤال کاربر مربوط به یک تابع مشخص است، به‌صورت خودکار پارامترهای موردنیاز آن تابع را استخراج کند و برای اجرای آن تابع پیشنهاد دهد.

در ادامه، نحوه استفاده از Function calling با استفاده از OpenAI SDK در زبان‌های برنامه‌نویسی مختلف، توضیح داده شده است.

در ابتدا، فرض کنید که تمام کارهای اتصال به مدل را با استفاده از ماژول openai انجام داده‌اید:

کپی
import { OpenAI } from "openai";

const openai = new OpenAI({
  baseURL: '<baseUrl>',
  apiKey: '<LIARA_API_KEY>',
});

اکنون، فرض کنید که در برنامه خود، یک تابع تعریف کرده‌اید که با گرفتن دو ورودی نام شهر و واحد دما، دمای هوای شهر مذکور را در خروجی، بر می‌گرداند:

کپی
function getCurrentWeather(location, unit = "celsius") {
  return {
    location: location,
    temperature: unit === "celsius" ? 35 : 68, // Celsius or Fahrenheit
    unit: unit,
    condition: "Sunny"
  };
}

در نظر داشته باشید که تابع فوق، یک تابع شبیه‌سازی‌شده (mocked) است. در اصل، این تابع، هیچ‌گونه داده واقعی را واکشی نمی‌کند و فقط یک پاسخ ثابت را برمی‌گرداند. در صورتی که، واحد دما، celsius باشد، دمای ۳۵ درجه سانتی‌گراد و در غیر این صورت، دمای ۶۸ درجه فارنهایت را برمی‌گرداند.

پس از ساخت openai برای اتصال به مدل و یک تابع برای دریافت وضعیت آب‌وهوا، اکنون باید یک Tool برای مدل تعریف کنید که تابع getCurrentWeather را به مدل معرفی کند. برای این‌کار یک آرایه یک عضوی به نام tools مشابه قطعه کد زیر، ایجاد کنید:

کپی
const tools = [{
    "type": "function",
    "function": {
        "name": "getCurrentWeather",
        "description": "Get current temperature for a given location.",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City and country e.g. Bogotá, Colombia"
                },
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
            },
            "required": [
                "location"
            ],  
        },
    }
}];

مدل، می‌تواند بیش از یک Tool داشته باشد؛ به‌همین خاطر، در این مثال، Toolها در قالب یک لیست تعریف شده‌اند.

در قطعه کد فوق، با استفاده از "type": "function"، نوع Tool، تابع تعریف شده است و با انجام این کار، مدل متوجه می‌شود که این Tool، عملیات پردازشی با ورودی/خروجی، انجام می‌دهد.

در ادامه، تابع، به شکل زیر تعریف شده است:

کپی
"function": {
  "name": "getCurrentWeather",
  "description": "Get current temperature for a given location.",
  "parameters": {
      "type": "object",
      "properties": {
          "location": {
              "type": "string",
              "description": "City and country e.g. Bogotá, Colombia"
          },
          "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
      },
      "required": [
          "location"
      ],  
  },
}

فیلد name اسم تابع است و باید با نام تابعی که در برنامه خود تعریف کرده‌اید، یکسان باشد. فیلد description، توضیحاتی درباره تابع است که به مدل کمک می‌کند تا متوجه شود این تابع چه کاری انجام می‌دهد و چه زمانی باید از آن استفاده کند.

فیلد parameters، ورودی‌های تابع، نوع آن‌ها و اجباری بودن یا اختیاری بودن استفاده از آن‌ها را مشخص می‌کند:

کپی
"parameters": {
  "type": "object",
  "properties": {
    "location": {
      "type": "string",
      "description": "The city and state, e.g. San Francisco, CA",
    },
    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
  },
  "required": ["location"],
  },

مقدار فیلد properties، یک Object است که شامل ورودی‌های تابع می‌باشد. در این مثال، تابع getCurrentWeather، دو ورودی به نام‌های location و unit دارد.

ورودی location، یک رشته است که نام شهر و ایالت را دریافت می‌کند و ورودی unit، یک رشته است که می‌تواند یکی از دو مقدار celsius یا fahrenheit باشد. فیلد enum، می‌گوید که این ورودی، محدود به یکی از مقادیر مشخص شده است.

فیلد required، مشخص می‌کند که ورودی location، اجباری است و مدل باید حتماً این ورودی را دریافت کند. ورودی‌های دیگر، اختیاری هستند و مدل می‌تواند آن‌ها را دریافت نکند.

پس از تعریف Tool، کافیست تا propmt نهایی که قرار است به مدل ارسال شود را، ایجاد کنید:

کپی
const messages = [{ role: "user", content: "What is the weather like in Paris today?" }];

حال، شما می‌توانید با استفاده از متد chat.completions.create و مانند شکل زیر، پرامپت را به مدل ارسال کنید:

کپی
const completion = await openai.chat.completions.create({
    model: "openai/gpt-4.1",
    messages: messages,
    tools,
    tool_choice: "auto",
});

در قطعه کد فوق، با استفاده از model، مدل مورد نظر برای پردازش پرامپت مشخص شده است. با استفاده از messages، پرامپت به مدل ارسال می‌شود و با استفاده از tools، Toolهایی که مدل می‌تواند از آن‌ها استفاده کند، مشخص شده است. وقتی که مقدار فیلد tool_choice، بر روی auto تنظیم شده باشد، خود مدل تصمیم می‌گیرد که آیا لازم است از توابع تعریف‌شده استفاده کند یا خیر.

خروجی completion، شامل اطلاعات مربوط به پاسخ مدل است. برای مشاهده خروجی خواناتر، می‌توان مانند قطعه کد زیر، عمل کرد:

کپی
console.log(JSON.stringify(completion, null, 2));

خروجی، به شکل زیر خواهد بود:

کپی
{
  "id": "6834381c546e1efa313fa872",
  "model": "openai/gpt-4.1",
  "object": "chat.completion",
  "created": 1748252700,
  "choices": [
    {
      "logprobs": null,
      "finish_reason": "tool_calls",
      "native_finish_reason": "tool_calls",
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "",
        "refusal": null,
        "reasoning": null,
        "tool_calls": [
          {
            "index": 0,
            "id": "call_DzeyygbKgYRe6gYvk73fv152",
            "type": "function",
            "function": {
              "name": "getCurrentWeather",
              "arguments": "{"location":"Paris, France"}"
            }
          }
        ]
      }
    }
  ],
  "usage": {
    "prompt_tokens": 77,
    "completion_tokens": 17,
    "total_tokens": 94,
    "prompt_tokens_details": {
      "cached_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0
    }
  }
}

نمودار قطعه کد JSON فوق، به شکل زیر است (برای وضوح بیشتر، بر روی تصویر کلیک کنید):

completion output

در ادامه، فیلدهای خروجی فوق، به‌صورت سطح به سطح، توضیح داده شده است:

سطح اول

  • id: شناسه یکتای درخواست ایجاد شده
  • model: نام مدل مورد استفاده
  • object: نوع شیء بازگشتی (همیشه chat.completion)
  • created: زمان ایجاد پاسخ (Unix Timestamp)
  • choices: لیست پاسخ‌های مدل (معمولاً فقط یکی)
  • usage: اطلاعات مربوط به تعداد توکن‌های استفاده‌شده

داخل choices[0]

  • logprobs: احتمال کلمات تولیدی (در حالت عادی null)
  • finish_reason: دلیل توقف تولید مدل (اینجا بخاطر فراخوانی ابزار)
  • native_finish_reason: مشابه finish_reason برای سازگاری با API جدید
  • index: شماره پاسخ در لیست (0 یعنی اولین)
  • message: پاسخ تولیدشده شامل محتوا و اطلاعات فراخوانی تابع

داخل choices[0].message

  • role: نقش گوینده (در اینجا assistant)
  • content: محتوای متنی پاسخ (در حالت فراخوانی ابزار، خالی است)
  • refusal , reasoning: قابلیت‌های جدیدتر (در اینجا همه null هستند)
  • tool_calls: لیست توابعی که مدل پیشنهاد اجرای آن‌ها را می‌دهد

داخل tool_calls[0]

  • index: شماره ترتیب این فراخوان در لیست tool_calls
  • id: شناسه فراخوان تابع توسط مدل
  • type: نوع فراخوان (اینجا همیشه function)
  • function.name: نام تابعی که مدل تصمیم می‌گیرد صدا بزند
  • function.arguments: پارامترهای استخراج‌شده از prompt به‌شکل رشته JSON

داخل usage

  • prompt_tokens: تعداد توکن‌های استفاده‌شده برای پیام‌های ورودی
  • completion_tokens: تعداد توکن‌های استفاده‌شده برای تولید پاسخ مدل
  • total_tokens: مجموع توکن‌ها (prompt + completion)
  • prompt_tokens_details: اطلاعات جزئی‌تر برای ورودی
  • cached_tokens: تعداد توکن‌هایی از ورودی که با استفاده از حافظه‌ی کش مدل، بدون پردازش مجدد مورد استفاده قرار گرفته‌اند (0 یعنی هیچی)
  • completion_tokens_details: جزئیات پیشرفته برای آنالیز مدل
  • reasoning_tokens: تعداد توکن‌هایی که مدل برای تحلیل، استدلال یا تصمیم‌گیری در فرآیند تولید پاسخ صرف کرده است

پس از دریافت خروجی، برای یافتن پارامترهایی که مدل برای فراخوانی تابع پیشنهاد داده است، می‌توان از کد زیر استفاده کرد:

کپی
const argsRaw = completion.choices[0].message.tool_calls[0].function.arguments;
const args = JSON.parse(argsRaw);
console.log(args);

خروجی کد فوق، مانند شکل زیر، خواهد بود:

کپی
{ location: 'Paris, France' }

خروجی فوق، نشان می‌دهد که مدل، با موفقیت، رابطه Tool با پرامپت را تشخیص داده و پارامترهای لازم برای فراخوانی تابع getCurrentWeather را استخراج کرده است. اکنون؛ می‌توان این پارامترها را به تابع getCurrentWeather ارسال کرد:

کپی
const weather = getCurrentWeather(
  args["location"],
  args["unit"] || "celsius"
);

در نهایت، می‌توان از خروجی تابع getCurrentWeather، برای پاسخ به کاربر استفاده کرد:

کپی
console.log(`The current weather in ${args.location} is ${weather.temperature}°${weather.unit === "celsius" ? "C" : "F"} and ${weather.condition}.`);

خروجی نهایی، به شکل زیر خواهد بود:

کپی
The current weather in Paris, France is 35°C and Sunny.

قطعه کد کامل برنامه، به شکل زیر است:

کپی
import { OpenAI } from "openai";

const openai = new OpenAI({
  baseURL: '<baseUrl>',
  apiKey: '<LIARA_API_KEY>',
});

function getCurrentWeather(location, unit = "celsius") {
  return {
    location: location,
    temperature: unit === "celsius" ? 35 : 68, // Celsius or Fahrenheit
    unit: unit,
    condition: "Sunny"
  };
}

const tools = [{
    "type": "function",
    "function": {
        "name": "getCurrentWeather",
        "description": "Get current temperature for a given location.",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City and country e.g. Bogotá, Colombia"
                },
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
            },
            "required": [
                "location"
            ],  
        },
    }
}];



const messages = [{ role: "user", content: "What is the weather like in Paris today?" }];

const completion = await openai.chat.completions.create({
    model: "openai/gpt-4.1",
    messages: messages,
    tools,
    tool_choice: "auto",
});

const argsRaw = completion.choices[0].message.tool_calls[0].function.arguments;
const args = JSON.parse(argsRaw);

const weather = getCurrentWeather(
  args["location"],
  args["unit"] || "celsius"
);

console.log(`The current weather in ${args.location} is ${weather.temperature}°${weather.unit === "celsius" ? "C" : "F"} and ${weather.condition}.`);

بدین صورت، شما می‌توانید با استفاده از قابلیت Function calling، توابع خود را به مدل معرفی کنید و از مدل، در پاسخ به سؤالات کاربران خود، استفاده کنید.

شما می‌توانید برنامه واقعی مثال فوق را در گیت‌هاب لیارا مشاهده و استفاده کنید.