تصور کنید یک عامل هوش مصنوعی را برای پروژهای چندروزه به کار گرفتهاید، اما در روز سوم، مدل تمام پیشرفتهای روز اول را فراموش کرده و دوباره از نقطه صفر شروع میکند. این کابوس برای توسعهدهندگانی که بر روی عاملهای پیچیده کار میکنند، یک واقعیت فنی است، نه یک احتمال. در حالی که محیطهای اجرای پایدار (Durable Execution Runtimes) عکسهایی از وضعیت گراف را ذخیره میکنند، آنها نمیتوانند تأیید کنند که آیا دنیای خارجی — مانند یک پایگاهداده یا یک مخزن کد — واقعاً بازتابدهنده پیشرفتی است که عامل ادعا میکند.
بسیاری از برنامهنویسان تصور میکنند با استفاده از یک محیط اجرای پایدار، مسئلهی ذخیرهسازی وضعیت حل شده است. اما حقیقت این است که ذخیره کردن یک عکس از وضعیت داخلی گراف، با این حقیقت که آیا تغییرات در دنیای واقعی اعمال شده است، تفاوت دارد. وقتی عاملها به این شکل رشتهی افکار خود را گم میکنند، تغییر محیط اجرا معمولاً مشکلی را حل نمیکند. همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، شکاف بین «ادعای مدل» و «واقعیت سیستم» جایی است که توهمات عملیاتی شکل میگیرند.
صفحه مقایسهی خودِ LangChain، ابزارهای LangGraph، Temporal و Inngest را در یک گروه به عنوان محیطهای اجرا (Runtimes) قرار میدهد. وظیفه اصلی آنها اجرای پایدار، استریمینگ، مدیریت انسان-در-حلقه (human-in-the-loop) و پایداری است. در LangGraph، یک نقطه بازرسی (Checkpoint) وضعیت گراف را در هر «ابر-گام» (super-step) برای هر رشته (thread) ذخیره میکند. با این حال، اینکه چه چیزی در آن وضعیت قرار میگیرد و آیا آن اطلاعات درست هستند یا خیر، کاملاً بر عهده توسعهدهنده است.
اکثر توسعهدهندگان پس از پیادهسازی یک محیط اجرا، تصور میکنند پایداری مسئلهای حلشده است. اما برای عاملهایی که روزها در حال اجرا هستند، شکاف بین عکس وضعیت داخلی و واقعیت خارجی، نقاط شکست بحرانی ایجاد میکند. این موضوع بهویژه زمانی صادق است که عاملها باید کار را بین جلسات مختلف منتقل کنند یا از کرشهای حین اجرا بازیابی شوند.
طبق یک گزارش فنی از dev.to که در ۱۰ اکتبر ۲۰۲۶ منتشر شد، چهار شکاف اصلی در سیستمهای نقاط بازرسی استاندارد وجود دارد. این شکافها با استفاده از Flowness شناسایی شدند؛ ابزار مهارکننده (harness) عاملی که نویسندگان در کارهای تحویلی خود از آن استفاده کردهاند.
۱. مشکل تحویل (Handoff)
اولین شکاف، مشکل «تحویل» است؛ جایی که یک جلسه جدید شروع میشود و یا از یک تصویر قدیمی و منقضیشده ادامه میدهد و یا کارهایی را که جلسه قبلی هنوز در اختیار دارد، دوباره تکرار میکند. برای رفع این مشکل، توسعهدهندگان باید یک رکورد تحویل در وضعیت گراف یا یک ذخیرهساز (store) نگهداری کنند. این چالش شباهت زیادی به مشکلاتی دارد که مکانیزم اجاره دسترسی در Critic برای حل قطع ارتباطات به کار گرفت تا تداوم عملیات حفظ شود.
- راهکار: در ابتدای هر گرهی که هنگام شروع جلسه جدید اجرا میشود، یک بررسی (check) فراخوانی کنید.
- مکانیزم: رکورد تحویل باید وظایف در جریان (
in_flight) شامل مالک، گام، مصنوعات (artifact) و موانع، وضعیت «انتظار برای بعدی» (next_waits_on) و مراجع خاص (refs) مانند بستههای وظیفه یا نسخههای گزارش را ردیابی کند. - اعتبارسنجی: سیستم باید مالکیت را برای هر وظیفه بررسی کند، نه برای هر خط پروژه. دانستن اینکه «یک نفر روی بخش مجوزها کار میکند» کافی نیست؛ سیستم باید بداند که آیا یک وظیفه تست خاص توسط کسی گرفته شده است یا خیر.
در یک بررسی موردی در ۲ سپتامبر ۲۰۲۶ روی یکی از بازسازیها با استفاده از ابزار Flowness، رکوردها نشان دادند که در حالی که ۲۹ مورد از ۳۲ وظیفه موفق بودند، یک نیاز (requirement) شکست خورد زیرا هیچ تکوظیفهای آن را در تمام چرخه حیات دنبال نکرده بود. این ثابت میکند که خودِ «هدف» باید یک شیء پایدار باشد که به هر مرحله ارث برسد، به جای اینکه به حافظه جلسه تکیه شود.
۲. شکاف تأیید (Verification)
دومین شکست، ادعای «انجام شد» (Done) است. یک گره ممکن است پیام موفقیت چاپ کند و با کد ۰ خارج شود، اما فایل هدف یا سرویس خارجی بدون تغییر باقی بماند. نقطه بازرسی فقط ثبت میکند که یک گره بازگشته است؛ اما نمیتواند مخزن یا فایلی را که گره ادعای تغییر آن را دارد، ببیند. این نوع توهمات عملیاتی دقیقاً همان چیزی است که در مورد دو باگ سیستمی که یک عامل را ۱۹ روز در حلقه تکرار انداخت تحلیل کردیم، جایی که مدل موفقیت کاذبی را گزارش میکرد.
- راهکار: پیادهسازی مکانیزم بازخوانی (Read-back). برای هر گام با اثر خارجی، مشخص کنید چه چیزی را در کجا مشاهده کنید.
- فرآیند: گام را اجرا کنید، سپس یک خوانش تازه از هدف انجام دهید (نه از همان فرآیندی که تغییر را ایجاد کرده است).
- برچسبگذاری: بهجای یک تیک سبز واحد، وضعیتها را به صورت برچسبهای مجزای «تلاش» (Attempt)، «اثر» (Effect)، «پذیرش» (Adoption) و «تأیید» (Acceptance) گزارش کنید.
دادههای حاصل از ۱۷ سناریوی واقعی در Flowness نشان داد که برچسبهای سادهی ترمینال در ۱۰ مورد اشتباه بودهاند. در یک مطالعه مجزا روی ۹ عملیات، خروجی استاندارد (stdout) و کدهای خروج تنها در ۴ مورد با وضعیت واقعی مطابقت داشتند، در حالی که یک «قرارداد اثر» با بازخوانی در هر ۹ مورد دقیق بود. برای درک بهتر این نیاز به دقت، میتوان به متدولوژی جدید سنجش کیفیت مدلها اشاره کرد که تلاش میکند جلوی دروغهای احتمالی در بنچمارکها را بگیرد.
۳. بازیابی و بازپخش (Recovery and Replay)
سوم، علامت «بازپخش» (Replay) باعث شمارش یا اقدام دوگانه پس از یک کرش میشود. چون LangGraph گرهها را پس از یک نقطه بازرسی انتخابی دوباره اجرا میکند (سفر در زمان)، فراخوانیهای LLM و درخواستهای API دوباره ارسال میشوند. همچنین توقفها (Interrupts) گره خود را دوباره اجرا میکنند، به این معنی که اثرات جانبی قبل از توقف باید «همتوان» (idempotent) باشند.
- ریسک: در حالت «پایداری خروجی» (exit durability mode)، وضعیتهای میانی ذخیره نمیشوند و کرشهای حین اجرا غیرقابل بازیابی هستند.
- راهکار: نتیجه و شواهد حذف تکرار (deduplication) را در یک نوشتن اتمیک (atomic write) ذخیره کنید و سپس نشانگر پیشرفت را در آخرین مرحله جلو ببرید.
- مثال: با استفاده از آفستهای مصنوعی (۴۰، ۸۰، ۱۲۰)، یک کرش قبل از حرکت مکاننما ممکن است شمارش ۲ را باقی بگذارد. یک شروع مجدد که سه سیگنال را دوباره میخواند باید به ۳ ختم شود (۲+۰+۰+۱)، در حالی که افزودن ساده و ناشیانه منجر به نتیجه اشتباه ۵ (۲+۳) میشود.
۴. توقفها و استقرارها (Pauses and Deploys)
در نهایت، توقفها و استقرارها میتوانند اجراهای در جریان را بشکنند. شما ممکن است سیستم را متوقف کنید در حالی که کارها همچنان در حال رسیدن هستند، یا اصلاحی را منتشر کنید که رفتار اجراهای فعال را تغییر دهد.
- مدیریت توقف: کنترلهای مجزایی برای ارسالهای جدید (new dispatch)، کارهای در جریان، مسیرهای بررسی/اصلاح و گشتهای هماهنگکننده تعریف کنید. هنگام شروع مجدد، قبل از بازگرداندن ارسالها، آنچه در زمان توقف رسیده است را بخوانید تا از تکرار کاری که کسی در اختیار دارد جلوگیری شود.
- ریسک استقرار: LangGraph آخرین نسخه گراف را روی تمام رشتهها اعمال میکند، حتی آنهایی که از یک نقطه بازرسی بازمیگردند. تغییر نام یا حذف یک گره در حالی که رشتهها در آن نقطه متوقف شدهاند، باعث شکست بازگشت (resume) میشود.
- راهکار: در ابتدای رشته، یک نسخه رفتاری (مثلاً
flow_version) روی وضعیت بزنید و از منطق شاخهای برای مدیریت متفاوت رشتههای قدیمی نسبت به جدید استفاده کنید.
در یک مورد توقف در ۱۵ سپتامبر، رکوردها نشان دادند که دو مجری در جریان، بخش فعلی خود را تمام کردند، ارسالهای جدید به صفر رسید و مسیرهای بررسی و اصلاح فعال ماندند.
برای توسعهدهندگان، این به معنای تغییر مدل ذهنی از «ذخیره وضعیت» به «تأیید اثرات» است. فارغ از اینکه از LangGraph، Temporal یا Inngest استفاده میکنید، بار مسئولیت قابلیت اطمینان از زیرساخت به طراحی وضعیت منتقل شده است. با treating هر گام به عنوان چیزی که احتمالاً دو بار اجرا میشود و هر «موفقیت» را به عنوان فرضیهای که نیاز به تأیید دارد، توسعهدهندگان میتوانند عاملهایی بسازند که واقعاً در استقرارهای چندروزه دوام بیاورند.
گام بعدی شما
- هر گرهی که اثر خارجی (مانند نوشتن در دیتابیس) دارد را با یک مرحله «بازخوانی و تأیید» مجهز کنید.
- برای جلوگیری از اجرای تکراری APIها، از شناسههای Idempotency در درخواستهای خود استفاده کنید.
- نسخه گراف (
flow_version) را به وضعیت هر رشته اضافه کنید تا استقرار نسخههای جدید باعث شکست رشتههای فعال نشود.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو