فاز 14 · درس 13

ارکستراسیون گراف وضعیت‌دار: اجرای پایدار و چک‌پوینت در LangGraph

نوع
مفهومی و ساختنی
زمان
حدود 75 دقیقه
زبان‌ها
Python (stdlib)
پیش‌نیاز
فاز 14 · بخش 01 (حلقه‌ی ایجنت)، فاز 14 · بخش 12 (الگوهای گردش کار)
یک نقشه‌ی مسیر مکانیکی و نورانی شامل ایستگاه‌های متصل به هم با گوی‌های نشان‌دهنده‌ی موقعیت ذخیره‌شده و مسیرهای انشعابی
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفهوم اصلی
  4. گراف
  5. اجرای پایدار
  6. استریمینگ
  7. انسان در چرخه
  8. حافظه
  9. سه توپولوژی اصلی
  10. خطاهای رایج در این الگو
  11. پیاده‌سازی از صفر
  12. استفاده از ابزارهای واقعی
  13. خروجی این درس
  14. تمرین‌ها
  15. اصطلاحات کلیدی
  16. برای مطالعه‌ی بیشتر

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

راهکار استاندارد برای حل این چالش، نگاه به ایجنت به‌عنوان یک ماشین وضعیت (state machine) است. در این الگو، وضعیت به‌صورت یک ساختار داده‌ی نوع‌دار و درجه‌یک مدیریت می‌شود و بعد از اتمام کار هر گره، یک نقطه‌ی بازرسی یا چک‌پوینت (checkpoint) از کل داده‌ها ذخیره می‌گردد. در صورت بروز هرگونه قطعی شبکه یا خطای غیرمنتظره، سیستم دقیقاً از آخرین گامِ موفق و با همان حافظه از سر گرفته می‌شود.

در این درس ساختار پایه‌ای ارکستراسیون وضعیت‌دار، اجرای پایدار (durable execution)، جریان داده‌ها و توپولوژی‌های مختلف نظیر سوپروایزر و سوارم را بررسی می‌کنیم و سپس یک موتور گراف کامل با چک‌پوینت‌گیری را بدون وابستگی اضافه و صرفاً با پایتون استاندارد پیاده‌سازی می‌نماییم.

ایجنت یک ماشین وضعیت (state machine) است؛ گره‌ها تابع‌اند؛ یال‌ها همان جابه‌جایی‌ها هستند؛ وضعیت هم بعد از هر گره چک‌پوینت می‌شود. با این ساختار، بعد از هر خرابی دقیقاً از آخرین چک‌پوینتِ موفق کار را ادامه دهید. در سال 2026، مرجع پیاده‌سازی این الگوی ارکستراسیونِ سطح‌پایین و وضعیت‌دار (stateful)، کتابخانه‌ی LangGraph است.

اهداف یادگیری

  • تشریح مدل هسته‌ی LangGraph: ماشین وضعیت با وضعیت نوع‌دار (typed state)، گره‌های تابعی، یال‌های شرطی، و چک‌پوینت‌های پس از اجرای هر گره.
  • نام بردن از چهار قابلیتی که در مستندات رسمی برجسته شده‌اند: اجرای پایدار (durable execution)، استریمینگ، انسان در چرخه، و حافظه‌ی جامع.
  • توضیح سه توپولوژی ارکستراسیون که LangGraph پشتیبانی می‌کند: سرپرست (supervisor)، همتا‌به‌همتا یا سوارم (peer-to-peer / swarm)، و سلسله‌مراتبی (hierarchical با زیرگراف‌های تو‌در‌تو).
  • پیاده‌سازی یک گراف وضعیت با کتابخانه‌ی استاندارد پایتون، با وضعیت نوع‌دار، یال‌های شرطی، و چرخه‌ی چک‌پوینت/ادامه‌ی اجرا (checkpoint/resume).

صورت مسئله

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

پاسخ معماری LangGraph به این مسئله روشن است: وضعیت، یک شیء نوع‌دار درجه‌یک است؛ تغییراتش کاملاً صریح‌اند؛ و بعد از هر گره، چک‌پوینت ذخیره می‌شود. ادامه‌ی کار هم صرفاً با یک فراخوانیِ load_state(session_id) انجام می‌گیرد.

مفهوم اصلی

گراف

