چیت‌شیت

فراخوانی ابزار و خروجی‌های ساختاریافته

Tool Calling and Structured Outputs

تعریف ابزارها، خواندن فراخوانی‌ها، بازگرداندن نتایج، اجرای موازی فراخوانی‌ها، استریمینگ آرگومان‌ها و اجبار به تولید JSON معتبر.

  • ۱۳ بخش
  • ۹ درس مرتبط
  • کد و دستورها عیناً از دوره‌ی اصلی
فهرست مطالب
  1. وظایف فراخوانی تابع
  2. وظایف خروجی ساختاریافته
  3. حلقه‌ی ابزار
  4. یک فراخوانی ابزار
  5. رفت‌وبرگشت کامل در OpenAI
  6. اعتبارسنجی، سپس اصلاح یا امتناع
  7. ساختارها بر اساس ارائه‌دهنده
  8. فراخوانی‌های موازی و استریمینگ
  9. قوانین طراحی اسکیمای JSON
  10. محدودیت‌ها و پیش‌فرض‌ها
  11. عیب‌یابی
  12. پرسش و پاسخ
  13. نکات

وظایف فراخوانی تابع

کار و کد
وظیفهکد
تعریف یک ابزار، OpenAI{"type": "function", "function": {...}}
تعریف یک ابزار، Anthropic{"name": ..., "input_schema": {...}}
واگذاری تصمیم به مدلtool_choice="auto"
اجبار به فراخوانی ابزارtool_choice="required"
اجبار به یک ابزار خاصtool_choice={"type":"function", ...}
خواندن فراخوانی‌های OpenAImessage.tool_calls
یافتن فراخوانی Anthropicb.type == "tool_use"
بازگرداندن نتیجه‌ی Anthropic{"type": "tool_result", "tool_use_id": ...}

وظایف خروجی ساختاریافته

کار و کد
وظیفهکد
JSON معتبر، بدون اسک Schema{ type: "json_object" }
JSON منطبق بر اسکیمای JSON{type: "json_schema", strict: true}
پارس کردن به مدل Pydanticresponse_format=Product
خواندن نتیجه‌ی تایپ‌شدهmessage.parsed
تلاش مجدد در خطاهای اعتبارسنجیinstructor.from_openai(OpenAI())

حلقه‌ی ابزار

معماری
پیامابزارهافراخوانی ابزارآرگومان‌های معتبرنتیجهمشاهدهکاربرپیاممیزبانرجیستری، سقف حلقهمدلمتن، فراخوانی یا امتناعنتیجه‌ی ابزارپیام tool، همان شناسهمجریکد شما آن را اجرا می‌کنداعتبارسنجاسکیمای JSON 2020-12

یک فراخوانی ابزار

گام‌به‌گام
  1. میزباننام، توضیحات و اسکیمای ورودی را تعریف می‌کند.
  2. مدلپاسخ می‌دهد، ابزارها را فراخوانی می‌کند، یا امتناع می‌کند.
  3. مدلهر فراخوانی دارای id، name و arguments است.
  4. میزبانآرگومان‌ها را بر اساس اسکیمای JSON اعتبارسنجی می‌کند.
  5. مجریکد را اجرا کرده و نتیجه‌ای قابل سریال‌سازی برمی‌گرداند.
  6. میزبانیک پیام tool با همان شناسه ضمیمه می‌کند.
  7. میزباناین روند را تا نبود فراخوانی جدید یا رسیدن به MAX_TURNS تکرار می‌کند.

رفت‌وبرگشت کامل در OpenAI

کد
python
response = client.chat.completions.create(
    model="gpt-4o", messages=messages,
    tools=tools, tool_choice="auto",                # مدل ابزار یا متن را انتخاب می‌کند
)
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)     # آرگومان‌ها از جنس رشته هستند
result = get_weather(**args)                        # کد شما اجرا می‌شود
messages += [
    response.choices[0].message,                    # حفظ نوبت گفت‌وگوی assistant
    {"role": "tool", "tool_call_id": tool_call.id,  # همان شناسه مشابه فراخوانی
     "content": json.dumps(result)},
]
final = client.chat.completions.create(model="gpt-4o", messages=messages)

اعتبارسنجی، سپس اصلاح یا امتناع

کد
python
def process_model_output(raw: str, schema: dict) -> ParsedResult:
    if raw.startswith("__REFUSAL__"):                   # امتناع مدل: بدون تلاش مجدد
        return ParsedResult("refusal", raw.removeprefix("__REFUSAL__").strip(), [])
    try:
        parsed = json.loads(raw)
    except json.JSONDecodeError as e:                   # خطای 1: داده JSON نیست
        return ParsedResult("parse_error", None, [ValidationError("$", str(e))])
    errs = validate(schema, parsed)                     # فهرستی از مسیر و پیام خطا
    if errs:
        return ParsedResult("violation", parsed, errs)  # تزریق خطاها، تلاش مجدد
    return ParsedResult("ok", parsed, [])

ساختارها بر اساس ارائه‌دهنده

مفهوم‌ها
فیلد اسکیمای JSON
parameters، input_schema، و در Gemini فیلد parameters.
فراخوانی
tool_calls[]، یک بلوک tool_use، یک بخش functionCall.
آرگومان‌ها
OpenAI رشته می‌فرستد. بقیه یک شیء ارسال می‌کنند.
پیوند نتیجه
tool_call_id، tool_use_id، شناسه‌ی functionResponse.
ممنوعیت ابزارها
tool_choice: "none"، {type: "none"}، mode: "NONE".
حالت سخت‌گیرانه
strict: true، همیشه روشن، responseSchema.

فراخوانی‌های موازی و استریمینگ

مفهوم‌ها
فعال‌سازی
parallel_tool_calls: true حالت پیش‌فرض OpenAI است.
ترتیبی
در صورت وابستگی فراخوانی‌ها به یکدیگر، آن را خاموش کنید.
تطبیق
هر نتیجه شناسه‌ی فراخوانی خود را دارد. ترتیب اختیاری است.
استریمینگ OpenAI
تکه‌ها را بر اساس index متصل کنید تا به finish_reason = "tool_calls" برسید.
استریمینگ Anthropic
تکه‌های input_json_delta تا رسیدن به content_block_stop.
پارس با تاخیر
JSON ناقص خطا می‌دهد. در سیگنال پایانی پارس کنید.
تاخیر
400، 600، 800 میلی‌ثانیه: 1800 میلی‌ثانیه ترتیبی، 800 میلی‌ثانیه موازی.

قوانین طراحی اسکیمای JSON

مفهوم‌ها
نام
snake_case، فعل و سپس اسم: get_weather. بدون آرگومان در نام.
توضیحات
"زمانی استفاده شود که {شرط}. برای {موارد-مشابه-اما-غلط} استفاده نشود."
Enumها
هر مجموعه‌ی بسته‌ای را در یک enum قرار دهید.
ابزارهای تجزیه‌ناپذیر
اگر action بیش از 3 مقدار دارد، ابزار را تفکیک کنید.
حالت سخت‌گیرانه
همه‌ی خصوصیات در required، مقدار additionalProperties: false، بدون $ref.

محدودیت‌ها و پیش‌فرض‌ها

پیش‌فرض‌ها
تنظیمپیش‌فرضنکته
OpenAI tools per request128محدودیت قطعی
Anthropic tools per request64محدودیت قطعی
OpenAI schema depth5حالت سخت‌گیرانه
OpenAI argument string8192 bytesحداکثر اندازه
Description length1024 charactersمتن‌های طولانی‌تر بریده می‌شوند
MAX_TURNS5سقف حلقه‌ی درس
Repair retries3xتعداد بیشتر یعنی اسکیمای نامناسب
timeout_ms30_000به ازای هر رکورد ابزار

عیب‌یابی

عیب‌یابی
  • خطای json.loads اواسط استریمینگ

    علت
    آرگومان‌ها JSON ناقص هستند
    راه‌حل
    پارس کردن پس از سیگنال پایان فراخوانی
  • خطای 400 در زمان درخواست، حالت سخت‌گیرانه

    علت
    نقض قوانین حالت سخت‌گیرانه در اسکیمای JSON
    راه‌حل
    همه در required، بدون $ref
  • انتخاب ابزار اشتباه

    علت
    همپوشانی توضیحات دو ابزار
    راه‌حل
    افزودن خط "استفاده نشود برای"
  • مقدار خارج از enum

    علت
    خروجی مبتنی بر پرامپت
    راه‌حل
    استفاده از رمزگشایی مقید
  • refusal در پاسخ

    علت
    ورودی با اسکیمای JSON همخوانی ندارد
    راه‌حل
    مدیریت آن به عنوان یک پیامد تایپ‌شده
  • فیلدهای اضافی در input

    علت
    اسکیمای Anthropic صرفاً مشورتی است
    راه‌حل
    اعتبارسنجی سمت سرور
  • تلاش مجدد روی خطاهای اسکیمای JSON

    علت
    خطاها قطعی هستند
    راه‌حل
    اصلاح آرگومان‌ها، بدون تلاش مجدد
  • ارسال نتایج به فراخوانی اشتباه

    علت
    تطبیق بر اساس نام به جای شناسه
    راه‌حل
    بازگرداندن هر نتیجه به همراه شناسه‌ی آن

پرسش و پاسخ

پرسش و پاسخ
خروجی ساختاریافته یا فراخوانی ابزار؟
خروجی داده‌ی نهایی است. فراخوانی درخواست اقدام است.
چرا پرامپت ساده برای JSON مناسب نیست؟
بین 5 تا 15 درصد مواقع ناموفق است.
چرا شناسه‌ی فراخوانی نیاز است؟
نتایج موازی بدون ترتیب بازمی‌گردند.
آیا اسکیمای JSON می‌تواند مقدار غلط را تشخیص دهد؟
خیر. نوع داده درست است، اما مقدار ساختگی است.

نکات

نکته‌ها
  • خطاها را به عنوان نتیجه برگردانید: {"error": true, "code": "CITY_NOT_FOUND"}.
  • خطاها را برای مدل بنویسید: "'city' is required."
  • گزارش خطاها در قالب مسیرهای اشاره‌گر جی‌سان: /user/email.
  • فیلدهای کلیدی را اجباری کنید. مدل در صورت نیاز null می‌نویسد.
  • فقط توابعی را افشا کنید که کاربر به آن‌ها نیاز دارد.