Ранас Мукминов – Оркестрация ИИ-агентов. Claude Opus 4.7 (страница 91)
Из этого следует, что валидация на входе потребителя — не дублирование валидации на выходе производителя, а отдельная граница с другой целью. Производитель валидирует, чтобы не выпустить структурно битое сообщение (защита формы). Потребитель валидирует, чтобы не принять опасное или несогласованное (защита от недоверенного источника). На критических стыках валидация стоит дважды и сознательно: цена пропуска выше цены двойной проверки (та же логика, что и для проверки контракта в главе 18). Особо опасны управляющие конструкции внутри полезной нагрузки: текстовое поле, пришедшее от другого агента и попадающее в контекст получателя-модели, — это вектор инъекции, и его нужно трактовать как данные, а не как инструкции (см. главу 86). Схема проверит, что это строка; от того, что строка несёт команду, защищает не схема, а изоляция данных от инструкций в том, как получатель строит свой контекст.
Валидация не бесплатна, и её размещение — это распределение координационного налога (см. главу 5). Дешёвые детерминированные проверки (схема, синтаксис, простые свойства) стоят пренебрежимо мало по сравнению с вызовом модели и потому уместны на каждом сообщении на границе кода. Дорогие проверки — семантические, требующие ещё одного агента-критика (см. главу 65) или человека, — нельзя ставить на каждое сообщение: они сами по себе сопоставимы по стоимости с породившей сообщение работой.
Отсюда разделение, аналогичное разделению уровней контракта (см. главу 18). Структурная валидация и проверки свойств — на каждом сообщении, синхронно, на границе перехода к коду: это та мембрана, без которой недетерминизм просачивается дальше. Семантическая проверка — выборочно и, как правило, асинхронно: по части сообщений собирается статистика «доля прошедших содержательную проверку», и эта доля становится метрикой здоровья стыка (см. главу 79), а её падение — сигналом тревоги. Ставить семантическую проверку на каждое сообщение — значит удвоить стоимость роя ради покрытия, которое статистически достигается выборкой; не ставить её вовсе — значит не замечать содержательную деградацию, проходящую сквозь структурно валидную форму.
Есть и обратная ошибка — экономия на дешёвой валидации «ради скорости». Структурная проверка дёшева настолько, что её отсутствие почти никогда не оправдано производительностью: цена, которую платит рой за просочившийся структурный мусор (сбой далеко от причины, испорченное состояние, тяжёлый постмортем), на порядки выше сэкономленного на валидации. Дешёвую границу убирают не ради скорости, а по недосмотру, и это один из самых частых дефектов проектирования протокола сообщений.
Форматы, схемы и парсинг — сами по себе механизмы, и у них есть собственные режимы отказа, отличные от отказа агента и опасные тем, что создают ложное чувство, будто сообщение проверено.
Структурно валидный, семантически неверный мусор. Сообщение проходит схему — поля на месте, типы верны, — а значения выдуманы моделью. Самый частый режим, прямое следствие того, что схема проверяет форму, а не смысл. Рой принимает прошедшее схему за корректное и распространяет мусор дальше. Защита — не путать прохождение схемы с корректностью; для критических сообщений добавлять проверки свойств и выборочную семантическую проверку, опуская постусловия по лестнице проверяемости (см. главу 18).
Тихий ремонт, домысливающий содержание. Стадия ремонта, выйдя за границу «чинить форму, не трогать смысл», подставляет правдоподобное значение в недостающее или битое поле. Сообщение становится валидным ценой выдуманных данных, и это опаснее честного отказа, потому что выглядит как успех. Защита — жёсткая дисциплина ремонта: только однозначно исправимые дефекты формы, любая неоднозначность содержания ведёт к отказу, а не к домысливанию.
Тихая потеря невалидного сообщения. Сообщение, не прошедшее разбор, отвергается без регистрации. Получатель ведёт себя так, будто сообщения не было; отправитель считает, что отправил. Результат работы потерян, и потеря не наблюдаема — она неотличима от случая, когда работа не выполнялась. Защита — обязательная регистрация всякого исхода, кроме чистого успеха; доля провалов разбора как метрика (см. главу 79).
Дрейф схемы при неизменной структуре. Новая версия модели или переписанный промпт меняют наполнение полей, не нарушая схему: необязательное поле заполняется иначе, формулировки в свободных подполях смещаются. Версия схемы в конверте не меняется, валидатор пропускает, а семантика стыка тихо разъехалась (см. главу 22). Защита — контрактные тесты сообщений при смене модели и наблюдение распределения значений полей во времени.
Несовместимая эволюция схемы. В схему добавлено обязательное поле или ужесточён тип — изменение, ломающее производителей или потребителей, которые его не учли. Если версия схемы не проверяется, сбой проявляется как поток отвергнутых сообщений или, хуже, как принятые сообщения с неверной интерпретацией. Защита — правило вариантности (добавлять необязательное, не ужесточать существующее), явная версия схемы в конверте, совместимость вперёд и назад на стыке.
Инъекция через полезную нагрузку. Текстовое поле, пришедшее от другого агента и попавшее в контекст получателя-модели, несёт инструкцию, выводящую получателя за рамки задачи (см. главу 86). Схема подтверждает, что это валидная строка, и пропускает; вред наносит то, что получатель трактует данные как инструкции. Защита — изоляция данных от инструкций в построении контекста получателя; валидация содержания на принадлежность ожидаемому домену, а не только формы.
Смешение конверта и нагрузки. Координационное поле (адрес, тип, корреляция) кладётся в полезную нагрузку, где его формирует и портит модель; или, наоборот, содержательное поле прячется в конверт, где его не видит логика роли. В первом случае маршрутизация и дедупликация начинают зависеть от недетерминированного вывода и становятся хрупкими; во втором — содержательная проверка пропускает поле, которое считала служебным. Защита — строгое разделение слоёв: конверт формируется и читается только кодом, нагрузка — единственное, что производит модель.
Перегруженная схема как хрупкость. Желая поймать всё, схему делают чрезмерно строгой и детальной: множество обязательных полей, узкие перечни, жёсткие форматы. Это зеркало слишком тесного предусловия (см. главу 18): чем уже схема, тем больше реальных, по смыслу годных выводов модели в неё не попадает, тем выше доля отвергнутых сообщений и тем чаще нужен повтор или ремонт. Перегруженная схема перекладывает сложность с одного сообщения на поток отказов и повторов. Защита — строгость по месту: жёстко там, где сообщение машинно запускает необратимое, мягче там, где получатель толерантен.
Формат сообщения и схема — связующая абстракция уровня коммуникации, и полезно видеть их смыкание с соседними уровнями сквозной модели, не дублируя их.
С ролями и контрактами (часть III): схема — это структурная часть контракта агента (см. главу 18), вынесенная на провод; совместимость схем на стыке — это совместимость контрактов; тип-отказ в протоколе — это форма частичного контракта с честным отказом.
С каналами коммуникации (часть IV): на канале сообщений формат явный и проверяется на границе сообщения (эта глава); на канале общей памяти (см. главу 23, blackboard — глава 11) схема становится свойством данных в общем пространстве, проверяемым без знания о том, кто и когда прочитает; на канале артефактов схема — это инварианты артефакта, проверяемые при handoff (см. главу 47). Семантика доставки (см. главу 29) определяет, при каких условиях сообщение вообще доходит до валидации: дубликат опознаётся по message_id, потеря оставляет пробел, который виден только при наличии корреляции.
С координацией (часть VI): ключ идемпотентности в конверте (см. главу 43) — это то, что делает повтор сообщения безопасным; без него повторная доставка (см. главу 29) приводит к повторной обработке.
С наблюдаемостью (часть XI): поля correlation_id и causation_id — причинно-следственный скелет, по которому собираются трассировка (см. главу 77), корреляция событий (см. главу 78) и реконструкция сессии (см. главу 81). Если этих полей нет в формате с самого начала, наблюдаемость нельзя добавить позже — нечего коррелировать.
С безопасностью (часть XII): валидация на входе — точка применения zero trust (см. главу 85); изоляция данных нагрузки от инструкций — защита от распространения инъекции через сообщения (см. главу 86).
Эта связность объясняет, почему формат сообщений стоит проектировать целиком и заранее, а не наращивать по мере надобности: конверт несёт поля, от которых зависят координация, наблюдаемость и безопасность сразу нескольких уровней, и попытка добавить недостающее поле в долгоживущий рой задним числом упирается в то, что прошлые сообщения его не несут, а значит, соответствующий уровень системы на них слеп.
— Сообщение между агентами — это конверт (детерминированные метаданные доставки, корреляции, идемпотентности) и полезная нагрузка (содержательная часть, которую производит недетерминированная модель). Слои нужно строго разделять: координация и маршрутизация опираются только на конверт, нагрузку формирует и читает как структуру только она. Смешение слоёв делает маршрутизацию хрупкой, а проверку — дырявой.