یک گراف از اجزای زیر تشکیل می‌شود:

  • نوع وضعیت (State type): یک دیکشنری نوع‌دار (یا مدل Pydantic) که هر گره آن را می‌خواند و تغییر می‌دهد.
  • گره‌ها (Nodes): توابع خالص با ساختار (state) -> state_update. این به‌روزرسانی‌ها پس از بازگشت تابع، با وضعیت ادغام (merge) می‌شوند.
  • یال‌ها (Edges): جابه‌جایی‌های مستقیم یا شرطی بین گره‌ها.
  • ورودی و خروجی: گره‌های نگهبانِ START و END که مرزهای گراف را مشخص می‌کنند.

مثال: ایجنتی با گره‌های classify، refund، bug، sales و done؛ یک جریان کاریِ مسیریابی در قالب گراف.

اجرای پایدار

بعد از بازگشت هر گره، محیط اجرا وضعیت را سریال‌سازی کرده و در یک چک‌پوینتر (SQLite، Postgres، Redis یا سفارشی) می‌نویسد. اگر در گام N خطایی رخ دهد، محیط اجرا با resume(session_id) کار را از گام N+1 با همان وضعیت دقیق از سر می‌گیرد.

مستندات LangGraph صراحتاً به مشتریان سازمانی معتبری اشاره می‌کنند که این قابلیت برایشان حیاتی است: Klarna، Uber و J.P. Morgan. ادعای اصلی بر سر ظاهر گراف نیست؛ بلکه این است که ساختار گراف به همراه چک‌پوینت‌گیری، هزینه‌ی بازیابی پس از خرابی را بسیار ارزان و کم‌هزینه می‌کند.

استریمینگ

هر گره می‌تواند خروجی جزئی (partial output) تولید کند. گراف تغییراتِ هر گره (per-node-delta) را به شکل استریم به فراخواننده تحویل می‌دهد تا رابط کاربری هم‌زمان با اجرای گراف به‌روز شود.

انسان در چرخه

بررسی و دستکاری وضعیت در فاصله‌ی بین اجرای گره‌ها. شیوه‌های پیاده‌سازی: توقف پیش از یک گره‌ی حساس، ارائه‌ی وضعیت به کاربر انسانی، اعمال تغییرات او، و سپس ادامه‌ی اجرا. از آنجا که وضعیت از قبل سریال‌سازی شده، چک‌پوینتر پیاده‌سازی این سناریو را بسیار ساده می‌کند.

حافظه

کوتاه‌مدت (درون یک اجرا — تاریخچه‌ی مکالمه در دل وضعیت) و بلندمدت (میان اجراهای گوناگون — ماندگار به‌کمک چک‌پوینتر به همراه یک مخزن ذخیره‌سازی بلندمدت مجزا). LangGraph از طریق ابزارها با سیستم‌های حافظه‌ی خارجی (مانند Mem0 یا سیستم‌های سفارشی) یکپارچه می‌شود.

سه توپولوژی اصلی

  1. سرپرست (Supervisor): یک مدل زبانی مسیریاب مرکزی که کار را به ایجنت‌های فرعی تخصصی محول می‌کند. متد create_supervisor() در بسته‌ی langgraph-supervisor این نقش را بر عهده دارد (هرچند تیم LangChain در سال 2026 توصیه می‌کند برای کنترل بیشتر روی بستر متنی، این کار مستقیماً از طریق فراخوانی ابزار انجام شود).
  2. سوارم / همتا‌به‌همتا (Swarm / peer-to-peer): ایجنت‌ها مستقیماً و از طریق ابزارهای مشترک دست‌به‌دست می‌شوند؛ بدون نیاز به هیچ مسیریاب مرکزی.
  3. سلسله‌مراتبی (Hierarchical): سرپرست‌هایی که سرپرست‌های زیردست را مدیریت می‌کنند؛ این الگو در قالب زیرگراف‌های تو‌در‌تو پیاده می‌شود.

خطاهای رایج در این الگو

  • چک‌پوینت‌های بیش از حد کوچک: اگر فقط نوبت‌های گفت‌وگو ذخیره شوند، وضعیت ابزارها و داده‌های ذخیره‌شده در حافظه بازیابی‌ناپذیر می‌مانند. باید کل وضعیت سریال‌سازی شود.
  • گره‌های غیرقطعی (Non-deterministic): ادامه‌ی اجرا فرض می‌کند ورودی‌های یکسان گره خروجی وضعیت یکسانی تولید می‌کنند. متغیرهایی مثل دانه‌های تصادفی (random seeds)، ساعت سیستم و پاسخ ای‌پی‌آی‌های خارجی حتماً باید ثبت و کنترل شوند.
  • استفاده‌ی بیش از حد از یال‌های شرطی: گرافی که تک‌تک یال‌هایش شرطی باشند، ماشین وضعیتی می‌سازد که دیگر نمی‌توان رفتارش را تحلیل و بررسی کرد. ترجیحاً از زنجیره‌های خطی با انشعاب‌های انگشت‌شمار استفاده کنید.
