شما یک ابزار داخلی ساخته‌اید که به یک تیم اجازه می‌دهد ۲۸ تست واحد را روی یک قابلیت مبتنی بر LLM اجرا کند، بدون اینکه حتی یک بار API مدل را فراخوانی کنند. شما این کار را با قرار دادن مدل در یک رابط کاربری قابل جایگزینی با نسخه جعلی (fakeable interface) و افزودن سه لایه ارزیابی قطعی (deterministic)، اکتشافی (heuristic) و مبتنی بر LLM انجام دادید.

ادعاهای استاندارد (Standard assertions) به محض اینکه یک LLM شروع به تولید متن می‌کند، از کار می‌افتند. یک پرامپت یکسان می‌تواند در هر بار اجرا، جمله‌ای متفاوت تولید کند، بنابراین assertEqual(output, expected) حتی زمانی که مدل درست عمل کرده است، خطا اعلام می‌کند. اکثر گروه‌های مهندسی یا قابلیت را بدون هیچ تأییدی عرضه می‌کنند و یا سعی می‌کنند خودِ مدل را تست کنند، و با یک هدف دائماً در حال تغییر، مانند یک کتابخانه ایستا (static library) برخورد می‌کنند.

چرا این مسئله اهمیت دارد

اکنون LLMها در جریان‌های کاری رو به مشتری قرار دارند—ارسال ایمیل، پاسخ‌های پشتیبانی، تولید محتوا. یک واقعیت توهم‌آمیز (hallucinated fact) یا یک شناسه فاش‌شده می‌تواند به اعتبار برند آسیب بزند، داده‌های خصوصی را افشا کند یا باعث نقض قوانین انطباق (compliance) شود. بدون یک استراتژی تست قابل اعتماد، تیم‌ها وقت خود را صرف تعقیب شکست‌های ناپایدار (flaky failures) می‌کنند یا باگ‌هایی را عرضه می‌کنند که فقط در محیط عملیاتی (production) خود را نشان می‌دهند.

رویکرد: محدود کردن مسئولیت مدل

اولین قدم، محدود کردن کاری بود که LLM واقعاً انجام می‌دهد. در سیستم نویسنده، مدل فقط پیش‌نویس پیام‌های ارتباطی را تهیه می‌کند. تمام منطق مسیریابی (routing logic)، مدیریت وضعیت (state management) و بررسی‌های ایمنی در کدهای معمولی باقی می‌مانند. با محدود کردن مدل به یک خروجی واحد و مشخص، سیستم پیرامون آن قطعی (deterministic) و قابل تست باقی می‌ماند.

برای ممکن ساختن این کار، LLM پشت یک رابط ارائه‌دهنده (provider interface) قرار می‌گیرد که اجازه می‌دهد از یک نسخه جعلی (fake) در تست‌ها استفاده شود. در محیط عملیاتی، پیاده‌سازی API خارجی را فراخوانی می‌کند؛ در مجموعه تست، یک نسخه جعلی سبک، یک پاسخ از پیش تعیین‌شده (canned response) را برمی‌گرداند. از آنجایی که بقیه کدها فقط با این رابط تعامل دارند، کل جریان کاری می‌تواند توسط تست‌های واحدی که هرگز با شبکه تماس نمی‌گیرند، اجرا شود. نتیجه، یک هسته قابل پیش‌بینی است که آن ۲۸ تست آن را تأیید می‌کنند.

یک چارچوب ارزیابی صادقانه

حتی با محدود کردن دامنه، خروجی مدل همچنان غیرقطعی (nondeterministic) باقی می‌ماند. بنابراین، نویسنده یک چارچوب ارزیابی (evaluation harness) سه لایه ساخت که هر لایه کلاس متفاوتی از ریسک را مدیریت می‌کند.

  • لایه ۱ – بررسی‌های قطعی (Deterministic checks) قوانین ساده عبارت‌های منظم (regular-expression) خطاهای مشخصی مانند شناسه اشتباه ساختمان یا توکن‌های ممنوعه را شناسایی می‌کنند. این بررسی‌ها سریع هستند و نتیجه‌ای دوگانه (قبولی/رد) دارند.

  • لایه ۲ – بررسی‌های اکتشافی (Heuristic checks) اسکریپت‌ها به دنبال اعداد یا تاریخ‌های توهم‌آمیز می‌گردند و جعل‌های فکت‌های آشکار را علامت‌گذاری می‌کنند. آن‌ها ادعاهای اشتباهی را که فاقد نشانه‌های عددی هستند از دست می‌دهند و نویسنده صراحتاً به این محدودیت اذعان دارد.

  • لایه ۳ – داور LLM (LLM judge) یک مدل ثانویه، لحن و حرفه‌ای بودن را رتبه‌بندی می‌کند. از آنجایی که این مرحله به یک سیستم احتمالی (probabilistic system) دیگر متکی است، تنها برای جنبه‌های ذهنی (subjective) که قوانین قطعی در آن‌ها غیرممکن است، استفاده می‌شود.

کلید این چارچوب، مجموعه داده‌ای است که برای ارزیابی استفاده می‌شود. نویسنده الگوهای شکست شناخته‌شده—تله‌های خاص و دانش دامنه (domain knowledge)—را کدگذاری کرده است تا چارچوب دقیقاً همان اشتباهاتی را تست کند که در عمل ظاهر شده‌اند. این یک «جامع‌الاطراف» جادویی نیست، بلکه یک شبکه ایمنی هدفمند است.

این موضوع برای تیم‌ها چه معنایی دارد

  • وظیفه LLM را کوچک نگه دارید. مسئولیت‌های کمتر، جداسازی و تست را آسان‌تر می‌کند.
  • مسیریابی، وضعیت و ایمنی را در کد قرار دهید. منطق سنتی، قطعی و کاملاً قابل تست باقی می‌ماند.
  • مدل را از طریق یک رابط قابل جعل (fakeable interface) ارائه دهید. تست‌های واحد بدون فراخوانی‌های خارجی اجرا می‌شوند و مجموعه تست را سریع و قابل اعتماد نگه می‌دارند.
  • ارزیابی‌های خود را لایه‌بندی کنید. با قوانین قطعی شروع کنید، اکتشافی‌ها را برای توهم‌های شناخته‌شده اضافه کنید و داوران LLM را برای بررسی‌های کیفی ذهنی (subjective) رزرو کنید.
  • محدودیت‌ها را بیان کنید. هیچ لایه‌ای تضمین‌کننده کمال نیست؛ این چارچوب فقط آنچه را که صراحتاً برای شناسایی برنامه‌ریزی کرده‌اید، شکار می‌کند.

نکته متقابل: شما هنوز نمی‌توانید خودِ مدل را تست واحد کنید

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

نتیجه‌گیری

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