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

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

18

Зазор необработанного исхода. Контракт роли описывает её поведение для ожидаемых исходов и молчит о неожиданных. Роль-извлекатель данных описана для случая «данные найдены» и «данные не найдены», но не для «источник вернул данные в неожиданном формате». Неописанный исход — это зазор: роль не знает, что делать, и либо падает, либо, что хуже, продолжает с мусором. Failure modes коммуникации (см. главу 30) — искажение, частичный ответ — массово порождают именно такие зазоры.

Зазор отказа. Что происходит, когда роль не справилась? Если ни одна роль не назначена обрабатывать отказ конкретной роли, отказ повисает. Воркер завис — кто это заметит и переподхватит работу (см. главу 72)? Если ответ «никто», зазор отказа открыт, и зависание воркера превращается в зависание всей подзадачи без следов.

Зазор межролевого инварианта. Самый тонкий. Бывают инварианты, которые не принадлежат ни одной роли, потому что относятся к согласованности между их выходами. Пример: исполнитель отвечает за код, тестировщик — за тесты, но за то, что тесты вообще проверяют именно тот код, который написал исполнитель (а не его прошлую версию), не отвечает явно никто. Инвариант «тесты соответствуют коду» лежит в зазоре между двумя ролями, каждая из которых корректна по своему контракту.

Зазор времени. Ответственность может проваливаться не в пространстве ролей, а во времени — в моменты передачи. Во время handoff между агентами есть интервал, когда работа уже покинула отправителя, но ещё не принята получателем. Кто отвечает за неё в этот момент? Если handoff не транзакционен, сбой ровно в этот интервал теряет работу: отправитель считает, что передал, получатель не знает, что должен принять. Это зазор во времени передачи, и он подробно разбирается как failure mode handoff в части VII.

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

Отсюда практический вывод: зазоры нельзя найти, проверяя роли по отдельности. Каждая роль может пройти свой контракт идеально, а зазор между ними останется. Зазоры ищутся только при взгляде на стыки и на пространство ситуаций целиком — этому посвящён раздел о диагностике.

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

Роль-перехватчик (catch-all, fallback) — это роль, чья зона ответственности определена отрицательно: «всё, что не обработала ни одна другая роль». Её назначение — превратить молчаливый провал в явное событие. Перехватчик не обязан решать непредусмотренную ситуацию; он обязан её зафиксировать и эскалировать, чтобы зазор стал видимым, а не тихим.

Без роли-дна непокрытая ситуация исчезает бесследно. С ролью-дном она превращается в обработанный отказ: зарегистрирована, передана человеку или вышестоящей роли, не потеряна. Это превращает класс отказов «молчаливый зазор» в класс «явная эскалация», а явный отказ всегда управляем лучше тихого. Связь с надёжностью прямая: роль-дно — это аналог обработчика по умолчанию и graceful degradation (см. главу 73), вынесенный на уровень распределения ответственности.

У перехватчика есть собственный failure mode, который нельзя игнорировать: он притягивает к себе слишком много. Если в перехватчик начинает регулярно проваливаться большая доля ситуаций, это не означает, что перехватчик работает хорошо, — это означает, что зоны основных ролей нарезаны с большими дырами. Здоровый перехватчик срабатывает редко; частые срабатывания — это метрика дефекта нарезки, а не успеха дна (об этом в разделе диагностики).

За пределами роя должна быть точка, в которую упирается эскалация и которая отвечает за всё, что не разрешилось внутри. Обычно это человек-оператор (см. часть XIII), реже — вышестоящий оркестратор. Принципиально, что эта точка существует и явно названа: владелец последней инстанции замыкает цепочку ответственности, не давая ей закончиться в пустоте.

Цепочка ответственности должна быть полной и конечной: для любой ситуации существует путь «роль → перехватчик → владелец последней инстанции», который не обрывается. Обрыв цепочки — это и есть зазор в чистом виде: ситуация, для которой нет следующего ответственного. Проектирование границ ответственности можно свести к одному требованию: ни одна цепочка эскалации не должна обрываться раньше, чем достигнет точки, которая обязана принять решение.

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

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

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

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

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

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

Матрица делает дефекты видимыми механически:

— Строка без ответственного за итог — зазор: ситуация, за исход которой никто не отвечает.

— Строка с двумя и более обязанными действовать — перекрытие: его нужно либо устранить, либо подтвердить как преднамеренное.

— Пустая строка целиком — ситуация, которую вообще никто не видит; кандидат на зону перехватчика.

— Колонка роли с полномочиями, но без строк ответственности — полномочия шире ответственности.

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

Статически зазоры лучше всего вскрываются не на нормальных сценариях, а на сценариях отказа. Для каждой роли задаётся вопрос: «что происходит, когда эта роль отказывает / возвращает мусор / зависает / отвечает не вовремя?» — и прослеживается, есть ли роль, которая это поймает. Если на вопрос «кто обработает отказ роли X» нет ответа — найден зазор отказа.

Это применение проектирования от failure modes (сквозной принцип книги) к границам ответственности. Нормальный путь обычно покрыт — роли для того и созданы. Зазоры концентрируются на путях отказа, потому что эти пути проектируют в последнюю очередь или не проектируют вовсе.

В работающей системе зазоры и перекрытия оставляют наблюдаемые следы. Перечень сигналов — это, по сути, чеклист для наблюдаемости роя (см. часть XI), направленный конкретно на дефекты границ.