В понедельник сотрудник отдела закупок просит агента сверить новый прайс-лист поставщика с рыночными ценами и собрать отчёт по позициям, где отклонение выше порога. Агент выполняет задачу за десяток шагов: читает Excel, ищет рыночные цены, считает отклонения, пишет выводы. Через неделю приходит следующий прайс-лист, и задачу нужно повторить.
При повторном запуске агент заново выбирает инструменты и порядок шагов, и за это планирование каждый раз приходится платить токенами и временем. Отчёт приходит в другом формате, потому что модель пишет его с нуля, а иногда в нём пропущен шаг, который агент выполнил неделю назад.
Агентные системы решают эту проблему четырьмя способами, и у крупных вендоров встречаются все четыре.
Кто составляет план при повторном запуске
Способы различаются тем, что система сохраняет после успешного прогона: текст запроса, инструкцию, граф шагов или программу. От этого зависит, кто составляет план при повторе: модель заново или сохранённая структура вне модели.
Чем большая часть плана вынесена из модели, тем меньше токенов уходит на повторный запуск и тем ближе его результат к предыдущему. Платить за это приходится устойчивостью к изменениям во входных данных: зафиксированный план рассчитан на тот вход, под который его составили.
Сколько стоит перепланирование
Агентный прогон устроен как цикл: модель получает контекст, выбирает инструмент, получает результат вызова, и всё это добавляется в контекст следующего шага. Входной контекст растёт с каждым шагом, а модель вызывается последовательно.
Условный расчёт для задачи из примера. Системный промпт с описаниями инструментов занимает 8 000 токенов, каждый шаг добавляет в контекст 1 500 токенов (вызов инструмента и его результат), шагов 10. Суммарный вход по всем вызовам модели в токенах:
Если тот же процесс зафиксирован графом, модель вызывается один раз, в узле анализа, и получает уже собранные данные. При входе в 6 000 токенов разница по входу получается примерно в 25 раз, а 10 последовательных вызовов модели превращаются в один.
Кэширование префикса снижает цену повторяющейся части контекста. Облачные провайдеры тарифицируют кэшированные токены дешевле, а в vLLM Automatic Prefix Caching переиспользует KV-кэш общего префикса и пропускает его повторное вычисление. Число последовательных вызовов и задержка при этом остаются прежними.
Уровень 1. Сохранённый промпт
Система хранит текст запроса и условие запуска. По расписанию или событию она открывает новую сессию агента и передаёт ей этот текст.
ChatGPT: Scheduled Tasks
В документации OpenAI описаны три режима: разовая или повторяющаяся задача по расписанию, мониторинг изменений и задача по событию. Задача по событию состоит из трёх частей, которые пользователь проверяет перед сохранением: триггер, условие и промпт. Триггером служит новое письмо в Gmail (с фильтром по отправителю или теме), сообщение в канале Slack или активность в pull request на GitHub. Такие задачи срабатывают не чаще 30 раз в час и 720 раз в сутки по всем задачам пользователя, несколько событий могут объединяться в один запуск.
Состояние между запусками есть у задач мониторинга: по документации они используют информацию из предыдущих запусков и останавливаются, когда выполнено заданное условие окончания. Действия, которые отправляют сообщения или меняют данные во внешних системах, могут требовать подтверждения, и тогда задача встаёт на паузу до решения пользователя.
Claude: задачи по расписанию в Cowork
В Claude Cowork задачи по расписанию появились в феврале 2026 года. Курс Claude Academy описывает два пути создания: описать задачу с нуля командой /schedule или сначала выполнить её в Cowork, проверить результат и той же командой превратить выполненный процесс в повторяющийся. Во втором случае Claude составляет промпт по выполненной задаче, пользователь просматривает его и подтверждает.
По справке Anthropic каждый запуск идёт отдельной сессией Cowork с теми же возможностями, что у обычной задачи: подключённые инструменты, скиллы, плагины. Состояние между запусками дают проекты Cowork: у проекта есть своя память, и задачи по расписанию внутри проекта видят контекст предыдущих задач.
Процесс фиксируется после успешного выполнения, как и в сценариях Айвы, но формат записи другой: текст, по которому модель на каждом запуске заново составляет план.
Claude in Chrome: запись действий
В расширении Claude для Chrome задачу можно показать вместо описания. Пользователь включает запись, выполняет действия в браузере, и запись сохраняется как шорткат. Тем же механизмом шорткатов сохраняют удачные промпты: их вызывают командой через / или ставят на расписание.
Свойства уровня
При повторе агент проходит весь цикл из раздела про стоимость. Если поставщик переименовал колонку в прайс-листе, агент обработает новую структуру как любой незнакомый файл. Формат результата меняется от запуска к запуску, а качество зависит от того, насколько удачно модель спланировала задачу в этот раз. Чем чаще модель ошибается в многошаговом планировании, тем сильнее расходятся результаты соседних запусков.
Уровень 2. Скиллы
Скилл (Agent Skills) — папка с файлом SKILL.md: в шапке YAML с названием и описанием, ниже инструкция в markdown, рядом при необходимости скрипты, справочные файлы и шаблоны. Формат появился в Claude Code, Anthropic описала его в инженерном блоге и затем опубликовала как открытую спецификацию. Сейчас её поддерживают Codex, ChatGPT, Gemini CLI, GitHub Copilot, Cursor и другие агенты.
price-audit/ ├── SKILL.md ├── scripts/ │ ├── read_price.py │ └── deviation.py └── assets/ └── report.xlsx
Загрузка по уровням
Anthropic называет этот механизм progressive disclosure: скилл попадает в контекст частями, по мере надобности.
Название и описание всех установленных скиллов агент загружает при старте. Спецификация закладывает на это около 100 токенов на скилл.
Тело
SKILL.mdагент читает, когда решает, что задача подходит под описание. Спецификация рекомендует держать его в пределах 5 000 токенов и 500 строк.Справочные файлы и скрипты агент открывает или запускает, когда до них доходит инструкция. Ссылки на файлы спецификация советует держать на одном уровне вложенности от
SKILL.md.
Скрипт выполняется в песочнице, и в контекст попадает только его вывод. Код скрипта токенов не расходует, поэтому детерминированную работу выгодно выносить в скрипты: парсинг файла, расчёты, сборку отчёта по шаблону.
--- name: price-audit description: Сверка прайс-листа поставщика с рыночными ценами. Использовать, когда пользователь присылает прайс-лист и просит найти завышенные позиции. --- # Аудит прайс-листа 1. Прочитай прайс-лист: `python scripts/read_price.py <файл>`. Скрипт вернёт позиции в JSON. 2. Для каждой позиции найди рыночную цену в справочнике закупок. 3. Посчитай отклонения: `python scripts/deviation.py --threshold <порог>`. Порог по умолчанию 15%. 4. Собери отчёт по шаблону assets/report.xlsx: позиция, цена поставщика, рыночная цена, отклонение.
Свойства уровня
Повторный запуск со скиллом — обычный агентный прогон из того же цикла, в котором у модели есть готовая процедура. Порядок шагов, вызов скриптов и толкование инструкции модель выбирает на каждом запуске. Скрипты дают детерминированные участки: на одинаковом входе они возвращают одинаковый результат.
В Claude Cowork первый и второй уровни работают вместе. Задача по расписанию запускает агентный прогон по промпту, а процедуру агент берёт из скилла. Промпт отвечает за то, когда и что запускать, скилл за то, как выполнять.
Скилл переносится между агентами, хранится в git и правится как текстовый файл. Регрессию проверяют прогоном эталонных задач (evals): от запуска к запуску модель может выполнить процедуру по-разному, и это видно только на наборе прогонов. Если в прайс-листе что-то поменялось, агент может молча обойти проблему, и пользователь получит отчёт, собранный иначе, чем в прошлый раз.
Уровень 3. Граф шагов
Задача описывается направленным ациклическим графом (DAG). У каждого узла фиксированы тип, входы и выходы, рёбра описывают зависимости по данным. Граф выполняет движок, модель вызывается только в узлах, где нужна интерпретация данных.
Модель данных
Ниже условная запись сценария сверки прайс-листа. Формат придуман для примера, у каждой платформы он свой, но набор сущностей похож: параметры запуска, триггер, узлы с типами и схемами, ссылки между узлами.
{ "scenario": "price-audit", "version": 3, "trigger": { "type": "schedule", "cron": "0 9 * * 1" }, "params": { "price_list": { "type": "file", "format": "xlsx" }, "report_date": { "type": "date" }, "threshold": { "type": "number", "min": 0, "max": 100, "default": 15 } }, "nodes": [ { "id": "read", "type": "tool", "tool": "spreadsheet.read", "input": { "file": "$params.price_list" }, "output_schema": "PriceRows" }, { "id": "market", "type": "tool", "tool": "procurement.market_prices", "input": { "date": "$params.report_date" }, "output_schema": "MarketPrices" }, { "id": "compare", "type": "compute", "fn": "price_deviation", "input": { "rows": "$read", "market": "$market", "threshold": "$params.threshold" }, "output_schema": "Deviations" }, { "id": "analyze", "type": "model", "prompt": "prompts/analyze.md", "input": { "deviations": "$compare" }, "output_schema": "Analysis" }, { "id": "report", "type": "render", "template": "templates/report.xlsx", "input": { "analysis": "$analyze", "deviations": "$compare", "date": "$params.report_date" } } ] }
Узлы read и market независимы и выполняются параллельно. Узел compare ждёт оба результата. Числа в отчёт попадают из compare, где их считает код, а модель в узле analyze пишет только интерпретацию.
Выполнение
Движок раскладывает граф на слои топологической сортировкой и выполняет узлы одного слоя параллельно. Схематично, с проверками и журналом:
def run_scenario(scenario, params, run_id): validate(params, scenario.params_schema) # вход проверяется до первого шага results = {} for layer in topological_layers(scenario.nodes): outputs = run_parallel( run_node(run_id, node, resolve(node.input, params, results)) for node in layer ) results.update(outputs) return results def run_node(run_id, node, inputs): key = f"{run_id}:{node.id}" if (saved := journal.get(key)) is not None: # перезапуск после сбоя return saved validate(inputs, node.input_schema) output = execute(node, inputs, idempotency_key=key) validate(output, node.output_schema) # ошибка указывает на узел journal.put(key, output) return output
Похоже устроен чекпоинтер LangGraph: он сохраняет состояние на границе каждого шага выполнения (super-step), а результаты узлов, успешно завершившихся в шаге, где упал соседний узел, хранит отдельно как pending writes. При возобновлении эти узлы повторно не выполняются.
Запуск привязывается к версии графа, с которой он начался. Правки создают новую версию и действуют со следующего запуска, поэтому прогон, начатый до правки, доходит до конца по старой.
Детерминизм узла модели
Путь по графу фиксирован, а ответ узла с моделью от запуска к запуску может различаться. Источников разброса три:
сэмплирование при температуре выше нуля;
недетерминизм инференса при температуре 0. Thinking Machines Lab показала, что основная причина в зависимости ядер от размера батча: ядра выбирают порядок редукций по размеру батча, а размер батча на сервере зависит от нагрузки. Лаборатория опубликовала batch-invariant ядра и с ними получила воспроизводимый вывод в vLLM;
обновление модели у провайдера.
Для узлов модели применяют четыре приёма. Ответ ограничивают JSON-схемой через structured outputs: в vLLM это guided decoding на бэкендах xgrammar или guidance, и на каждом шаге генерации модель выбирает только из токенов, допустимых схемой. Числа считают в узлах расчёта и передают модели готовыми. Версию модели фиксируют в описании узла. Температуру ставят в 0, помня, что полной воспроизводимости это не даёт. В результате структура и числа воспроизводятся точно, а текст интерпретации остаётся вариативным.
Как прогон агента превращается в граф
Граф можно нарисовать в редакторе, описать словами или собрать из уже выполненного агентом прогона. Для третьего пути нужна трасса прогона: список вызовов инструментов с аргументами и результатами. Один из способов её обработки:
Удалить из трассы неудачные вызовы, повторы и тупиковые ветки поиска.
Восстановить зависимости по данным: если результат одного вызова попал в аргументы другого, между ними ребро.
Вызовы без взаимных зависимостей поставить в параллельные ветки.
Разделить литералы в аргументах. Значения из сообщения пользователя (файл, дата, порог) становятся параметрами запуска. Значения, которые агент нашёл сам (имя листа, номер колонки), становятся константами графа.
Рассуждения модели между вызовами, от которых зависит результат, вынести в узлы модели с отдельным промптом.
По данным, которые прошли через граф в эталонном прогоне, построить схемы входа для проверки на следующих запусках.
Шаг 4 определяет, насколько сценарий переживёт изменения входа: каждая константа из этого шага — место, где новый файл может разойтись с эталонным.
n8n: AI Workflow Builder
В n8n с октября 2025 года есть AI Workflow Builder. Пользователь описывает задачу словами, система подбирает, размещает и настраивает узлы и дорабатывает граф по следующим запросам. Граф собирает автоматизатор в редакторе воркфлоу, отдельно от инструментов, в которых сотрудники решают повседневные задачи.
Microsoft Copilot Studio: agent flows
Microsoft разделяет в Copilot Studio агентов и потоки (agent flows). Поток — цепочка из триггера и действий, которую Microsoft называет детерминированной. Среди действий есть вызовы LLM: сгенерировать текст, обработать документ, выполнить промпт, вызвать агента. Поток создают в визуальном дизайнере или описанием на естественном языке в одном или нескольких диалогах. Каждое выполненное действие расходует ёмкость Copilot Studio, поэтому стоимость запуска считается по числу шагов.
OpenAI: Agent Builder
В октябре 2025 года OpenAI выпустила AgentKit с Agent Builder, визуальным холстом для многоагентных воркфлоу с версионированием. В нём были узлы агентов, поиска по файлам, MCP, guardrails (проверок входа и выхода) и подтверждения пользователем. В июне 2026 года OpenAI добавила в анонс пометку о том, что сворачивает Agent Builder.
Сценарии в Айве
Айва — корпоративный ИИ-агент для сотрудников компании: ищет по рабочим системам и документам, считает, готовит отчёты и выполняет действия в системах через MCP-инструменты (Model Context Protocol, стандарт подключения инструментов к агентам). Сценарий в Айве — граф, который сотрудник собирает в том же чате, где работает с агентом. Правки он вносит сообщением в чате, и они применяются со следующего запуска.
В терминах модели данных выше сценарий сверки прайс-листа состоит из пяти узлов:
Запуск: по расписанию (понедельник, 9:00) или вручную.
Инструмент: чтение прайс-листа, файл передаётся при запуске.
Расчёт: сверка цен с порогом отклонения из параметров запуска.
Модель: анализ данных, узел ждёт результатов обеих веток.
Результат: отчёт в фиксированном формате.
Файл, дату отчёта и порог пользователь заполняет в форме запуска, граф между запусками остаётся прежним. Перед выполнением Айва проверяет входные данные: если файл или параметры не проходят проверку, сценарий останавливается и выдаёт ошибку.
Что из этого следует на практике:
Порядок шагов и структура отчёта одинаковы на каждом запуске. Текст анализа узел модели генерирует заново, поэтому формулировки и акценты в выводах меняются от запуска к запуску.
Подбор инструментов и планирование выполняются один раз, при сборке сценария. Повторный запуск расходует токены только в узлах модели.
Если проверка отклоняет изменённый вход, сценарий правит человек. Агент с промптом или скиллом в той же ситуации попробовал бы обработать файл.
Процессы, где следующий шаг определяется найденным на предыдущем, в заранее собранный граф укладываются плохо. Такие задачи удобнее оставлять агенту.
Из разобранных систем к сценариям Айвы ближе всего agent flows в Copilot Studio: граф тоже создаётся описанием на естественном языке, а модель работает в отдельных узлах. Различается место сборки. В Copilot Studio поток собирает создатель агента в отдельной среде, в Айве сотрудник собирает сценарий в рабочем чате, из которого потом его и запускает.
Айва работает на моделях, развёрнутых в России: GigaChat, YandexGPT, DeepSeek, Qwen и других. Сценарии мы проектировали из расчёта, что удачный план выгоднее зафиксировать один раз, чем просить модель составлять его на каждом запуске, а модель вызывать только там, где нужна интерпретация данных.
Уровень 4. Код и кэш действий
Агент решает задачу один раз и записывает решение программой, дальше скрипт запускается без модели. Близкий приём — кэш действий: система сохраняет результат каждого шага, найденный моделью, и при повторе проигрывает его без обращения к модели.
Stagehand: кэш с откатом к модели
Stagehand, библиотека для браузерной автоматизации от Browserbase, работает по второй схеме. При первом вызове act() модель получает инструкцию и снимок дерева доступности страницы и возвращает действие: метод (клик, ввод, прокрутка) и селектор. Stagehand выполняет действие детерминированно через Chrome DevTools Protocol и сохраняет его в кэш.
Ключ кэша складывается из инструкции, URL и состояния страницы. Пока ключ совпадает, следующие вызовы проигрывают сохранённый селектор без вызова модели. По документации о кэшировании, если записанный селектор больше не находится, Stagehand возвращается к полному вызову модели.
const stagehand = new Stagehand({ cacheDir: "./stagehand-cache" }); await stagehand.init(); // Первый запуск: модель находит кнопку, действие пишется в кэш. // Следующие запуски: селектор берётся из кэша, модель не вызывается. await stagehand.act("click the login button");
Параметры в Stagehand устроены так же, как в графе. Модель видит имя переменной, а реальное значение подставляется в найденное действие перед выполнением. Значение до модели не доходит, и закэшированное действие подходит для любого значения переменной.
Свойства уровня
Повторный запуск обходится без вызовов модели, и результат воспроизводится полностью. Изменение формата входа ломает скрипт или кэш, а читать и править код может только разработчик. Поэтому такие системы добавляют откат к агенту: если сохранённый шаг не сработал, агент разбирает причину и переписывает шаг. Stagehand делает это на уровне отдельного действия, для скриптов целиком откат строят вручную.
Что происходит при сбое
Громкий отказ, тихая адаптация, пауза
Промпт и скилл при неожиданном входе выполняют задачу любым доступным способом, и о том, что процесс прошёл иначе, пользователь узнаёт только из журнала. Граф с проверкой входа и код останавливаются и сообщают об ошибке: пользователь получает ошибку вместо отчёта, посчитанного по другой логике. Если по отчёту отдел закупок пересматривает цены, ошибка безопаснее. Для разовой справки удобнее адаптация.
Третий вариант: остановиться и спросить человека. Так ведут себя задачи ChatGPT перед действиями, которые отправляют сообщения или меняют внешние данные. В Agent Builder для этого был отдельный узел подтверждения, в графах его ставят перед действиями с внешними последствиями.
Повторы при временных сбоях
Ошибки узла делятся на два класса. Временные (сетевой таймаут, ответ 429 от провайдера модели, недоступность внешней системы) лечатся повтором с экспоненциальной задержкой. Ошибки данных (вход не прошёл схему, ответ модели не прошёл валидацию) повтором не лечатся, и движок сразу отдаёт их пользователю с указанием узла. Исключение — ответ модели, не прошедший схему: его разумно повторить один-два раза, потому что следующий ответ может пройти.
Повторные побочные эффекты
Журнал из схемы выполнения даёт гарантию at-least-once. Если узел создал задачу в трекере, а процесс упал до записи в журнал, при перезапуске узел выполнится второй раз. Так же устроен Temporal: результат завершённой activity записывается в историю событий и при восстановлении берётся оттуда, повторно activity не выполняется, но до записи результата возможен повтор. Поэтому Temporal рекомендует делать activities идемпотентными.
Защита строится на трёх механизмах:
идемпотентные ключи: операция получает ключ вида
run_id:node_id, и внешний сервис распознаёт повторный вызов. Например, Stripe сохраняет код ответа и тело первого запроса с данным ключом и на повторные запросы с тем же ключом возвращает тот же результат, включая ошибки 500;журнал выполненных шагов: при перезапуске движок берёт результаты завершённых узлов из журнала и продолжает с места сбоя;
durable execution: движок сохраняет состояние после каждого шага и после падения процесса восстанавливает выполнение с последнего сохранённого. Так работают Temporal и durable execution в LangGraph.
Идемпотентный ключ работает, только если его поддерживает внешняя система. Для систем без такой поддержки инструмент перед действием проверяет, нет ли уже результата: ищет задачу с тем же внешним идентификатором или письмо с тем же заголовком в отправленных.
В Айве каждый вызов MCP-инструмента записывается в журнал для разбора инцидентов и контроля действий агента.
Сравнение
Подход |
Примеры |
Что хранится |
Кто выбирает шаги при повторе |
Вызовы модели при повторе |
Если вход изменился |
Кто и как правит |
|---|---|---|---|---|---|---|
Промпт |
ChatGPT Scheduled Tasks, задачи по расписанию в Claude Cowork, шорткаты Claude in Chrome |
Текст запроса или запись действий |
Модель, заново |
На каждом шаге |
Агент обрабатывает новый вход, формат результата меняется |
Пользователь, правкой текста |
Скилл |
Agent Skills в Claude, Codex, ChatGPT |
Инструкция и скрипты |
Модель, по инструкции |
На каждом шаге, скрипты без модели |
Агент обрабатывает новый вход, может отступить от процедуры |
Автор markdown и скриптов |
Граф |
n8n, agent flows в Copilot Studio |
Граф узлов |
Движок |
В узлах модели |
Ошибка узла |
Автоматизатор или создатель агента, в редакторе или описанием |
Граф |
Сценарии в Айве |
Граф узлов и параметры запуска |
Движок |
В узлах модели |
Проверка входа, ошибка |
Сотрудник, через чат |
Код и кэш |
Stagehand, скрипт от агента |
Код или кэш действий |
Код |
При промахе кэша |
Откат к модели или ошибка |
Разработчик |
Как выбирать
Задачи, которые повторяются редко и каждый раз немного по-разному, удобнее отдавать промпту или скиллу: перепланирование на каждом запуске обходится дешевле поддержки графа. Регулярный процесс со стабильным входом, где получателям важен постоянный формат результата, стоит фиксировать графом, а числа в нём считать кодом. Код и кэш действий оправданы, когда повторов тысячи, а вход строго формализован. Если процесс выполняет действия во внешних системах, идемпотентные ключи и журнал шагов нужны на любом уровне.