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

درون سازوکار Corral برای بستن دستورات اجرا شده توسط AI

·۸ مهر ۱۴۰۵۶ دقیقه مطالعه
لوگوی GitHub برای مخزن Cardinal44/corral: شاخه کورال با پس‌زمینه تیره.
لوگوی GitHub برای مخزن Cardinal44/corral: شاخه کورال با پس‌زمینه تیره.
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

جایگزینی مدیریت فرآیندها از طریق سیگنال‌های متداول با استفاده از cgroup v2 و subreaper برای تضمین حذف ۱۰۰ درصدی درخت فرآیندها در عامل‌های AI.

یک فرآیند پس‌زمینهٔ نشت‌کرده می‌تواند کل چرخه توسعه یک عامل هوش مصنوعی را متوقف کند. Corral، یک ابزار تخصصی لینوکس، تضمین می‌کند که وقتی دستوری متوقف می‌شود، تک‌تک فرآیندهای فرزند آن نیز هم‌زمان نابود شوند. وقتی Corral بازمی‌گردد، هیچ فرآیندی که توسط آن دستور شروع شده باشد، زنده نمی‌ماند؛ Corral پیش از بازگشت، این موضوع را تأیید می‌کند. اگر ابزار نتواند این پاک‌سازی را اثبات کند، با کد خروجی ۱۲۰ خارج می‌شود.

اکثر عامل‌های کدنویس هوش مصنوعی و اجراکننده‌های CI دستوراتی را در شل اجرا می‌کنند که خودشان ننوشته‌اند. آن‌ها بر اساس یک مدل ناقص عمل می‌کنند: یک سیگنال به فرآیند فرزند یا گروه پردازشی فرزند می‌فرستند و سپس منتظر بسته شدن لوله‌های خروجی (output pipes) می‌مانند. این روش در سه مورد رایج شکست می‌خورد:

۱. دی‌مونیزه شدن (Daemonization): یک دی‌مون دو بار فورک (fork) می‌کند و تابع setsid() را فراخوانی می‌کند. در این حالت، فرآیند در یک گروه پردازشی و نشست (session) متفاوت قرار می‌گیرد و init به عنوان والد آن شناخته می‌شود، بنابراین سیگنال هرگز به آن نمی‌رسد.
۲. تعلیق لوله (Pipe Hanging): یک فرآیند پس‌زمینه، خروجی‌های استاندارد (stdout) یا خطاهای استاندارد (stderr) را باز نگه می‌دارد. در نتیجه، اجراکننده هرگز علامت پایان فایل (EOF) را نمی‌خواند و حتی پس از خروج دستور، در حالت تعلیق باقی می‌ماند.
۳. نادیده گرفتن سیگنال: یک فرآیند سیگنال SIGTERM را نادیده می‌گیرد و به اجرای خود ادامه می‌دهد.

همان‌طور که در تحلیل‌های پیشین ما درباره‌ی پایداری زیرساخت‌های عامل‌محور اشاره کردیم، این فرآیندهای «زامبی» باعث اشغال قفل فایل‌ها، پورت‌ها و منابع CPU می‌شوند و اجرای بعدی عامل را با شکست مواجه می‌کنند. این چالش‌ها در محیط‌های اتوماسیون شدیدتر است؛ برای مثال در استفاده از حالت بدون سر (headless) در Claude Code برای بازبینی کد، مدیریت دقیق فرآیندهای پس‌زمینه برای جلوگیری از تداخل در تسک‌های متوالی حیاتی است. طبق مستندات github.com، Corral این مشکل را با کنترل کامل درخت فرآیند، به‌جای تمرکز بر فرزند مستقیم، حل می‌کند. این ابزار برای تضمین پاک‌سازی از دو حالت عملیاتی متمایز بهره می‌برد:

حالت اجباری (Enforced Mode)

در حالت اجباری، Corral دستور را در یک گروه cgroup v2 اختصاصی قرار می‌دهد. این قابلیت — که شبیه به یک حصار سخت‌افزاری برای هر برنامه است — به هسته لینوکس اجازه می‌دهد تمام فرآیندهای فرزند را، فارغ از اینکه چند بار فورک شده‌اند یا نشست خود را تغییر داده‌اند، ردیابی کند. این رویکرد یادآور راهکار Cognous در انتقال حفاظ‌ها به سطح سخت‌افزار است تا از رفتارهای پیش‌بینی‌نشده عامل‌های خودمختار جلوگیری شود. یک نوشتن ساده در فایل cgroup.kill تمام فرآیندهای آن گروه را فوراً متوقف می‌کند. این حالت نیازمند یک cgroup تفویض‌شده است؛ اسکریپت ارائه شده در scripts/corral-enforced یکی از این گروه‌ها را با استفاده از systemd-run ایجاد می‌کند.

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

  • محدودیت حافظه از طریق پرچم --mem (مثلاً --mem 512M).
  • محدودیت تعداد فرآیندها از طریق پرچم --pids (مثلاً --pids 64).

حالت جایگزین (Fallback Mode)

زمانی که cgroups در دسترس نباشند، Corral به‌عنوان یک child subreaper عمل می‌کند. این بدان معناست که هر فرآیند یتیمی به‌طور خودکار فرزند Corral می‌شود. ابزار با اسکن /proc و بررسی والد، گروه پردازشی و نشست، تمام فرآیندهای باقی‌مانده را می‌یابد تا زمانی که هیچ فرآیندی باقی نماند. Corral سیگنال‌ها را به فرآیندهایی که فرزند مستقیم آن نیستند، تنها از طریق pidfds و پس از بررسی مجدد فرآیند ارسال می‌کند تا اطمینان حاصل شود که یک PID بازیافت‌شده به‌طور تصادفی سیگنالی دریافت نمی‌کند.

پیکربندی و گزینه‌ها

این ابزار به‌صورت پیش‌فرض از --cgroup-mode=auto استفاده می‌کند که در صورت امکان، حالت اجباری را انتخاب می‌کند. برخی از گزینه‌های کلیدی عبارت‌اند از:

  • --wall DURATION: تعیین محدودیت زمانی برای اجرا (مثلاً 30s یا 5m).
  • --grace DURATION: فاصله زمانی بین ارسال سیگنال SIGTERM و SIGKILL (پیش‌فرض ۲ ثانیه).
  • --verify-timeout DURATION: محدودیت زمانی برای بررسی نهایی پاک‌سازی (پیش‌فرض ۲ ثانیه).
  • --max-output SIZE: محدود کردن حجم ترکیبی stdout و stderr (مثلاً 1M).
  • --json PATH: ثبت یک رکورد حسابرسی شامل حالت اجرا، محدودیت‌ها، دلیل پایان، زمان‌بندی مراحل و PIDهای هر فرآیندی که در توقف شکست خورده است.
  • --stdin POLICY: تنظیم سیاست ورودی استاندارد روی null یا inherit.

عملکرد و بنچمارک‌ها

در تست‌های رودررو با ابزارهای استاندارد مانند timeout -k 1s 2s، Corral قابلیت اطمینان برتری از خود نشان داد. با استفاده از bench/compare.py، ده برنامه تست از پوشه faults/ هر کدام پنج بار با محدودیت زمانی ۲ ثانیه اجرا شدند. Corral (در هر دو حالت اجباری و جایگزین) در تک‌تک موارد تست، صفر فرآیند زنده باقی گذاشت.

در مقابل، سایر اجراکننده‌ها شکست‌های قابل‌توجهی داشتند:

  • NV (اجراکننده پایتونی): در موارد F3، F4، F5، F7 و F8 دچار تعلیق شد یا فرآیندها را زنده باقی گذاشت.
  • TO (timeout): در موارد F5 و F7 (در ۱ مورد از ۵ اجرا) فرآیندها را زنده باقی گذاشت. در مورد F7، جایی که دستور ۲۰۰ فرزند ایجاد کرده بود، اجراکننده پایتونی ۱۹۲ فرآیند را زنده باقی گذاشت.

نتایج خاص نشان داد که حالت اجباری (CE) برنامه F9 را در لحظه رسیدن به محدودیت ۶۴ مگابایت حافظه، تنها در ۰.۱۲ ثانیه متوقف کرد. از نظر سربار، اجرای دستور /bin/true در حالت جایگزین ۶.۶۴ میلی‌ثانیه (P50) و در حالت اجباری ۱۱.۳۳ میلی‌ثانیه (P50) زمان می‌برد، در حالی که اجرای مستقیم آن ۰.۸۳ میلی‌ثانیه است. این تست‌ها روی یک سرور ابری Hetzner با ۲ پردازنده مجازی اشتراکی (Intel Xeon, Skylake)، اوبونتو ۲۶.۰۴ و هسته ۷.۰ انجام شده است.

الزامات فنی و نصب

