پرش به محتوای اصلی
پرش به محتوای مقاله

کدهای قطعی در برابر LLMها برای مدیریت استثنائات در ReviewMind

·۷ مهر ۱۴۰۵۶ دقیقه مطالعه
بینش گذشته استثنا را به خاطر می‌سپارد. کد من تصمیم می‌گیرد آیا قابل اعمال است.
بینش گذشته استثنا را به خاطر می‌سپارد. کد من تصمیم می‌گیرد آیا قابل اعمال است.
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

معرفی یک معماری ترکیبی که در آن LLM فقط برای بازیابی معنایی (Semantic Recall) استفاده می‌شود و تصمیم‌گیری نهایی بر اساس قوانین سخت‌گیرانه کد (Hard-coded logic) صورت می‌گیرد تا از تعمیم اشتباه مجوزها جلوگیری شود.

تصور کنید یک برنامه‌نویس در تیمی بزرگ، برای یک فایل قدیمی استثنایی در قوانین کدنویسی می‌گیرد، اما ماه‌ها بعد هیچ‌کس به یاد نمی‌آورد این مجوز چه زمانی صادر شده، چرا صادر شده، برای کدام مسیرها بوده یا چه زمانی منقضی می‌شود. اغلب در رشته‌های گفتگو (threads) بازبینی، هیچ‌کس نمی‌داند چه کسی تاییدیه داده است. یک بازبین ممکن است پیشنهاد استفاده از یک wrapper انتقال مشترک را بدهد و نویسنده کد پاسخ دهد: «ما برای این فایل استثنا تایید شده داریم.» ReviewMind، سیستم جدید بازبینی کدی که جزئیات آن در ۲۹ سپتامبر ۲۰۲۶ منتشر شد، با جداسازی «عمل یادآوری یک استثنا» از «عمل اعمال آن»، این حفره‌های مستند نشده و دائمی را در بازبینی کد می‌بندد.

بسیاری از عامل‌های هوش مصنوعی سعی می‌کنند منطق و حافظه را در یک شبکه عصبی (Neural Network) — شبیه نقشه مترویی که سیگنال را از ورودی به جواب می‌رساند — مدیریت کنند. این رویکرد اغلب منجر به پدیده‌ای به نام «خزش مجوزها» (permission creep) می‌شود؛ جایی که یک معافیت خاص به‌اشتباه به کل پروژه تعمیم می‌یابد. در مهندسی نرم‌افزار حرفه‌ای، یک «بله» که برای یک فایل قدیمی (legacy) داده شده، نباید به یک «بله» کلی برای بقیه مخزن کد تبدیل شود. این چالش‌ها در واقع تلاشی برای حل تقابل میان حافظه معنایی و اجرای بدون وضعیت در بازبینی کد است تا تداوم تصمیمات در طول زمان حفظ شود.

همان‌طور که در تحلیل‌های پیشین ما درباره‌ی امنیت مدل‌های بازمتن اشاره کردیم، تکیه مطلق بر خروجی مدل‌های زبانی در محیط‌های حساس ریسک بالایی دارد. ReviewMind این مشکل را با ایجاد یک مرز سخت حل کرده است: هوش مصنوعی تاریخچه را به یاد می‌آورد، اما کدهای قطعی (deterministic code) تصمیم نهایی را می‌گیرند. این ساختار تضمین می‌کند که بررسی‌های حیاتی — مانند مقایسه‌های تاریخی یا تطبیق مسیر فایل — هرگز به «نظر» یا حدس یک مدل زبانی وابسته نباشند.

معماری سه لایه

به نقل از گزارش dev.to، این سامانه مسئولیت‌ها را بین سه بخش مجزا تقسیم کرده است تا تداخل منطقی ایجاد نشود:

  • Supabase: به عنوان مرجع نهایی (Authority) برای مدیریت کاربران، مالکیت مخازن، رویدادهای منبع تغییرناپذیر، نسخه‌های تاییدیه، ابطال مجوزها و مدیریت کارهای پس‌زمینه (worker jobs) عمل می‌کند.
  • Hindsight: لایه حافظه معنایی است که سه عملیات اصلی «نگهداری» (retain)، «یادآوری» (recall) و «تامل» (reflect) را مدیریت می‌کند. این لایه در واقع تصمیمات جعبه‌سیاه ایجنت‌ها را به شواهد قابل‌حسابررسی تبدیل می‌کند تا هر خروجی قابل ردیابی باشد.
  • مدل مولد (Generation Model): هر نقطه انتهایی سازگار با OpenAI که تغییرات را توضیح داده و شواهد را با استفاده از خروجی JSON Schema ارائه می‌کند.

