18+
реклама
18+
Бургер менюБургер меню

Ранас Мукминов – Оркестрация ИИ-агентов. Claude Opus 4.7 (страница 35)

18

Вывод для проектирования: бюджет стоимости задаётся не числом листьев, а числом узлов и объёмом контекста на ребро. Дерево, которое выглядит компактным по листьям, может быть дорогим по узлам.

Самая трудноизмеримая цена глубины — размывание ответственности. В плоской топологии ответственность локализована: корень отвечает за итог, воркер — за свою подзадачу, граница между ними одна и явная. В дереве ответственность дробится по уровням, и появляются зазоры (см. главу 20): когда итог неверен, неочевидно, на каком уровне произошла потеря — в декомпозиции родителя, в работе ребёнка или в агрегации. Каждый узел может справедливо указать, что он выполнил свой контракт корректно, а суммарный результат всё равно неверен из-за накопленного дрейфа или из-за неудачного разбиения наверху.

Архитектурное противоядие — делать контракт каждого ребра проверяемым и фиксировать на каждом узле, какие инварианты он обязался обеспечить и проверил. Тогда ответственность привязывается к рёбрам дерева: нарушение локализуется тем уровнем, на котором контракт впервые перестал выполняться. Без явных контрактов иерархия превращается в систему, где все правы локально и результат неверен глобально, а причину найти нельзя. Это та же проблема границ ответственности, что и в плоских системах, но в иерархии она умножается на число уровней и потому требует дисциплины контрактов как обязательного, а не желательного элемента.

Дерево агентов бывает статическим или динамическим. В статическом дереве форма задана проектировщиком: известны уровни, роли узлов, допустимое ветвление. Поведение предсказуемо, стоимость и латентность оцениваются заранее, отказы локализуются по известной структуре. Плата — жёсткость: статическое дерево плохо адаптируется к задаче, форма которой заранее неизвестна.

В динамическом дереве узлам разрешено самим решать, разбивать ли задачу дальше и на сколько частей. Форма возникает в момент исполнения. Это даёт адаптивность — дерево подстраивается под фактическую сложность фрагмента, — но открывает специфический и опасный класс отказов: неконтролируемое разрастание. Узел, склонный делегировать, может породить детей, которые тоже делегируют, и так далее. Без явных ограничителей дерево способно расти и вглубь (дрейф намерения накапливается, латентность критического пути неограниченно растёт), и вширь (стоимость взрывается), вплоть до исчерпания бюджета или зацикливания на уровне роя (см. главу 74).

Динамическая иерархия безопасна только при наличии жёстких ограничителей, заданных вне самих агентов (агенту нельзя доверять самоограничение — оно тоже недетерминированно). Минимальный набор:

— Лимит глубины. Жёсткий предел числа уровней. По достижении предела узел обязан решать задачу сам как лист, делегирование запрещается. Это прямое противоядие и дрейфу намерения, и неограниченной латентности.

— Лимит ветвления. Предел числа детей на узел. Защищает от взрыва ширины и от перегрузки агрегации в родителе (свернуть результаты слишком многих детей — само по себе ненадёжная операция).

— Бюджет на поддерево. Лимит токенов (или вызовов модели) на всё поддерево узла, а не только на сам узел. По исчерпании поддерево обязано вернуть частичный результат (см. главу 73), а не продолжать тратить. Бюджет — это backpressure, спускаемый по дереву вниз.

— Условие остановки рекурсии. Явный критерий «эта подзадача достаточно мала, чтобы решать её без дальнейшего деления». Без явного критерия узел не имеет детерминированного основания прекратить деление, и рекурсия управляется только случайностью генерации.

Эти ограничители — не оптимизация, а условие корректности динамического дерева. Иерархия без лимита глубины и без бюджета на поддерево — это незавершённая рекурсия с недетерминированным условием выхода, то есть конструкция, у которой нет гарантии завершения.

Отдельный вопрос — где принимается решение о делегировании. Возможны два режима. В первом форму дерева определяет внешний по отношению к агентам управляющий слой (планировщик, оркестрационная оболочка): агенты лишь исполняют узлы, а решение «делить ли дальше» принимает детерминированный код по явным правилам. Во втором решение принимает сам агент-узел внутри своего рассуждения. Первый режим предсказуемее и безопаснее: ограничители проверяет код, а не модель. Второй гибче, но переносит контроль разрастания внутрь недетерминированного компонента, и потому требует тем более жёстких внешних лимитов как страховки. На практике устойчивые системы тяготеют к гибриду: агент может предложить разбиение, но окончательное решение и проверку лимитов выполняет управляющий слой. Это частный случай выбора между оркестрованной и эмерджентной координацией (см. главу 44), приложенный к форме дерева.

