Skip to main content

Durable Execution для агентів: п'ята дисципліна, до якої ваш .NET-бекграунд вас уже підготував

Спека — це правда. Контекст — складання. Evals — доказ. OpenSpec — операційна система. А субстрат під усім цим — те, що тримає багатокроковий агент живим через ретраї, рестарти й людину, яка пішла з роботи о 17:00, не підтвердивши approval-чекпоінт — це durable execution. Будь-який .NET-інженер, який хоч раз відвантажував MassTransit-сагу, уже розуміє цей патерн; ось як він лягає на серйозних AI-агентів у 2026, і чому саме це та п'ята дисципліна, що нарешті закриває арку.

Durable Execution для агентів: п'ята дисципліна, до якої ваш .NET-бекграунд вас уже підготував

Два тижні тому агент, якого я ганяв сорок п’ять секунд, упав, бо downstream HTTP-запит відвалився за таймаутом. Оркестратор мовчки ретрайнув із самого початку, і другий прогін нагалюцинував половину того, що перший прогін уже виконав — включаючи запис рядка в продакшен-базу, який нам потім довелося вручну звіряти з eval-трейсом, який ми встигли загубити. Фікс — три рядки коду в чекпоінт-хелпері, який я мав написати в перший же день. Урок — що я два роки думав про агентів як prompt-інженер, а десять років — як distributed-systems-інженер, і distributed-systems-інженер увесь цей час тихо бурчав із задніх рядів.

Це п’ятий пост в арці, яку я пишу. Context engineering був рантайм-дисципліною — як ти збираєш входи моделі на кожному кроці. Spec-driven development — design-time-філософія: твоя кодова база — це не код, а спеки. Evals — шар верифікації: якщо шипиш AI-фічу без evals, у тебе не продукт, а демо з користувачами. OpenSpec — операційна система, яка запускає всі три на brownfield-команді, не розвалюючись. Кожен із цих постів неявно припускав агента, який доходить до кінця задачі. У продакшені агенти не доходять. Вони падають посеред tool-call. Вони виїдають context window на середині long-horizon задачі. Їх ретрайнить оркестратор, який не знає, які сайд-ефекти вже сіли. Вони стопоряться на human-in-the-loop чекпоінті, про який людина забуває на три дні.

Durable execution — це субстрат під рештою чотирьох дисциплін. Це п’ята, і без неї арка завжди була неповною.

Ось що я попросив би будь-якого senior .NET-інженера помітити до того, як пост почнеться всерйоз: ви вже розумієте durable execution. Ви це вже шипили — на території csharp-to-claude-agents-path, ще до того, як LLM стали продуктом. Кожна MassTransit-сага, яку ви писали, була durable execution. Кожен MediatR-pipeline з compensation handler — durable execution. Кожна Hangfire-задача з idempotency key — durable execution. Кожен NServiceBus-контракт, у якому розрізнялися OnceOnly і AtLeastOnce, — durable execution. Патерн ідентичний. Змінилося одне: учасник став недетермінованим і пече токени. Це не нова проблема — це нові обмеження для старої проблеми, і в старої проблеми є відпрацьовані патерни.

Що значить “durable” для агента, конкретно

Durable execution — це виконання, чий прогрес переживає смерть процесу, що його запустив. Гепнули контейнер, рестартнули оркестратор, поміняли модель, відвалилася мережа — workflow продовжується з останнього закомміченого чекпоінта, не дублює сайд-ефекти, не переупорядковує їх і приходить до того ж результату, до якого прийшов би, якби нічого не падало.

Дві речі ламають наївний ретрофіт цієї ідеї на агентний loop, який під неї не проектувався. Перше: агенти стохастичні — повторення того ж промпта при тій же температурі на тій же моделі часто дає інший tool-call, тому “просто ретрайнемо агента з початку” гарантує інші сайд-ефекти на другому прогоні. Друге: агенти дорогі за токенами — програвати історію на сорок тисяч токенів щоразу на resume — це питання бюджету, а не інженерії, і фіндиректор рано чи пізно це помітить. Durable execution для агентів — це дисципліна проектування loop так, щоб жодна з цих двох речей не вистрелила у продакшені.

Лексика лягає один-в-один на workflow-engine-концепції, які .NET-інженер уже розуміє:

Workflow / saga концептЕквівалент для агентаЦіна пропуску
Idempotent activityIdempotent tool callПодвійні списання, дублікати рядків у БД, той самий reconcile-пейджер, який у мене загорівся два тижні тому
Детермінізм + replayЧекпоінт плану + replay з останнього закомміченого крокуТокени, які неможливо виправдати; reasoning-трейси, які на кожен ретрай виглядають як новий агент
Saga compensation handlerВідкат tool-call (refund, delete, retract)Половинчасто застосовані зміни; ручне розгрібання в ops; втрата довіри downstream-систем
Workflow-as-state-machineПлан-як-state-machine, агент — учасникОркестратор не знає, де агент у плані; не може ні відновити, ні спостерігати
OnceOnly-семантикаDedupe за tool_use_id на межі activityТули стріляють двічі на ретраї; race conditions; eventual-consistency-сюрпризи
Human-in-the-loop чекпоінтApproval як durable waitWorkflow стопориться; людина забуває; прогін помирає; губляться три дні накопиченого state

Якщо ви прочитали цю таблицю і не побачили нічого нового — це й є пойнт. Anthropic Agent SDK уже шипить durable run primitive, який саме цю форму й оголює: dedupe за tool_use_id, чекпоінти на кожен plan-step, resumable conversation state через vendor-side ретраї. Inngest Agent Kit, AI-розширення Temporal, agent-рантайм Restate, Cloudflare Workflows, AWS Step Functions — усі зійшлися до приблизно одного й того ж примітиву за останні дванадцять місяців. Конвергенція відбулася швидко, бо патерн, що лежить в основі, уже був стандартом поза AI. Вендори наздоганяють те, що saga-orchestration-спільнота робить із початку 2010-х.

Чотири failure mode не-durable агентів

Кожен агент, не спроектований під durable execution, у продакшені вмирає одним із чотирьох способів. У мене шрам по кожному.

1. Crash посеред tool-call. Агент викликає tool, який повертається за десять секунд. На шостій секунді контейнер витісняється, функція відвалюється за таймаутом, або сам model API віддає 502 через бліп вище. Сайд-ефект tool’у застосувався чи ні? Якщо на стороні, що приймає, немає dedupe-таблиці за tool_use_id, дізнатися неможливо. Ретрайнеш — подвійне списання. Не ретрайнеш — мовчки втрачаєш роботу. Коректної відповіді на цьому шарі немає — коректною відповіддю було зробити tool ідемпотентним на етапі проектування. Якщо винести з усього посту одне правило: кожен tool, що мутує state поза контекстом агента, зобов’язаний приймати idempotency key, і система-приймач зобов’язана перевіряти його до застосування зміни.

2. Виїдений context window посеред прогону. Агент сорок п’ять кроків усередині long-horizon задачі. System prompt — дві тисячі токенів; накопичена історія tool-call’ів — сорок тисяч. Наступному planning-кроку потрібно вісім тисяч токенів reasoning. Модель повертає refusal, обрізаний план чи — що гірше — впевнений план на контексті, який модель мовчки суммарізувала не на тому шарі. Це те, що Context Engineering називає “вийшли за working set” — тут стопориться більшість продакшен-агентів. Фікс — на runtime-шарі: агресивна компакція історії на чітких межах чекпоінтів, зі стислим summary, записаним у durable storage, щоб відновлений прогін гідратувався з того ж summary, а не реплеїв сиру історію.

3. Retry storm на неідемпотентних тулах. Агент упав посередині. Оркестратор ретрайнить. Ретрай потрапляє в tool, який попередній прогін уже викликав. Tool неідемпотентний. Другий прогін породжує третій сайд-ефект. До моменту, коли ви це помічаєте, у вас три Stripe-charge’и, два Slack-повідомлення й один продакшен-рядок БД у трьох екземплярах. Механізм ретраю зробив гірше, не краще — агент не відновився, оркестратор просто помножив шкоду. Це та failure mode, яка навчила saga-orchestration-спільноту запікати idempotency keys у контракт, а не прикручувати їх потім.

4. Зависла human-in-the-loop пауза. Агент дійшов до approval-чекпоінта. Пінг у Slack. Людина на обіді, у літаку чи — найчастіше — відкрила повідомлення, вирішила відповісти пізніше й забула. Процес агента продовжує крутитися, чекає синхронної відповіді, пече ресурси, тримає відкритим мережевий сокет. Або гірше: процес агента виходить, поки чекає, людина підтверджує через три години, і відповідь летить у Slack-тред, який ніхто не слухає. Патерн у не-LLM saga-території — моделювати human-in-the-loop pause як durable wait: workflow засинає, resume-сигнал — durable callback, і workflow байдуже — resume може прийти через три секунди чи через три дні. Той же патерн переноситься напряму.

Кожне з цих — failure mode рантайм-субстрату, не моделі. Кидати на це розумнішу модель не лагодить жодне з них.

П’ять правил, які я вистраждав, відвантажуючи durable-агентів

Ці правила я б вписав у project.md будь-якого нового репозиторію, що шипить агентів у 2026. Вони не оригінальні — це те, що workflow-engineering-спільнота каже вже десятиліття, перекладене на агентний лексикон.

Правило 1: idempotent tools за замовчуванням

Кожен tool, що мутує state поза локальним контекстом агента, приймає idempotency key як first-class параметр, і система-приймач перевіряє його до застосування зміни. У найпростішій реалізації key — це tool_use_id зі tool-call-схеми Anthropic/OpenAI; для тулів, що охоплюють кілька ходів чи компонують інші тули, — стабільний хеш plan-step ID. Винятків немає. Ціна реалізації — один зайвий параметр на кожному tool; ціна пропуску — той самий продакшен-reconcile, з якого починався цей пост.

Чому це не обговорюється. Тули, які сьогодні виглядають “read-only”, завтра ретрофітяться кешуванням чи телеметрією — і стають side-effecting тим способом, який агентний loop побачити не може. Зробіть усю поверхню тулів ідемпотентною на рівні контракту — і більше ніколи не доведеться переглядати, які тули “є чи не є”; усі є.

Правило 2: чекпоінт після кожного зовнішнього запису

План агента розбитий на кроки. Після кожного кроку, який виробляє зовнішній сайд-ефект — запис у БД, виклик API третьої сторони, повідомлення в чергу — оркестратор коммітить durable-чекпоінт. Чекпоінт містить: step ID, виконаний tool-call, повернений результат і хеш working context’у агента в цей момент. На resume оркестратор реплеїть план з останнього закомміченого чекпоінта, а не з початку.

Сховище чекпоінтів не зобов’язане бути складним. Postgres-таблиці з унікальним обмеженням на (workflow_id, step_id) достатньо. Cloudflare Workflows API оголює це як step.do(). Anthropic Agent SDK — як callback checkpoint. Temporal — як activity history. Виберіть один і стандартизуйте по всій кодовій базі.

Правило 3: ніколи не відновлюйтеся у застарілий план

Найважчий баг у durable-агентів — resume-into-staleness. Агент упав на сьомому з дванадцяти кроків плану. План був згенерований із контексту, що включав дані — скажімо, snapshot інвентарю, — які на той момент були свіжими. Через три години workflow відновлюється. Snapshot інвентарю тепер неправильний, але план про це не знає, і агент впевнено йде з восьмого кроку проти світу, що змінився.

Правило: будь-який елемент плану, що залежить від зовнішнього state, має freshness-бюджет, і resume за межами бюджету тригерить re-plan з останнього доброго чекпоінта, а не сліпе продовження. Freshness-бюджет — частина плану, а не частина runtime-конфігу. Агент вирішує, що свіже; оркестратор це забезпечує.

Правило 4: бюджетуйте токени на resume, а не лише на старті

Відновлений агент успадковує context window, який виростив оригінальний прогін. Якщо не компактувати агресивно на межах чекпоінтів, кожен resume дорожчий за попередній, і workflow, ретрайнутий чотири рази, на п’ятій спробі може коштувати більше токенів, ніж сумарно перші чотири. Це та failure mode, яка перетворює “добре налаштований eval-suite” на “тикет із фінансів”.

Дисципліна — компактувати історію розмови на кожному durable-чекпоінті: складати сирі ходи в структуроване summary, що живе в payload чекпоінта, і регідратувати зі summary на resume, а не з сирих ходів. Claude API робить це простим через prompt caching: summary чекпоінта стає кешованим префіксом, а лише нові working-ходи сидять поза кешем. Важіль на 80% вартості, про який я писав у csharp-to-claude-agents-path, — це саме цей важіль; більшість команд просто не застосовують його до відновлених прогонів, лише до свіжих.

Правило 5: workflow — джерело істини, агент — учасник

Це правило saga-orchestration-спільнота засвоїла п’ятнадцять років тому, і LLM-екосистема все ще наздоганяє. Workflow — це не “те, що запускає агент”; workflow — це контракт, а агент — учасник у ньому. Агент може бути замінений на іншу модель, іншого вендора чи детерміновану функцію, і workflow продовжить працювати. State живе у workflow; в агента немає свого durable state.

Якщо ви ловите себе на міркуванні “що агент знає на сьомому кроці” чи “що агент пам’ятає з третього”, — ви вже програли. Агент знає те, що workflow йому розповість на сьомому кроці, крапка. Агент пам’ятає те, що лежить у payload чекпоінта на третьому кроці, крапка. “Пам’ять” агента — це state workflow, матеріалізований у промпт на кожному кроці. Ось і вся ментальна модель.

Де це все ще розвалюється

Чесна частина. Durable execution розв’язує три з чотирьох продакшен-failure-mode чисто. Четверта — і кілька суміжних — залишаються відкритими проблемами, на які в мене немає чистих відповідей. Якщо, прочитавши наступні чотири абзаци, ви зрозуміли, що відповіді є, — напишіть пост і пришліть лінк; я його прилінкую.

Довгий human-in-the-loop — це UX-проблема, перевдягнута в інфраструктурну. Durable waits розв’язують workflow-сторону коректності: workflow засинає, resume-сигнал приходить, workflow продовжує. Але людська сторона не вирішена. Через три дні в паузі людина забула контекст, який зробив approval-питання осмисленим. Подача контексту заново на resume — це generation-проблема, не retrieval-проблема: треба перескласти workflow для людини, а не просто показати, де зупинилися. У 2026 я не бачив, щоб хтось вирішив це добре; найближче — трактувати resume-сповіщення як окремий generation-прохід, що синтезує why-this-matters-контекст заново.

Cross-vendor swap моделі посеред прогону теоретично можливий, практично болючий. Можна компактнути контекст, персистнути й регідратити проти іншої моделі на resume — Opus на Sonnet за cost-причинами, Claude на GPT за capability-причинами. На практиці різниця у форматах промптів, діалектах tool-call-схем і model-specific behavioral quirks означає, що відновлений прогін поводиться інакше, навіть якщо контекст “той самий”. Інфраструктура може свапнути модель. Агент свап може не пережити. Сьогодні я трактую mid-run vendor swap як code smell, не feature.

Retry-семантика для LLM-as-judge неідемпотентна. Evals на LLM-judge-шарі недетерміновані за побудовою. Якщо durable workflow ретрайнить judge-крок, друге судження може розійтися з першим. Чесна відповідь — або snapshot’ити judgment у payload чекпоінта (тоді ретрай реплеїть закешований judgment, не модель), або коммітити на рівні “ми спитали judge один раз”, з усіма failure-mode-наслідками, що з цього випливають. Я зараз роблю перше і не дуже радий цьому.

Вартість самої durable-execution інфраструктури. Кожен чекпоінт — запис. Кожен resume — читання. Кожен ретрайнутий workflow платить storage і read двічі. Для більшості продакшен-агентів оверхед в однозначних відсотках, але для high-fanout multi-agent-систем математика жорсткіша. Я не бачив чистого розбору “коли durable execution занадто дорогий, щоб окупитися”; моя евристика — будь-який workflow зі зовнішнім сайд-ефектом варто чекпоінтити, а workflow, який лише генерує текст без сайд-ефектів, ймовірно, ні.

Кар’єрний кут: durable-agent engineer — наступна названа роль

Патерн по всій арці один. Context engineering став названою роллю; eval engineer стає. Spec author — наступна роль, на яку бренд робить ставку. Durable-agent engineer — це роль після неї, і в неї найглибший moat для senior .NET-бекграунду.

Junior (нуль-два роки після школи). Вивчайте інструменти. Claude Agent SDK і Anthropic SDK шиплять durable-run-примітиви на поверхні; читати їх доки — найдешевший спосіб увійти. Якщо .NET-а чи distributed-systems-фону немає — пройдіть RAG and Agents, там покриті agent-loop-основи, без яких durable execution як концепт не складеться. Зберіть один маленький durable-агент end-to-end (workflow + idempotent tool + checkpoint store + resume) — і у вас буде портфоліо-кейс, якого майже в жодного junior’а у 2026 насправді немає.

Mid (три-сім років). Овнайте субстрат. Виберіть оркестратор, на якому ваша команда стандартизується — Temporal, Inngest, Restate, Cloudflare Workflows чи native runtime Agent SDK — і овнайте його по всій кодовій базі. Напишіть конвенції: яка форма idempotency-key, яка схема payload чекпоінтів, яка retry-політика. Mid-level-інженер, який тихо пише durable-execution-секцію команди в AGENTS.md, через вісімнадцять місяців стає незамінним. Якщо фон — .NET, AI-Powered .NET Development — це місце, де agent-loop / saga-orchestration / ASP.NET-Core-інтеграція складаються в одну лінію; це природний крок після стандартної backend-програми.

Senior і staff (вісім років і більше). Трактуйте durable execution як архітектурне питання, а не вибір бібліотеки. Цікаві питання на цьому рівні: як durable-агенти поєднуються з наявними message-broker-контрактами? Як мігрувати brownfield-кодову базу з агентами з “agent loop крутиться in-process” на “agent loop — це workflow”? Як ставити token-бюджет, який переживе ретраї? Як durable-execution-шар взаємодіє зі шаром evals, коли judgment сам — workflow-крок? Це ті питання, за якими в будь-якого senior .NET-інженера, що мігрує в AI-інженерію, є прайор-арт; усвідомлення, що прайор-арт переноситься, — це high-leverage-хід. Курси Spec-Driven Development і OpenSpec Mastery дають методологічний фрейм, щоб ці рішення були захищеними перед рештою команди.

Закриття арки

Арка завжди була з п’яти дисциплін, не чотирьох. Context engineering — як збирати входи. Spec-driven development — як виражати намір. Evals — як доводити, що вихід той, що хотіли. OpenSpec — операційна система, яка запускає всі три на живій команді. Durable execution — субстрат, який тримає все це живим у вівторок удень, коли блипає мережа, модель віддає 502 посеред tool-call, а людина йде додому до того, як схвалити чекпоінт.

Кожен senior .NET-інженер, що читає цей пост, уже шипив цей патерн. Залишилося його назвати — і вбудувати в agent loop у перший день, а не пригвинчувати після першого продакшен-інциденту. Ціна впровадження правил у нову агентну кодову базу — день. Ціна ретрофітнути їх після першого reconcile-пейджера — тиждень прибирання й повільне відновлення довіри з системами, у які пишеш.

Субстрат — durable. Агент — учасник. Workflow — істина. Spec, context, evals, OpenSpec і durable execution — це арка з п’яти дисциплін. Усе інше — інтерфейс над нею.

Поділитися
X LinkedIn
Наступний крок

Закріпіть цю тему на курсі

Структурований шлях від теорії до production-коду — з проєктами та код-рев'ю.

Просунутий 7 тижнів

Побудова агентів на Claude Agent SDK

Проєктуйте та запускайте власних AI-агентів на Claude Agent SDK. Будуйте agent loops, визначайте інструменти, керуйте пам'яттю і суб-агентами, оцінюйте поведінку та деплойте мультиагентні системи для реальних інженерних задач.

Дізнатися більше
Середній 8 тижнів

AI-розробка на .NET

Інтегруйте AI у .NET-застосунки через OpenAI та Azure OpenAI API. Будуйте інтелектуальні функції: чат, резюмування, embeddings, семантичний пошук і RAG-пайплайни — на C# і ASP.NET Core.

Дізнатися більше
Середній 6 тижнів

Spec-Driven Development: від філософії до робочої моделі

Навчіться писати специфікації, яким агенти справді коряться, випускати код як кеш довговічної специфікації і керувати тріадою spec→context→evals на реальних кодових базах. Vendor-agnostic, tool-agnostic, brownfield-ready — методологічний курс, що поєднується з будь-яким agentic-стеком.

Дізнатися більше
Просунутий 8 тижнів

Побудова LLM-застосунків: RAG та агенти

Будуйте production AI-застосунки на основі великих мовних моделей. Vector databases, RAG, автономні агенти, виклик інструментів, оцінка та патерни деплою.

Дізнатися більше
Середній 6 тижнів

Розробка на Claude API: production AI-застосунки з Anthropic SDK

Опануйте Claude API від Anthropic: messages API, prompt caching, tool use, extended thinking, стрімінг, batch-обробка, files, citations та vision. Будуйте економічні production AI-функції в будь-якому backend.

Дізнатися більше
Просунутий 6 тижнів

OpenSpec на практиці: production spec-driven workflows для AI coding agents

Операціоналізуйте SDD з OpenSpec — open-source spec framework, що ставиться до специфікацій як Git до коду. Опануйте /opsx:propose, /opsx:apply та /opsx:archive на справжній brownfield-кодовій базі. CI-гейти, мульти-інженерна колаборація, retrofitting legacy-специфікацій і workflow-ритуали, що приживаються.

Дізнатися більше
Oleksii Anzhiiak

Автор статті

Oleksii Anzhiiak

Софтвер-архітектор, Senior .NET інженер та співзасновник

Олексій Анжіяк — софтвер-архітектор, Senior .NET інженер та співзасновник ToyCRM.com і ProfectusLab. Має понад 15 років досвіду у розподілених системах, хмарній інфраструктурі, high-load backend-розробці та identity-платформах. Проєктує складні архітектури, створює безпечні системи автентифікації та розробляє сучасні освітні програми, які допомагають студентам досягати реальних кар'єрних результатів.

LinkedIn

Рекомендуємо подивитися

Підібрані сторонні відео за темою. Відкриваються на YouTube.

~2:00:00
Середній AI Engineer (Thariq Shihipar, Anthropic)

Claude Agent SDK — повний воркшоп (Thariq Shihipar, Anthropic)

Практичний воркшоп Anthropic зі створення продакшн-агентів на Claude Agent SDK — tool use, sub-agents, hooks, MCP-сервери і патерни, що працюють поза рамками демо.

~8:00:00
Середній AI Engineer (AI Engineer World's Fair)

AI Engineer World's Fair 2024 — кейноути і трек CodeGen

Кейноут-стрім найбільшої технічної AI-конференції 2024. Зріз стану AI-інженерії — що випустили, що спрацювало, що ні — безпосередньо від команд, які це будують.

~6:00:00
Середній AI Engineer (AI Engineer World's Fair)

AI Engineer World's Fair 2025 — кейноути Дня 1 і трек MCP (з командою Anthropic MCP)

Кейноут MCP-треку з командою Anthropic. Якщо хочете зрозуміти, чому в 2025 MCP став індустріальним стандартом підключення LLM до інструментів — це найкраще першоджерело.

Зв'язатися з нами