تصور کنید برنامهنویسی هستید که یک عامل هوش مصنوعی محلی برای مدیریت کدها دارد، اما ناگهان متوجه میشود کلیدهای خصوصی و فایلهای حساس پروژه به سرورهای ابری ارسال شده است. این کابوس امنیتی زمانی رخ میدهد که ما با هر پرامپت یکسان برخورد کنیم و تفاوت بین یک ویرایش ساده و یک بازبینی جامع را نادیده بگیریم.
این سناریو دقیقاً از یک الزام سختگیرانه مدیر محصول شروع شد: «هرگز نباید فایلهای .env، کلیدهای خصوصی یا دمپهای دادههای مشتریان را به پنجرههای کانتکست میزبانیشده ارسال کرد.» این دستور پس از آن صادر شد که یک تیم بکاند، عاملی را مستقر کرد که اولویت را به محیط محلی میداد اما اسرار مخزن (Repository Secrets) را روی لپتاپهای توسعهدهندگان نگه میداشت. در حالی که این عامل پرسوجوهای کوچک را سریعاً پاسخ میداد، بازبینیهای دستهای (Batch Reviews) آخر هفته هرگاه لپتاپها به حالت خواب (Sleep) میرفتند یا از شبکه دفتر خارج میشدند، متوقف میشدند. این موضوع منجر به درخواست برای یک جایگزین دوردست (Remote Fallback) شد. این تجربه یک آسیبپذیری حیاتی را برجسته کرد: یک عامل کدنویسی محلی-اول (Local-first) تنها به اندازه منطق مسیریابیاش امن است. اگر با هر پرامپت به عنوان موردی به یک اندازه امن برخورد کنیم، ارسال کلیدهای خصوصی یا پایگاههای داده مشتریان به یک پنجره کانتکست ابری اجتنابناپذیر خواهد بود.
طبق گزارشهای فنی اخیر، بسیاری از عاملهای هوش مصنوعی (AI Agents) — شبیه دستیارهای هوشمندی که میتوانند بهجای ما ابزارها را اجرا کنند — در یک تضاد همیشگی گیر کردهاند: یا کاملاً محلی میمانند و با بستن درب لپتاپ متوقف میشوند، یا بهصورت پیشفرض به ابر متصل میشوند و ریسک نشت دادهها را به شدت بالا میبرند. این وضعیت تضادی میان نیاز به تأخیر کم برای ویرایشهای تعاملی و نیاز به «میزبانهای بیدار» (Awake Hosts) ایجاد میکند که بتوانند بازسازیهای کد (Refactors) شبانه را بدون نظارت انسانی انجام دهند. راهکار این مشکل نه در انتخاب مدل قویتر یا مقایسه مدلها، بلکه در طراحی یک «مسیریاب وظایف» (Job Router) است که پیش از مصرف حتی یک توکن (Token) — تکههای کوچکی از متن که مدلها میخورند — نوع کار را طبقهبندی کند.
زمینه: شکست محیطهای پیشفرض
نوشتههای عمومی اخیر درباره جریانهای کاری عاملها مدام به یک شکست مشترک بازمیگردند: سیستمها بهجای بررسی محدودیتها، یک محیط پیشفرض را فرض میکنند. این رویکرد در واقع یکی از مسیرهای شکست رایجی است که مانع از استقرار تجاری عاملهای هوش مصنوعی میشود و باعث میشود سیستمها در محیطهای واقعی ناکارآمد باشند. یک مسیریاب وظایف راهی است تا این فرض تبدیل به یک حادثه نشت داده (Data-residency incident) نشود. بررسی باید پیش از اولین توکن دوردست اتفاق بیفتد، زیرا این تنها لحظهای است که سیاست امنیتی هنوز میتواند پاسخ «نه» بدهد.
عاملهای محلی-اول به روشهای قابل پیشبینی شکست میخورند؛ زمانی که هر پرامپت به اندازه پرامپت دیگر برای ارسال به جای دیگری امن تلقی شود. ویرایشهای تعاملی به تأخیر کم و یک محیط اجرای محلی گرم (Warm Runtime) نیاز دارند، در حالی که بازسازیهای شبانه به ماشینی نیاز دارند که بدون بستن درب لپتاپ، بیدار بماند. مطالب حساس به دیسک و حافظهای نیاز دارند که تیم از قبل کنترل میکند، در حالی که دادههای عمومی (Public Fixtures) میتوانند بدون نقض قوانین اقامت دادهها جابهجا شوند.
برای حل این چالش، مسیریاب پیشنهادی پیش از فراخوانی هر نقطه انتهایی (Endpoint) مدل، چهار سیگنال خاص را بررسی میکند. این سیگنالها توسط یک پوشش (Wrapper) محاسبه میشوند، به این معنی که تصمیمگیری پیش از ساخته شدن کلاینت HTTP رخ میدهد. این امر تضمین میکند که سیاست امنیتی در تنها لحظهای که اهمیت دارد، بتواند «نه» بگوید. تأخیر همچنان مهم است، اما تأخیر یک اندازهگیری ثانویه است، نه مجوزی برای جابهجایی اسرار.
چهار سیگنال مسیریابی
هیچیک از این سیگنالها نیازی به امتیازات جدولهای ردهبندی عمومی ندارند و فرض را بر فروشنده یا نسل سختافزاری خاصی نمیگذارند. تیمها باید اکتشافات مربوط به مدتزمان (Duration Heuristics) را با اندازهگیریهای لپتاپهای خود جایگزین کنند، زیرا بارگذاری محلی سرد (Cold Load) و بارگذاری محلی گرم، دو وظیفه متفاوت هستند. این سیگنالها شمارهگذاری شدهاند تا در بازبینیها بتوان هر یک را به یک فیلد در لاگها متصل کرد:
- اقامت دادههای حساس (Secret Residency): این پرچم زمانی True است که پرامپت، ابزارها یا تکههای بازیابیشده شامل اعتبارنامهها (Credentials)، رکوردهای مشتریان یا مطالب خصوصی مخزن کد باشند.
- الزام آفلاین بودن (Offline Requirement): این پرچم زمانی True است که کار باید بدون مسیر شبکه به پایان برسد، از جمله کارهای زمان پرواز یا محیطهای اجرای بسته (Locked-down runners).
- بودجه تعاملی (Interactive Budget): این پرچم زمانی True است که یک انسان در یک ویرایشگر یا پنل چت منتظر جریان توکن بعدی است.
- نیاز به میزبان بیدار (Awake-Host Need): این پرچم زمانی True است که زمان واقعی تخمینی (Wall Time) از بازه بیداری قابل اعتماد لپتاپ بیشتر باشد، مانند یک بازبینی چند-فایلی در جمعهشب.
ماتریس تصمیمگیری
مسیریاب از یک جدول سیاست سختگیرانه برای تعیین مقصد پیروی میکند. ستون آخر یک نتیجه سیاستی است، نه رتبهبندی کیفی مدلها، و باید به عنوان یک قرارداد اولیه در نظر گرفته شود:
- اسرار = بله: مسیر «فقط محلی، یا رد درخواست دوردست» است، صرفنظر از سایر سیگنالها.
- آفلاین = بله: مسیر «فقط محلی، یا رد درخواست دوردست» است، صرفنظر از سایر سیگنالها.
- تعاملی = بله / نیاز به میزبان بیدار = خیر: مسیر «ترجیح محلی» است تا تأخیر کم تضمین شود.
- تعاملی = خیر / نیاز به میزبان بیدار = بله: مسیر «ترجیح سرور دوردست رایگان» برای کارهای دستهای (Batch) است.
- تعاملی = بله / نیاز به میزبان بیدار = بله: مسیر «تقسیم: برنامهریزی محلی، اجرای دستهای دوردست» است.
- همه خیر: مسیر «هر دو؛ ترجیح محلی اگر محیط از قبل گرم است».
یکی از حیاتیترین نتایج، مسیر «تقسیم» (Split) است. وقتی یک کار تعاملی است اما از بودجه بیداری لپتاپ فراتر میرود، مسیریاب فاز برنامهریزی را محلی نگه میدارد. این کار تضمین میکند که طرحهای ابزار (Tool Schemas) و مسیرهای داخلی فایلها در طول فاز تفکر خصوصی بمانند. سپس تنها یک دسته پاکسازیشده از تستهای واحد یا مراحل اجرا به سرور دوردست ارسال میشود. این دقیقاً برعکس ارسال کل تاریخچه عامل به ابر و امید به اینکه سیستمهای حذف داده (Redaction) بعد از آن درست عمل کنند، است.
پیادهسازی و ایمنی
پیادهسازی پیشنهادی پایتون، این شاخهها را بهطور صریح در ماژول job_router.py کدگذاری میکند. این کار به بازبینهای کد اجازه میدهد تا هر مسیر «رد» (Deny) را بدون جستوجو در پرامپتها ببینند. این ماژول از یک dataclass به نام JobSignals استفاده میکند و یک RoutingDecision برمیگرداند که شامل مسیر، دلیل و یک پرچم اجباری به نام sanitize_before_remote است.
برای اینکه سیاستها در طول بازبینی حوادث قابل مشاهده باشند، یک CLI کوچک (route_cli.py) به اپراتورها اجازه میدهد سیگنالها را از لاگها کپی کنند، بهجای اینکه درباره سرعت مدل بحث کنند. برای مثال:
python route_cli.py --secrets --interactive --seconds 12 --warm$
ightarrow$ درخواست دوردست را رد میکند زیرا اسرار در یک نوبت تعاملی حضور دارند.python route_cli.py --seconds 5400$
ightarrow$ یک سرور دوردست رایگان را برای یک کار دستهای طولانی بدون پرچم اسرار و محدودیت آفلاین ترجیح میدهد.python route_cli.py --interactive --seconds 5400 --warm$
ightarrow$ برنامهریزی را از اجرا جدا میکند زیرا کاربر منتظر است در حالی که کار تخمینی از بودجه بیداری فراتر میرود.python route_cli.py --offline --seconds 30$
ightarrow$ محلی میماند زیرا کار آفلاین نمیتواند ماشین را ترک کند، حتی اگر کوتاه باشد.
برای جلوگیری از «جابهجایی خاموش دادهها»، این پیشنهاد از تستهای قراردادی در test_job_router.py حمایت میکند. باگهای مسیریابی به صورت جابهجایی خاموش دادهها ظاهر میشوند، نه به صورت Stack Trace در کلاینت مدل. این تستها مسیرهای رد را قفل میکنند تا بهینهسازیهای عملکردی آینده بهطور تصادفی یک کار پر از اسرار را به میزبان دوردست منتقل نکنند. تأکیدات (Assertions) سیاست را بررسی میکنند، نه کیفیت توکن را، که باعث میشود مجموعه تستها با تغییر مدلها پایدار بمانند. برای مثال، یک تست تضمین میکند که کاری با contains_secrets=True حتی اگر تخمین زده شود لپتاپ ۱۰,۰۰۰ ثانیه میخوابد، دسترسی دوردست را رد کند.
نردههای حفاظتی عملیاتی
پاکسازی (Sanitization) برای هر مسیر دوردست، از جمله مسیر تقسیم، اجباری است. یک خط پایه عملیاتی حداقل شامل موارد زیر است:
- اسکن لیست سیاه (Denylist Scan): جستوجو برای الگوهای حساس (مانند هدرهای
AuthorizationیاBEGIN PRIVATE KEYیا الگوهای ایمیل مشتریان). تیمی که ردپاهای عامل را سریالایز میکند، میتواند یک تأکید دیگر در پوشش (Wrapper) اضافه کند تا اینها را پیش از ساخته شدن کلاینت HTTP بگیرد. - لیست سفید مسیرها (Path Allowlist): حذف فایلهای
.envو فایلهای کلید. - سقف اندازه (Size Cap): تضمین اینکه یک دامپ داده عمومی ادعایی، نتواند بهطور تصادفی یک خروجی پایگاه داده را قاچاق کند.
علاوه بر این، دسترسی به ابزارها در کارکنان دوردست باید از طریق یک لیست سفید مجزا محدود شود. یک پرامپت پاک نمیتواند مانع از این شود که یک ابزار دوردست بعداً اسرار را واکشی کند اگر مجوزها بیش از حد گسترده باشند. مسیر تقسیم باید تنها مصنوعات دستهای (مانند یک tarball از تستها) را ارسال کند و هرگز تاریخچه برنامهریزی اصلی را که نام میزبانهای داخلی را ذکر میکند، ارسال نکند. این لایههای حفاظتی در کنار مدلهای Zero-Trust برای تأمین امنیت ارتباطات بین عاملها میتواند یک اکوسیستم کاملاً امن ایجاد کند.
کجا یک سرور رایگان بیدار برنده میشود
استنتاج محلی همچنان زمانی برنده است که کانتکست خصوصی باشد، کاربر منتظر باشد یا شبکه قطع باشد. یک سرور دوردست رایگان زمانی برنده است که محموله (Payload) از قبل عمومی یا مصنوعی باشد، نتوان به بیدار ماندن لپتاپ اعتماد کرد و کار بهجای یک ضربه کلید، یک کار دستهای باشد.
این شرایط معمولاً در موارد زیر ظاهر میشوند:
- ارزیابیهای گسترده (Eval sweeps) روی دادههای عمومی.
- پیشنویس تغییرات (Changelog) از روی ایشوهای عمومی.
- تحلیل استاتیک طولانی مجموعهدادههایی که هرگز شامل رکوردهای تولیدی نبودهاند.
این پیروزی عملیاتی است، نه لفاظی: میزبان دوردست اجازه دارد بیشتر از جلسه لپتاپ عمر کند.
گردش کار نصب
تیمها میتوانند این مسیریاب را با استفاده از حلقه کنترلی شش مرحلهای زیر پیاده کنند:
- سیاهه (Inventory): لیست انواع وظایف را برای یک هفته (چت تعاملی، بازسازی محلی، ارزیابی شبانه، سفر آفلاین) و مالکان آنها فهرست کنید.
- نگاشت سیگنال: هر نوع را با چهار سیگنال با استفاده از سیاست مکتوب به عنوان اولین فیلتر علامتگذاری کنید و ثبت کنید چه کسی میتواند یک پرچم را نادیده بگیرد.
- یکپارچهسازی: تابع
classify_jobرا در پوشش عامل، پیش از کلاینت HTTP و فراخوانی محیط اجرای محلی پیاده کنید تا هیچ مسیری نتواند جدول را دور بزند. - تست: تستهای مسیر رد و خطوط لاگ را اضافه کنید که مسیر، دلیل، ثانیههای تخمینی و اینکه آیا پاکسازی پیش از ارسال بایتهای دوردست اجرا شده است یا خیر را ثبت کند.
- سیمکشی:
FREE_SERVERرا به میزبانی متصل کنید که بیدار میماند (مانند دسترسی به مدلهای رایگان و گزینه سرور MonkeyCode). اپراتورها باید پیش از برنامهریزی ظرفیت، صفحه محصول زنده را برای در دسترس بودن و شرایط فعلی بررسی کنند. - بازبینی: یک هفته از لاگها را برای تضادها تحلیل کنید، مانند کارهای تعاملی که به صورت دوردست مسیریابی شدهاند یا کارهای حساس که بهجای رد شدن، درخواست پاکسازی دادهاند.
مرحله ششم حلقه کنترلی واقعی است. مسیریابی که هرگز با ردپاها (Traces) مقایسه نشود، تبدیل به افسانه میشود و افسانهها باعث بازگشت پیشفرضهای ابری میشوند. تیمها باید مقدار گمشده contains_secrets را به عنوان True در نظر بگیرند، نه False، تا زمانی که پوشش بتواند ثابت کند محموله عمومی است. مسیریابی «بسته در صورت شکست» (Failure-closed) در بارهای کاری ترکیبی کندتر است، اما با وعده اصلی محصول که کانتکست محلی محلی بماند، مطابقت دارد.
محدودیتها و ریسکها
این رویکرد کیفیت مدل، نرخ توهم (Hallucination) یا دقت فراخوانی ابزارها را در برابر یک مجموعه داده جداشده اندازهگیری نمیکند. اگر سیاست دیکته کند که لپتاپ خواهد خوابید، این سیستم یک دسته عمومی را به یک مدل دوردست ضعیف میفرستد و این ممکن است برای یک سند کاربر-محور، تبادل مهندسی اشتباهی باشد. برای بهینهسازی این بخش، میتوان از معماریهای جدیدی مانند مدلهای ۴ بیتی کوانتیده برای کنترل دقیقتر عاملهای کدنویسی در محیطهای محلی استفاده کرد تا کیفیت خروجی حفظ شود.
علاوه بر این، تخمینهای مدتزمان تا زمانی که یک تیم زمانهای واقعی را روی همان سختافزار ثبت کند، حدس باقی میمانند. یک تخمین اشتباه میتواند یا یک کار کوتاه را بهطور غیرضروری تقسیم کند یا یک کار طولانی را به لپتاپی بچسباند که در حال خاموش شدن است و دوباره توقفات آخر هفته را ایجاد کند.
تشخیص اسرار تنها به اندازه اسکنرهایی است که پرچم contains_secrets را تغذیه میکنند. اسکنرهای اسرار فرمتهای جدید را از دست میدهند، بنابراین مسیر رد همچنان به یک پرچم تنظیمشده توسط انسان برای مجموعههای داده تحت نظارت نیاز دارد. اگر توسعهدهندهای یک توکن تولیدی را در یک داده عمومی قرار دهد، مسیریاب به پرچم عمومی اعتماد کرده و داده را به صورت دوردست مسیریابی میکند. مسیر تقسیم همچنین به یک قرارداد سخت نیاز دارد: کارکنان دوردست نباید ابزارهایی را فراخوانی کنند که به سیستمهای تولیدی یا ذخیرهسازهای شیء خصوصی دسترسی دارند. حالت آفلاین نیز نمیتواند یک پرچم «بهترین تلاش» باشد؛ اگر محیط اجرای محلی غایب است، نتیجه صادقانه شکست است، نه یک فراخوانی دوردست بیصدا که قانون هواپیما را نقض کند.
چه کسانی نباید از این رویکرد استفاده کنند
برخی تیمها باید از این معماری دوری کنند:
- تیمهای با امنیت بالا: کسانی که باید هر توکن را روی سختافزار تأیید شده نگه دارند، نباید شاخه
FREE_SERVERرا اصلاً اضافه کنند، حتی برای متنی که عمومی به نظر میرسد، تا زمانی که بررسی حقوقی آن را تأیید کند. - تیمهای بدون حفاظت: کسانی که فاقد پاکساز (Sanitizer) و لیست سفید ابزارها هستند، نباید مسیرهای
FREE_SERVERیاSPLITرا فعال کنند، زیرا این مسیرها بایتهایی را جابهجا میکنند که پوشش دیگر کنترلی روی آنها ندارد. - محصولات با تحمل صفر: محصولات تعاملی که نمیتوانند یک باگ طبقهبندی را تحمل کنند، باید در صورت نبود سیگنالها، به صورت محلی بسته شوند یا درخواست را رد کنند، بهجای اینکه به صورت پیشفرض دوردست عمل کنند.
- عاملهای فقط-ابری: عاملهای کاملاً متصل ابری بدون محیط اجرای محلی به داستان جداسازی متفاوتی نیاز دارند و این جدول پاسخی برای آنها نخواهد بود.
وعده محلی-اول تنها زمانی در مواجهه با لپتاپهای در حال خواب زنده میماند که وظایف پیش از فراخوانی مدلها طبقهبندی شوند. اسرار، محدودیتهای آفلاین، بودجههای تعاملی و نیاز به میزبان بیدار فیلدهای خستهکنندهای هستند، و به همین دلیل است که آنها به جای پرامپت، به یک مسیریاب تعلق دارند. یک سرور دوردست رایگان یک ردیف مشروع در آن جدول برای کارهای دستهای عمومی است و برای هر چیز دیگری، یک نقض سیاست است.




گفتگو