گراف دارای وضعیت (STATEFUL)برای پیش‌روی گام‌به‌گام بکشید
STATEFUL GRAPHA stateful graph models an agent as nodes connected by edges, threading one shared state object through every node. Each node reads the state, does its work, and writes back. Conditional edges branch on the state, so a failed grade can loop back to rewrite instead of finishing. The graph makes control flow explicit and the state inspectable at every step.STARTبازیابیتولیدارزیابیبازنویسیgrade=fail
یک گراف دارای وضعیت، ایجنت را به‌صورت گره‌هایی متصل با یال‌ها مدل‌سازی می‌کند و یک شیء وضعیت مشترک را از میان تمام گره‌ها عبور می‌دهد. هر گره وضعیت را می‌خواند، کارش را انجام می‌دهد و تغییرات را بازمی‌نویسد. یال‌های شرطی بر اساس وضعیت branch می‌کنند، بنابراین یک ارزیابی ناموفق می‌تواند به‌جای پایان، به بازنویسی بازگردد. گراف جریان کنترل را صریح و وضعیت را در هر گام قابل‌بررسی می‌کند.

پیاده‌سازی از صفر

فایل code/main.py یک گراف وضعیت‌دار را با کتابخانه‌ی استاندارد پایتون پیاده می‌کند:

  • State — دیکشنری نوع‌داری شامل messages، step، route، output و human_approval.
  • Node — شیء فراخوان‌پذیری (callable) که وضعیت را می‌گیرد و یک دیکشنریِ به‌روزرسانی برمی‌گرداند.
  • StateGraph — شامل گره‌ها، یال‌ها، یال‌های شرطی، به همراه متدهای run و resume.
  • SQLiteCheckpointer (نسخه‌ی شبیه‌سازی‌شده در حافظه) — وضعیت را پس از هر گره سریال‌سازی می‌کند؛ با متد load(session_id) هم آن را برمی‌گرداند.
  • یک گراف نمونه: classify -> branch(refund / bug / sales) -> human gate -> send.

اجرای کد:

python3 code/main.py

ردگیری محاسبات نشان می‌دهد که اجرای اول در مرحله‌ی بررسی انسانی متوقف می‌شود، وضعیت در دیتابیس ماندگار می‌گردد و سپس با ادامه‌ی اجرا (resume)، خروجی نهایی تولید می‌شود.

استفاده از ابزارهای واقعی

  • LangGraph — گزینه‌ی مرجع و آماده‌ی محیط پروداکشن. می‌توانید از create_react_agent یا create_supervisor استفاده کنید، یا گراف اختصاصی خودتان را بسازید.
  • AutoGen نسخه 0.4 (درس 14) — جایگزینی مبتنی بر مدل اکتور (actor model) برای سناریوهای با هم‌زمانی بالا.
  • Claude Agent SDK (درس 17) — بستر آزمایشیِ مدیریت‌شده با مخزن داخلی ذخیره‌سازی نشست‌ها.
  • پیاده‌سازی سفارشی — زمانی که به کنترل دقیق روی ساختار وضعیت یا زیرساخت چک‌پوینتر نیاز دارید.

خروجی این درس

سند outputs/skill-state-graph.md یک گراف وضعیت شبیه به معماری LangGraph تولید می‌کند که می‌توان آن را به هر محیط اجرایی دلخواهی منتقل کرد؛ درحالی‌که قابلیت‌های چک‌پوینت‌گیری و ادامه‌ی اجرا از قبل در آن تعبیه شده‌اند.

