Перейти к основному содержимому

Kill switch предполагает один процесс: семантика завершения для флотов агентов

Kill switch и обещания изоляции предполагают один управляемый процесс на агента. Развёрнутый флот — это граф родителей, потомков, сессий инструментов и lease-ов, и ему нужен протокол завершения, а не выключатель.

Макроснимок поверхности пористой вулканической породы с текстурными узорами

Допущение об одном процессе

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

В продакшене такой единицы не существует. Развёрнутый агент — это узел в графе. Родительский агент порождает потомков — субагентов для retrieval, исполнения кода, ревью, эскалации. Каждый потомок может держать сессии инструментов: открытый shell, аутентифицированный API-клиент, контекст браузера, транзакцию базы данных. Эти сессии держат lease-ы: короткоживущие учётные данные, блокировки файлов, резервации очередей, токены rate-limit. Граф динамичен; потомки создаются во время выполнения и могут пережить запрос, который их создал.

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

Что на самом деле нужно протоколу завершения

Флоту нужен протокол как минимум с тремя свойствами. Они независимы, и пропуск любого из них оставляет режим отказа, до которого kill switch не дотянется.

Состояние drain. Завершение не бинарно. Между running и terminated должно быть состояние, которое отвергает новые вызовы инструментов, позволяя выполняющимся вызовам разрешиться или прерваться детерминированно. Без него резкая остановка оставляет вызовы инструментов в неизвестном состоянии: платёж отправлен, но не подтверждён, файл наполовину записан, сообщение отправлено, но не подтверждено. Состояние drain заставляет принять решение по каждому выполняющемуся вызову — дождаться результата или отменить и зафиксировать отмену, — вместо того чтобы оставлять решение тому, что сделает транспорт при закрытии сокета.

Wind turbine blades against a clear blue sky, stock photo

Минимальный конечный автомат выглядит так:

requested -> draining -> reconciling -> terminated
                    \-> aborting   -> reconciling -> terminated

draining отвергает новые вызовы инструментов и позволяет незавершённым закончиться в ограниченном окне. aborting отменяет их и требует, чтобы каждая отмена была подтверждена слоем инструментов. reconciling записывает запись, описанную ниже. Только после этого достижимо terminated. Переход из requested инициируется полномочным органом вне рабочей нагрузки, а не самим агентом.

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

Запись сверки, созданная до выхода. Post-mortem не должен зависеть от собственных логов агента. Агент, которого завершают — особенно тот, что ведёт себя неправильно, — наименее надёжный рассказчик о своих последних действиях. Запись сверки пишет супервизор или control plane, снаружи, и в ней указано: какие вызовы инструментов выполнялись, как каждый разрешился, какие lease-ы отозваны, а какие истекли, какие потомки подтверждённо завершены, а какие не учтены. Неучтённые потомки — важнейшее поле. Протокол, который не может их перечислить, не может утверждать, что флот остановлен.

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

Где заканчивается рамка правил завершения

Close-up of a disassembled hard drive showing its internal platter and components

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

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

Полезный ход — поднять явный конечный автомат из агента в инфраструктуру. Самоописанные условия завершения агента становятся одним из входов супервизора, который владеет фактическими переходами. Агент предлагает; control plane располагает. Именно это разделение делает конечный автомат тестируемым независимо от поведения конкретной модели.

Правило проектирования: завершение до графа задач

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

Флот, который нельзя осушить, нельзя и безопасно обновить. Тот же протокол, который чисто останавливает флот, позволяет заменить версию модели, ротировать учётные данные или выкатить новую схему инструментов, не оставляя незавершённой работы в старой генерации. Drain, reconcile, restart — это путь обновления; если завершение — это kill switch, обновление — это азартная игра.

Поэтому каждому гранту возможности сопоставьте handle отзыва, хранящийся вне рабочей нагрузки. Handle живёт в control plane, индексируется по цепочке делегирования и осуществим любым предком. Агент никогда не держит собственный выключатель, потому что выключатель, который держит то, что выключают, — это предложение.

Честный компромисс: это стоит латентности и сложности. Окно drain означает, что завершение занимает время, и кто-то должен выбрать границу. Записи сверки — ещё одно хранилище в эксплуатации и ещё одна схема для миграции. Lease-ы, отзываемые предком, требуют capability-модели, с которой большинство фреймворков агентов не поставляются, так что команды построят её сами или примут более слабую гарантию. Ничего из этого не избежать, если флот должен быть управляемым. Альтернатива — kill switch, который убивает один процесс и оставляет остальной граф с учётными данными, — а это не изоляция, только её видимость.

ПоделитьсяXLinkedInПостоянная ссылка5 мин чтения

Связанное чтение

На какие вопросы это отвечает

Why is a kill switch insufficient for a multi-agent fleet?

A kill switch terminates one process. A deployed fleet is a graph of parent agents, spawned children, tool sessions and leases; terminating the root leaves children running with credentials issued through the delegation chain. Containment requires a termination protocol that drains sessions, propagates revocation to descendants and records what was left unaccounted for.

What is a drain state in agent shutdown?

A drain state sits between running and terminated. It refuses new tool calls while allowing in-flight calls to resolve or abort deterministically, so no tool call is left in an unknown state when the process exits.

Who should be able to revoke a child agent's lease?

Any ancestor in the delegation chain, not only the component that issued the lease. If revocation depends solely on the direct parent and that parent has failed, the credential becomes effectively permanent.

Why write a reconciliation record outside the agent?

An agent being terminated is the least reliable narrator of its own final actions. A record written by the supervisor or control plane captures in-flight calls, revocation outcomes and unaccounted-for children independently of the agent's own logs.