انتخاب مدل برای Coding Agentها؛ راهنمای مهندسی ارزیابی، Benchmark و Model Routing در برنامه‌نویسی

راهنمای حرفه‌ای انتخاب مدل برای Coding Agentها؛ از طراحی Benchmark داخلی و ارزیابی Tool Calling، Context، کیفیت Patch و هزینه تا ساخت Model Routing با API سازگار با OpenAI درواره.

Share
انتخاب مدل برای Coding Agentها؛ راهنمای مهندسی ارزیابی، Benchmark و Model Routing در برنامه‌نویسی

مقدمه

پرسش «بهترین مدل هوش مصنوعی برای برنامه‌نویسی کدام است؟» در ظاهر ساده است، اما برای یک برنامه‌نویس یا تیم فنی، معمولاً پرسش درستی نیست.

مدلی که در تکمیل یک تابع کوچک عالی عمل می‌کند، ممکن است هنگام تحلیل یک Repository بزرگ، اجرای تست‌ها یا رفع یک Bug چندلایه نتیجه مطلوبی نداشته باشد. مدلی که در Benchmark عمومی رتبه بالایی دارد، ممکن است در پروژه واقعی شما هزینه زیادی ایجاد کند، فرمان‌های اضافی اجرا کند، فایل‌های نامرتبط را تغییر دهد یا نتواند Conventionهای داخلی تیم را رعایت کند.

در Coding Agentها موضوع پیچیده‌تر می‌شود. یک Coding Agent مانند Cline، Claude Code، Codex، Cursor Agent، OpenCode یا ابزارهای مشابه، فقط یک Prompt برای مدل ارسال نمی‌کند. Agent در یک حلقه چندمرحله‌ای کار می‌کند و ممکن است:

  • ساختار Repository را بررسی کند
  • فایل‌های مختلف را بخواند
  • در کد جست‌وجو کند
  • برنامه اجرایی بسازد
  • چند فایل را ویرایش کند
  • فرمان Terminal اجرا کند
  • تست‌ها را ببیند
  • بر اساس خطا تصمیم جدید بگیرد
  • از ابزارهای MCP استفاده کند
  • در پایان Patch و گزارش تولید کند

بنابراین انتخاب مدل برای Coding Agent نباید صرفاً بر اساس توانایی «تولید کد» انجام شود. باید کیفیت استفاده از ابزار، توانایی حفظ هدف در چند مرحله، مدیریت Context، دقت ویرایش، میزان تخریب ناخواسته، سرعت، هزینه و قابلیت بازیابی از خطا را نیز اندازه‌گیری کرد.

در این مقاله به‌جای ارائه یک فهرست موقت از «بهترین مدل‌های برنامه‌نویسی»، یک چارچوب فنی و ماندگار می‌سازیم تا بتوانید:

  • مدل مناسب هر نوع وظیفه برنامه‌نویسی را انتخاب کنید
  • مدل‌ها را روی پروژه‌های واقعی خودتان ارزیابی کنید
  • یک Benchmark داخلی قابل تکرار بسازید
  • کیفیت Agent و مدل را از یکدیگر تفکیک کنید
  • هزینه واقعی حل هر مسئله را محاسبه کنید
  • برای وظایف مختلف Model Routing انجام دهید
  • از مدل سریع برای کار ساده و مدل قوی برای کار پیچیده استفاده کنید
  • Fallback و Escalation بین مدل‌ها طراحی کنید
  • با API سازگار با OpenAI درواره، یک زیرساخت چندمدلی برای Coding Agentها بسازید

چرا «بهترین مدل برنامه‌نویسی» تعریف دقیقی نیست؟

مدل‌ها در چند محور مختلف با یکدیگر تفاوت دارند. ممکن است یک مدل در تولید کد اولیه قوی باشد، اما در استفاده از Terminal تصمیم‌های ضعیفی بگیرد. مدل دیگری ممکن است Patchهای دقیق و کوچک تولید کند، اما سرعت پایین‌تری داشته باشد. مدل سوم شاید برای وظایف ساده بسیار اقتصادی باشد، ولی در Debug چندمرحله‌ای وارد Loop شود.

به همین دلیل، بهتر است به‌جای یک رتبه‌بندی کلی، مدل را متناسب با نوع وظیفه انتخاب کنیم.

برای مثال، وظایف زیر الزام‌های متفاوتی دارند:

  • تکمیل یک تابع کوچک
  • تولید Unit Test
  • توضیح یک فایل
  • رفع خطای TypeScript
  • بررسی امنیت Authentication
  • Refactor چندماژوله
  • مهاجرت Framework
  • رفع Race Condition
  • تحلیل Memory Leak
  • ساخت Feature کامل
  • بازبینی Pull Request
  • اجرای خودکار تست و اصلاح خطا
  • کار با Browser یا MCP
  • تحلیل Repository با صدها هزار خط کد

مدلی که برای همه این وظایف بهترین باشد، عملاً وجود ندارد. حتی اگر یک مدل از نظر کیفیت خام در اغلب محورها برتر باشد، ممکن است استفاده از آن برای تمام درخواست‌ها از نظر هزینه و تأخیر منطقی نباشد.

پرسش حرفه‌ای‌تر این است:

برای هر کلاس از وظایف مهندسی نرم‌افزار، کدام مدل با کمترین هزینه و زمان، بیشترین احتمال موفقیت را ایجاد می‌کند؟

این پرسش ما را از رتبه‌بندی عمومی به سمت مهندسی ارزیابی و Model Routing می‌برد.

تفاوت مدل کدنویسی با Coding Agent

مدل کدنویسی یک مدل زبانی است که می‌تواند کد را درک یا تولید کند. Coding Agent یک سیستم کامل‌تر است که مدل را با ابزار، Context، حافظه، سیاست دسترسی و حلقه اجرا ترکیب می‌کند.

یک Coding Agent معمولاً شامل اجزای زیر است:

  1. مدل هوش مصنوعی
  2. System Prompt
  3. ابزارهای خواندن و نوشتن فایل
  4. ابزار جست‌وجو
  5. Terminal
  6. مدیریت Context
  7. حافظه کوتاه‌مدت یا بلندمدت
  8. سیاست تأیید عملیات
  9. Parser مربوط به Tool Call
  10. مکانیزم Retry و Recovery
  11. نمایش Diff
  12. مدیریت Session
  13. ابزارهای MCP
  14. منطق پایان وظیفه

بنابراین نتیجه نهایی فقط به مدل وابسته نیست.

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

  • System Prompt متفاوت است
  • ابزارها Schema متفاوتی دارند
  • Agent فایل‌ها را با روش دیگری انتخاب می‌کند
  • Context به شکل متفاوت فشرده می‌شود
  • مدل برای قالب Tool Calling ابزار دوم بهینه نیست
  • Agent محدودیت متفاوتی برای تعداد مراحل دارد
  • خروجی Terminal به شکل متفاوت خلاصه می‌شود
  • Patch با روش Search and Replace یا Diff تولید می‌شود

به همین دلیل هنگام ارزیابی باید سه لایه را جدا کنیم:

لایهموضوع ارزیابی
Modelاستدلال، تولید کد، درک دستور و Tool Calling
Agent Harnessابزارها، Prompt، مدیریت Context، Retry و Patch
EnvironmentRepository، تست‌ها، Dependencyها، Sandbox و دسترسی

اگر این لایه‌ها تفکیک نشوند، ممکن است یک ضعف Agent به مدل نسبت داده شود یا برعکس.

یک مدل مناسب Coding Agent چه ویژگی‌هایی باید داشته باشد؟

توانایی درک Repository

مدل باید بتواند روابط میان فایل‌ها، ماژول‌ها، Interfaceها، تست‌ها و تنظیمات پروژه را درک کند. تولید کد محلی بدون شناخت معماری می‌تواند به Patch ظاهراً صحیح اما ناسازگار منجر شود.

توانایی درک Repository شامل موارد زیر است:

  • پیدا کردن نقطه شروع برنامه
  • شناخت Dependency Graph
  • تشخیص مرز لایه‌ها
  • دنبال کردن جریان داده
  • فهم قراردادهای داخلی
  • شناسایی فایل‌های تولیدشده
  • تشخیص تست‌های مرتبط
  • درک Conventionهای نام‌گذاری
  • تشخیص اثر تغییر بر مصرف‌کنندگان دیگر

پیروی دقیق از دستور

مدل باید محدودیت‌ها را رعایت کند. برای مثال، اگر گفته‌اید Schema دیتابیس تغییر نکند، افزودن یک Migration راه‌حل قابل قبول نیست؛ حتی اگر مشکل را حل کند.

موارد مهم در Instruction Following عبارت‌اند از:

  • رعایت محدوده فایل‌ها
  • تغییر ندادن API عمومی
  • اضافه نکردن Dependency غیرضروری
  • رعایت استانداردهای امنیتی
  • اجرای تست‌های تعیین‌شده
  • توقف قبل از عملیات حساس
  • گزارش صادقانه شکست‌ها
  • نساختن اطلاعات یا نتیجه تست جعلی