بازنگری استثنا را به خاطر می‌سپارد. کد من تصمیم می‌گیرد که آیا قابل اعمال است.

چرخه تصمیم‌گیری

برای جلوگیری از ورود هرگونه ادعای تاییدنشده به کد، سیستم از یک خط لوله (pipeline) سخت‌گیرانه پیروی می‌کند. این چرخه که به صورت end-to-end در سطح API و worker پیاده‌سازی شده، به شرح زیر عمل می‌کند:

  • جذب (Ingestion): یک diff (تفاوت کد) چسبانده شده دریافت می‌شود و Hindsight تاریخچه مرتبط را بازیابی می‌کند.
  • تایید (Verification): حقایق بازیابی شده مجدداً به رویدادهای رسمی (canonical events) نگاشت می‌شوند؛ هر چیزی که قابل تایید نباشد، حذف می‌گردد.
  • بازخورد انسانی (Human Feedback): یک بازبینی محدود (scoped review) اجرا شده و یک انسان بازخوردی مستدل درباره یک یافته ارائه می‌دهد. این مرحله برای این طراحی شده تا ناظران انسانی از تبدیل شدن به یک مهر تایید ساده جلوگیری شود و تحلیل واقعی جایگزین تاییدات کورکورانه گردد.
  • تامل (Reflection): قابلیت reflect در Hindsight، یک پیش‌نویس تصمیم ساختاریافته را از روی آن بازخورد تهیه می‌کند.
  • تایید (Approval): یک نگهدارنده (maintainer) پیش‌نویس را تایید می‌کند و نسخه تایید شده «نگهداری» می‌شود.
  • فعال‌سازی (Activation): پس از یک بررسی یادآوری، یک جلسه (session) جدید می‌تواند از این تصمیم استفاده کند.

بینش گذشته استثنا را به خاطر می‌سپارد. کد من تصمیم می‌گیرد آیا قابل اعمال است.

اجرای قطعی و سخت‌گیرانه

قلب این سیستم تابع classify است که یک تصمیم را در برابر بافت (context) فعلی بازبینی ارزیابی می‌کند. توسعه‌دهنده تاکید می‌کند که سوالاتی مثل «آیا این تاریخ قبل از آن تاریخ است؟» و «آیا این الگوی glob با این مسیر مطابقت دارد؟» هرگز نباید به نظر یک مدل زبانی بزرگ (LLM) — مثل کتابخانه‌داری که میلیاردها صفحه خوانده و حالا با همان لحن جواب می‌دهد — واگذار شود.

برای اینکه یک استثنا قابل اعمال باشد، باید چندین معیار سخت‌گیرانه را برآورده کند:

  • وضعیت (Status): باید صراحتاً به عنوان «تایید شده» (approved) علامت‌گذاری شده باشد. در غیر این صورت، مقدار needs_context برمی‌گرداند.
  • پنجره زمانی (Temporal Window): زمان بازبینی باید بعد از تاریخ effectiveFrom و قبل از تاریخ expiresAt باشد. این مرز انحصاری است: effective_from <= review_time < expires_at. اگر خارج از این بازه باشد، مقدار expired برمی‌گرداند.
  • دامنه (Scope): مسیر فایل باید با یک الگوی glob خاص مطابقت داشته باشد. در غیر این صورت، مقدار out_of_scope برمی‌گرداند.
  • نسخه (Version): نسخه وابستگی باید محدوده semver تعریف شده را برآورده کند. اگر نسخه موجود نباشد، needs_context و اگر محدوده را برآورده نکند، out_of_scope برمی‌گرداند.
  • یکپارچگی (Integrity): تصمیم باید در همان مخزن و همان run باشد، پیش‌نیازهایش کامل شده باشد و ابطال یا جایگزین نشده باشد.

بینش گذشته استثنا را به خاطر می‌سپارد. کد من تصمیم می‌گیرد که آیا قابل اجراست.

حافظه عامل Hindsight

انتخاب Hindsight به‌جای یک جدول ساده با جست‌وجوی کلمات کلیدی، انتخابی آگاهانه بود. گردش کار سیستم دقیقاً بازتاب‌دهنده سه عملیات Hindsight است:

  • نگهداری (Retain): بازخوردها و نسخه‌های تایید شده تصمیمات را به عنوان اسناد تغییرناپذیر event:<uuid> ذخیره می‌کند. این کار مانع از آن می‌شود که تلاش‌های مجدد برای ارسال (transport retries)، رویدادهای منطقی تکراری ایجاد کنند یا تاریخچه را بازنویسی کنند.
  • یادآوری (Recall): تاریخچه‌های مرتبط از نظر معنایی را می‌یابد، حتی اگر تصمیمات با کلماتی متفاوت از diff فعلی نوشته شده باشند. تمام حقایق بازیابی شده باید به رویدادهای مجاز در مخزن فعلی ختم شوند.
  • تامل (Reflect): بازخوردهای انتخاب شده را به یک پیش‌نویس تصمیم ساختاریافته تبدیل می‌کند. نکته حیاتی این است که «تامل» هرگز سیاست‌ها را تایید نمی‌کند؛ این کار فقط توسط یک انسان (maintainer) امکان‌پذیر است.

علاوه بر این، یک درخواست retain موفق، دلیلی بر قابل استفاده بودن حافظه نیست. اپلیکیشن وضعیت‌ها را ردیابی می‌کند: در صف (queued)، در حال اجرا (running)، نگهداری شده (retained) و آماده (ready). وضعیت «آماده» مستلزم هر دو موردِ «پایان جذب» و «یک یادآوری هدفمند که منشأ سند مورد انتظار را برگرداند» است.

تست‌های دنیای واقعی و شکست‌ها

تا ۲۸ سپتامبر ۲۰۲۶، توسعه‌دهنده گزارش داده است که ۶۲ تست قطعی (deterministic) و محلی PostgreSQL بدون هیچ خطایی پاس شده‌اند. بررسی‌های typecheck و build در محیط Production پاس شده و ممیزی وابستگی‌ها (dependency audit) صفر آسیب‌پذیری شناخته شده را گزارش کرده است.

یک دستور یکپارچه‌سازی با ارائه‌دهنده واقعی، با موفقیت از طریق Supabase احراز هویت کرد، از طریق Hindsight داده‌ها را نگهداری کرد، از یک کلاینت جدید آن‌ها را یادآوری کرد و یک تامل (reflection) تایید شده را درخواست نمود. در یک بازبینی زنده روی PR-A، سیستم به‌درستی گزارش داد که پیش از هرگونه تاییدیه، هیچ حافظه تاییدشده‌ای وجود ندارد؛ این امر تضمین کرد که قرارداد wrapper به عنوان یک یافته عادی باقی بماند و سیستم استنادهای خیالی اختراع نکند.

با این حال، برخی بخش‌ها هنوز تست نشده‌اند: سفر کامل کاربر در مرورگر (بازخورد، تامل، تایید، بازبینی در جلسه جدید) و یک مقایسه ۳۶-نسلی منجمد بین حالت‌های Generic، Static و Memory در دوازده مورد مجزا. در نتیجه، هنوز درصد دقیقی از بهبود عملکرد گزارش نشده است.

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

این پروژه حول یک مثال خاص ساخته شده است: یک استثنای موقت برای transport-wrapper در یک آداپتور قدیمی، محدود به یک مسیر، یک محدوده نسخه وابستگی و تاریخ انقضای ۳۰ سپتامبر ۲۰۲۶. در حالی که این مورد، الزام wrapper را در مسیر قدیمی حذف می‌کند، اما برای آداپتورهای جدید یا تاریخ‌های بعد از انقضا اعمال نمی‌شود.

یکی از مهم‌ترین تصمیمات طراحی، جداسازی استثنائات از الزامات پایه است. برای مثال، معافیت از الزام transport-wrapper باعث معافیت از بررسی «زمان پاسخ‌دهی ۲ ثانیه‌ای درخواست» (request timeout) نمی‌شود. بررسی timeout یک بررسی مجزای AST (درخت نحو انتزاعی) است که صرف‌نظر از سایر معافیت‌ها، فعال می‌ماند.

این بررسی timeout به‌طور عمدی محدود به fixtureها است: فقط importهای نام‌گذاری شده درخواست از کلاینت و helper ارائه شده را می‌شناسد، آن هم زمانی که با یک شیء options لیترال فراخوانی شوند. هرگونه نام مستعار (alias)، spread، مقادیر محاسباتی یا هر چیز ناشناخته‌ای، مقدار needs_context برمی‌گرداند و نه تایید (pass). این کار مانع از آن می‌شود که سیستم صرفاً به دلیل نشناختن یک الگو، فرض کند کد ایمن است.

باگی که درس بزرگی داد

