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

رخنهٔ Race Condition در درگاه‌های پرداخت عامل‌های هوش مصنوعی

·۲۹ تیر ۱۴۰۵۵ دقیقه مطالعه۱ بازدید
ساختم درب هزینه برای عامل‌های هوشمند. ثابت کردم تحت بار فرو می‌ریزد.
ساختم درب هزینه برای عامل‌های هوشمند. ثابت کردم تحت بار فرو می‌ریزد.
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

افشای یک Race Condition ساختاری در پروتکل A2A که نشان می‌دهد کنترل بودجه در لایه پروکسی، بدون هم‌گام‌سازی سخت‌گیرانه، در محیط‌های هم‌زمان عملاً بی‌اثر است.

تصور کنید برای یک عامل هوشمند سقف بودجه تعیین کرده‌اید، اما او در یک میلی‌ثانیه تمام موجودی شما را می‌مکد. این کابوس مالی، نتیجهٔ یک خطای فنی به نام «شرایط رقابتی» (Race Condition) است که در ابزارهای نظارتی بر هزینه رخ می‌دهد. در واقع، یک پروکسی در سطح شبکه برای پروتکل A2A (پروتکل باز برای انتقال تسک بین عامل‌های هوشمند) می‌تواند جلوی نشت بودجه را بگیرد، اما قادر نیست از بروز یک شرایط رقابتی جلوگیری کند.

به نقل از گزارش تحلیل پس از رخداد (Post-mortem) که در ۲۰ جولای ۲۰۲۶ توسط توسعه‌دهنده علی عبدالله منتشر شد، یک درگاه پرداخت (Spending Gateway) که با هدف محدود کردن هزینه‌ها در زمان ارجاع تسک بین عامل‌ها طراحی شده بود، در مواجهه با درخواست‌های هم‌زمان شکست می‌خورد. در چشم‌انداز فعلی سیستم‌های عامل‌محور (Agentic Landscape)، مسائلی مانند شناسایی (Discovery) و پیام‌رسانی تا حد زیادی حل شده‌اند. با این حال، ریسک مالی همچنان بسیار بالاست؛ وقتی عامل الف (Agent A)، عامل ب (Agent B) را استخدام می‌کند، اغلب هیچ مکانیسمی وجود ندارد که از تخلیه بی‌صدا و تدریجی بودجه توسط یک تسک ارجاع‌شده جلوگیری کند. این شکاف فنی، مانعی جدی برای سازمان‌ها و شرکت‌هایی است که می‌خواهند جریان‌های کاری خودمختار را در مقیاس بزرگ پیاده‌سازی کنند. این چالش‌ها به‌ویژه در سیستم‌های حساس مالی ملموس‌تر است، جایی که استفاده از گیت‌های انتشار برای کنترل دقیق‌تر عامل‌ها در گردش‌کارهای ERP به عنوان یکی از راهکارهای مدیریتی پیشنهاد شده است.

این مشکل شبیه به یک کارت هدیه پیش‌پرداخت است. فرض کنید ۵ دلار دارید و قهوه‌ای ۴ دلاری می‌خرید؛ سیستم موجودی را چک می‌کند و اگر موجودی ۵ دلار و قیمت قهوه ۴ دلار باشد، اجازه خرید می‌دهد. اما اگر ۵ نفر دقیقاً در یک میلی‌ثانیه بخواهند با همان کارت یک قهوه ۴ دلاری بخرند، یک سیستم کند ممکن است به هر ۵ نفر اجازه خرید بدهد، چون هنوز موجودی به‌روز نشده و برای همه ۵ دلار نشان می‌دهد و قبل از اینکه موجودی به صفر برسد، هر ۵ تراکنش تایید می‌شوند.

جزئیات معماری درگاه

برای حل این مسئله، عبدالله درگاهی ساخت که به‌صورت شفاف (Transparent) بین یک «عامل هماهنگ‌کننده» (Coordinator Agent) و یک «عامل متخصص» (Specialist Agent) قرار می‌گیرد. این درگاه آدرس تبلیغ‌شده‌ی عامل متخصص را بازنویسی می‌کند تا به خودش اشاره کند؛ بدین ترتیب اطمینان حاصل می‌شود که عامل هماهنگ‌کننده به جای خودِ عامل واقعی، درگاه را شناسایی می‌کند.

این ساختار به درگاه اجازه می‌دهد به عنوان یک پروکسی شفاف عمل کند. به غیر از بازنویسی آدرس، تمامی داده‌های دیگر به‌صورت بایت‌به‌بایت (Byte-for-byte) منتقل می‌شوند. در این موقعیت، درگاه می‌تواند هر درخواست و پاسخی را مشاهده کند و همین قابلیت، دید لازم برای تخمین هزینه و اجرای سخت‌گیرانه سقف بودجه را فراهم می‌کند.

جزئیات تخمین هزینه

از آنجایی که درگاه نمی‌تواند دستورات داخلی سیستم (System Prompts)، تلاش‌های مجدد (Retries) یا فراخوانی‌های ابزار (Tool Calls) یک مدل را ببیند، مجبور است هزینه‌ها را تنها بر اساس پیام ورودی و آرتیفکت خروجی تخمین بزند. برای اینکه در مورد دقت محاسبات دروغ گفته نشود، هر رکورد در لاگ‌ها به‌طور صریح مشخص می‌کند که تخمین از کدام‌یک از سه سطح زیر استخراج شده است:

  • گزارش خود-عامل (Self-reported): این حالت زمانی رخ می‌دهد که یک عامل همکاری‌کننده به‌صورت داوطلبانه داده‌های واقعی مصرف را ضمیمه می‌کند. در صورت موجود بودن، این داده به عنوان «حقیقت مطلق» (Ground Truth) در نظر گرفته می‌شود.
  • تخمین توکنایزر ارائه‌دهنده (Provider-tokenizer estimate): درگاه مدل پشتیبان عامل را شناسایی کرده و توکنایزر مخصوص آن ارائه‌دهنده را اجرا می‌کند. عبدالله برای تایید این مورد، به جای تکیه بر مستندات، کتابخانه‌های واقعی را نصب کرد و از tiktoken شرکت OpenAI، Tekken شرکت Mistral و توکنایزر محلی و تجربی Gemini شرکت گوگل استفاده نمود.
  • جایگزین عمومی (Generic fallback): یک شمارش تقریبی کاراکترها که مستقل از ارائه‌دهنده است و تنها زمانی استفاده می‌شود که هیچ اطلاعات دیگری در دسترس نباشد.

محدودیت ساختاری

طبق گزارش منتشر شده در dev.to، یک حقیقت بنیادین درباره پروکسی‌های شبکه این است که هزینه تنها «بعد» از دریافت پاسخ قابل محاسبه است. درگاه نمی‌تواند هزینه نهایی را قبل از ارسال درخواست بداند. در نتیجه، درگاه سوال متفاوتی را ارزیابی می‌کند: «آیا این عامل تا الان آن‌قدر هزینه کرده است که درخواست جدید باید مسدود شود؟»

برای مدیریت این مورد، درگاه مجموع هزینه‌های accumulated را ردیابی کرده و یک تخمین «پیش‌پرواز» (Pre-flight estimate) بر اساس بخش ورودی درخواست جدید اضافه می‌کند (که تنها بخشی است که قبل از ارسال قابل شناسایی است). اگر این مجموع از سقف تعیین‌شده فراتر رود، درخواست رد می‌شود.

با این حال، این به معنای آن است که یک پاسخ واحد و بسیار حجیم همچنان می‌تواند از بودجه فراتر رود، زیرا هزینه اضافی تنها پس از تحویل پاسخ görünbar می‌شود. عبدالله استدلال می‌کند که این یک حقیقت ساختاری در مورد پروکسی‌های سطح شبکه است؛ تظاهر به اینکه یک پروکسی می‌تواند هزینه درخواستی را که در حال ارسال است (In-flight) محدود کند، بدتر از پذیرش این محدودیت است.

باگ هم‌زمانی (The Concurrency Bug)

نقطه شکست بحرانی در توالی «بررسی-سپس-اجرا» (Check-then-act) رخ می‌دهد: درگاه هزینه فعلی را می‌خواند، تصمیم به ارسال می‌گیرد و سپس پس از رسیدن پاسخ، هزینه جدید را ثبت می‌کند. در فاصله بین «خواندن» و «ثبت»، یک دستور await واقعی برای تماس شبکه‌ای با عامل متخصص وجود دارد.

از آنجایی که asyncio در پایتون در طول هر await کارهای دیگر را به صورت متناوب (Interleave) پیش می‌برد، یک «شرایط رقابتی» ایجاد می‌شود. درگاه بر اساس وضعیتی تصمیم می‌گیرد که تا لحظه تاثیرگذاری آن تصمیم، قدیمی (Stale) شده است.

عبدالله این Bug را در فایل tests/test_budget_race_condition.py با یک مورد تست خاص بازتولید کرد:

  1. بودجه را به‌گونه‌ای تنظیم کرد که دقیقاً اجازه یک درخواست را بدهد.
  2. پنج ارجاع هم‌زمان به یک عامل فرستاد.
  3. مشاهده: هر پنج درخواست با موفقیت عبور کردند.

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

مسیر رسیدگی به مشکل

رفع این مشکل نیازمند «سریال‌سازی» (Serialization) درخواست‌ها به یک عامل واحد است. این کار را می‌توان با استفاده از یک قفل (Lock) برای هر عامل یا مکانیسم Compare-and-Set پیرامون کل توالی «بررسی-ارسال-ثبت» به دست آورد.

توسعه‌دهنده به‌جای ارائه یک وصله (Patch) فوری، ابتدا باگ را مستند کرد تا اطمینان حاصل شود که شکست به‌صورت اثباتی واقعی است و از نظم «تایید قبل از ساخت» پیروی کند. تست موجود در حال حاضر «ایمن شکست می‌رود» (Fails safe)؛ یعنی در حال حاضر با تایید حضور باگ، پاس می‌شود. زمانی که شرایط رقابتی در نهایت رفع شود، این تست به حالت «شکست» می‌رود و سیگنال می‌دهد که اصلاحیه به‌درستی کار می‌کند.

این شفافیت، تضاد بزرگی با دموهای «مسیر خوشحال» (Happy Path) در زیرساخت‌های هوش مصنوعی دارد. اکثر نسخه‌های ابزاری، دیوارهای معماری را که توسعه‌دهندگان در نهایت به آن‌ها برخورد می‌کنند، پنهان می‌کنند. در این مورد، شرایط رقابتی یک واقعیت ساختاری در مدیریت وضعیت (State Management) در محیط‌های ناهمگام (Asynchronous) است.

برای توسعه‌دهندگانی که بر بستر A2A می‌سازند، این یک هشدار است: اجرای بودجه نمی‌تواند یک پوشش یا Wrapper ساده باشد، بلکه نیازمند هم‌گام‌سازی سخت‌گیرانه وضعیت برای جلوگیری از نشت مالی در محیط‌های با تراکم بالا است. برای علاقه‌مندان به پیاده‌سازی، کد در github.com/AliAbdallah21/a2a-cost-gateway قرار دارد و استدلال‌های طراحی دقیق در فایل arch.md نوشته شده است.

گام بعدی شما

  • اگر از سیستم‌های Agentic با دسترسی به API استفاده می‌کنید، بررسی کنید آیا مکانیسم کنترل هزینه شما در برابر درخواست‌های هم‌زمان (Concurrent) مقاوم است یا خیر.
  • برای پیاده‌سازی لایه‌های نظارتی، به‌جای متغیرهای ساده، از دیتابیس‌هایی با قابلیت Atomic Updates یا قفل‌های توزیع‌شده استفاده کنید.
  • مستندات arch.md در مخزن گیت‌هاب این پروژه را برای درک عمیق‌تر تفاوت بین تخمین هزینه و ثبت هزینه مطالعه کنید.

اما داستان سخت‌افزاری این تحول حتی شگفت‌انگیزتر است — به تحلیل ما درباره‌ی تراشه‌های Blackwell مراجعه کنید.

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

این نقص فنی اعتبار سیستم‌های نظارتی بر هزینه را زیر سوال می‌برد. با تکیه بر تجربه عملی توسعه‌دهندگان، مشخص شد که در مقیاس سازمانی، عدم استفاده از مکانیزم‌های Atomic در کنترل بودجه، ریسک تخلیه سریع منابع مالی را به شدت افزایش می‌دهد.

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

برای توسعه‌دهندگان ایرانی که در حال ساخت سامانه های چندعاملی هستند، این یک هشدار فنی است تا در طراحی لایه پرداخت و کنترل توکن، از متدهای ساده Read-Write پرهیز کرده و از تراکنش‌های اتمیک استفاده کنند.

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

این رخداد ثابت می‌کند که در زیرساخت‌های عامل‌محور، «مدیریت وضعیت» (State Management) اهمیت بیشتری نسبت به خودِ مدل دارد. ما با گذار از مدل‌های چت-بات به سمت سیستم‌های خودکار، دوباره با چالش‌های کلاسیک مهندسی نرم‌افزار دهه ۸۰ میلادی روبرو شده‌ایم؛ جایی که یک خطای میلی‌ثانیه‌ای در هم‌گام‌سازی، می‌تواند منجر به خسارات مالی واقعی شود.

منابع

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

گفتگو

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

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

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

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

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

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

دات‌هوش

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

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