تمرین‌ها

  1. یک یال شرطی از classify به end اضافه کنید تا وقتی میزان اطمینان دسته‌بندی پایین‌تر از آستانه بود فعال شود. کاری کنید اجرای فرایند پس از تعیین دستیِ route توسط انسان ادامه یابد.
  2. ماکِ حافظه‌ایِ شبه-SQLite را با یک چک‌پوینتر واقعی SQLite جایگزین کنید. سربار ناشی از سریال‌سازی را در هر گام اندازه بگیرید.
  3. یال‌های موازی بسازید: دو گره به‌طور هم‌زمان اجرا شوند و خروجی‌شان با یک کاهنده‌ی (reducer) سفارشی ادغام گردد. وضعیت تغییرناپذیر (immutable) در اینجا چه مزیتی ایجاد می‌کند؟
  4. مستندات langgraph-supervisor را مطالعه کنید. کُد نمونه‌ی ساده را با create_supervisor بازنویسی کنید. شکل ردگیری محاسبات (trace) را در دو حالت مقایسه نمایید.
  5. قابلیت استریمینگ را اضافه کنید: هر گره حین اجرا خروجی جزئی وضعیت را yield کند. این تغییرات جزئی را به محض رسیدن چاپ کنید.

اصطلاحات کلیدی

اصطلاح در گفتار عامیانه معنای دقیق فنی
گراف وضعیت (State graph) «ایجنت به‌عنوان ماشین وضعیت» وضعیت نوع‌دار + گره‌ها + یال‌ها + کاهنده‌ها
چک‌پوینتر (Checkpointer) «محیط ماندگارسازی داده» وضعیت را بعد از هر گره سریال‌سازی می‌کند؛ ادامه‌ی اجرا را ممکن می‌سازد
کاهنده (Reducer) «ادغام‌کننده‌ی وضعیت» تابعی که وضعیت فعلی را با به‌روزرسانیِ ارسالی از گره ترکیب می‌کند
یال شرطی (Conditional edge) «انشعاب (branch)» یالی که با یک تابع روی وضعیت انتخاب می‌شود
زیرگراف (Subgraph) «گراف تو‌در‌تو» گرافی که خودش به‌عنوان یک گره درون گرافی دیگر قرار می‌گیرد
اجرای پایدار (Durable execution) «ادامه بعد از خرابی» شروع دوباره از آخرین گره‌ی موفق با وضعیت دقیقاً یکسان
سرپرست (Supervisor) «مدل زبانیِ مسیریاب» توزیع‌کننده‌ی مرکزی کارها میان ایجنت‌های فرعی تخصصی
سوارم (Swarm) «ایجنت‌های نظیربه‌نظیر» ایجنت‌ها با ابزارهای مشترک دست‌به‌دست می‌شوند؛ بدون مسیریاب مرکزی

برای مطالعه‌ی بیشتر

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسفریم‌ورک LangGraph چه چیزی را به‌عنوان واحد اصلی ایجنت در نظر می‌گیرد؟
  2. پیش از درساجرای بادوام (durable execution) چه مشکلی را حل می‌کند؟
  3. حین درسکدام‌یک از موارد زیر جزو سه توپولوژی پشتیبانی‌شده در LangGraph نیست؟
  4. حین درسچرا گره‌ها باید قطعی (deterministic) باشند تا فرآیند ازسرگیری به‌درستی کار کند؟
  5. حین درسیال شرطی (conditional edge) چیست؟
  6. پس از درساگر چک‌پوینت‌ها بیش از حد کوچک باشند چه مشکلی پیش می‌آید؟
  7. پس از درسانسان در چرخه (Human-in-the-loop) چگونه در معماری LangGraph پیاده می‌شود؟

سؤالات متداول

منظور از اجرای پایدار (Durable Execution) در ایجنت‌های هوشمند چیست؟

روشی از اجرا که در آن وضعیت ایجنت پس از هر گام ذخیره می‌شود تا در صورت توقف، خطا یا نیاز به تایید کاربر، پردازش بتواند دقیقاً از آخرین گره موفق ادامه یابد و نیازی به اجرای مجدد از گام اول نباشد.

چه تفاوتی میان الگوی Supervisor و Swarm در ارکستراسیون چند ایجنتی وجود دارد؟

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

چرا ذخیره‌سازی متن مکالمات به‌تنهایی برای چک‌پوینت‌گیری ایجنت کافی نیست؟

زیرا اگر فقط پیام‌های چت ذخیره شوند، وضعیت ابزارها، متغیرهای محیطی و داده‌های پردازش‌شده در حافظه ثبت نمی‌شوند و سیستم نمی‌تواند پس از خطا وضعیت اجرایی دقیق را بازسازی کند.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.