وقتی ساخت ایجنتهای هوش مصنوعی را از سناریوهای آزمایشی فراتر میبرید و ابزارهایی مثل اجرای دستورات شل یا خواندن فایلها را در اختیار مدل میگذارید، خیلی زود با سه چالش فلجکننده روبهرو میشوید: خروجیهای حجیمی که پنجره زمینه را در یک نوبت میبلعند و هزینهی توکن را نجومی میکنند، اطلاعات کهنهای که به حافظه تزریق میشوند، و مدلهایی که با خزش دسترسیها ابزارهای تاییدنشده یا پرخطر را فراخوانی میکنند.
اگر لایهی اجرای ابزار بدون نظارت و به امید رفتار هوشمندانه مدل رها شود، نتیجه چیزی جز شکست یا رفتارهای غیرقابلپیشبینی نیست. مدلهای زبانی نمیتوانند قاضی قطعی دسترسیهای خود باشند؛ کنترل این مرزها وظیفهی قطعی بستر اجرایی کد شماست.
در این درس یاد میگیرید که چگونه یک زنجیره گیت اعتبارسنجی کامپوزیت با ارزیابی قطعی بسازید. این زنجیره پیش از اجرای هر ابزار، نوع درخواست، آرگومانها و بودجهی تجمعی توکنهای مشاهدهشده را بررسی میکند و در صورت نیاز جلوی ادامه کار را میگیرد.
یک بستر آزمایشی ایجنت (agent harness) بدون لایهی اعتبارسنجی، مثل آرزویی توخالی در لباسی فریبنده است. این درس زنجیرهای قطعی از گیتها (deterministic gate chain) را میسازد؛ سازوکاری که تصمیم میگیرد آیا فراخوانی ابزار مجاز است یا نه، ایجنت چه مقدار از خروجی آن را میتواند ببیند، و چه زمانی به دلیل خواندن بیش از حد داده باید حلقه را متوقف کرد. این زنجیره از چند گیت کوچک و نامگذاریشده در کنار یک دفترکل مشاهدات (observation ledger) تشکیل میشود که تکتک توکنهای دیدهشده توسط مدل را ردگیری میکند.
اهداف یادگیری
- ساخت پروتکل
VerificationGateهمراه با متد قطعیevaluate(call). - ترکیب گیتهای بودجه (budget)، تازگی (recency)، فهرست مجاز (whitelist) و رجکس (regex) در قالب زنجیرهای با منطق اتصالکوتاه (short-circuit).
- ردگیری تکتک مشاهدات از طریق یک
ObservationLedgerبر اساس ابزار و نوبت گفتوگو (turn). - رد فراخوانی ابزار در صورت عبور از سقف بودجهی تجمعی مشاهدات.
- ارائهی یک رکورد ساختاریافته از نوع
GateDecisionبرای مصرف در سیستمهای مشاهدهپذیری (observability) پاییندست.
صورت مسئله
وقتی بستر آزمایشی ایجنت به مدل اجازه میدهد ابزارها را آزادانه فراخوانی کند، ظرف همان ساعت اول استفادهی واقعی، سه دسته باگ سر برمیآورند.
اولی، مشاهدات بیحدومرز (unbounded observation) است. اجرای یک grep روی مخزنی با 200 هزار خط کد، نیم میلیون توکن خروجی را وارد نوبت بعدی میکند. مدل به ازای هر کیلوبایت داده فقط یک تطابق میبیند و بقیهی فضای زمینه (context) هدر میرود. قبض توکن سر به فلک میکشد و ایجنت در انجام وظیفه نهتنها بهتر نمیشود، بلکه ضعیفتر عمل میکند.
دومی، کهنگی اطلاعات (stale recency) است. در یک وظیفهی طولانی، 50 فراخوانی ابزار روی هم انباشته میشود. مدل اولین فراخوانی read_file در نوبت 3 را طوری بازخوانی میکند که انگار وضعیت زنده و فعلی است. ویرایشهای نوبت 47 هیچوقت دیده نمیشوند، چون پرامپتساز (prompt builder) مشاهدات اولیه را اول از همه در پرامپت چیده است.
سومی، خزش دسترسیها (privilege creep) است. وظیفهای پژوهشی با فراخوانی web_search شروع میشود، اما ناگهان کار به اجرای shell میکشد؛ چون مدل نام ابزاری را از خودش درآورده و بستر آزمایشی هم بهصورت پیشفرض دسترسی را باز گذاشته است. تا کسی بیاید و ردگیری محاسبات (trace) را نگاه کند، فایلی بیهوده در /tmp نشسته و یک درخواست curl به API خصوصی ارسال شده است.
گیت اعتبارسنجی (verification gate) همان بخش از بستر آزمایشی است که دست رد به سینه میزند. این گیت یک مدل یا قاضی نیست؛ یک تابع کاملاً قطعی از (call, history, ledger) است که وضعیت ALLOW یا DENY را همراه با دلیل برمیگرداند. این دلیل لاگ میشود، به اطلاع مدل میرسد، و حلقه تصمیم میگیرد ادامه دهد یا متوقف شود.
مفاهیم پایه
هر ساختاری که متدی با امضای evaluate(call, ctx) -> GateDecision داشته باشد، یک گیت است. زنجیره هم یک لیست مرتب است. ارزیابی زنجیره به محض رسیدن به اولین پاسخ منفی متوقف میشود (short-circuit). ترتیب اجرای گیتها مهم است: گیتهای ساختاری سبک باید قبل از گیتهای سنگینِ شمارش توکن اجرا شوند.
این درس چهار گیت را پیاده میکند:
WhitelistGate: نام ابزارهای مجاز در قالب یک مجموعهی صریح تعریف میشود. هر نامی خارج از این مجموعه رد خواهد شد. این سبکترین گیت است و اول از همه اجرا میشود.RegexGate: آرگومانهای ابزار با یک رجکس (regex) تطبیق داده میشوند. برای رد کردن فراخوانیهای شل حاویrm -rfیا درخواستهای HTTP به IPهای داخلی کاربرد دارد و مستقیماً روی بدنهی دادههای ورودی (payload) کار میکند.RecencyGate: مدل فقط مشاهدات مربوط به N نوبت اخیر را میبیند. مشاهدات قدیمیتر ماسک میشوند. این گیت فراخوانی ابزاری را که نتیجهاش پنجرهی مشاهداتِ منقضیشده را کش بدهد، رد میکند.BudgetGate: مجموع کل توکنهایی که مدل در طول نشست (session) خوانده است سقف مشخصی دارد. وقتی دفترکل اعلام کند سقف پر شده، تمام فراخوانیهای بعدی رد میشوند.
دفترکل مشاهدات کار حسابوکتاب را به عهده دارد. هر فراخوانی موفق ابزار، یک ردیف ثبت میکند: نام ابزار، نوبت گفتوگو، توکنهای خارجشده و مقدار تجمعی. این دفترکل به دو پرسش پاسخ میدهد: مدل در مجموع چه مقدار توکن دیده، و سهم ابزار X چقدر بوده است. گیت بودجه پرسش اول را میخواند. گیت بودجهی مجزا به ازای هر ابزار، که در قالب تمرین مینویسید، پرسش دوم را بررسی میکند.
معماری
بستر آزمایشی از زنجیره استعلام میگیرد. زنجیره یا تأیید میکند یا رد. اگر تأیید کند، ابزار اجرا میشود، دفترکل بهروزرسانی میشود و نتیجه به مخزن پیامها اضافه میگردد. اگر رد کند، امتناع مدل (refusal) در قالب یک پیام سیستمی (system message) به مدل تحویل داده میشود و حلقه تصمیم میگیرد دوباره تلاش کند یا کار را متوقف سازد.
آنچه خواهید ساخت
کل پیادهسازی شامل یک فایل main.py به همراه تستهاست:
- کلاسهای دادهای
ObservationوToolCallساختار دادههای تبادلی را تعریف میکنند. - کلاس
ObservationLedgerردیفهای(turn, tool, tokens)را ثبت میکند و متدهایcumulative()وper_tool(name)را در اختیارتان میگذارد. - کلاس
GateDecisionدادههای(allow, reason, gate_name)را منتقل میکند. - پروتکل
VerificationGateاستاندارد کار است. هر گیت متدevaluate(call, ctx)را پیادهسازی میکند. - کلاس
GateChainیک لیست مرتب از گیتها را در بر میگیرد؛ هر گیت را صدا میزند، اولین پاسخ منفی را برمیگرداند، یا در صورت قبولی همهی گیتها، مجوز را صادر میکند. - بخش دمو یک حلقهی ایجنت مصنوعی و کوچک را در 3 نوبت اجرا میکند. نوبت سوم به سد گیت بودجه میخورد و حلقه یک رد درخواست تمیز با شمارندهی غیرصفر گزارش میدهد.
شمارندهی توکن را عمداً یک تقریب ساده و سرانگشتی با رابطهی len(text) // 4 در نظر گرفتهایم. هدف این درس ساختاربندی و اتصال گیتهاست، نه نحوهی کار توکنایزر. در محیط عملیاتی (پروداکشن) حتماً از یک توکنایزر واقعی استفاده کنید.
چرا ترتیب زنجیره مهم است؟
هزینهی پردازشیِ رد کردن همیشه کمتر از تأیید کردن است. WhitelistGate با جستوجوی جدول هش در زمان اجرا میشود. RegexGate در زمان کار میکند. RecencyGate تکهی کوچکی از مخزن پیامها را بررسی میکند، اما BudgetGate کل دفترکل را میخواند. گیتها را به ترتیب صعودی هزینه میچینید تا درخواستهای غیرمجاز پیش از رسیدن به مراحل سنگین، با منطق اتصالکوتاه متوقف شوند.
علاوه بر هزینه، ترتیب باید بر اساس شعاع تخریب (blast radius) باشد. فهرست مجاز قویترین ادعاست: این ابزار اصلاً در قرارداد نیامده است. گیت رجکس در رتبهی بعدی است: این آرگومان در قرارداد نیست. بعد از آن گیت تازگی مینشیند: بستر آزمایشی هنوز به موضوع اهمیت میدهد اما فراخوانی از نظر ساختاری مجاز است. گیت بودجه هم در آخر میآید؛ چون اساساً زمانی فعال میشود که همه چیز قبلاً تأیید شده باشد.
هماهنگی با سایر بخشهای مسیر A
در درسهای قبلی حلقه، رجیستری ابزار (Tool Registry)، مخزن پیامها، پرامپتساز و مسیریاب مدل را ساختید. این درس لایهی میانی بین مدل و ابزارها را اضافه میکند. در درس 26 ساندباکس (sandbox) را میسازیم؛ محیط ایزولهای که دیسپچر بعد از چراغ سبز زنجیرهی گیتها، فراخوانی ابزار را به آن میسپارد. در درس 27 بستر آزمایشی ارزیابی را پیاده میکنیم که تعداد امتناعها را به عنوان سیگنال کیفیت ثبت میکند. در درس 28 تصمیمات گیتها را به اسپنهای OpenTelemetry متصل میکنیم و در نهایت در درس 29 همهی اینها را سر هم میکنیم تا یک ایجنت برنامهنویس واقعی داشته باشیم.
اجرای پروژه
cd phases/19-capstone-projects/25-verification-gates-observation-budget
python3 code/main.py
python3 -m pytest code/tests/ -v
دمو یک ردگیری محاسبات گامبهگام از هر نوبت را همراه با تکتک تصمیمات گیتها چاپ میکند و با کد صفر خارج میشود. تستها نیز دفترکل، تکتک گیتها بهصورت مجزا، منطق اتصالکوتاه زنجیره و حلقهی مصنوعی را بهصورت سرتاسری (End-to-end) پوشش میدهند.
