اگر در حال توسعه برنامههایی هستید که از ابزارهای خارجی استفاده میکنند، انتخاب بین دو پروتکل ارتباطی میتواند تفاوت بین یک سیستم پایدار و یک برنامه پر از باگ باشد. ادغام Modelflare یا ابزارهای سازگار با OpenAI نیازمند انتخابی دقیق بین دو پروتکل متمایز است: Responses API و Chat Completions. اشتباه در انتخاب بین این دو تنها کد شما را تغییر نمیدهد، بلکه نحوه مدیریت وضعیت (State) و چرخه تعامل (Tool Loop) را که به هوش مصنوعی اجازه میدهد با دنیای واقعی تعامل داشته باشد، دگرگون میکند.
در پوشش پیشین ما از نحوه ساخت عاملهای چندمرحلهای با Gemini، دیدیم که صنعت به سمت تعاملات ساختاریافتهتر و تایپشده حرکت میکند. برای یک توسعهدهنده، این تفاوت شبیه انتخاب بین یک متن گفتگو (Chat) و یک گزارش رویداد ساختاریافته (Responses) است؛ هر دو میتوانند یک تابع را اجرا کنند، اما جریان دادهها در لایه انتقال (Wire Level) کاملاً متفاوت است. در واقع، درک این تفاوتها اولین قدم برای تبدیل یک مدل ساده به یک عامل عملیاتی است، همانطور که در بررسی الگوهای معماری تبدیل مدلهای زبانی به عاملها به تفصیل پرداختیم.
مکانیسم چرخه ابزار
به نقل از یک راهنمای فنی منتشر شده در ۱۳ اکتبر ۲۰۲۶، ماشین وضعیت برنامه فارغ از نوع API، یکسان باقی میماند. این فرآیند از چهار گام سختگیرانه پیروی میکند:
۱. اعلام (Declare): تعریف یک تابع مجاز و طرحواره (Schema) آرگومانهای آن.
۲. دریافت (Receive): دریافت یک یا چند فراخوانی تابع پیشنهادی از سوی مدل.
۳. اعتبارسنجی، مجوزدهی و اجرا (Validate, Authorize, Execute): اجرای هر فراخوانی در کد برنامه پس از بررسیهای امنیتی.
۴. بازگرداندن (Return): بازگرداندن هر نتیجه با استفاده از شناسه همبستگی (Correlation ID) مربوط به آن فراخوانی.
تنها پس از گام چهارم است که مدل میتواند پاسخی مبنی بر نتیجه ابزار تولید کند که بر اساس دادههای واقعی باشد. اگر مدل ابزار دیگری بخواهد، چرخه با یک شناسه فراخوانی جدید تکرار میشود. OpenAI در راهنمای فراخوانی تابع (Function Calling) این فرآیند را یک تبادل چندمرحلهای توصیف میکند. یک خطای رایج در ادغام زمانی رخ میدهد که توسعهدهندگان اولین فراخوانی ابزار را به عنوان پاسخ نهایی تلقی کرده و حلقه بازگشت ضروری را نادیده میگیرند. این پیچیدگیها نشان میدهد که چگونه تنها با چند خط کد میتوان مرز میان یک مدل چت ساده و یک عامل هوشمند را تغییر داد.

تفاوتهای ساختاری: Responses در برابر Chat
تفاوتهای اصلی بیشتر ساختاری هستند تا مفهومی. Responses API از تعاریف تخت توابع استفاده کرده و خروجیهای تایپشده function_call برمیگرداند. در مقابل، Chat Completions تعاریف ابزار را در زیرمجموعه tools[].function قرار داده و message.tool_calls را درون یک پیام دستیار (Assistant Message) بازمیگرداند.
برای درک مقایسه در سطح لایه انتقال، این تمایزات فنی دقیق را بررسی کنید:
- تعریف تابع: در Responses از یک آیتم تخت
tools[]شامل نام، توضیحات، پارامترها و فیلد strict استفاده میشود. در Chat Completions، این فیلدها در زیرمجموعهfunctionدرون آیتمtools[]قرار میگیرند. - فراخوانی پیشنهادی: Responses یک آیتم خروجی تایپشده
function_callبرمیگرداند، در حالی که Chat Completions یک ورودیtool_calls[]را در پیام دستیار ارائه میدهد. - شناسههای همبستگی: در Responses از
call_idو در Chat Completions ازtool_call_id(که به عنوانtool_call_idبازگردانده میشود) استفاده میشود. - نام تابع: در Responses از طریق
function_call.nameو در Chat Completions ازtool_calls[].function.nameقابل دسترسی است. - آرگومانها: هر دو رشته JSON ارائه میدهند، اما مسیر دسترسی متفاوت است:
function_call.argumentsدر برابرtool_calls[].function.arguments. - مدیریت نتیجه: Responses آیتمهای ورودی
function_call_outputرا میپذیرد که توسطcall_idپیوند داده شدهاند. اما Chat Completions به پیامی با نقش (Role)toolنیاز دارد. - استریمینگ: Responses از رویدادهای دلتای آرگومانهای تایپشده استفاده میکند. Chat Completions تکهها را در
choices[0].delta.tool_calls[]ارسال میکند. - متن نهایی: Responses از آیتمهای خروجی تایپشده و کمکیهای متن-خروجی بهره میبرد، در حالی که Chat Completions از
choices[0].message.contentاستفاده میکند.
پیادهسازی اجرای ایمن
بر اساس مستندات فنی، آرگومانهای تولید شده توسط مدل ورودیهای غیرقابل اعتمادی هستند. تأکید میشود که طرحواره strict: true ساختار را بهبود میبخشد اما مجوز دسترسی (Authorization) صادر نمیکند. پارامتر strict از مدلهای پشتیبانیشده میخواهد به طرحواره پایبند باشند، اما برنامه همچنان باید JSON را پیش از اجرا تجزیه و اعتبارسنجی کند. از آنجایی که پشتیبانی از الگوها (Pattern) و ویژگیهای JSON Schema در ارائهدهندگان مختلف متفاوت است، همان گیت سازگاری که برای خروجیهای ساختاریافته (Structured Outputs) استفاده میشود، برای آرگومانهای توابع نیز اعمال میگردد.
برای مثال، یک تابع فقط-خواندنی مانند get_delivery_status باید طرحواره محدودی داشته باشد تا مدل نتواند سفارشات را تغییر دهد یا وجهی را مسترد کند. یک طرحواره امن به این شکل خواهد بود:
{
"type": "object",
"properties": {
"order_id": {
"type": "string",
"pattern": "^ORDER-[0-9]{4}$"
}
},
"required": [ "order_id" ],
"additionalProperties": false
}
توسعهدهندگان باید کنترلهای ایمنی زیر را پیاده کنند:
- فهرستهای مجاز (Allowlists): تنها نام توابع ثبتشده و تایید شده پذیرفته شوند.
- تجزیه (Parsing): آرگومانها با یک محدودیت اندازه سختگیرانه تجزیه شوند تا از حملات DoS جلوگیری شود.
- اعتبارسنجی: بررسی کامل طرحواره در کد برنامه پیش از هرگونه عملیات.
- مجوزدهی: تأیید دسترسی کاربر فعلی یا بار کاری (Workload) به منبع درخواستی.
- جداسازی: ابزارهای فقط-خواندنی از ابزارهای دارای اثر جانبی (Side effects) کاملاً جدا شوند.
- پاکسازی (Redaction): حذف اسرار (Secrets) و خروجیهای حساس پیش از بازگرداندن آنها به مدل.
- زمانبندی (Timeouts): استفاده از ضربالاجل (Deadline) و تلاشهای مجدد محدود در لایههای پاییندستی.
برای ابزارهایی که اثر جانبی دارند — مانند استرداد وجه یا بهروزرسانی پایگاهداده — تکرارپذیری (Idempotency) اجباری است. توسعهدهندگان باید یک کلید تکرارپذیری را از یک درخواست پایدار برنامه و شناسه فراخوانی استخراج کنند. نتیجه تکمیل شده باید پیش از بازگرداندن به مدل ذخیره شود. اگر یک تلاش مجدد شبکه همان فراخوانی را تکرار کند، باید نتیجه ذخیره شده بازگردانده شود، نه اینکه استرداد وجه، پیام یا تغییر دیتابیس دوم اجرا شود.
مدیریت موازیسازی و استریمینگ
وقتی parallel_tool_calls فعال است، ترتیب تکمیل ممکن است با ترتیب درخواست متفاوت باشد. فراخوانیهای موازی و تکههای استریم شده میتوانند در ترتیبی برسند که با نحوه اتمام عملیات در برنامه شما متفاوت باشد. توسعهدهندگان باید نتایج را از طریق شناسه فراخوانی صریح (Explicit Call ID) همبست کنند، نه بر اساس موقعیت در آرایه، تا از عدم تراز دادهها (Data Misalignment) جلوگیری شود. شناسه صریح تنها کلید پیوند پایدار است.
در صورت فعال بودن فراخوانیهای موازی، باید:
- حداکثر تعداد فراخوانیها در هر پاسخ را محدود کنید.
- محدودیت همزمانی (Concurrency) را در سطح برنامه اعمال کنید.
- تعریف کنید که آیا شکست یک ابزار، سایر ابزارهای موفق را لغو میکند، مسدود میکند یا با آنها همزیستی دارد.
- برای هر فراخوانی پذیرفته شده، دقیقاً یک نتیجه بازگردانید.
- عملیات دارای اثر جانبی را در صورتی که ترتیب اهمیت دارد، سریالسازی کنید.
استریمینگ چالش خاصی دارد: آرگومانها به صورت تکه تکه (Fragments) میرسند. یک تکه مانند {"order جیسون معتبری نیست. رویکرد ایمن این است که برای هر شناسه فراخوانی یک بافر (Buffer) نگه دارید: شناسه فراخوانی یا اسلات ایندکس شده را از رویداد شناسایی کنید، هر دلتای آرگومان را به آن بافر اضافه کنید و منتظر سیگنال argument-done یا سیگنال تکمیل نقطه انتهایی بمانید. تنها پس از آن است که باید رشته کامل را تجزیه، اعتبارسنجی و اجرا کنید.
راهنمای استریمینگ AI API اشاره میکند که برای تضمین قابلیت اطمینان، زمان اتصال، اولین رویداد، اولین خروجی مؤثر، زمان انتظار بیکاری (Idle Timeout) و تکمیل باید به طور جداگانه اندازهگیری شوند.
لایه سازگاری Modelflare
Modelflare یک مرز سازگاری ایجاد میکند که این ساختارها را بین دو API در مسیرهای واجد شرایط OpenAI/Codex نگاشت میکند. با این حال، این نگاشت راهبهراه و کامل نیست و تعمداً محدودتر از سطح کامل Responses است. ابزارهای توابع تعریف شده توسط برنامه را میتوان در هر دو قالب نمایش داد، اما ابزارهای میزبانیشده مخصوص Responses — مانند جستوجوی ارائهدهنده یا اجرای کد توسط ارائهدهنده — با فراخوانی توابع برنامه یکسان نیستند و نمیتوان فرض کرد که به Chat Completions تبدیل میشوند.
سایر خانوادههای مدل سازگار با OpenAI از طریق عبور مستقیم (Pass-through) Chat Completions در دسترس هستند، مگر اینکه به طور جداگانه تأیید شده باشند. برای این مسیرها، ارائهدهنده بالادستی تصمیم میگیرد که آیا strict، فراخوانیهای موازی یا تکههای استریمینگ پشتیبانی میشوند یا خیر.
این بدان معناست که توسعهدهندگان باید کل چرخه را تست کنند، نه اینکه صرفاً بررسی کنند آیا درخواست اول کد ۲۰۰ برمیگرداند یا خیر. شواهد لازم برای یک مسیر آماده تولید شامل موارد زیر است:
- فراخوانی فقط-خواندنی: تأیید نام تابع، آرگومانهای تجزیه شده، شناسه فراخوانی و پیوند نتیجه.
- آرگومانهای نامعتبر: اطمینان از شکست صریح اعتبارسنجی بدون اجرای ابزار.
- تابع ناشناخته: تأیید رد درخواست توسط فهرست مجاز برنامه.
- عدم نیاز به ابزار: تأیید تولید متن نهایی عادی بدون ساختن فراخوانی جعلی.
- فراخوانی استریمینگ: بازسازی آرگومانهای کامل با شناسه درست.
- درخواست تکراری: تأیید وقوع تنها یک اثر جانبی یا بازگشت یک نتیجه کششده، نه اجرای تکراری.
- فراخوانیهای متعدد: تأیید همبستگی درست مستقل از ترتیب تکمیل.
- جایگزینی مسیر (Fallback): اطمینان از حفظ مدل، پروتکل، طرحواره ابزار و قرارداد نتیجه.
انتخاب پروتکل مناسب
انتخاب شما به قرارداد فعلی برنامه شما بستگی دارد. اگر سیستم شما از آیتمهای خروجی تایپشده، مدل رویداد Responses، گزینههای تداوم وضعیت (State-continuation) یا سایر قابلیتهای تأیید شده Responses بهره میبرد، از Responses API استفاده کنید. اگر یک تاریخچه پیام پایدار (Message Transcript) دارید و قرارداد ابزار ارائهدهنده شما تأیید شده است، Chat Completions گزینه مناسب است.
در نهایت، قابلیت اطمینان یک گردشکار فراخوانی تابع به کنترلهای سمت برنامه — مجوزدهی، اعتبارسنجی و تکرارپذیری — بستگی دارد، نه نام نقطه انتهایی (Endpoint). این کنترلها هستند که یک گردشکار فراخوانی تابع را قابل اعتماد میکنند.
گام بعدی شما
برای اطمینان از اینکه عاملهای هوش مصنوعی شما آماده تولید هستند:
- هندلرهای فراخوانی ابزار خود را برای وجود کلیدهای تکرارپذیری (Idempotency Keys) بازبینی کنید.
- بررسی کنید که آیا نتایج را بر اساس شناسه (ID) همبست میکنید یا بر اساس ترتیب توالی (Sequence).
- برای حفظ صراحت در تغییرات مسیر، از مسیریابی قابل اعتماد AI API استفاده کنید و برای جداسازی بار کاری و مجوزها، از امنیت کلیدهای AI API بهره ببرید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو