تصور کنید یک برنامهنویس در تیمی کوچک است که برای اولین بار یک عامل هوشمند را به محیط عملیاتی میبرد؛ او فکر میکند یک جدول ساده در پایگاهداده برای تأیید اقدامات کافی است، اما خیلی زود متوجه میشود که واقعیت بسیار تلختر است. اگر امروز از یک سیستم تأیید ساده استفاده میکنید، احتمالاً به زودی با بحران دادههای منقضیشده یا نبودِ سوابق دقیق برای پاسخ به مشتریان مواجه خواهید شد.
یک صف تأیید ابتدایی را میتوان در یک بعدازظهر با یک نمونه Postgres و یک وبهوک Slack ساخت، اما این نسخهٔ مینیمال بهندرت در محیط تولید (Production) دوام میآورد. هزینهٔ واقعی در شش ماه آینده ظاهر میشود؛ یعنی زمانی که موارد استثنایی — مانند تأییدهای قدیمی یا نبودِ لاگهای بازرسی — شروع به شکستن سیستم میکنند.
برای تیمهایی که عاملهای (Agents) خودکار را مستقر میکنند، شکاف عمیقی میان یک دموی موفق و یک محصول قابلاتکا وجود دارد. اکثر توسعهدهندگان با ایجاد جدولی شروع میکنند که در آن وضعیت برابر با «در انتظار» است، اما سریعاً میفهمند که سیستمهای «انسان در حلقه» (Human-in-the-loop) — شبیه به یک ایستگاه بازرسی که هر کامیون باید توسط یک افسر بررسی شود تا تصادفی رخ ندهد — با اصطکاکهای عملیاتی زیادی همراه هستند. این چالشها نشان میدهد که چرا صرفاً دادن دسترسی به ابزارها بدون یک گیت تأیید در زمان اجرا منجر به شکست عملیاتی میشود. برای مثال، بازبینیکنندهای پیشنویس را ویرایش میکند، اما عامل نسخهٔ اصلی و قدیمی را اجرا میکند، یا مشتری میپرسد چه کسی این اقدام را تأیید کرده و تنها رکورد موجود، یک پیام دفنشده در تاریخچهٔ اسلک است.
همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، اعتماد به خروجیهای مدل بدون لایههای حفاظتی، ریسکهای سیستمی ایجاد میکند.
نسخهٔ مینیمال بهطور فریبندهای کوچک است. با این حال، نسخهای که در برابر یک عامل واقعی در محیط تولید دوام بیاورد، به سطحی از استواری نیاز دارد که اکثر تیمها آن را دستکم میگیرند. طبق یک راهنمای فنی که در ۴ سپتامبر ۲۰۲۶ توسط dev.to منتشر شد، یک صف در سطح تولید برای جلوگیری از شکست سیستمی به چندین مؤلفه غیرقابلجایگزین نیاز دارد:
مؤلفههای ضروری یک صف تأیید
- ذخیرهسازی با قابلیت انقضا: جلوگیری از تأییدهای «کهنه»؛ جایی که انسان به پیشنویسی دو روز پیش پاسخ مثبت میدهد، در حالی که آن درخواست دیگر مرتبط نیست.
- توزیع اعلانها (Fan-out): اطمینان از اینکه تأییدها نادیده گرفته نمیشوند و از طریق اسلک، اعلانهای Push یا پیامک ارسال میشوند، نه فقط ایمیل.
- ویرایش سپس تأیید: بازبینیکنندگان بیشتر از آنکه درخواست را رد کنند، آن را بازنویسی میکنند. این کار نیازمند سیستمی است که تفاوت (Diff) بین نسخه اصلی و ویرایششده را ردیابی کند.
- ردپای بازرسی (Audit Trails): ایجاد یک رکورد دائمی برای انطباق قانونی و پشتیبانی مشتری که فراتر از تاریخچهٔ سادهٔ چت باشد.
- محدودسازی نرخ (Rate Limiting): جلوگیری از اشباع شدن صف توسط عاملهایی که در حلقهٔ تلاش مجدد (Retry Loop) گیر کردهاند.
- حفاظهای اجرای یکتا (Idempotency): تضمین اینکه تلاش مجدد برای یک درخواست تایم-اوت شده یا تأیید دوجانبه، منجر به ارسال دو بارهٔ یک ایمیل نشود.
ساخت این ویژگیها در داخل سازمان، منجر به ایجاد یک سرویس کوچک میشود که نیاز به چرخش تیم پشتیبانی (On-call) برای زیرساختی دارد که اصلاً محصول اصلی شرکت نیست. یک طرح دادهٔ داخلی معمولاً در عرض چند هفته از یک بررسی وضعیت ساده به یک شیء پیچیده تبدیل میشود که editedPayload و expiresAt و auditEvents را ردیابی میکند.
واقعیتِ یک طرح دادهٔ «ساده»
شش هفته پس از شروع توسعه، یک رابط TypeScript برای یک اقدام در انتظار معمولاً به این شکل در میآید:
interface PendingAction {
id: string;
kind: string;
originalPayload: Record<string, unknown>;
editedPayload?: Record<string, unknown>;
editDiff?: string;
status: 'pending' | 'approved' | 'rejected' | 'expired';
expiresAt: Date;
notifiedVia: ('slack' | 'email' | 'sms')[];
executedAt?: Date;
auditEvents: { actor: string; action: string; at: Date }[];
}
این کد تنها ۲۰٪ از مسیر آسان است. ۸۰٪ باقیمانده شامل نقاط انتهایی (Endpoints) تعاملی اسلک، کرونجابهای پاکسازی انقضا و نمای بازرسی مدیران است؛ بخشهایی که به بار نگهداری تبدیل میشوند و هیچکس برای مدیریت آنها استخدام نشده است.
سرویس Impri یک API فراهم میکند که این زیرساخت را به سه فراخوانی اصلی کاهش میدهد: ارسال اقدام، نظارت بر تصمیم و گزارش نتیجه. این ابزار با مدیریت سمت سرور برای انقضا و پیشنویسهای قابل ویرایش، نیاز توسعهدهندگان به نوشتن کرونجابهای دستی را از بین میبرد.
با استفاده از SDK این سرویس، توسعهدهنده میتواند یک اقدام با مقدار expires_in مشخص (مثلاً ۸۶,۴۰۰ ثانیه) ایجاد کند و فیلدهای خاصی را به عنوان editable علامتگذاری نماید. سیستم سپس نسخه ویرایششده توسط انسان را مدیریت کرده و به عامل اجازه میدهد final_preview.body را به جای پیشنویس اصلی اجرا کند.
با این حال، خرید یک سرویس، تمام مسئولیتها را حذف نمیکند. کار یکپارچهسازی — یعنی اتصال فراخوانی نهایی ارسال و اطمینان از اینکه عامل نمیتواند گیت تأیید را دور بزند — همچنان بر عهده توسعهدهنده است. Impri اقدام پیشنهادی را ذخیره کرده و تصمیم را نگه میدارد، اما محتوا تولید نمیکند و فراخوانی نهایی را اجرا نمینماید.
چه زمانی باید سیستم را داخلی ساخت؟
خرید سرویس همیشه راهکار درست نیست. ساخت داخلی در موارد زیر منطقی است:
- محصول اصلی: اگر در حال ساخت یک پلتفرم نظارت (Moderation) هستید، نه اینکه فقط از یکی استفاده کنید.
- ارکستراسیون پیچیده: نیاز به شاخهبندی، مراحل چندگانه یا جابهجایی بین عاملها (که وظیفه موتورهای گردشکار مانند Temporal یا n8n است).
- انطباق سختگیرانه: زمانی که دادهها هرگز نباید از زیرساخت داخلی خارج شوند.
برای اکثر تیمها، موازنه بین شش هفته تلاش مهندسی و یک API مدیریتشده است. در برخی سناریوهای پیشرفتهتر، میتوان به جای تأییدات کلی، از سیستمهای درجهبندی ریسک برای بهینهسازی جریان تاییدات استفاده کرد تا اصطکاک عملیاتی کاهش یابد. هدف این است که «نقطه گلوگاه» در گردشکار عاملمحور از یک بار نگهداری به یک زیرساخت قابلاتکا تبدیل شود.
گام بعدی شما
- اگر سیستم تأیید داخلی دارید، لیست تمام اقداماتی که به دلیل فراموشی کاربر «منقضی» شدهاند اما در دیتابیس «در انتظار» ماندهاند را استخراج کنید.
- برای هر اقدام حساس، یک فیلد
audit_logاضافه کنید که نام تأییدکننده و زمان دقیق را ثبت کند تا از وابستگی به تاریخچهٔ چتها摆 خلاص شوید. - بررسی کنید آیا عامل شما در صورت بروز خطا در API تأیید، وارد حلقهٔ ارسال پیامهای تکراری (Spam) میشود یا خیر.
اما مدیریت این صفها تنها بخشی از چالش است؛ برای درک نحوه مدیریت حافظه در مقیاس بزرگ، به تحلیل ما دربارهی پروتکل MCP مراجعه کنید.




گفتگو