Function Calling چیست؟
ساخت AI Agent با OpenAI و Claude

قابلیتی که AI را از یک چت‌بات منفعل به یک ایجنت فعال تبدیل می‌کند

Function Calling انقلاب اصلی LLMها در سال‌های اخیر است. بدون آن، AI فقط یک تولیدکننده‌ی متن است — با آن، AI به یک ایجنت تبدیل می‌شود که می‌تواند آب‌وهوا را چک کند، دیتابیس را query بزند، ایمیل بفرستد، و پرداخت ثبت کند. در این مقاله یاد می‌گیریم چطور Function Calling در OpenAI، Claude و Gemini کار می‌کند، کد عملی Python برای هر سه، الگوی ReAct برای ساخت ایجنت‌های پیچیده، و نکات امنیتی که نباید فراموش کنی.

پاسخ کوتاه: Function Calling قابلیتی است که به مدل هوش مصنوعی اجازه می‌دهد به‌جای متن آزاد، یک خروجی ساخت‌یافته (JSON) تولید کند تا یک تابع یا API مشخص را فراخوانی کند. این همان پایه‌ی ساخت AI Agent است: مدل تصمیم می‌گیرد کدام ابزار را با چه ورودی‌هایی صدا بزند.

Function Calling چیست؟

Function Calling قابلیتی در API مدل‌های زبانی است که اجازه می‌دهد مدل به‌جای پاسخ متنی، یک تابع از کد شما را با پارامترهای مشخص فراخوانی کند. شما لیست توابع را با JSON Schema به مدل معرفی می‌کنید، مدل بر اساس درخواست کاربر تصمیم می‌گیرد کدام تابع را با چه پارامترهایی فراخوانی کند، شما اجرا می‌کنید، نتیجه را به مدل برمی‌گردانید، و مدل پاسخ نهایی را به زبان طبیعی تولید می‌کند.

این مفهوم در نوامبر ۲۰۲۳ توسط OpenAI معرفی شد و الان همه‌ی provider های اصلی (OpenAI، Anthropic، Google، Mistral) آن را پشتیبانی می‌کنند.

نحوه‌ی کار — جریان کامل

  1. تعریف توابع: لیست توابع را با JSON Schema می‌نویسی (نام، توضیح، پارامترها، نوع‌ها).
  2. ارسال به مدل: پیام کاربر + لیست توابع را به API می‌دهی.
  3. تصمیم مدل: مدل یا پاسخ متنی می‌دهد، یا یکی از توابع را با پارامترهای استخراج‌شده فراخوانی می‌کند.
  4. اجرای تابع: اگر مدل تابعی را خواسته، تو در کد خودت آن را اجرا می‌کنی.
  5. بازگشت نتیجه: خروجی تابع را به‌عنوان پیام جدید به مدل برمی‌گردانی.
  6. پاسخ نهایی: مدل با اطلاعات تابع، پاسخ طبیعی برای کاربر تولید می‌کند.

پیاده‌سازی در OpenAI (کد Python)

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

from openai import OpenAI
import json
client = OpenAI()

tools = [{
    "type": "function",
    "function": {
        "name": "get_menu",
        "description": "دریافت منوی روز رستوران",
        "parameters": {
            "type": "object",
            "properties": {
                "category": {
                    "type": "string",
                    "enum": ["پیش‌غذا", "غذای اصلی", "دسر"]
                }
            },
            "required": ["category"]
        }
    }
}]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "چی دسر دارید؟"}],
    tools=tools
)

# اگر مدل تابع را فراخوانی کرد
if response.choices[0].message.tool_calls:
    call = response.choices[0].message.tool_calls[0]
    args = json.loads(call.function.arguments)
    # اجرای تابع واقعی
    menu = get_menu(args["category"])
    # برگشت نتیجه به مدل برای پاسخ نهایی
    final = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "user", "content": "چی دسر دارید؟"},
            response.choices[0].message,
            {"role": "tool", "tool_call_id": call.id, "content": str(menu)}
        ]
    )
    print(final.choices[0].message.content)

پیاده‌سازی در Anthropic Claude (Tool Use)

Claude همان مفهوم را با اسم Tool Use ارائه می‌دهد. ساختار کد مشابه است:

from anthropic import Anthropic
client = Anthropic()

tools = [{
    "name": "get_weather",
    "description": "دریافت آب‌و‌هوای فعلی یک شهر",
    "input_schema": {
        "type": "object",
        "properties": {
            "city": {"type": "string", "description": "نام شهر"}
        },
        "required": ["city"]
    }
}]

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "هوای تهران چطوره؟"}]
)

for block in response.content:
    if block.type == "tool_use":
        result = get_weather(block.input["city"])
        # ادامه با دور دوم پیام...

تفاوت کلیدی: Claude در پیروی از JSON Schema دقیق‌تر است و کمتر hallucinate می‌کند. برای جزئیات بیشتر، مقایسه‌ی سه مدل را ببین.

پیاده‌سازی در Google Gemini

Gemini از همان OpenAPI/JSON Schema استفاده می‌کند. کد Python:

import google.generativeai as genai
genai.configure(api_key="YOUR_KEY")

def schedule_meeting(participants: list[str], date: str, topic: str):
    """تنظیم جلسه‌ی کاری"""
    return {"status": "scheduled", "meeting_id": "M-1234"}

model = genai.GenerativeModel(
    "gemini-2.5-pro",
    tools=[schedule_meeting]
)

chat = model.start_chat(enable_automatic_function_calling=True)
response = chat.send_message(
    "یه جلسه با علی و سارا برای فردا ساعت ۱۰ بذار، موضوع طراحی UI"
)
print(response.text)

Parallel Function Calling در GPT-4

یکی از قدرتمندترین قابلیت‌های GPT-4 این است که می‌تواند چند تابع را همزمان فراخوانی کند. مثلاً اگر کاربر بگوید «هوای تهران و اصفهان رو بگو و یه یادآور بساز»، مدل سه تابع را موازی صدا می‌زند.

این کار latency را به‌شدت کاهش می‌دهد — به‌جای ۳ دور رفت و برگشت سریال، فقط ۲ دور می‌خواهد. در API OpenAI این رفتار به‌صورت پیش‌فرض فعال است.

الگوی ReAct — ساخت ایجنت کامل

ReAct (Reasoning + Acting) الگویی برای ساخت ایجنت‌های پیچیده است که Function Calling را با Chain-of-Thought ترکیب می‌کند. در هر گام، AI:

  1. درباره‌ی مسئله فکر می‌کند (Reasoning)
  2. تابعی را فراخوانی می‌کند یا پاسخ می‌دهد (Acting)
  3. نتیجه را مشاهده می‌کند (Observation)
  4. دوباره فکر می‌کند و تصمیم بعدی را می‌گیرد

این چرخه تا رسیدن به جواب نهایی ادامه می‌یابد. ReAct پایه‌ی ایجنت‌های قدرتمندی مثل LangChain Agents و OpenAI Assistants است.

تفاوت Function Calling با MCP و Tool Use

اصطلاحتوضیح
Function Callingاصطلاح OpenAI
Tool Useاصطلاح Anthropic (هم‌معنی)
MCPاستاندارد باز Anthropic — لایه‌ی بالاتر cross-model
Plugins (قدیمی)نسخه‌ی منسوخ‌شده‌ی ChatGPT برای اتصال به سرویس‌های خارجی

نکات امنیتی حیاتی

  • Validation پارامترها: هرگز خروجی LLM را مستقیم به دیتابیس یا فایل‌سیستم ندهی. حتماً validation و escape کن.
  • Sandbox برای exec: اگر تابع کد اجرا می‌کند، در Docker یا VM ایزوله اجرا کن.
  • Rate limiting: برای هر کاربر و هر تابع، rate limit بگذار.
  • Authentication: توابع حساس (پرداخت، حذف داده) را به authentication جداگانه نیاز کن.
  • Audit log: همه‌ی فراخوانی توابع را لاگ کن.
  • Prompt injection: کاربر نباید بتواند با پیام، توابع تعریف‌نشده را فراخوانی کند.

اشتباهات رایج

  • توضیحات JSON Schema را خلاصه نوشتن — مدل سردرگم می‌شود.
  • تعداد توابع زیاد (>۱۰) — مدل گیج می‌شود و توابع اشتباه انتخاب می‌کند.
  • عدم بازگشت خروجی تابع — مدل نمی‌تواند پاسخ نهایی تولید کند.
  • اعتماد به temperature بالا برای Function Calling — همیشه `temperature=0` استفاده کن.
  • عدم استفاده از strict: true در OpenAI — این پارامتر تضمین می‌کند خروجی دقیقاً JSON Schema را رعایت کند.

برای اشتباهات بیشتر، ۱۵ اشتباه رایج پرامپت‌نویسی را بخوان.

سوالات متداول

Function Calling چیست به زبان ساده؟

قابلیتی که AI را به ابزارها و توابع برنامه‌نویسی متصل می‌کند تا بتواند کارهای واقعی انجام دهد، نه فقط متن تولید کند.

چه مدلی بهتر است؟

GPT-4o و Claude 4.5 Sonnet هر دو عالی هستند. Claude برای دقت JSON بهتر است؛ GPT-4o برای parallel calling قوی‌تر.

هزینه‌اش چقدر است؟

هر تعامل کامل ~$۰.۰۱-۰.۰۳ در GPT-4o.

تفاوت با MCP چیست؟

MCP لایه‌ی بالاتر cross-model است؛ Function Calling سطح API هر مدل است.

کِی استفاده نکنم؟

وقتی فقط می‌خواهی متن تولید کنی. وقتی تابع‌ها قابل‌تعریف ساده نیستند. وقتی latency حیاتی است.

آیا Function Calling برای فارسی هم کار می‌کند؟

بله. مدل از زبان طبیعی فارسی پارامترهای انگلیسی توابع را به‌خوبی استخراج می‌کند.

می‌خوای یه AI Agent واقعی بسازی؟

در دوره‌ی جامع مهندسی پرامپت یک پکیج کامل به نام «ساخت ایجنت‌های AI با Function Calling» داریم — از صفر تا یک ایجنت آماده‌ی production. ۱۴ میلیون تومان، ۳ روز ضمانت بازگشت.

شروع
متین لب‌خندق

متین لب‌خندق

مهندس هوش مصنوعی و مدرس مهندسی پرامپت

۱۰ سال تجربه برنامه‌نویسی، ۵ سال تخصص اختصاصی در AI و ساخت ایجنت‌های هوشمند. پروفایل کامل.

نویسنده: متین لب‌خندق — مهندس هوش مصنوعی با ۱۰ سال برنامه‌نویسی و ۵ سال تمرکز روی مدل‌های زبانی (LLM)؛ سازنده‌ی سیستم‌های واقعیِ production با ChatGPT، Claude و Gemini و بنیان‌گذار آکادمی متین لب‌خندق. مقاله‌ی پایه: راهنمای جامع مهندسی پرامپت.