تصور کنید یک برنامهنویس جونیور را استخدام کردهاید و به او میگویید «دقیقتر عمل کن»؛ شما توانایی او را زیاد نکردهاید، بلکه روی دستورالعمل عملیاتیاش تغییر ایجاد کردهاید. مشکل اینجاست که وقتی این دستورالعملها به زبان انگلیسی یا فارسی نوشته میشوند، تستهای واحد (Unit Tests) سنتی شکست میخورند، چون نمیتوان یک جمله را تست کرد، بلکه باید رفتاری را که آن جمله ایجاد میکند، سنجید.
به نقل از سازنده AIDDSkeleton، دستورالعملهای متنی برای عاملهای هوش مصنوعی (AI Agents) — شبیه به دستورالعملهای سختگیرانهی یک سرپرست کارخانه که تعیین میکند هر قطعه چطور بررسی شود — صرفاً مستندات نیستند، بلکه سیاستهای اجرایی هستند که نحوه نوشتن و بازبینی کد را دیکته میکنند. این متدولوژی پیشنهاد میکند که با این قوانین مانند نرمافزار برخورد شود و از تستهای رگرسیون (Regression Testing) برای اطمینان از این موضوع استفاده شود که دستورالعملهای «شفافتر»، واقعاً نتایج رفتاری بهتری تولید میکنند.
بسیاری از توسعهدهندگان هنگام بهروزرسانی پرامپتها به شهود تکیه میکنند و میگویند «به نظر میرسد این یکی بهتر است». اما این رویکرد شکننده است؛ زیرا عامل ممکن است به دلایل اشتباهی نتیجه بهتری بگیرد. برای مثال، ممکن است عامل نتیجه بهتری تولید کند چون پرامپت کمی متفاوت بوده، یا بستر گفتگوهای قبلی پاسخ مورد انتظار را لو داده باشد، یا عامل به کامیتهای بعدی دسترسی داشته باشد، یا کاربر بهطور تصادفی سرنخی از مشکل داده باشد، و یا مدل صرفاً در آن روز مسیر استدلالی متفاوتی را طی کرده باشد. در یک نقطه، این احساس که نتیجه «بهتر به نظر میرسد» دیگر به عنوان یک معیار کافی برای موفقیت پذیرفته نیست.
برای حل این مشکل، AIDDSkeleton حاکمیت در سطح مخزن (Repository-level Governance) را پیاده میکند. این در واقع یک اسکلت مخزن برای توسعه مبتنی بر هوش مصنوعی است که در آن، رفتارهای جالب نه از طریق اسکریپتها یا فریمورکها، بلکه از طریق حاکمیت محلی مخزن (Repository-local Governance) ایجاد میشوند. این حاکمیت در قالب فایلهای Markdown است که به عامل هوش مصنوعی میگوید اطلاعات پروژه را چگونه تفسیر کند، چه چیزی به عنوان مرجع اعتبار (Authority) شناخته شود، کار چگونه در چرخه حیات خود پیش برود، شواهد چگونه مورد بررسی قرار گیرند و یافتههای بازبینی چگونه بر کارهای جاری اثر بگذارند.
تکامل حاکمیت بازبینی
بر اساس مستندات پروژه، تغییرات اولیه در حاکمیت بر جداسازی ماهیت یافته از اقدام متمرکز بود. در کامیت 08ded669 با عنوان «docs: govern feedback triage and review recall»، توسعهدهنده دو مفهوم را که پیش از این با هم ترکیب شده بودند، از هم جدا کرد: «این یافته چقدر جدی است؟» و «اکنون باید با آن چه کنیم؟».
این تفکیک مانع از آن شد که هر پیشنهاد جالب، بهطور خودکار و بیصدا باعث گسترش محدوده (Scope) تسک شود. یک نظر بازبینی میتوانست معتبر باشد بدون اینکه لزوماً به بخشی از کارهای جاری تبدیل شود. حاکمیت شروع به تفکیک بین موارد زیر کرد:
- وضعیتها (Dispositions): پذیرش فوری (Accept now)، رد (Reject)، تعویق (Defer) یا مشاهده (Observe).
- طبقهبندیها (Classifications): مسدودکننده (Blocker) یا نقص در محدوده / پیگیری (In-scope deficiency / Follow-up).
سپس در کامیت 0611d61b با عنوان «docs: shift review learning into adversarial self-review»، مدل تغییر اساسی کرد. یک یافته معتبر دیگر فقط هدفی برای یک وصله (Patch) نبود، بلکه ماشگی برای یک حلقه استدلالی میشد: یافته $\rightarrow$ چه چیزی را نادیده گرفتیم؟ $\rightarrow$ آیا این دیدگاه نادیده شده در جای دیگری هم اهمیت دارد؟
این تغییر به این معنا بود که یک یافته میتوانست چیزی را درباره استدلالی فاش کند که پیشتر در شناسایی مشکل شکست خورده بود. با این حال، این موضوع مسئله تست را سختتر کرد. اگر توسعهدهنده صراحتاً از عامل میخواست مسیرهای همتراز (Sibling paths) را بررسی کند یا به دنبال یک علت مشترک بگردد، دیگر نمیدانست که آیا کشف مشکل به دلیل خودِ قوانین حاکمیت بوده یا به دلیل درخواست مستقیم توسعهدهنده. این چالشها در تعامل با سیستمهای خارجی نیز دیده میشود، جایی که برخی باگهای بحرانی دلیل شکست عاملها در اتصال به APIها را فاش کردند و نشان دادند که استدلال مدل لزوماً با واقعیت اجرایی همسو نیست.
چارچوب تست رفتاری
برای اعتبارسنجی این تغییرات، AIDDSkeleton از متدولوژی «گذشته منجمد» (Frozen Past) استفاده میکند. این روش شامل انتخاب یک کامیت تاریخی واقعی از یک مخزن گیت است تا به عنوان یک خط پایه (Baseline) ثابت یا یک فیکسچر (Fixture) عمل کند.
- گروه کنترل: عامل با استفاده از قوانین حاکمیتی قدیمی روی کامیت تاریخی کار میکند.
- گروه آزمایش: عامل با استفاده از قوانین حاکمیتی کاندید (جدید) روی همان کامیت تاریخی کار میکند.
نکته حیاتی این است که عامل نسبت به آینده کور است. هر چیزی بعد از آن فیکسچر، غیرموجود تلقی میشود: کامیتهای بعدی، Pull Requestهای بعدی، نظرات بازبینی بعدی، اصلاحات شناخته شده و نتایج رگرسیونهای قبلی. این کار دو خط زمانی مصنوعی از تاریخچه گیت ایجاد میکند. اگر یک بازبینی در آینده باگی را شناسایی کرده باشد، اجازه دادن به عامل برای دیدن آن نظر، آزمایش را نابود میکند؛ زیرا در این صورت ما تست میکنیم که آیا عامل میتواند پاسخ را بخواند یا اینکه آیا حاکمیت به او کمک میکند تا مشکل را پیدا کند. برای سنجش دقیقتر امنیت و ایزولاسیون در چنین محیطهایی، میتوان از رویکردهای فایلهای تله برای شناسایی نفوذهای احتمالی عاملها به سیستمفایل استفاده کرد تا اطمینان حاصل شود که عامل از مرزهای تعیینشده فراتر نمیرود.
حل باگ «راهنمایی» و ریسک دانش ماندگار
آزمایشهای اولیه نشان داد که یک نقص بحرانی وجود دارد: خودِ پرامپتهای تست اغلب حاوی پاسخ مورد انتظار بودند. توسعهدهنده به عامل یک یافته بازبینی میداد و میپرسید: «آیا علت مشترکی وجود دارد؟» یا «آیا سطوح همترازی با همین مشکل وجود دارند؟» یا «آیا این مورد باید در سطحی بالاتر مورد بازبینی قرار گیرد؟».
در حالی که عامل تعمیم میداد و اصلاحات گستردهتری تولید میکرد، اما پرامپت تست همان ایدهای را منتقل میکرد که در حاکمیت کاندید وجود داشت. این در واقع توانایی مدل در دنبال کردن یک «راهنمایی» (Hint) را تست میکرد، نه توانایی قانون در هدایت عامل را. برای رفع این مشکل، پرامپتها خنثی شدند. هدف از درخواست نتایج خاص به مشاهده رفتارهای خودجوش تغییر یافت.
این تغییر فاش کرد که برخی قوانین «تمیزتر» در واقع عملکرد را کاهش میدهند. در یک سناریوی ذخیرهسازی رسانه (MediaStorage)، شاخه کنترل مسئله تداخل (Collision) را تهاجمیتر بررسی کرد. مشکل اصلی «وجود داشتن مقصد» (destination already exists) بود و عامل گروه کنترل بهطور خودجوش پیش رفت تا بپرسد: «چه میشود اگر دو نویسنده برای یک مقصد رقابت کنند (Race condition)؟».
عامل گروه آزمایش سطح درخواستی را بهبود بخشید اما تا حد شرایط رقابتی پیش نرفت. این شواهد عالی بود که نشان داد حاکمیت جدید ممکن است در برخی تعمیمها قویتر باشد اما در وسعت اکتشاف فوری ضعیفتر عمل کند. چون حاکمیت کاندید در هر راند پیروز نمیشد، توسعهدهنده بیشتر به این متد اعتماد کرد و به پالایش قوانین ادامه داد.
همچنین در کامیت 94d163b8 با عنوان «docs: remove knowledge base governance»، توسعهدهنده روی «دانش بازبینی ماندگار» آزمایش کرد. هدف این بود که درسهای مفید از یک تسک ذخیره شده و بعداً دوباره استفاده شوند.
اگرچه آزمایش موفق بود، اما «بیش از حد» موفق بود. دانش حفظ شده بهطور مادی استدلالهای بعدی را تغییر داد و به عامل کمک کرد عمیقتر برود. با این حال، این دانش بر تصمیماتی خارج از تسک اصلی چنان اثر گذاشت که مرز بین «دانش پیشین مفید» و «سلطه تصادفی بر طراحی» غیرقابل کنترل شد. توسعهدهنده این ویژگی را حذف کرد و نتیجه گرفت که یک تست موفق تستی است که به شما بگوید: «این ایده بر رفتار اثر میگذارد، اما اثرات جانبی آن بهاندازه کافی محدود نیستند. پس آن را منتشر نکن».
شکستهای بازسازی زبان طبیعی
یکی از تکاندهندهترین یافتهها این بود که بازسازی (Refactoring) زبان طبیعی دقیقاً مانند بازسازی کد میتواند شکست بخورد. در کامیت e5033e6d با عنوان «docs: compact adversarial self-review escalation»، توسعهدهنده تلاش کرد قوانین بازبینی را در ساختاری کوچکتر و تمیزتر فشرده کند، با این باور که معنای قوانین حفظ شده است.
تستهای رگرسیون این باور را رد کردند. نسخه فشرده باعث شد عامل جزئیات حیاتی را از دست بدهد، از جمله:
- تشخیص اینکه چرا یک مشکل از شناسایی اولیه گریخته است.
- حفظ بستر عینی (Concrete Context) که باگ را آشکار کرده بود.
- باز کردن مجدد بازبینی زمانی که شواهد بعدی مبنای کار را تغییر میداد.
- متناسب و محدود نگه داشتن بازبینی.
- باز کردن مجدد بازبینی گسترده پس از یک اصلاح گسترده.
این موضوع ثابت کرد که «تعداد کمتر بولتها» معیاری برای حاکمیت بهتر نیست. نتیجه ممکن است معادل به نظر برسد، اما شرایط مهم از نظر رفتاری ممکن است نباشند. در نهایت در کامیت 1f5dafd6 با عنوان «docs: separate adversarial review responsibilities»، قوانین حول پنج مسئولیت اصلی سازماندهی شدند:
- بازبینی خصمانه اولیه (Initial adversarial review)
- جذب سیگنال (Signal assimilation)
- به چالش کشیدن اصلاحات (Correction challenge)
- تداوم یا ورود مجدد به بازبینی (Review continuation / re-entry)
- ارزیابی مجدد ساختاری (Structural reassessment)
مرز بین نقص و بهبود
تستها یک حالت شکست ظریف دیگر را هم نشان دادند: عامل ایدههای «خوبی» پیدا میکرد که اجازه اجرای آنها را نداشت. پس از اینکه آخرین حاکمیت کاندید روی گذشته منجمد اجرا شد، عامل بهطور مستقل از مشکل تداخل کلید موجود به سمت انتشار همزمان با کلید یکسان (Concurrent same-key publication) حرکت کرد.
سپس، خواندن رسانهها را بررسی کرد و الزاماتی را معرفی کرد درباره:
- اجتناب از بافر کردن کل آرتیفکت (Whole-artifact buffering)
- فشار معکوس (Backpressure)
- لغو عملیات هنگام قطع اتصال کلاینت (Client-disconnect cancellation)
- مدیریت شکستهای خواندن از ذخیرهساز پس از شروع پاسخ
در حالی که اینها از نظر مهندسی انتخابهای درستی بودند، اما «اشتباه» بودند چون از محدوده (Scope) فعلی پروژه فراتر رفته بودند. طراحی تایید شده، این موارد را به عنوان معیارهای پذیرش جاری تعیین نکرده بود. عامل از «یافتن نقصها در طراحی پذیرفته شده» به «بهبود طراحی چون اینطور بهتر میشود» تغییر مسیر داده بود. این رویکرد یادآور رفتارهای مشابه در عامل Sonjomon است که با اولویت دادن به خویشتنداری، از اصلاحات خودسرانه در محیطهای عملیاتی اجتناب میکند تا از ایجاد ناپایداری در سیستم جلوگیری شود.
برای اصلاح این مورد، توسعهدهنده یک چالش محدود به عامل داد: «آیا این قراردادهای جدید عملکرد خواندن واقعاً توسط محدوده تایید شده فعلی مورد نیاز هستند، یا بهبودهای مفیدی بدون داشتن صلاحیت کافی به طراحی رسمی ارتقا یافتهاند؟».
عامل دوباره ارزیابی کرد و الزامات عملکرد خواندن را حذف کرد اما تغییرات ایمنی تداخل را حفظ نمود. دلیل این بود که ایمنی تداخل توسط یک ناوردا (Invariant) پذیرفته شده پشتیبانی میشد: «کلید موجود را بهطور بیصدا بازنویسی نکن». انتشار همزمان میتوانست این ناوردا را نقض کند، بنابراین یک اصلاح در محدوده (In-scope) محسوب میشد. این موضوع توانایی عامل در تمایز بین یک نقص واقعی و یک بهبود خارج از محدوده را نشان داد.
چرخه توسعه جدید
این فرآیند، حاکمیت هوش مصنوعی را به یک چرخه استاندارد توسعه نرمافزار تبدیل میکند. این حلقه اکنون مسیر سختگیرانهای را دنبال میکند: تغییر حاکمیت $\rightarrow$ اجرای رگرسیون مصرفکننده $\rightarrow$ مشاهده رفتار غیرمنتظره $\rightarrow$ پالایش حاکمیت $\rightarrow$ اجرای مجدد رگرسیون.
با تبدیل فایلهای Markdown به سیاستهای اجرایی، توسعهدهنده از ماهیت غیرقطعی (Non-deterministic) پرامپتهای LLM فاصله میگیرد. این متدولوژی اکنون نیازمند موارد زیر است:
- فیکسچرهای تاریخی ثابت
- تست کنترلشده کاندیدها
- ایزولاسیون تاریخی
- اجرای جعبه سیاه (Black-box execution)
- مقایسه رفتاری
- رگرسیون پس از پالایش
- رگرسیون کاندید نهایی
اگرچه یک اجرای موفق به دلیل غیرقطعی بودن LLMها ثابت نمیکند که یک قانون «درست» است، اما شواهدی بسیار قویتر از این است که یک انسان پرامپتی را بخواند و فکر کند «شفاف به نظر میرسد». این تغییر نشان میدهد که وقتی عاملهای هوش مصنوعی به شرکتکنندگانی فعال در کدبیس تبدیل میشوند، دستورالعملهایی که دنبال میکنند باید با همان انضباطی که کدهای TypeScript یا Python نسخهبندی، تست و رگرسیون میشوند، مدیریت شوند. زبان طبیعی به معنای «غیرقابل تست بودن» نیست؛ بلکه صرفاً نیازمند نوع متفاوتی از تست است — تستی بر اساس تاریخچه منجمد و رفتار مشاهده شده.
گام بعدی شما
- اگر از پرامپتهای سیستمی پیچیده استفاده میکنید، یک مجموعه از «موارد تاریخی» (Historical Fixtures) ایجاد کنید تا تغییرات پرامپت را روی آنها تست کنید.
- به جای سادهسازی متنی پرامپتها برای زیبایی، اثر هر حذف یا ادغام را با خروجیهای مدل در سناریوهای تکرارپذیر بسنجید.
- مرز بین «اصلاح نقص» و «بهبود خارج از محدوده» را در دستورالعملهای عامل خود بهطور صریح تعریف کنید.
اما مدیریت این حجم از تستهای رفتاری نیازمند زیرساختی است که بتواند نسخههای مختلف حاکمیت را مدیریت کند — در گزارش بعدی به ابزارهای Versioning برای پرامپتهای سیستمی خواهیم پرداخت.




گفتگو