Иерархия наследует отказы плоской топологии (глава 8) и добавляет собственные, специфические для дерева. Ниже — те, что возникают именно из-за вложенности и глубины. Все они должны учитываться явно при проектировании, а не обнаруживаться в эксплуатации.

Неверная или смещённая декомпозиция на верхнем уровне отравляет всё поддерево под ним. Если корень или субдирижёр неверно понял или переформулировал задачу, все его дети получают искажённые контракты, и их добросовестная работа умножает ошибку, а не исправляет. Каскад однонаправлен: дети не имеют доступа к исходной задаче и не могут оспорить искажённую постановку. Это наиболее дорогой отказ иерархии, потому что цена ошибки пропорциональна размеру отравленного поддерева. Противоядия: передача неизменяемой исходной цели вниз, ограничение глубины (меньше уровней — меньше точек, где может произойти исходное искажение), и явная валидация контракта ребёнком на входе (ребёнок проверяет, что полученная подзадача внутренне непротиворечива и согласована с переданным фрагментом исходной цели).

Симметричный отказ на пути вверх: внутренний узел неверно агрегирует результаты детей — теряет часть, неправильно объединяет, отбрасывает важное при сжатии. Результат отдельных листьев был корректен, но свёртка его исказила или потеряла. Чем больше детей у узла и чем агрессивнее сжатие, тем выше риск. Это аргумент против чрезмерного ветвления (агрегация многих результатов — ненадёжная операция) и за явный, проверяемый контракт агрегации: родитель обязан подтвердить, что свёрнутый результат сохраняет инварианты, заявленные в контрактах детей.

Если внутренний узел зависает или отказывает, всё его поддерево осиротевает: дети могут продолжать работать (тратя бюджет) на результат, который некому принять, либо результаты детей оказываются никому не нужны. В отличие от плоской топологии, где падение воркера локально и виден корню, в дереве отказ внутреннего узла невидим сверху до момента агрегации и обрывает целую ветвь. Это требует механизмов восстановления, работающих по поддеревьям (см. главу 72): тайм-аут и lease должны действовать на уровне ветви, переподхват зависшего внутреннего узла должен переназначать или останавливать всё его поддерево, а не только сам узел. Без этого иерархия накапливает осиротевшие ветви, которые тратят ресурсы и не дают результата.

Уже разобранный отказ динамического дерева: при отсутствии ограничителей дерево растёт неконтролируемо вглубь или вширь. Частный случай — рекурсивное зацикливание, когда узел порождает подзадачу, эквивалентную своей собственной, и дерево уходит в бесконечную глубину без приближения к решению. Это livelock на уровне роя (см. главу 74): работа идёт, ресурсы тратятся, прогресса нет. Защита — жёсткие лимиты глубины и бюджета на поддерево, а также условие остановки рекурсии, проверяемое внешним кодом, а не самим агентом.

Уже разобранный, но требующий повторного выделения как самостоятельный failure mode именно потому, что он тихий. В отличие от каскада искажения, у дрейфа нет единичной точки сбоя — он накапливается малыми смещениями на каждом шве. Система не падает и не выдаёт ошибку; она успешно завершает работу с результатом, не соответствующим исходной постановке, и каждый узел при этом прошёл свою локальную проверку. Это самый трудный для наблюдаемости отказ иерархии: его не видно ни в логах отдельных узлов, ни в их статусах, только в сопоставлении конечного результата с исходной целью. Противоядие — сквозная сверка с неизменяемой исходной постановкой на каждом уровне и ограничение глубины как способ ограничить накопленное смещение.

Каждый внутренний узел дерева — единая точка отказа для своего поддерева, а корень — для всей системы (общая проблема SPOF оркестратора разобрана в главе 75). Чем выше узел, тем больше работы он обрушивает при отказе. Это усиливает аргумент против глубоких узких деревьев: длинная цепочка внутренних узлов — это длинная цепочка последовательных единых точек отказа на критическом пути, и отказ любой из них обрывает всё, что под ней. Широкое мелкое дерево распределяет риск: отказ одного субдирижёра в широком слое теряет одну ветвь, а не всю глубину под собой.

Failure mode | Направление | Корневая причина | Основное противоядие

Каскад искажения | сверху вниз | неверная декомпозиция на узле | исходная цель вниз, лимит глубины, валидация контракта на входе