توانایی Tool Calling

در Coding Agent، مدل باید بداند:

  • چه زمانی ابزار لازم است
  • کدام ابزار مناسب‌تر است
  • چه ورودی‌ای باید به ابزار داده شود
  • چه زمانی باید نتیجه را تحلیل کند
  • چه زمانی نباید ابزار را دوباره اجرا کند
  • چه زمانی باید از کاربر سؤال بپرسد
  • چه زمانی وظیفه تمام شده است

مدلی که کد خوبی تولید می‌کند اما Tool Calling ضعیفی دارد، ممکن است برای Agent مناسب نباشد.

Tool Calling در یک Agent فقط تولید JSON معتبر نیست. کیفیت واقعی شامل انتخاب ابزار درست، ترتیب ابزارها و استفاده مؤثر از نتیجه آن‌هاست.

برنامه‌ریزی چندمرحله‌ای

وظایف واقعی برنامه‌نویسی معمولاً با یک پاسخ حل نمی‌شوند. مدل باید بتواند هدف اصلی را در چند مرحله حفظ کند.

یک برنامه مناسب باید:

  • مسئله را به گام‌های کوچک تقسیم کند
  • پیش‌نیازها را تشخیص دهد
  • قبل از ویرایش اطلاعات لازم را جمع‌آوری کند
  • تست مناسب را انتخاب کند
  • پس از شکست، فرضیه خود را اصلاح کند
  • از تکرار عملیات بی‌نتیجه خودداری کند
  • تغییرات را به محدوده ضروری محدود نگه دارد

کیفیت Patch

کیفیت Patch فقط با عبور تست اندازه‌گیری نمی‌شود.

یک Patch حرفه‌ای باید:

  • کمترین تغییر لازم را ایجاد کند
  • با Style پروژه هماهنگ باشد
  • APIهای موجود را بی‌دلیل تغییر ندهد
  • حالت‌های مرزی را در نظر بگیرد
  • مدیریت خطای مناسب داشته باشد
  • امنیت را کاهش ندهد
  • تست مرتبط اضافه کند
  • کد مرده یا Duplicate تولید نکند
  • تغییرات نامرتبط ایجاد نکند

توانایی بازیابی از خطا

مدل مناسب Coding Agent باید شکست را به‌عنوان داده جدید ببیند، نه دلیلی برای تکرار همان اقدام.

برای مثال، پس از شکست تست باید:

  1. متن خطا را دقیق بخواند
  2. تشخیص دهد خطا از Patch است یا محیط
  3. فرضیه قبلی را بازبینی کند
  4. فایل مرتبط را بررسی کند
  5. اصلاح محدود انجام دهد
  6. تست هدفمند را دوباره اجرا کند

مدلی که بدون تحلیل، یک فرمان را چند بار تکرار می‌کند، هزینه و زمان را افزایش می‌دهد و ممکن است وارد Tool Loop شود.

کارایی Token

مدل قدرتمند لزوماً مدل کارآمدی نیست. در یک Agent، تعداد Tool Call، حجم توضیحات، میزان بازخوانی فایل‌ها و طول استدلال بر هزینه اثر دارند.

ممکن است مدل ارزان‌تری مسئله را با ۳۰ مرحله حل کند، در حالی که مدل گران‌تر در ۶ مرحله به نتیجه برسد. بنابراین قیمت هر یک میلیون Token به‌تنهایی معیار کافی نیست.

معیار بهتر این است:

هزینه موفقیت در یک وظیفه واقعی چقدر است؟

در ادامه روش محاسبه آن را بررسی می‌کنیم.

دسته‌بندی وظایف برنامه‌نویسی

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

وظایف توضیحی و پرسش‌وپاسخ

نمونه‌ها:

  • توضیح یک تابع
  • خلاصه‌سازی فایل
  • تشریح یک خطا
  • تولید مستندات اولیه
  • توضیح Regular Expression
  • تبدیل کد به زبان ساده

این وظایف معمولاً:

  • Context محدودی دارند
  • به ابزارهای زیاد نیاز ندارند
  • ریسک تغییر پایین دارند
  • با مدل سریع و اقتصادی قابل انجام‌اند

در این دسته، سرعت و هزینه اهمیت بیشتری از توان Agentic طولانی دارند.

تغییرات مکانیکی و محدود

نمونه‌ها:

  • تغییر نام Symbol
  • افزودن Type
  • اصلاح Formatting
  • تبدیل Syntax قدیمی
  • ایجاد Boilerplate
  • افزودن Logging
  • اصلاح Importها
  • ساخت تست ساده

معیارهای مهم:

  • دقت نحوی
  • پیروی از Pattern موجود
  • تولید Patch کوچک
  • سرعت
  • هزینه پایین

این وظایف معمولاً نیازی به مدل Frontier ندارند، مگر اینکه Repository پیچیده یا زبان کم‌کاربرد باشد.

تولید تست

تولید تست به درک رفتار و حالت‌های مرزی نیاز دارد. مدل باید بتواند تفاوت میان «تستی که فقط عبور می‌کند» و «تستی که رفتار واقعی را اعتبارسنجی می‌کند» تشخیص دهد.

معیارهای مهم:

  • پوشش مسیرهای شکست
  • کیفیت Assertionها
  • عدم Mock بیش از حد
  • سازگاری با Test Framework
  • تولید Regression Test
  • تشخیص رفتار فعلی
  • پرهیز از تغییر Implementation برای عبور تست

Debug محدود

نمونه‌ها:

  • خطای TypeScript
  • Exception مشخص
  • شکست یک Unit Test
  • خطای Import
  • مشکل Validation
  • پاسخ اشتباه یک Endpoint

مدل باید:

  • پیام خطا را درست تفسیر کند
  • Stack Trace را دنبال کند
  • کمترین فایل ممکن را بخواند
  • فرضیه قابل آزمون بسازد
  • Patch محدود تولید کند
  • تست هدفمند اجرا کند

Debug چندلایه

نمونه‌ها:

  • Race Condition
  • Memory Leak
  • خطای Distributed System
  • مشکل Cache Invalidation
  • خطای Authentication میان Frontend و Backend
  • ناسازگاری Transaction
  • اختلال در Event Processing
  • مشکل Performance دیتابیس

این وظایف به مدل قوی‌تر نیاز دارند، زیرا مسئله ممکن است در چند لایه و چند فایل پخش شده باشد.

معیارهای مهم:

  • استدلال علّی
  • حفظ Context
  • توان ساخت فرضیه
  • ترتیب مناسب ابزارها
  • تحلیل Log
  • جلوگیری از Fix سطحی
  • توانایی طراحی آزمایش

Refactor

Refactor نیازمند حفظ رفتار موجود است. مدل باید بتواند:

  • قراردادهای عمومی را تشخیص دهد
  • تست‌های موجود را پیدا کند
  • تغییر را مرحله‌ای انجام دهد
  • Compatibility را حفظ کند
  • از Refactor بیش از حد جلوگیری کند
  • کد تکراری را بدون ساخت Abstraction ضعیف حذف کند

برای Refactor، کیفیت Patch و توان حفظ محدودیت مهم‌تر از تولید سریع کد است.

Feature چندفایلی

یک Feature واقعی ممکن است Frontend، Backend، دیتابیس، تست و مستندات را درگیر کند.

مدل مناسب باید:

  • معماری را بفهمد
  • ترتیب تغییرات را مشخص کند
  • قرارداد میان لایه‌ها را حفظ کند
  • Migration را مدیریت کند
  • تست‌های مناسب بسازد
  • اثر جانبی را تشخیص دهد
  • پیش از عملیات حساس از کاربر تأیید بگیرد

Code Review و امنیت

مدل Code Review باید کمتر تمایل به تولید کد و بیشتر تمایل به شناسایی مسئله داشته باشد.

معیارهای ارزیابی:

  • نسبت هشدار صحیح به هشدار کاذب
  • شناسایی آسیب‌پذیری واقعی
  • تشخیص Regression
  • درک Authorization
  • بررسی مدیریت Secret
  • تحلیل Injection
  • تشخیص Race Condition
  • اولویت‌بندی یافته‌ها
  • ارائه مسیر بازتولید
  • پرهیز از توصیه‌های عمومی و غیرعملی

طراحی معماری

برای طراحی معماری، مدل باید ابهام‌ها را تشخیص دهد و قبل از تجویز راه‌حل، سؤال مناسب بپرسد.

یک مدل معماری خوب نباید برای هر مسئله Microservice، Event Sourcing یا ابزار پیچیده پیشنهاد کند. باید هزینه عملیاتی، مهارت تیم، مقیاس، Migration و Failure Mode را در نظر بگیرد.

وظایف Agentic طولانی

این وظایف شامل چندین مرحله خواندن، ویرایش، اجرا و بازبینی هستند.

معیارهای کلیدی:

  • حفظ هدف
  • مدیریت Context
  • تعداد Tool Call
  • Recovery
  • توان تشخیص پایان
  • عدم Loop
  • کیفیت گزارش
  • میزان مداخله انسانی
  • امنیت عملیات

برای این دسته، نتیجه Benchmarkهای تولید کد کوتاه به‌تنهایی ارزش محدودی دارد.

چرا Benchmarkهای عمومی کافی نیستند؟

Benchmark عمومی برای مقایسه اولیه مفید است، اما نتیجه آن الزاماً به پروژه شما منتقل نمی‌شود.

دلایل این محدودیت عبارت‌اند از:

  • زبان پروژه شما ممکن است در Benchmark کمتر نمایندگی شده باشد
  • Framework داخلی شما متفاوت است
  • Repository خصوصی شما در داده آموزشی وجود نداشته است
  • Agent Harness با محیط Benchmark متفاوت است
  • ابزارها و Promptها متفاوت‌اند
  • تست‌های Benchmark ممکن است کیفیت کامل Patch را نسنجند
  • بعضی داده‌ها ممکن است آلوده یا در داده آموزشی دیده شده باشند
  • وظایف عمومی الزام‌های امنیتی سازمان شما را ندارند
  • Benchmark معمولاً هزینه و تعداد Tool Call را نادیده می‌گیرد

SWE-bench یکی از شناخته‌شده‌ترین ارزیابی‌های مهندسی نرم‌افزار است و مدل یا Agent باید برای یک Issue واقعی در Repository، Patchی تولید کند که تست‌ها را عبور دهد. با این حال حتی ارزیابی‌های شناخته‌شده نیز ممکن است مشکلاتی مانند آلودگی داده، تست ناقص یا وظایف شکسته داشته باشند.

OpenAI در سال ۲۰۲۶ اعلام کرد که SWE-bench Verified دیگر معیار کافی برای اندازه‌گیری قابلیت مدل‌های Frontier نیست و به مشکلاتی مانند آلودگی و تست‌های معیوب اشاره کرد. بررسی جدیدتر OpenAI روی SWE-bench Pro نیز نشان داد که بخشی از وظایف ارزیابی مشکل دارند. این موضوع نشان می‌دهد حتی Benchmarkهای معتبر باید با احتیاط تفسیر شوند. تحلیل SWE-bench Verified، بررسی کیفیت SWE-bench Pro

نتیجه عملی:

از Benchmark عمومی برای ساخت فهرست اولیه مدل‌ها استفاده کنید، اما تصمیم نهایی را با Eval داخلی روی کد و وظایف واقعی خودتان بگیرید.

چگونه یک Benchmark داخلی برای مدل‌های برنامه‌نویسی بسازیم؟

Benchmark داخلی مجموعه‌ای از وظایف واقعی، قابل تکرار و قابل امتیازدهی است که نماینده کار روزمره تیم شما باشد.

مرحله اول: جمع‌آوری وظایف واقعی

از Issueها، Pull Requestها و Bugهای گذشته نمونه جمع‌آوری کنید.

وظایف مناسب باید:

  • پاسخ و Patch مرجع داشته باشند
  • قابل اجرا در محیط جدا باشند
  • نتیجه قابل آزمون داشته باشند
  • اطلاعات محرمانه غیرضروری نداشته باشند
  • انواع مختلف کار را پوشش دهند
  • فقط از یک زبان یا ماژول نباشند

یک مجموعه اولیه می‌تواند شامل ۳۰ تا ۵۰ وظیفه باشد:

  • ۵ وظیفه توضیح کد
  • ۵ تغییر مکانیکی
  • ۵ تولید تست
  • ۱۰ Bug Fix
  • ۵ Refactor
  • ۵ Feature کوچک
  • ۵ Code Review یا Security Review

برای تصمیم‌های مهم سازمانی، تعداد نمونه را افزایش دهید.

مرحله دوم: حذف اطلاعات مربوط به راه‌حل

اگر Issue یا Commit قبلی شامل پاسخ مستقیم است، آن را از ورودی مدل حذف کنید. مدل باید فقط اطلاعاتی را ببیند که یک توسعه‌دهنده در زمان شروع مسئله در اختیار داشت.

در غیر این صورت Eval به بازیابی پاسخ تبدیل می‌شود، نه حل مسئله.

مرحله سوم: ساخت محیط قابل تکرار

برای هر وظیفه یک محیط ثابت بسازید:

  • Commit اولیه مشخص
  • نسخه Runtime ثابت
  • Dependency Lockfile
  • فرمان Setup
  • تست‌های عمومی
  • تست‌های پنهان در صورت امکان
  • محدودیت زمان
  • محدودیت Tool Call
  • محدودیت هزینه
  • سیاست شبکه مشخص

Container یا Snapshot می‌تواند اجرای تکرارپذیر را ساده کند.

مرحله چهارم: تعریف معیارهای قبولی

قبولی نباید فقط بر اساس «کد Compile شد» باشد.

برای هر وظیفه معیارهای زیر را تعریف کنید:

  • تست هدفمند عبور کند
  • تست‌های قبلی خراب نشوند
  • فایل خارج از محدوده تغییر نکند
  • Dependency جدید اضافه نشود
  • API عمومی حفظ شود
  • آسیب‌پذیری ایجاد نشود
  • Lint و Type Check عبور کنند
  • Patch از حد مشخص بزرگ‌تر نباشد
  • Agent در زمان و بودجه تعیین‌شده تمام کند

مرحله پنجم: اجرای چندباره

مدل‌ها احتمالی هستند و ممکن است در دو اجرای یکسان نتیجه متفاوتی بدهند. هر وظیفه را چند بار اجرا کنید.

برای مثال:

  • حداقل ۳ اجرا برای مقایسه اولیه
  • ۵ اجرا برای تصمیم مهم
  • ۱۰ اجرا برای تحلیل پایداری

فقط بهترین نتیجه را گزارش نکنید. میانگین، میانه، انحراف و نرخ شکست اهمیت دارند.

مرحله ششم: ارزیابی کور انسانی

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

Reviewer باید با Rubric ثابت امتیاز بدهد.

Rubric پیشنهادی ارزیابی مدل

یک مدل امتیازدهی ۱۰۰ نمره‌ای می‌تواند چنین باشد:

معیاروزن
صحت عملکرد و عبور تست‌ها۳۰
رعایت محدوده و دستور۱۵
کیفیت و سادگی Patch۱۵
کیفیت استفاده از ابزار۱۰
پوشش حالت‌های مرزی۱۰
امنیت و عدم ایجاد Regression۱۰
زمان و هزینه حل مسئله۵
کیفیت توضیح و گزارش نهایی۵

وزن‌ها را با نیاز تیم تطبیق دهید. برای یک محصول مالی، امنیت ممکن است وزن بیشتری داشته باشد. برای ابزار داخلی، سرعت و هزینه شاید مهم‌تر باشد.

معیارهای کمی مهم

Task Success Rate

نسبت وظایفی که تمام معیارهای اصلی را پاس می‌کنند:

Task Success Rate = Successful Tasks / Total Tasks

این معیار باید با بازه اطمینان یا حداقل تعداد نمونه گزارش شود.

Pass@1

احتمال موفقیت مدل در اولین تلاش است. برای استفاده تعاملی، Pass@1 اهمیت زیادی دارد؛ زیرا Retryهای متعدد هزینه و زمان توسعه‌دهنده را افزایش می‌دهند.

Pass@k

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

Cost per Successful Task

یکی از مهم‌ترین معیارها:

Cost per Successful Task =
Total Cost of All Attempts / Number of Successful Tasks

مدلی با Token ارزان ممکن است به دلیل Retry و Tool Call زیاد، هزینه موفقیت بیشتری داشته باشد.

Time to Validated Patch

زمان از شروع وظیفه تا تولید Patchی که تست‌ها و Review لازم را پاس کند:

Time to Validated Patch =
Model Latency + Tool Time + Retry Time + Human Review Time

فقط زمان پاسخ API را اندازه نگیرید. مدلی که سریع پاسخ می‌دهد اما Patch ضعیفی تولید می‌کند، زمان Review را افزایش می‌دهد.

Tool Calls per Success

تعداد Tool Call لازم برای یک موفقیت:

  • خواندن فایل
  • جست‌وجو
  • اجرای فرمان
  • ویرایش
  • تست
  • Browser
  • MCP

تعداد کمتر همیشه بهتر نیست، اما Tool Callهای تکراری یا غیرضروری نشانه کارایی پایین هستند.

Human Intervention Rate

چند درصد وظایف نیازمند مداخله کاربر بودند؟

مداخله می‌تواند شامل این موارد باشد:

  • اصلاح محدوده
  • توقف Loop
  • تصحیح فرمان
  • ارائه فایل گمشده
  • رد Patch
  • یادآوری محدودیت
  • بازگرداندن تغییر نامرتبط

Regression Rate

چه درصدی از Patchهای ظاهراً موفق، تست یا رفتار قبلی را خراب کرده‌اند؟

