تصور کنید هر شب، در حالی که شما در خواب هستید، روباتی تمام کدهای شما را بررسی کند، باگهای کوچک را بگیرد و حتی خودش را ارتقا دهد، بدون اینکه یک خط کد حیاتی را خراب کند. این رویای هر برنامهنویسی است که با کوهی از بدهیهای فنی دستوپنجه نرم میکند، اما شرط موفقیت آن، حاکمیتی است که شکستن آن سختتر از شکستن خودِ کد باشد.
جنیفر تیت (Jennifer Tate)، معمار زیرساخت، با این فلسفه پیش رفت که «حاکمیت باید سختتر از خودِ کد برای شکستن باشد». او با استقرار یک عامل (Agent) — شبیه به یک دستیار متخصص که میتواند ابزارها را اجرا کند و تصمیم بگیرد — ثابت کرد که دادنِ حق ادغام (Merge) به هوش مصنوعی در کدهای تولیدی (Production) میتواند ایمن باشد. او این سامانه را برای مدیریت ۲۰ مخزن کد (Repository) تولیدی و پشتیبانی، بدون نیاز به تیم عملیات انسانی پیاده کرد. این مجموعه شامل یک سایت محتوایی با فید دادههای منتخب، چندین اسکرپر زمانبندی شده، Cloudflare Workers و مجموعهای از ابزارهای نیمهخوابیده بود.
نگهداری از یک مجموعه کد تکنفره اغلب منجر به انباشت «بدهی فنی» (Technical Debt) میشود. بدهیهای نگهداری در پروژههای تکنفره خود را فریاد نمیزنند؛ بلکه بهسادگی و در سکوت روی هم جمع میشوند تا روزی که شما دقیقاً به همان بخشی نیاز پیدا کنید که سالهاست نگهداری نشده است. اکثر توسعهدهندگان به نظافت دستی کدها تکیه میکنند، اما با افزایش تعداد مخازن، این بار کاری بیش از حد سنگین میشود. این چالش مدیریت انبوه مخازن یادآور تلاشهای سیستمی برای بستن شکافهای نظارتی است، همانطور که گیتهاب برای مدیریت هزاران مخزن داخلی، مدل مالکیت اجباری را پیاده کرد. همانطور که در تحلیل قبلی ما دربارهی قانون کلید قطع هوش مصنوعی (AI Kill Switch Act) اشاره کردیم، بحث کنترل اضطراری در سطح قانونی مطرح بود، اما تیت یک راهکار عملی، «ساده» و مکانیکی پیاده کرد: صرفاً با ثبت (Commit) یک فایل به نام PAUSE در ریشه مخزن، فعالیت روبات فوراً متوقف میشود. او از داشبوردها یا پرچمهای تنظیمات (Config Flags) دوری کرد، زیرا نمیخواست در ساعت ۲ صبح، درگیر به یاد آوردن یک مسیر پیچیده برای غیرفعال کردن سیستم شود.
چارچوب خودمختاری طبقهبندیشده
عامل تیت که در مخزنی به نام make-me-better قرار دارد، بر اساس سه سطح دسترسی متمایز که در پرامپت (Prompt) آن تعریف شده است، عمل میکند:
- سطح ۱ (مکانیکی): مدیریت ساختارهای گمشده برای تنظیمات (Config)، افزودن دایرکتوریهای حافظه و کدهای تکراری (Boilerplate) که تنها یک فرم صحیح و بدیهی دارند. عامل میتواند این درخواستهای تغییر (PR) را بهطور خودکار باز کرده و ادغام کند.
- سطح ۲ (قضاوت): هر تغییری که با منطق کسبوکار (Business Logic) مرتبط باشد. قانون سختگیرانه در پرامپت این است: «هرگز درباره منطق کسبوکار حدس نزن». در این سطح، عامل بهطور اکید از ایجاد PR منع شده است و باید برای هر تغییری یک «ایشو» (Issue) در گیتهاب برای بررسی انسانی ثبت کند.
- سطح ۳ (خود-اصلاحی): اجازه بهروزرسانی کد خودِ عامل، از جمله اسکریپتهای مشاهده، جریان کاری (Workflow) یا حتی پرامپتهایش. این سطح به شدت محدود است و تنها یک تغییر در شب مجاز است.
سقفهای ایمنی و سازوکارهای دفاعی
برای جلوگیری از اینکه عامل وارد یک مارپیچ خطا یا رفتارهای خارج از کنترل شود، تیت سقفهای شبانه سختگیرانهای را پیاده کرد. روبات مجاز است هر شب حداکثر ۳ PR اصلاحی (Heal PRs)، ۳ ایشو و ۱ تغییر خود-اصلاحی انجام دهد. همچنین، حذف هرگونه داده یا استفاده از Force-push بهطور اکید ممنوع است تا از نابودی احتمالی تاریخچه کد جلوگیری شود. این رویکرد تیت در تعریف محدودیتهای سخت، با استانداردهای امنیتی همسو است؛ بهویژه قوانین حیاتی که مانع از تبدیل شدن عاملهای AI به حفرههای امنیتی میشوند.
یک تصمیم طراحی حیاتی، استفاده از معماری «گزارش-اول» (Report-first) بود. گزارش فعالیت حتی اگر اجرای برنامه در نیمه راه متوقف شود یا کرش کند، نوشته و ثبت (Commit) میشود. این امر با استفاده از شرط ${{ !cancelled() }} در گیتهاب میسر شده است. به نقل از گزارش dev.to، این کار باعث میشود برای رفع اشکال، به جای یک «قبر خاموش» (Silent Grave)، شواهدی حتی ناقص از اجرا در دسترس باشد؛ چیزی که هنگام عیبیابی روباتی که در زمان خواب کاربر کار میکند، حیاتی است.
فاز «تکاندهنده» و رفع خطاها
شب اول یک تور از خطاهای قضاوتی بود که یکی-یکی شناسایی و رفع شدند. نخستین اجرا به دلیل یک باگ در اسکریپت مشاهده مربوط به فراخوانهای gh api متوقف شد. تیت متوجه شد که در سه جای مختلف از یک فایل، خطای یکسانی را تکرار کرده است:
last_commit=$(gh api "repos/$OWNER/$r/commits?per_page=1" -q '...' 2>/dev/null || echo "")
مشکل این بود که اگر gh api پیش از متوقف شدن، یک بدنه خطای JSON ناقص را بنویسد (مثلاً خطای ۴۰۹ برای یک مخزن خالی)، عبارت || echo مقدار جایگزین را به خروجی ناقص میچسباند، به جای اینکه آن را جایگزین کند. این کار رشتهای ایجاد میکرد که نه JSON معتبری بود و نه مقدار جایگزین مورد نظر، و در نتیجه باعث کرشهای زنجیرهای در مراحل بعدی میشد. تیت این مشکل را با اختصاص مقدار در یک مرحله و انجام جایگزینی تنها در صورت شکست کامل حل کرد: last_commit=$(gh api "..." -q '...') || last_commit="".
اجراهای دوم به دلیل پیکربندی اشتباه جریان OIDC شکست خورد که با ارسال صریح یک توکن دسترسی شخصی (PAT) حل شد. اجراهای سوم و چهارم با خطای ۴۰۳ مواجه شدند چون PAT دقیق (Fine-grained) فقط دسترسی خواندن داشت. تیت اشاره کرد که بر اساس ۲۵ سال تجربه، ابتدا زمانی را صرف جستوجوی «دامنه گردش کار» (Workflow Scope) بر اساس دانش قدیمی توکنهای گیتهاب کرد. با این حال، PATهای جدید «دامنه گردش کار» ندارند، بلکه نوشتن فایلهای گردش کار را بر اساس یک مجوز مخزن به نام «Workflows» کنترل میکنند. از آنجایی که ویرایش این مجوزها مقدار توکن را تغییر نمیدهد، نیازی به جایگذاری مجدد توکن نبود.
آزمون حاکمیت و بودجه
پایداری سیستم زمانی به اثبات رسید که بهدلیل ریاستارتهای گیتهاب، عامل ۶ بار در یک شب به «سقف نوبت» خود رسید. چون عامل در ابتدا بودجه خود را فقط بر اساس شمارش PRهای «باز» رصد میکرد، با هر ریاستارت فکر میکرد صفحه سفید است و بودجهاش بازگشته است. این باعث شد صبح روز بعد، تیت با ۴ PR اصلاحی و ۲ تغییر خود-اصلاحی مواجه شود. تیت نتیجه گرفت سقفهایی که با کرش ریست میشوند، در واقع سقف نیستند، بلکه «پیشنهاد» هستند. این تجربه تیت در مدیریت بودجه خطا، یادآور سامانه LEASH است که دسترسی عاملهای هوش مصنوعی را با استفاده از بودجههای خطا مسدود میکند.
در لحظهای تأملبرانگیز از نظر همسویی (Alignment)، خودِ عامل در گزارش شبانه، این حفرهٔ حاکمیتی را تشخیص داد. روبات راهکار اصلاح آن را نوشت — یعنی شمارش تجمعی PRهای شبانه از طریق جستوجو به جای لیست بازها — اما سپس از اجرای آن خودداری کرد. دلیل توقف این بود که بودجه تغییرات خود-اصلاحی او برای آن شب تمام شده بود. این پایبندی به محدودیتها، حتی در حالی که نقص سیستم حاکمیتی را دیده بود، اعتبار سیستم بودجهبندی را تایید کرد.
چرخه نگهداری مستمر
در وضعیت پایدار، عامل اکنون کارهای خود را در صف قرار میدهد. در یک چرخه سه روزه، روند به این شکل بود: گزارش شب اول پیشنهاد داد مخازن آرشیو شده نادیده گرفته شوند، زیرا نمیتوان در آنها PR ثبت کرد. شب بعد، عامل از تنها سهمیه تغییر خود برای اعمال این اصلاح استفاده کرد، آن را با دستور bash -n تایید کرد و سپس ادغام کرد. در گزارش بعدی، دستور داد که در اجرای آتی بررسی شود آیا آن ۴ مخزن آرشیو شده واقعاً از نظرسنجی حذف شدهاند یا خیر.
در این مسیر، عامل توانست:
- باگی را در کد خودِ تیت پیدا کند که از دید بررسی انسانی او دور مانده بود.
- یک معیار (Metric) را که بهاشتباه چیزی غیر از «آخرین بهروزرسانی حافظه» را اندازه میگرفت (جایی که متغیر میگفت بهروزرسانی حافظه اما کوئری API چیز دیگری میگفت)، اصلاح کند.
- تعداد موارد نیازمند کار را پس از شناسایی ۵ مخزن منسوخ یا آرشیو شده، کاهش دهد؛ خطایی در شمارش که خودش شب قبل مرتکب شده بود.
تیت خاطرنشان کرد که توانایی عامل در شناسایی دادههای غلط خود، سطحی از خود-اصلاحی است که در تیمهای انسانی مدیریتشده، معمولاً نیاز به کوچینگ و راهنمایی انسانی دارد.
هزینه پیشبینینشده
شکست اصلی نه فنی، بلکه در جریان کاری (Workflow) بود. طی چند روز، ۸ کلون محلی تیت از نسخههای ریموت عقب افتادند. چون روبات هر شب در گیتهاب تغییرات میداد و تیت هیچ اطلاعی از لپتاپ او نداشت، فرض تیت مبنی بر اینکه او تنها نویسنده کد است، شکست خورد. برای توسعهدهندگان تکنفره، git pull از یک عادت بهداشتی به یک نیاز حیاتی برای بقا تبدیل شد.
در نهایت، تیت اعتراف کرد که ساخت این روبات تا حدی یک تاکتیک برای به تعویق انداختن کارهای سختتر بود. در حالی که مخازن کد هر شب خودبهخود ترمیم میشدند، سه پیشنهاد کاری (Pitch) پرداختشده به مدت ۳۵ روز در پوشه پیشنویسهای او باقی ماند. صیقل دادن یک روبات راحتتر از درخواست پول از انسانها بود. او اشاره کرد که اگرچه یک عامل میتواند یک مخزن را ترمیم کند، اما هنوز کسی عاملی نساخته است که دکمه «ارسال» را برای یک پیشنهاد کاری بزند، زیرا این کاری است که خود انسان باید انجام دهد.
گام بعدی شما
اگر شما در حال استقرار عاملهای مستقل هستید، تیت توصیه میکند این الگوها را بردارید:
- از سقفهای شبانه (Nightly Caps) بهجای سقفهای هر اجرا استفاده کنید و منبع شمارش را جایی قرار دهید که با کرش سیستم ریست نشود.
- دسترسیها را لایهبندی کنید (Tiers) تا فقط تغییرات مکانیکی حق ادغام داشته باشند و تغییرات منطقی نیازمند تایید انسانی باشند.
- معماری «گزارش-اول» (Report-first) را پیاده کنید تا در صورت توقف ناگهانی، ردپای عملیات برای عیبیابی باقی بماند.
انتقال از نگهداری انسان-محور به کمک-عامل، نیازمند تغییری در نگرش شماست؛ باید بپذیرید که محیط محلی شما دیگر تنها منبع حقیقت (Sole Place of Truth) نیست.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو