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

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

18

Артефакт — естественный канал, когда результат работы по своей природе устойчив и предназначен для многократного или отложенного потребления. Если агент произвёл нечто, что должно сохраниться (код, отчёт, набор данных), что может понадобиться нескольким потребителям, что нужно будет проверить, версионировать, откатить, — это артефакт, а не сообщение. Сообщение эфемерно и плохо подходит для хранения; пытаться передать через сообщение крупный устойчивый результат — значит нагружать транспорт тем, для чего он не предназначен.

Артефакты особенно уместны как граница между стадиями, разнесёнными во времени или по доверию. Стадия конвейера (см. главу 10) может оставлять результат артефактом, а не сообщением, если следующая стадия запускается не сразу, или если промежуточный результат сам по себе ценен и должен быть доступен для проверки и аудита. Артефакт — точка, в которой работу можно остановить, осмотреть, при необходимости вмешаться вручную (см. главу 91), а затем продолжить. Это делает артефакт удобным местом для контроля человеком: в отличие от эфемерного сообщения и текучего общего состояния, артефакт стоит и ждёт ревизии. У этого свойства есть и оборотная сторона для безопасности: устойчивый артефакт, в отличие от исчезающего сообщения, оставляет след, который можно проверить постфактум, но и хранит содержимое дольше, поэтому артефакт с недоверенными или чувствительными данными требует тех же дисциплин доступа и времени жизни, что и любое хранимое состояние (см. главу 90).

Третье достоинство артефакта — он естественно совместим с share-nothing-параллелизмом (см. главу 54). Параллельные воркеры, работающие в изолированных областях (см. главу 55), производят артефакты в своих областях, не имея общего изменяемого состояния; артефакты затем собираются на стадии fan-in (см. главу 37). Поскольку артефакт неизменяем, его производство одним воркером не конфликтует с производством другим — нет гонок записи, как в общей памяти. Артефакт даёт устойчивость общего хранилища без совместной изменяемости, и в этом его инженерная ценность для масштабируемого параллелизма.

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

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

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

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

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

Failure modes артефактов по характеру ближе к отказам сообщений (затрагивают конкретную связь производитель—потребитель), чем к глобальным отказам общей памяти, но имеют временну́ю природу: артефакт переживает передачу, и потому проблемы видимости, версий и времени жизни растянуты во времени сильнее, чем у эфемерного сообщения.

На практике рой почти никогда не использует один канал. Каналы комбинируются, и важно понимать типовые композиции и то, как один канал маскируется под другой.

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

Вторая композиция — общая память поверх артефактов. Изменяемое общее состояние реализуют не как единый изменяемый объект, а как последовательность неизменяемых артефактов-версий: каждое «изменение» состояния — это новый артефакт, а текущее состояние — последний в последовательности. Это превращает изменяемую общую память в журнал неизменяемых записей и снимает часть отказов: нет затирания (старые версии сохранены), есть происхождение (видно, кто какую версию породил), возможен откат. Ценой становится рост (все версии хранятся) и необходимость определить, какая версия актуальна. Этот приём — общий способ приручить общую память, заменив изменяемость накоплением неизменяемого; он связан с темой append-only-состояния (см. главу 11) и согласованности (см. главу 49).

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

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

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

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

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

Вопрос о связи | Сообщение | Общая память | Артефакт