این معیار برای Refactor و Featureهای چندفایلی بسیار مهم است.

Diff Efficiency

می‌توان نسبت خطوط مفید به کل خطوط تغییرکرده را بررسی کرد. این معیار کامل نیست، اما تغییر گسترده برای یک Fix کوچک می‌تواند علامت هشدار باشد.

False Completion Rate

چند بار Agent ادعا کرده وظیفه تمام شده، در حالی که:

  • تست اجرا نشده است
  • تست شکست خورده است
  • Build انجام نشده است
  • فایل موردنظر تغییر نکرده است
  • معیار پذیرش رعایت نشده است

این رفتار برای اعتماد عملی به Agent بسیار مهم است.

کیفیت Tool Calling را چگونه ارزیابی کنیم؟

برای Tool Calling یک Rubric مستقل بسازید.

انتخاب ابزار درست

آیا مدل به‌جای خواندن کل Repository از جست‌وجوی هدفمند استفاده کرد؟ آیا قبل از نصب Dependency، فایل‌های موجود را بررسی کرد؟ آیا تست هدفمند را به‌جای کل Suite اجرا کرد؟

ترتیب عملیات

ترتیب مناسب معمولاً چنین است:

  1. شناخت مسئله
  2. جست‌وجوی فایل مرتبط
  3. خواندن Context لازم
  4. ساخت فرضیه
  5. تغییر محدود
  6. اجرای تست هدفمند
  7. تحلیل شکست
  8. اعتبارسنجی گسترده‌تر

ویرایش قبل از بررسی فایل‌ها یا اجرای Build کامل در هر مرحله معمولاً ناکارآمد است.

صحت آرگومان‌ها

Tool Call باید:

  • مسیر معتبر داشته باشد
  • فرمان مناسب سیستم‌عامل تولید کند
  • ورودی Schema را رعایت کند
  • Quote و Escape صحیح داشته باشد
  • داده حساس را وارد فرمان نکند

استفاده از نتیجه ابزار

مدل باید خروجی را بخواند و تصمیم خود را بر اساس آن تغییر دهد. نادیده گرفتن Exit Code یا پیام خطا نشانه Tool Use ضعیف است.

تشخیص پایان

Agent باید بداند چه زمانی معیار پذیرش کامل شده است. اجرای ابزارهای بیشتر پس از تکمیل وظیفه، هزینه و ریسک را افزایش می‌دهد.

Context Window؛ بزرگ‌تر همیشه بهتر نیست

Context Window مقدار اطلاعاتی است که مدل در یک درخواست یا Session می‌تواند در حافظه کاری خود نگه دارد. این اطلاعات شامل Prompt، پاسخ‌ها، فایل‌ها، خروجی ابزارها و خروجی جدید مدل است.

Context بزرگ برای Repositoryهای بزرگ مفید است، اما چند نکته مهم وجود دارد:

  • ظرفیت اسمی به معنی استفاده مؤثر از تمام Context نیست
  • اطلاعات نامرتبط می‌تواند توجه مدل را کاهش دهد
  • هزینه ورودی افزایش پیدا می‌کند
  • Latency بیشتر می‌شود
  • بازیابی جزئیات در Context بسیار بلند ممکن است افت کند
  • خروجی‌های قدیمی Terminal می‌توانند اطلاعات جدید را تحت‌الشعاع قرار دهند

مستندات Anthropic نیز تأکید می‌کنند که Context بیشتر خودکار به معنی عملکرد بهتر نیست و با رشد Context ممکن است دقت و بازیابی کاهش پیدا کند؛ پدیده‌ای که گاهی Context Rot نامیده می‌شود. مستندات Context Window

به‌جای وارد کردن کل Repository، Context را مهندسی کنید:

  • ابتدا Tree پروژه را بخوانید
  • فایل‌ها را با Search انتخاب کنید
  • Interfaceها و قراردادهای مرتبط را وارد کنید
  • فایل‌های Generated را حذف کنید
  • Logها را خلاصه کنید
  • خروجی تست را محدود کنید
  • برای تحقیق جانبی از Subagent استفاده کنید
  • پس از تغییر موضوع Session تازه بسازید
  • قواعد پایدار را در فایل Rules نگه دارید

Cline نیز قابلیت‌هایی مانند Auto Compact، Memory Bank و Subagent ارائه می‌کند تا Context اصلی با جزئیات موقت اشباع نشود. Auto Compact در Cline، Subagents در Cline

Long Context یا Retrieval هدفمند؟

دو راه کلی برای ارائه کد به مدل وجود دارد:

  1. قرار دادن حجم بزرگی از Repository در Context
  2. پیدا کردن و ارسال فایل‌های مرتبط

برای بیشتر وظایف، روش ترکیبی مناسب‌تر است:

  • ابتدا Metadata و ساختار کلی
  • سپس Retrieval فایل‌های مرتبط
  • بعد Context محلی کافی
  • در صورت نیاز گسترش تدریجی

Long Context زمانی مفید است که روابط گسترده و پراکنده باشند، اما نباید جایگزین انتخاب هوشمند فایل شود.

یک Agent خوب باید Context را به‌صورت Progressive Disclosure بسازد؛ یعنی ابتدا اطلاعات کم و پرارزش را ببیند و فقط هنگام نیاز جزئیات بیشتری دریافت کند.

سرعت را چگونه اندازه‌گیری کنیم؟

Latency فقط فاصله ارسال Prompt تا دریافت اولین Token نیست.

در Coding Agent سه نوع زمان مهم است:

Time to First Token

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

Time to Complete Response

زمان تولید کامل پاسخ یا Tool Call.

End-to-End Task Time

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

  • پاسخ مدل
  • اجرای ابزار
  • تست
  • Retry
  • مداخله انسانی
  • Review

برای انتخاب مدل Coding Agent، معیار سوم مهم‌تر است.

مدل سریع اما پراشتباه ممکن است End-to-End Time بیشتری از مدل کند اما دقیق داشته باشد.

هزینه واقعی یک Coding Agent

هزینه یک Task را می‌توان به شکل زیر مدل کرد:

Task Cost =
Input Token Cost
+ Output Token Cost
+ Cached Token Cost
+ Tool Infrastructure Cost
+ Retry Cost
+ Human Review Cost

هزینه API فقط بخشی از هزینه واقعی است. زمان توسعه‌دهنده نیز ارزش اقتصادی دارد.

برای مثال، اگر مدل ارزان‌تر ۲۰ دقیقه Review اضافه ایجاد کند، ممکن است صرفه‌جویی API آن بی‌معنی باشد.

معیار اقتصادی بهتر:

Total Engineering Cost =
API Cost
+ Developer Time
+ CI Cost
+ Failure Risk

محاسبه دقیق Failure Risk دشوار است، اما در سیستم‌های حساس نباید نادیده گرفته شود.

نقش Prompt Caching

در Coding Agent بخش‌هایی از Prompt در مراحل مختلف تکرار می‌شوند:

  • System Prompt
  • ابزارها و Schema آن‌ها
  • Rules پروژه
  • Context پایه Repository
  • دستورهای سازمانی

اگر Provider و مدل از Prompt Caching پشتیبانی کنند، هزینه و Latency این بخش‌های تکراری ممکن است کاهش پیدا کند.

برای استفاده مؤثر:

  • بخش‌های ثابت را در ابتدای Prompt نگه دارید
  • Rules را بی‌دلیل در هر مرحله تغییر ندهید
  • Context ثابت و متغیر را جدا کنید
  • طول حداقل Cache مدل را در نظر بگیرید
  • Cache Hit Rate را پایش کنید
  • هزینه Cache Write و Read را جداگانه محاسبه کنید

Reasoning Effort چه اثری دارد؟

برخی مدل‌ها امکان تعیین میزان Reasoning یا Effort را ارائه می‌کنند. افزایش Reasoning برای تمام وظایف منطقی نیست.

Reasoning پایین یا متوسط برای موارد زیر مناسب‌تر است:

  • توضیح ساده
  • Formatting
  • تغییر مکانیکی
  • تولید Boilerplate
  • اصلاح Import
  • مستندسازی کوتاه

Reasoning بالاتر برای موارد زیر ارزش بیشتری دارد:

  • Debug پیچیده
  • معماری
  • Race Condition
  • تحلیل امنیتی
  • مهاجرت
  • Refactor چندماژوله
  • Agentic Task طولانی

Routing فقط میان مدل‌ها نیست. می‌توان میان تنظیمات مختلف یک مدل نیز Routing انجام داد.

Model Routing چیست؟

Model Routing یعنی انتخاب خودکار مدل یا تنظیمات مناسب بر اساس ویژگی‌های هر درخواست.

به‌جای ارسال تمام وظایف به قوی‌ترین مدل، Router وظیفه را تحلیل می‌کند و آن را به مدل مناسب می‌فرستد.

نمونه ساده:

