В понедельник сотрудник отдела закупок просит агента сверить новый прайс-лист поставщика с рыночными ценами и собрать отчёт по позициям, где отклонение выше порога. Агент выполняет задачу за десяток шагов: читает 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, скрипт от агента |
Код или кэш действий |
Код |
При промахе кэша |
Откат к модели или ошибка |
Разработчик |
Как выбирать
Задачи, которые повторяются редко и каждый раз немного по-разному, удобнее отдавать промпту или скиллу: перепланирование на каждом запуске обходится дешевле поддержки графа. Регулярный процесс со стабильным входом, где получателям важен постоянный формат результата, стоит фиксировать графом, а числа в нём считать кодом. Код и кэш действий оправданы, когда повторов тысячи, а вход строго формализован. Если процесс выполняет действия во внешних системах, идемпотентные ключи и журнал шагов нужны на любом уровне.
Автор: NoHatus