در طول یکپارچه‌سازی، نویسنده با یک باگ بحرانی مواجه شد که در آن نقطه انتهایی تامل (reflection endpoint) خطای HTTP 500 برمی‌گرداند. یک تامل ساختاریافته ساده کار می‌کرد، اما نقطه انتهایی پیکربندی شده، یک شمای آرایه-نوعِ nullable را رد می‌کرد. هنگام تلاش برای استفاده از واریانت anyOf ، مدل به‌جای مقدار null واقعی، رشته «null» را برمی‌گرداند و شناسه‌های منبع (source IDs) را به‌طور کامل حذف می‌کرد.

راه حل، پیاده‌سازی یک لایه ترجمه بود که از فیلدهای رشته‌ای برای مقادیر اختیاری استفاده می‌کند و تنها مقادیر خالی یا رشته‌های «null» را در فیلدهای nullable تعیین‌شده، پیش از اجرای اعتبارسنجی سخت‌گیرانه کانونی، تبدیل می‌کند. اکنون تامل صراحتاً UUIDهای منبع را در پاسخ نوشتاری خود درخواست می‌کند تا تضمین شود که آن‌ها در استخراج ساختاریافته باقی می‌مانند. این امر تضمین می‌کند که یک سیستم حافظه که پیش‌نویس‌های ساختاریافته را تحویل می‌دهد، هرگز اعتبارسنجی سیستم را تضعیف نکند.

درس‌های نهایی

این رویکرد نقش هوش مصنوعی را از یک «قاضی» به یک «کتابدار» تغییر می‌دهد. هوش مصنوعی قانون مرتبط را می‌یابد، اما کد آن قانون را اجرا می‌کند. نتایج کلیدی عبارتند از:

  • شرایط را ذخیره کنید، نه نتایج را: عبارت «تایید شده» بدون دامنه و تاریخ انقضا، صرفاً یک شایعه است.
  • ریاضیات بدون هوش مصنوعی: هرگز اجازه ندهید مدل محاسبات تاریخ یا مسیر را انجام دهد؛ از کتابخانه‌های تست شده glob و semver استفاده کنید.
  • طراحی ناهمگام (Asynchronous): عملیات retain را ناهمگام در نظر بگیرید و آمادگی را با یک پروب یادآوری (recall probe) اثبات کنید.
  • شواهد قابل بازرسی: برای هر حقیقت بازیابی شده، نشان دهید چه چیزی تصمیم گرفته شده، توسط چه کسی، چرا، کجا اعمال می‌شود و منبع آن چیست.
  • گزارش‌دهی محافظه‌کارانه: نبودِ موردی در یادآوری، دلیلی بر عدم وجود تصمیم نیست. اگر یافته‌ای پیدا نشد، بازبین می‌گوید «هیچ یافته‌ای در بافت ارائه شده یافت نشد»، و هرگز نمی‌گوید «برای ادغام ایمن است».

گام بعدی شما

  • اگر از عامل‌های AI برای بازبینی کد استفاده می‌کنید، منطق تایید (Approval) را از منطق یادآوری (Recall) جدا کنید.
  • برای بررسی‌های زمانی و مسیر فایل، هرگز به LLM اعتماد نکنید و از کتابخانه‌های Regex یا Glob استفاده کنید.
  • خروجی‌های مدل را پیش از ذخیره در دیتابیس، از یک لایه اعتبارسنجی Schema عبور دهید.

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

چرا این موضوع مهم است؟

این معماری با تکیه بر اعتبار کدهای قطعی (Deterministic)، ریسک توهمات AI را در زیرساخت‌های حساس کدنویسی به صفر می‌رساند. این یک الگوی اجرایی برای تمام شرکت‌هایی است که می‌خواهند بدون ریسک، اتوماسیون AI را در چرخه تولید (Production) پیاده کنند.

تأثیر برای ایران

برنامه‌نویسان ایرانی که در پروژه‌های Open Source یا تیم‌های نرم‌افزاری بزرگ فعال‌اند، می‌توانند از این الگوی تفکیک حافظه و منطق برای ساخت ابزارهای بازبینی کد داخلی استفاده کنند.

·نگاه ما
تحریریه دات‌هوش

جایگزینی نقش AI از «قاضی» به «کتابدار» یک چرخش راهبردی در طراحی عامل‌های صنعتی است. این رویکرد ثابت می‌کند که برای رسیدن به قابلیت اطمینان در سطح سازمانی، نباید سعی کرد مدل‌های زبانی را «دقیق‌تر» کنیم، بلکه باید آن‌ها را در محیطی محصور کنیم که در آن هر ادعای مدل توسط یک کد قطعی بازبینی شود.

منابع

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

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

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

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.