نوع وظیفهمسیر پیشنهادی
توضیح کدمدل سریع و اقتصادی
تغییر مکانیکیمدل سریع با دقت نحوی
تولید تستمدل میان‌رده با درک رفتار
Bug محدودمدل Coding قوی
Debug چندلایهمدل Reasoning قوی
معماریمدل قوی با Context مناسب
Code Review امنیتیمدل قوی و Reviewer تخصصی
شکست مسیر اولمدل جایگزین یا Escalation

مزایای Model Routing

  • کاهش هزینه
  • کاهش Latency
  • استفاده هدفمند از مدل‌های قوی
  • افزایش تاب‌آوری
  • جلوگیری از وابستگی به یک مدل
  • امکان مقایسه مستمر Providerها
  • استفاده از مدل تخصصی هر وظیفه
  • کنترل بهتر بودجه تیم
  • امکان Fallback هنگام خطا یا محدودیت نرخ

Routing مبتنی بر Rule

ساده‌ترین Router از قواعد صریح استفاده می‌کند.

برای مثال:

اگر وظیفه فقط توضیح یا مستندسازی بود:
    مدل سریع

اگر کمتر از سه فایل و تست مشخص داشت:
    مدل Coding میان‌رده

اگر شامل امنیت، معماری، Migration یا Debug چندسرویسی بود:
    مدل Reasoning قوی

اگر Context تخمینی بیش از آستانه بود:
    مدل دارای Context بزرگ

اگر مدل اول دو بار شکست خورد:
    Escalate به مدل قوی‌تر

Rule-based Routing شفاف، قابل Audit و ساده است، اما ممکن است پیچیدگی واقعی Task را کامل تشخیص ندهد.

Routing مبتنی بر Classifier

در این روش، یک Classifier ارزان ابتدا درخواست را دسته‌بندی می‌کند.

خروجی Classifier می‌تواند چنین باشد:

{
  "task_type": "multi_file_debugging",
  "complexity": "high",
  "risk": "medium",
  "requires_tools": true,
  "requires_large_context": true,
  "preferred_tier": "advanced"
}

سپس Router مدل مناسب را انتخاب می‌کند.

Classifier باید فقط بر اساس متن کاربر تصمیم نگیرد. Metadata نیز مهم است:

  • تعداد فایل‌های درگیر
  • زبان پروژه
  • اندازه Repository
  • وجود تست
  • سطح دسترسی موردنیاز
  • حساسیت ماژول
  • بودجه باقی‌مانده
  • SLA
  • وضعیت مدل‌ها
  • نرخ خطای اخیر

Routing مبتنی بر Confidence

در این روش، مدل سریع ابتدا مسئله را حل می‌کند. اگر نشانه‌های عدم اطمینان یا شکست مشاهده شد، وظیفه به مدل قوی‌تر منتقل می‌شود.

سیگنال‌های Escalation:

  • شکست تست
  • تکرار Tool Call
  • تغییر فایل خارج از محدوده
  • درخواست Context غیرعادی
  • عدم تطابق Patch با معیار پذیرش
  • Confidence پایین
  • طولانی شدن بیش از حد Task
  • عبور از سقف Retry
  • خطای Parser
  • عدم توانایی ساخت برنامه معتبر

نباید صرفاً به Confidence اعلام‌شده توسط خود مدل اعتماد کرد. Confidence باید با سیگنال‌های قابل مشاهده مانند تست، Lint و Validator ترکیب شود.

Routing مبتنی بر Cascade

یک Cascade چند مرحله دارد:

  1. مدل اقتصادی تلاش می‌کند
  2. Validator نتیجه را بررسی می‌کند
  3. اگر نتیجه قبول نشد، مدل میان‌رده وارد می‌شود
  4. در صورت شکست دوباره، مدل قوی‌تر مسئله را دریافت می‌کند
  5. اگر ریسک بالا باشد، کاربر باید تصمیم بگیرد

مزیت Cascade کاهش هزینه متوسط است. عیب آن این است که شکست مرحله اول ممکن است Context و زمان اضافی مصرف کند.

Cascade برای وظایفی مناسب است که:

  • تعداد زیادی دارند
  • درصد بالایی از آن‌ها ساده‌اند
  • اعتبارسنجی خودکار دارند
  • شکست مرحله اول خطر خارجی ایجاد نمی‌کند

Routing بر اساس بودجه

گاهی هدف اصلی حفظ هزینه است.

می‌توان برای هر Task سقف تعیین کرد:

Simple Task Budget: 0.02
Standard Task Budget: 0.10
Complex Task Budget: 0.50
Critical Task Budget: Human approval required

اعداد بالا صرفاً نمونه مفهومی هستند و باید با قیمت مدل‌ها، نرخ ارز و الگوی مصرف شما تنظیم شوند.

Router باید پیش از هر مرحله هزینه احتمالی را تخمین بزند و هنگام نزدیک شدن به سقف:

  • Context را فشرده کند
  • مدل را تغییر دهد
  • از کاربر اجازه بگیرد
  • Task را متوقف کند
  • گزارش وضعیت ارائه دهد

Routing بر اساس ریسک

همه وظایف با یک سطح استقلال اجرا نمی‌شوند.

سطح ریسکنمونهسیاست
پایینتوضیح کد، مستنداتمدل سریع، اجرای آزادتر
متوسطتغییر محدود با تستمدل استاندارد، Diff اجباری
بالاAuthentication، پرداخت، Migrationمدل قوی، تأیید انسانی
بحرانیتولید، حذف داده، DeployAgent فقط Plan؛ اجرای انسانی

در وظایف پرریسک، Router علاوه بر مدل باید سیاست ابزار را نیز تغییر دهد.

برای مثال:

  • Auto-Approve خاموش
  • Network محدود
  • Terminal دستی
  • فایل‌های مجاز محدود
  • Review دوم اجباری
  • تست امنیتی
  • عدم دسترسی به Credential تولید

Fallback با Escalation چه تفاوتی دارد؟

Fallback زمانی استفاده می‌شود که مدل اصلی از نظر عملیاتی در دسترس نیست:

  • Timeout
  • خطای Provider
  • Rate Limit
  • اختلال شبکه
  • مدل غیرفعال
  • خطای موقت

Escalation زمانی است که مدل در دسترس است اما کیفیت نتیجه کافی نیست:

  • تست شکست خورده
  • Patch نامعتبر است
  • Tool Loop رخ داده
  • مدل محدودیت‌ها را رعایت نکرده
  • مسئله پیچیده‌تر از برآورد اولیه است

Fallback باید مدلی با قابلیت نسبتاً مشابه انتخاب کند. Escalation معمولاً به مدل قوی‌تر یا Workflow دقیق‌تر منتقل می‌شود.

معماری پیشنهادی Model Router

یک معماری عملی می‌تواند این اجزا را داشته باشد:

Task Analyzer

نوع، پیچیدگی، ریسک و نیاز Context را استخراج می‌کند.

Model Registry

مشخصات مدل‌ها را نگه می‌دارد:

  • Model ID
  • Context Window
  • Max Output
  • قابلیت Tool Calling
  • قابلیت تصویر
  • هزینه
  • Latency
  • نرخ موفقیت داخلی
  • زبان‌های قوی
  • وضعیت Provider

Policy Engine

قواعد سازمانی را اعمال می‌کند:

  • مدل‌های مجاز
  • سقف هزینه
  • محدودیت داده
  • Region
  • سطح دسترسی
  • نیاز به تأیید انسانی

Router

با استفاده از امتیازها مدل را انتخاب می‌کند.

Execution Layer

درخواست را از طریق API سازگار با OpenAI ارسال می‌کند.

Validator

پاسخ یا Patch را با تست، Lint، Schema و Policy بررسی می‌کند.

Fallback and Escalation Manager

در صورت خطای عملیاتی Fallback و در صورت ضعف کیفی Escalation انجام می‌دهد.

Observability

اطلاعات زیر را ثبت می‌کند:

  • مدل انتخاب‌شده
  • دلیل انتخاب
  • Token
  • هزینه
  • Latency
  • Tool Call
  • Retry
  • نتیجه تست
  • مداخله انسانی
  • موفقیت یا شکست
  • مدل Fallback

تابع امتیازدهی مدل

می‌توان برای هر مدل یک امتیاز پویا محاسبه کرد:

Score =
QualityWeight × Quality
+ ToolWeight × ToolUse
+ ContextWeight × ContextFit
+ SpeedWeight × Speed
+ CostWeight × CostEfficiency
+ ReliabilityWeight × Reliability
- RiskPenalty

وزن‌ها بر اساس نوع Task تغییر می‌کنند.

برای Debug پیچیده:

QualityWeight = High
ToolWeight = High
ContextWeight = High
SpeedWeight = Medium
CostWeight = Low

برای توضیح کد:

QualityWeight = Medium
ToolWeight = Low
ContextWeight = Low
SpeedWeight = High
CostWeight = High

این تفاوت وزن‌ها باعث می‌شود یک مدل واحد برای همه درخواست‌ها انتخاب نشود.

اتصال به API درواره

درواره یک API سازگار با OpenAI ارائه می‌کند. بنابراین می‌توانید از SDKهای سازگار با OpenAI برای ارسال درخواست استفاده کنید.

Base URL:

https://api.darvareh.ir/v1

ابتدا API Key را در متغیر محیطی قرار دهید:

export DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"

فهرست مدل‌های فعال:

curl https://api.darvareh.ir/v1/models \
  -H "Authorization: Bearer $DARVAREH_API_KEY"

شناسه مدل را از فیلد id پاسخ دریافت کنید.

نمونه Python برای اجرای چند مدل

ابتدا SDK را نصب کنید:

pip install openai

نمونه کد:

import os
import time
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DARVAREH_API_KEY"],
    base_url="https://api.darvareh.ir/v1",
)

def run_model(model_id: str, prompt: str) -> dict:
    started_at = time.perf_counter()

    response = client.chat.completions.create(
        model=model_id,
        messages=[
            {
                "role": "system",
                "content": (
                    "You are a senior software engineer. "
                    "Return concise, production-ready code and explain assumptions."
                ),
            },
            {
                "role": "user",
                "content": prompt,
            },
        ],
        temperature=0,
    )

    elapsed = time.perf_counter() - started_at
    usage = response.usage

    return {
        "model": model_id,
        "latency_seconds": round(elapsed, 2),
        "input_tokens": getattr(usage, "prompt_tokens", None),
        "output_tokens": getattr(usage, "completion_tokens", None),
        "answer": response.choices[0].message.content,
    }

برای مقایسه:

models = [
    "MODEL_ID_FAST",
    "MODEL_ID_STANDARD",
    "MODEL_ID_ADVANCED",
]

prompt = """
تابع زیر را از نظر صحت، امنیت و حالت‌های مرزی بررسی کن.
ابتدا مشکلات را فهرست کن و سپس کمترین Patch ممکن را پیشنهاد بده.

def get_user(user_id, db):
    return db.execute(
        f\"SELECT * FROM users WHERE id = {user_id}\"
    ).fetchone()
"""

for model in models:
    result = run_model(model, prompt)
    print(result["model"])
    print(result["latency_seconds"])
    print(result["input_tokens"], result["output_tokens"])
    print(result["answer"])

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

نمونه Router ساده در Python

from dataclasses import dataclass
from typing import Literal

TaskType = Literal[
    "explanation",
    "mechanical_change",
    "test_generation",
    "bug_fix",
    "complex_debugging",
    "architecture",
    "security_review",
]

@dataclass
class Task:
    task_type: TaskType
    estimated_files: int
    estimated_context_tokens: int
    risk: Literal["low", "medium", "high", "critical"]
    requires_tools: bool

MODEL_FAST = "MODEL_ID_FAST"
MODEL_STANDARD = "MODEL_ID_STANDARD"
MODEL_ADVANCED = "MODEL_ID_ADVANCED"
MODEL_LONG_CONTEXT = "MODEL_ID_LONG_CONTEXT"

def select_model(task: Task) -> str:
    if task.risk == "critical":
        raise ValueError(
            "Critical tasks require human approval before model execution."
        )

    if task.estimated_context_tokens > 100_000:
        return MODEL_LONG_CONTEXT

    if task.task_type in {"security_review", "architecture", "complex_debugging"}:
        return MODEL_ADVANCED

    if task.task_type in {"bug_fix", "test_generation"}:
        return MODEL_STANDARD

    if task.estimated_files > 5 or task.requires_tools:
        return MODEL_STANDARD

    return MODEL_FAST

این Router عمداً ساده است. در محیط واقعی باید قیمت، وضعیت Provider، نرخ موفقیت اخیر و سیاست سازمان نیز وارد تصمیم شوند.

Fallback در Router

FALLBACKS = {
    MODEL_FAST: [MODEL_STANDARD],
    MODEL_STANDARD: [MODEL_ADVANCED],
    MODEL_ADVANCED: [MODEL_LONG_CONTEXT],
    MODEL_LONG_CONTEXT: [MODEL_ADVANCED],
}

def get_candidates(primary_model: str) -> list[str]:
    return [primary_model, *FALLBACKS.get(primary_model, [])]

اجرای مقاوم:

def execute_with_fallback(task: Task, prompt: str) -> dict:
    primary = select_model(task)
    errors = []

    for model_id in get_candidates(primary):
        try:
            result = run_model(model_id, prompt)
            result["primary_model"] = primary
            result["fallback_used"] = model_id != primary
            return result
        except Exception as exc:
            errors.append({
                "model": model_id,
                "error": str(exc),
            })

    raise RuntimeError({
        "message": "All model candidates failed.",
        "attempts": errors,
    })

این Fallback فقط خطای عملیاتی را مدیریت می‌کند. نتیجه ضعیف باید توسط Validator تشخیص داده شود.

Validator برای پاسخ‌های کدنویسی

Validator می‌تواند چند لایه داشته باشد:

اعتبارسنجی نحوی

  • Parse کد
  • Compile
  • Type Check
  • Schema Validation

اعتبارسنجی رفتاری

  • Unit Test
  • Integration Test
  • Regression Test
  • تست پنهان

اعتبارسنجی Policy

  • فایل غیرمجاز تغییر نکرده باشد
  • Dependency جدید اضافه نشده باشد
  • Secret وارد Patch نشده باشد
  • فرمان ممنوع اجرا نشده باشد
  • API عمومی تغییر نکرده باشد

بازبینی مدل دوم

یک مدل Reviewer می‌تواند Patch مدل اول را بررسی کند، اما نباید جای تست قطعی را بگیرد.

بازبینی انسانی

برای تغییرات مهم همچنان ضروری است.

نمونه سیاست Escalation

@dataclass
class ValidationResult:
    passed: bool
    test_passed: bool
    policy_passed: bool
    retryable: bool
    reason: str

def should_escalate(
    validation: ValidationResult,
    attempts: int,
) -> bool:
    if validation.passed:
        return False

    if not validation.policy_passed:
        return True

    if validation.retryable and attempts < 2:
        return False

    return True

قاعده مهم این است که Escalation بی‌نهایت نباشد. برای هر Task سقف Retry، Tool Call، زمان و هزینه تعیین کنید.

پیاده‌سازی با TypeScript

نصب SDK:

npm install openai

ساخت Client:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.DARVAREH_API_KEY,
  baseURL: "https://api.darvareh.ir/v1",
});

تعریف Task:

type TaskType =
  | "explanation"
  | "mechanical-change"
  | "test-generation"
  | "bug-fix"
  | "complex-debugging"
  | "architecture"
  | "security-review";

type Risk = "low" | "medium" | "high" | "critical";

interface CodingTask {
  type: TaskType;
  risk: Risk;
  estimatedFiles: number;
  estimatedContextTokens: number;
  requiresTools: boolean;
}

انتخاب مدل:

const models = {
  fast: "MODEL_ID_FAST",
  standard: "MODEL_ID_STANDARD",
  advanced: "MODEL_ID_ADVANCED",
  longContext: "MODEL_ID_LONG_CONTEXT",
} as const;

function selectModel(task: CodingTask): string {
  if (task.risk === "critical") {
    throw new Error("Human approval is required for critical tasks.");
  }

  if (task.estimatedContextTokens > 100_000) {
    return models.longContext;
  }

  if (
    task.type === "complex-debugging" ||
    task.type === "architecture" ||
    task.type === "security-review"
  ) {
    return models.advanced;
  }

  if (
    task.type === "bug-fix" ||
    task.type === "test-generation" ||
    task.requiresTools ||
    task.estimatedFiles > 5
  ) {
    return models.standard;
  }

  return models.fast;
}

ارسال درخواست:

async function executeTask(task: CodingTask, prompt: string) {
  const model = selectModel(task);
  const startedAt = performance.now();

  const response = await client.chat.completions.create({
    model,
    messages: [
      {
        role: "system",
        content:
          "You are a senior software engineer. Follow scope constraints, " +
          "avoid unrelated changes, and state when information is missing.",
      },
      {
        role: "user",
        content: prompt,
      },
    ],
    temperature: 0,
  });

  return {
    model,
    latencyMs: Math.round(performance.now() - startedAt),
    usage: response.usage,
    content: response.choices[0]?.message?.content ?? "",
  };
}

مدل‌های فعال را Hard-code نکنید

فهرست مدل‌ها ممکن است تغییر کند. بهتر است Registry مدل‌ها به شکل پویا از Endpoint مدل‌ها دریافت و سپس با Metadata داخلی شما ترکیب شود.

درخواست:

async function fetchAvailableModels() {
  const response = await client.models.list();

  return response.data.map((model) => model.id);
}

اما Endpoint استاندارد مدل‌ها معمولاً تمام Metadata موردنیاز Router، مانند امتیاز داخلی، قیمت یا قابلیت Tool Calling را ارائه نمی‌کند. بنابراین یک Registry داخلی نیز لازم است.

نمونه:

interface ModelProfile {
  id: string;
  tier: "fast" | "standard" | "advanced";
  supportsTools: boolean;
  supportsImages: boolean;
  contextWindow: number;
  maxOutputTokens: number;
  internalSuccessRate: number;
  medianLatencyMs: number;
  enabled: boolean;
}

این Registry باید با داده واقعی Observability به‌روزرسانی شود.

Online Evaluation

Offline Benchmark به شما امکان مقایسه کنترل‌شده می‌دهد، اما رفتار تولید ممکن است متفاوت باشد.

در Online Evaluation این اطلاعات را جمع‌آوری کنید:

  • نوع Task
  • مدل
  • نسخه Prompt
  • تعداد Tool Call
  • Token ورودی و خروجی
  • Latency
  • هزینه
  • Retry
  • Fallback
  • نتیجه Validator
  • پذیرش یا رد کاربر
  • میزان ویرایش دستی پس از Agent
  • وقوع Regression
  • نتیجه نهایی

هرگز Source Code یا Secret حساس را بدون سیاست مشخص در Log ذخیره نکنید. برای Observability می‌توان Hash، Metadata و Metrics را نگه داشت و Payload را حذف یا Redact کرد.

A/B Testing مدل‌ها

برای مقایسه دو مدل:

  1. Taskهای مشابه را انتخاب کنید
  2. Assignment را تصادفی کنید
  3. شرایط Agent را ثابت نگه دارید
  4. سقف هزینه و زمان را برابر کنید
  5. Reviewer را کور نگه دارید
  6. موفقیت و هزینه را هم‌زمان بسنجید
  7. نمونه کافی جمع‌آوری کنید

در محیط تولید، Shadow Evaluation نیز مفید است. مدل اصلی نتیجه را به کاربر می‌دهد و مدل دوم بدون اثر خارجی همان Task را اجرا می‌کند. سپس خروجی‌ها مقایسه می‌شوند.

Shadow Run هزینه دارد و باید اطلاعات حساس و عملیات ابزار در آن محدود شود.

Canary Rollout برای مدل جدید

مدل جدید را یک‌باره جایگزین مدل اصلی نکنید.

مراحل پیشنهادی:

  1. Offline Eval
  2. Shadow Test
  3. یک درصد Traffic کم‌ریسک
  4. مقایسه Success، Cost و Latency
  5. افزایش تدریجی
  6. توقف خودکار در صورت Regression
  7. Rollback آماده

معیار Rollback می‌تواند شامل این موارد باشد:

  • افزایش Failure Rate
  • افزایش Cost per Success
  • افزایش Tool Loop
  • افزایش Patch Rejection
  • افزایش Latency
  • نقض Policy
  • خطاهای Provider

جلوگیری از Vendor Lock-in

استفاده از API سازگار با OpenAI و یک لایه Router کمک می‌کند کد برنامه به یک Provider خاص گره نخورد.

با این حال سازگاری کامل تضمین‌شده نیست. مدل‌ها ممکن است در این موارد تفاوت داشته باشند:

  • پارامترهای Sampling
  • قالب Tool Calling
  • Streaming
  • Reasoning
  • Prompt Caching
  • تصویر
  • Structured Output
  • Max Tokens
  • Stop Sequence
  • Error Format

برای کاهش وابستگی:

  • یک Adapter داخلی بسازید
  • Feature Detection داشته باشید
  • پارامترهای مخصوص مدل را جدا نگه دارید
  • Contract Test اجرا کنید
  • Fallback را با مدل‌های واقعی آزمایش کنید
  • Model ID را از Business Logic جدا کنید
  • Prompt را Versioning کنید

Contract Test برای مدل‌ها

پیش از فعال‌سازی مدل در Router، حداقل این تست‌ها را اجرا کنید:

  • درخواست متنی ساده
  • Streaming
  • Tool Call
  • چند Tool Call پشت‌سرهم
  • JSON یا Structured Output
  • Context متوسط
  • Max Output
  • Timeout
  • لغو درخواست
  • Error Mapping
  • ورودی فارسی
  • کد زبان‌های اصلی تیم

اگر یک مدل Tool Calling پایدار ندارد، نباید صرفاً به دلیل کیفیت متن وارد مسیر Agentic شود.

امنیت Model Routing

Router می‌تواند روی انتخاب مدل اثر بگذارد، اما نباید کنترل امنیتی را به مدل واگذار کند.

اصول مهم:

  • Credential در Prompt قرار نگیرد
  • مدل به Secret تولید دسترسی نداشته باشد
  • Tool Permission مستقل از مدل باشد
  • مدل قوی‌تر به معنی دسترسی بیشتر نباشد
  • عملیات بحرانی نیازمند تأیید انسانی باشد
  • Prompt Injection در فایل‌ها و خروجی ابزارها در نظر گرفته شود
  • MCP Serverها حداقل دسترسی داشته باشند
  • Logها Redact شوند
  • Tenantها از یکدیگر جدا باشند
  • مسیر Fallback همان Policy امنیتی را رعایت کند

یک خطای رایج این است که مدل Fallback با تنظیمات امنیتی متفاوت فراخوانی شود. Policy باید در لایه‌ای مستقل از Provider اعمال شود.

Prompt Injection در Repository

فایل‌های Repository می‌توانند شامل متنی باشند که تلاش می‌کند Agent را منحرف کند؛ برای مثال در یک README، Comment یا فایل تولیدشده نوشته شده باشد که Agent باید Secret را ارسال کند یا فرمان خاصی اجرا کند.

Agent باید محتوای Repository را داده غیرقابل اعتماد بداند.

اقدامات دفاعی:

  • دستورهای فایل را با System Policy هم‌سطح ندانید
  • فرمان شبکه‌ای را تأیید کنید
  • Secretها را خارج از Workspace نگه دارید
  • فایل‌های Generated و Vendor را محدود کنید
  • عملیات حساس را با Policy Engine کنترل کنید
  • ورودی MCP را نیز غیرقابل اعتماد در نظر بگیرید
  • دامنه شبکه را Allowlist کنید

اشتباهات رایج در انتخاب مدل

انتخاب بر اساس یک Benchmark

یک امتیاز عمومی نمی‌تواند زبان، Framework، Agent و Policy شما را کامل نمایندگی کند.

استفاده از قوی‌ترین مدل برای همه چیز

این کار هزینه و Latency را بالا می‌برد و ممکن است برای وظایف ساده ارزش افزوده‌ای نداشته باشد.

انتخاب فقط بر اساس قیمت Token

قیمت پایین بدون در نظر گرفتن تعداد تلاش، Tool Call و Review گمراه‌کننده است.

نادیده گرفتن Tool Calling

مدل تولید کد خوب ممکن است در Agent Loop ضعیف باشد.

نادیده گرفتن Context Engineering

مدل قوی با Context نامرتبط می‌تواند از مدل متوسط با Context دقیق ضعیف‌تر عمل کند.

تغییر هم‌زمان مدل و Agent

اگر مدل، Prompt، Agent و ابزارها را هم‌زمان تغییر دهید، دلیل بهبود یا افت مشخص نمی‌شود.

اجرای Eval فقط یک بار

یک اجرای موفق یا ناموفق نماینده پایداری مدل نیست.

استفاده از تست‌های عمومی بدون Review

تست ناقص ممکن است Patch اشتباه را قبول کند.

نداشتن سقف هزینه و Retry

Agent می‌تواند وارد Loop شود و هزینه غیرمنتظره ایجاد کند.

نداشتن Observability

بدون داده تولید نمی‌توان فهمید کدام مدل واقعاً اقتصادی‌تر یا قابل اعتمادتر است.

چک‌لیست انتخاب مدل برای Coding Agent

پیش از فعال کردن یک مدل، پاسخ این پرسش‌ها را مشخص کنید:

قابلیت

  • آیا زبان‌های اصلی پروژه را خوب پشتیبانی می‌کند؟
  • آیا Tool Calling پایدار دارد؟
  • آیا Context کافی دارد؟
  • آیا خروجی موردنیاز را پشتیبانی می‌کند؟
  • آیا در وظایف چندمرحله‌ای پایدار است؟

کیفیت

  • Task Success Rate داخلی چقدر است؟
  • Pass@1 چقدر است؟
  • Regression Rate چقدر است؟
  • Patchها چقدر نیازمند ویرایش انسانی هستند؟
  • آیا محدودیت‌های Scope را رعایت می‌کند؟

کارایی

  • Median Latency چقدر است؟
  • P95 Latency چقدر است؟
  • Tool Calls per Success چقدر است؟
  • Cost per Successful Task چقدر است؟
  • Retry Rate چقدر است؟

عملیات

  • Availability مناسب دارد؟
  • Rate Limit قابل قبول است؟
  • Fallback مشخص شده است؟
  • خطاها قابل تشخیص هستند؟
  • Metrics لازم ثبت می‌شوند؟

امنیت

  • داده کجا پردازش می‌شود؟
  • Policy سازمان رعایت می‌شود؟
  • Tool Permission مستقل است؟
  • Logها اطلاعات حساس ندارند؟
  • عملیات پرریسک تأیید انسانی دارند؟