برای استفاده از Corral، به لینوکس ۵.۱۱ یا بالاتر نیاز است و برای حالت اجباری، نسخه ۵.۱۴ الزامی است. باینری‌های پیش‌ساخته برای سیستم‌های x86-64 با glibc ۲.۳۶ یا بالاتر (سازگار با اوبونتو ۲۲.۱۰، دبیان ۱۲ یا فدورا ۳۷) طراحی شده‌اند.

نصب از طریق باینری:
curl -LO https://github.com/Cardinal44/corral/releases/latest/download/corral-linux-x86_64.tar.gz
tar -xzf corral-linux-x86_64.tar.gz
sudo cp corral-linux-x86_64/corral corral-linux-x86_64/corral-enforced /usr/local/bin/

ساخت از سورس:
نیازمند glibc ۲.۳۶، CMake 3.22، Ninja و GCC 11 یا Clang 14 است. برای اجرای تست‌ها به پایتون ۳.۱۰ نیاز است.
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build --output-on-failure

کدهای خروجی و محدودیت‌ها

Corral از کدهای خروجی خاصی برای گزارش نتیجه استفاده می‌کند:

  • کد دستور: دستور به‌طور طبیعی خارج شده است.
  • ۱۲۴: زمان محدود شده به پایان رسید.
  • ۱۲۱: محدودیت حافظه لمس شد.
  • ۱۲۲: محدودیت خروجی لمس شد.
  • ۱۲۰: شکست در پاک‌سازی (Corral نتوانست اثبات کند تمام فرآیندها متوقف شده‌اند). این کد بر تمام کدهای دیگر اولویت دارد.
  • ۱۲۵: شکست در راه‌اندازی یا گزینه نادرست.
  • ۱۲۶، ۱۲۷: دستور شروع نشد (۱۲۷: یافت نشد).
  • ۱۲۸ + N: سیگنال N دستور را متوقف کرد (مثلاً ۱۳۰ برای Ctrl-C).

محدودیت‌ها:
Corral یک Sandbox امنیتی نیست؛ دسترسی به شبکه، فایل‌ها یا امتیازات (privileges) را محدود نمی‌کند. این ابزار نمی‌تواند کارهای شروع شده خارج از درخت فرآیند خود (مثلاً از طریق at، D-Bus یا systemd-run) را ببیند. در حالت جایگزین، نمی‌تواند به فرزندان setuid سیگنال دهد و با کد ۱۲۰ خارج می‌شود. اگر خودِ Corral با SIGKILL متوقف شود، تنها توقف فرزند مستقیم تضمین می‌شود. در حال حاضر این ابزار فاقد پشتیبانی از PTY و محدودیت‌های زمان CPU است و فقط روی لینوکس اجرا می‌شود.

برای توسعه‌دهندگان، این ابزار بار پاک‌سازی را از دوش پرامپت‌های عامل یا منطق اجراکننده به هسته سیستم‌عامل منتقل می‌کند. با تضمین یک محیط پاک (clean slate)، یکی از منابع اصلی شکست‌های غیرقطعی در گردش‌کارهای کدنویسی خودکار حذف می‌شود.

برای توسعه‌دهندگان، این ابزار بار پاک‌سازی را از دوش پرامپت‌های عامل یا منطق اجراکننده به هسته سیستم‌عامل منتقل می‌کند. با تضمین یک محیط پاک (clean slate)، یکی از منابع اصلی شکست‌های غیرقطعی در گردش‌کارهای کدنویسی خودکار حذف می‌شود.

گام بعدی شما

  • اگر از عامل‌های کدنویس در محیط‌های Docker یا CI استفاده می‌کنید، Corral را جایگزین timeout کنید تا از اشغال منابع سرور جلوگیری شود.
  • برای محیط‌های حساس، از حالت Enforced و پرچم --mem استفاده کنید تا از مصرف بی‌رویه رم توسط مدل‌های کدنویس جلوگیری کنید.
  • خروجی JSON ابزار را به سیستم مانیتورینگ خود متصل کنید تا متوجه شوید کدام دستورات عامل شما تمایل به ایجاد فرآیندهای زامبی دارند.

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

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

این ابزار با حذف فرآیندهای زامبی، پایداری محیط‌های اجرای خودکار را افزایش می‌دهد و از شکست‌های تصادفی در خط لوله‌های CI/CD جلوگیری می‌کند. اعتبار این راهکار بر پایه قابلیت‌های cgroup v2 در هسته لینوکس است که دقیق‌ترین روش ردیابی فرآیندهاست.

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

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

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

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

منابع

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

گفتگو

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

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

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

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

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

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

دات‌هوش

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

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