Графовая инженерия для AI-агентов: узлы, рёбра и стоп-условия
Знакомый сценарий: вы даёте Claude Code или Codex нетривиальную задачу, агент какое-то время работает, а где-то посередине тихо теряет нить. Объявляет победу, не проверив результат. «Чинит» падающий тест его удалением. Забывает про ограничение, о котором вы говорили двадцать минут назад. Дело не в том, что модель «ухудшилась» посреди сессии. План, проверки и решения о следующем шаге спрятаны в одном длинном постоянно растущем контекстном окне — и ничто не заставляет их оставаться явными.
Графовая инженерия (graph engineering) — про то, как вынести эти решения наружу, в структуру. Это новейший слой в стеке практик 2026 года, и он отвечает на вопрос, который ни промпты, ни циклы, ни harness по отдельности не закрывают: когда у задачи несколько подвижных частей, кто решает, что произойдёт дальше, и как доказать, что всё случилось правильно?
Что такое графовая инженерия
Графовая инженерия — это практика представления AI-воркфлоу в виде явного графа вместо одного агента, который сам решает, что делать дальше. Каждая единица работы становится узлом (node) с одной задачей. Каждый переход между единицами — ребром (edge) с явным правилом. Информация, которая должна пережить переход от узла к узлу, путешествует как разделяемое состояние (shared state), а не хранится в надежде, что модель всё запомнила. И прежде чем воркфлоу объявит себя завершённым, он обычно обязан пройти через гейт (gate): набор тестов, валидатор или человека.
Сдвиг тонкий, но важный. В цикле одного агента модель сама решает, когда поиска достаточно, когда доказательств набралось и когда задача «сделана». Эти решения живут внутри её рассуждений, а значит, снаружи невидимы и неверифицируемы. В системе на основе графа те же решения вынесены в саму структуру. Агент внутри узла может свободно рассуждать о своей ограниченной задаче — он просто больше не решает в одиночку, что делает дальше вся система.
Место среди остальных слоёв
Эти четыре подхода — не конкурирующие тренды, а слои, которые складываются друг на друга:
- Prompt engineering — что вы говорите модели в отдельном ходе.
- Loop engineering — как модель итерирует: plan, act, verify, retry, stop. Термин распространился в середине 2026 года, когда Борис Черни (Anthropic) и Питер Стейнбергер (OpenClaw) начали описывать, как проектируют цикл вокруг агента, а Адди Османи из Google дал практике имя.
- Harness engineering — среда, внутри которой живёт цикл: права доступа, управление контекстом, файлы прогресса, git-чекпоинты. Именно это позволяет агенту пережить многочасовую или многодневную сессию, не забывая, где он остановился.
- Graph engineering — топология, соединяющая несколько узлов: агентов, инструменты, валидаторов или людей. К ней приходят, когда одного цикла уже недостаточно.
Четвёртый слой не отменяет первые три: хорошо построенный узел графа — обычно маленький, аккуратно обустроенный цикл сам по себе. И стоит сказать прямо: ни одно из этих четырёх названий — не официальный стандарт от вендора. Это ярлыки, на которых в этом году сошлось сообщество, чтобы описать паттерны, которые люди и так строили руками. Ярлык новый, идея — разбить задачу на куски, которые можно реально проверить, — старая.
Строительные блоки
Графовый воркфлоу каждый раз собирается из одних и тех же четырёх частей:
- Узлы — ограниченные единицы работы с одной ответственностью: спланировать изменение, написать код, прогнать тесты. Узел, пытающийся делать три вещи сразу, — верный признак, что граф нужно дробить дальше.
- Рёбра — решают, что происходит дальше, и делают это явно: «если тесты прошли — переход в Done; если упали — переход в Repair». Правило живёт в самом графе, а не в абзаце системного промпта, который модель при каждом перечитывании может истолковать по-своему.
- Разделяемое состояние — переносит информацию между узлами: план, дифф, вывод тестов, счётчик ретраев. Вместо надежды, что модель помнит решение, принятое три шага назад, состояние записывается и передаётся дальше явно.
- Гейты — проверки, которые результат обязан пройти, прежде чем граф объявит его готовым: автотесты, линтер, второй агент в роли ревьюера или человек — для всего, где ставка высока.
Рабочий пример
Вот форма, которую чаще всего принимает кодинг-граф. Задача входит в узел Plan, который разбивает запрос на конкретные шаги. Implement пишет код. Test запускает тесты. Если тесты прошли, ребро ведёт в Done, и изменение уходит. Если упали, ребро ведёт в Repair, который чинит конкретный отказ и возвращает управление в Test — а не в самое начало.
Именно это обратное ребро — самая важная деталь. Обычный агентный цикл после упавшего теста обычно просто продолжает с того места, где остановился контекст, — так появляются агенты, которые в пятый раз объясняют проблему самим себе. Путь отказа в графе скоуплен: узел Repair знает только о конкретной переданной ему ошибке, делает минимальное исправление и снова входит в Test. Ретрай дёшев, потому что узел, который его выполняет, делает одну узкую работу.
В виде кода тот же граф выглядит примерно так. Это иллюстрация, не привязанная к точному синтаксису конкретной библиотеки, но форма — узлы, рёбра, условная ветка — совпадает с тем, что вы найдёте в большинстве инструментов графовой оркестровки:
graph.add_node("plan", plan_fn)
graph.add_node("implement", implement_fn)
graph.add_node("test", test_fn)
graph.add_node("repair", repair_fn)
graph.add_node("done", done_fn)
graph.add_edge("plan", "implement")
graph.add_edge("implement", "test")
graph.add_conditional_edge("test", check_result,
{"pass": "done", "fail": "repair"})
graph.add_edge("repair", "test")
Чем это отличается от «просто цикла побольше»
Соблазнительно получить тот же результат более хитрым одноагентным циклом с длинным системным промптом, где описан каждый случай. На практике это ломается по той же причине, что длинные развесистые функции в обычном коде: каждая добавленная ветка повышает вероятность, что модель выберет не ту, и ни одну из веток нельзя протестировать независимо. Граф заставляет ветки быть явными и даёт каждой свою, гораздо меньшую задачу.
Кроме того, граф открывает то, что один цикл структурно не умеет:
- Параллельный fan-out. Независимые узлы — скажем, обновление трёх не связанных между собой модулей — могут работать одновременно, а не последовательно, если каждый владеет своими файлами. Разработчики, координирующие несколько кодинг-агентов в одном репозитории, сходятся на том же решении классической проблемы merge-конфликтов: явное владение файлами, чтобы два узла никогда не трогали один код.
- Верификация не моделью, оценивающей саму себя. Отдельный узел — иногда второй агент с другими инструкциями — проверяет результат. Разделение maker и checker ловит ошибки, которые агент пропускает, проверяя сам себя.
- Человеческий чекпоинт как настоящий узел графа, а не прерывание. Изменения с высокими ставками маршрутизируются к человеку до срабатывания ребра в Done — так же, как в любом другом пайплайне с ревью.
Где это уже применяют
Самый частый способ строить такие графы сегодня — библиотеки state-графов вроде LangGraph, где узлы и рёбра объявляются явно, а фреймворк берёт на себя исполнение и передачу состояния между ними. Те же идеи встречаются и вовсе без фреймворка: разработчики запускают несколько кодинг-агентов бок о бок в одном репозитории, закрепляя за каждым файлы по конвенции, чтобы их работа не пересекалась. Это графовая инженерия дисциплиной, а не библиотекой. Подборка паттернов оркестрации задач в виде графа собрана в репозитории graph-engineering.
Паттерн обобщается и за пределы кода. Исследовательский ассистент, который ищет информацию, пишет черновик, сам фактчекает его и только потом отправляет отчёт, — это та же структура из четырёх частей: узел, ребро, состояние, гейт. Просто в каждом узле сидит другая работа.
Когда граф действительно нужен
Не каждой задаче нужен граф. Если работу можно описать одной ясной инструкцией и один хорошо обустроенный цикл способен проверить собственный вывод — такой вариант проще собрать и легче отлаживать. Графовая инженерия уместна, когда вы замечаете одно из следующего:
- у задачи есть действительно независимые подзадачи, которые можно выполнять параллельно;
- нужна проверка, отделённая от агента, который сделал работу;
- отказам нужен более узкий путь восстановления, чем «начать всё с нуля»;
- человеку нужна настоящая, аудитруемая точка принятия решения до того, как что-то уйдёт в прод.
Начинайте с минимального графа, который закрывает эти требования. Три-четыре узла с одним честным ребром у каждого каждый раз выиграют у одного развесистого промпта — и их гораздо проще объяснить следующему инженеру, которому придётся дебажить это в два часа ночи.