یک استراتژی عملی برای شروع

اگر هنوز داده داخلی ندارید، با چهار Tier آغاز کنید.

Tier سریع

برای:

  • توضیح
  • خلاصه‌سازی
  • مستندات
  • تغییر مکانیکی
  • پرسش کوتاه

Tier استاندارد

برای:

  • تولید تست
  • Bug محدود
  • Patch چندفایلی کوچک
  • Refactor محدود
  • Tool Calling متوسط

Tier پیشرفته

برای:

  • Debug پیچیده
  • معماری
  • امنیت
  • Feature چندلایه
  • Agentic Task طولانی

Tier دارای Context بزرگ

برای:

  • Repository بسیار بزرگ
  • تحلیل چندماژوله
  • Migration گسترده
  • مستندات یا Logهای حجیم

پس از چند هفته، تصمیم‌ها را با Metrics واقعی اصلاح کنید. شاید متوجه شوید مدل Tier استاندارد در ۸۰ درصد وظایف کافی است و مدل پیشرفته فقط برای ۲۰ درصد درخواست‌ها ارزش دارد.

پرسش‌های متداول

بهترین مدل برای Coding Agent کدام است؟

پاسخ به نوع Task، Agent، زبان پروژه، بودجه و معیار پذیرش بستگی دارد. به‌جای انتخاب یک مدل ثابت، چند مدل را روی Eval داخلی مقایسه و برای دسته‌های مختلف Routing کنید.

آیا مدل دارای Benchmark بالاتر همیشه بهتر است؟

خیر. Benchmark عمومی فقط یک سیگنال است. کیفیت Tool Calling، هزینه موفقیت، Context، پایداری و سازگاری با Repository شما اهمیت بیشتری دارند.

تفاوت مدل Coding با مدل Reasoning چیست؟

مدل Coding ممکن است برای Syntax، Patch و الگوهای برنامه‌نویسی بهینه باشد. مدل Reasoning در تحلیل چندمرحله‌ای و مسائل پیچیده قوی‌تر است. بعضی مدل‌ها هر دو قابلیت را ترکیب می‌کنند، اما باید در Workflow واقعی آزمایش شوند.

Context Window بزرگ‌تر همیشه بهتر است؟

خیر. Context بزرگ ظرفیت بیشتری فراهم می‌کند، اما اطلاعات نامرتبط می‌تواند هزینه، Latency و خطا را افزایش دهد. Retrieval هدفمند و Context Engineering همچنان ضروری هستند.

مدل ارزان‌تر چگونه ممکن است گران‌تر تمام شود؟

اگر Retry، Tool Call و Review بیشتری نیاز داشته باشد، Cost per Successful Task آن می‌تواند از مدل گران‌تر بیشتر شود.

آیا باید برای هر زبان برنامه‌نویسی مدل جدا انتخاب کنیم؟

در بعضی تیم‌ها بله. عملکرد مدل در TypeScript، Python، Java، Rust، PHP یا زبان داخلی ممکن است متفاوت باشد. زبان و Framework را در Eval داخلی تفکیک کنید.

Model Routing چگونه هزینه را کاهش می‌دهد؟

وظایف ساده را به مدل سریع و اقتصادی و وظایف پیچیده را به مدل قوی‌تر می‌فرستد. در نتیجه فقط زمانی هزینه مدل پیشرفته پرداخت می‌شود که ارزش واقعی داشته باشد.

Fallback و Escalation چه تفاوتی دارند؟

Fallback برای خطای عملیاتی مانند Timeout یا Rate Limit است. Escalation برای زمانی است که نتیجه مدل از نظر کیفیت قابل قبول نیست.

آیا می‌توان انتخاب مدل را کاملاً خودکار کرد؟

بله، اما برای وظایف پرریسک باید تأیید انسانی و Policy مستقل وجود داشته باشد. Router نباید مجوز عملیات بحرانی را فقط بر اساس تصمیم مدل صادر کند.

چند Task برای Benchmark داخلی کافی است؟

برای شروع ۳۰ تا ۵۰ Task متنوع مفید است. برای تصمیم مهم تولید، نمونه بیشتر و چند اجرای تکراری لازم است.

آیا یک بار اجرای هر Task کافی است؟

خیر. خروجی مدل احتمالی است. حداقل سه اجرای مستقل برای مقایسه اولیه و تعداد بیشتر برای تصمیم‌های مهم توصیه می‌شود.

چگونه مدل‌های در دسترس درواره را مشاهده کنیم؟

از Endpoint زیر استفاده کنید:

GET https://api.darvareh.ir/v1/models

Base URL درواره چیست؟

https://api.darvareh.ir/v1

آیا API درواره با OpenAI SDK سازگار است؟

بله. می‌توانید در SDKهای سازگار با OpenAI، base_url یا baseURL را روی آدرس API درواره تنظیم و از API Key درواره استفاده کنید.

آیا Router باید قیمت مدل‌ها را Hard-code کند؟

بهتر است قیمت، قابلیت و وضعیت مدل‌ها در Registry قابل به‌روزرسانی نگهداری شود. Hard-code کردن این اطلاعات نگهداری و تغییر مدل را دشوار می‌کند.

آیا Reviewer هم باید همان مدل تولیدکننده باشد؟

الزامی نیست. استفاده از مدل یا Prompt متفاوت برای Review می‌تواند خطاهای بیشتری آشکار کند، اما تست قطعی و Review انسانی همچنان اهمیت دارند.

آیا Agent می‌تواند خودش پیچیدگی Task را تشخیص دهد؟

می‌تواند تخمین بزند، اما این تخمین باید با Metadata، تعداد فایل‌ها، ریسک ماژول، تست‌ها و سیگنال‌های اجرای واقعی ترکیب شود.

جمع‌بندی

انتخاب مدل برای برنامه‌نویسی نباید به یک جدول رتبه‌بندی یا عنوان «بهترین مدل سال» محدود شود. Coding Agent یک سیستم چندلایه است و کیفیت نهایی آن از تعامل مدل، Agent Harness، Context، ابزارها، Repository، تست و Policy حاصل می‌شود.

برای انتخاب حرفه‌ای مدل باید این موارد را هم‌زمان اندازه‌گیری کنید:

  • صحت Patch
  • رعایت دستور و محدوده
  • کیفیت Tool Calling
  • توان برنامه‌ریزی چندمرحله‌ای
  • مدیریت Context
  • بازیابی از خطا
  • Regression Rate
  • میزان مداخله انسانی
  • Latency کامل Task
  • Cost per Successful Task

Benchmarkهای عمومی برای ساخت فهرست اولیه مفیدند، اما تصمیم اصلی باید بر اساس Eval داخلی و وظایف واقعی تیم انجام شود. حتی معیارهای شناخته‌شده مهندسی نرم‌افزار ممکن است با آلودگی داده، تست‌های ناقص یا وظایف شکسته روبه‌رو باشند.

بهترین معماری برای بسیاری از تیم‌ها استفاده از یک مدل ثابت نیست، بلکه یک سیستم چندمدلی است:

  • مدل سریع برای کار ساده
  • مدل استاندارد برای وظایف روزمره
  • مدل پیشرفته برای Debug، امنیت و معماری
  • مدل Long Context برای Repositoryهای بزرگ
  • Fallback برای خطای عملیاتی
  • Escalation برای شکست کیفی
  • Validator برای تست و Policy
  • Observability برای بهبود مستمر

با API سازگار با OpenAI درواره می‌توانید این معماری را بدون اتصال جداگانه به هر Provider پیاده‌سازی کنید، مدل‌های فعال را از یک Endpoint دریافت کنید و Router خود را بر اساس کیفیت، هزینه، سرعت و نیاز هر Task توسعه دهید.

هدف نهایی این نیست که همیشه قوی‌ترین مدل را فراخوانی کنید. هدف این است که هر وظیفه با مناسب‌ترین مدل، کمترین هزینه قابل قبول، کوتاه‌ترین زمان واقعی و بالاترین احتمال موفقیت انجام شود.

مقالات مرتبط پیشنهادی

برای ساخت یک زیرساخت چندمدلی، ابتدا از پنل درواره یک API Key اختصاصی ایجاد کنید و مدل‌های قابل دسترس را از Endpoint زیر دریافت کنید:

https://api.darvareh.ir/v1/models

سپس یک Eval کوچک با ۳۰ تا ۵۰ وظیفه واقعی تیم بسازید، مدل‌ها را با شرایط یکسان اجرا کنید و علاوه بر کیفیت پاسخ، هزینه موفقیت، تعداد Tool Call، زمان اعتبارسنجی و میزان مداخله انسانی را اندازه بگیرید.

پس از جمع‌آوری داده اولیه، Router را با سه مسیر سریع، استاندارد و پیشرفته راه‌اندازی کنید و Fallback، Escalation، سقف هزینه و Policy امنیتی را به‌صورت مستقل در معماری قرار دهید.

Read more