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

Команда kagent прошла этот путь на практике: сначала много агентов выполнялись внутри общего runtime, затем каждый получил собственные Pod, Service и ServiceAccount, а теперь проект исследует промежуточный control plane — agent-substrate.

Главный вопрос здесь шире Kubernetes: что должно быть единицей исполнения, а что — единицей идентичности и жизненного цикла агента?

Почему один runtime на всех удобен только в начале

Общий процесс с несколькими агентами прост для прототипа. Не нужно создавать отдельные workload, ждать scheduler и поддерживать десятки сетевых объектов. Но по мере роста возникают вопросы, на которые общий runtime отвечает плохо:

  • как изолировать одного агента от другого;
  • какой identity использовать при доступе к API;
  • как назначать network policy и квоты;
  • как увидеть стоимость и трассировку конкретного агента;
  • кому принадлежит агент в multi-tenant среде.

Естественная реакция Kubernetes-команды — выделить каждому агенту Pod, Service и ServiceAccount. Это возвращает привычные механизмы изоляции, RBAC, сетевой политики, scheduling и observability.

Такое решение действительно работает. Проблема начинается, когда Pod одновременно становится и sandbox, и identity, и записью о жизненном цикле логического агента.

Чем агент отличается от микросервиса

Микросервис обычно должен быть доступен постоянно. Даже при scale-to-zero его модель остаётся сервисной: запрос приходит к известной конечной точке, платформа поднимает экземпляр и направляет трафик.

Агент ведёт себя иначе:

  • выполняет задачу несколько секунд или минут, затем простаивает;
  • может создать несколько временных субагентов;
  • приостанавливается в ожидании approval;
  • действует от имени конкретного пользователя;
  • сохраняет контекст дольше, чем живёт один процесс;
  • возобновляется на другом вычислительном узле.

Привязка identity к Pod ломается уже на pause/resume. После восстановления появляется новый Pod, но с точки зрения пользователя это тот же агент и тот же run. Логи, решения и права должны следовать за логическим актором, а не за случайным контейнером.

Модель agent-substrate

agent-substrate оставляет Kubernetes то, что он умеет лучше всего: управление долгоживущими worker-Pod, сетью, storage и вычислительными ресурсами. Новый слой управляет логическими агентами и размещает их на свободных исполнителях.

В модели появляются четыре сущности:

  • WorkerPool описывает группу исполнителей и напоминает NodePool;
  • Worker соответствует конкретному готовому исполнителю;
  • ActorTemplate задаёт образ, runtime и ограничения логического агента;
  • Actor представляет отдельный запуск агента.

Kubernetes видит WorkerPool и ActorTemplate. Сам Actor не обязан быть отдельным Custom Resource и отдельным Pod. Когда приходит работа, substrate назначает его свободному Worker; после завершения или приостановки освобождает вычислительный слот.

В результате фиксированное число worker-Pod может обслуживать значительно больше логических агентов. Pod остаётся execution sandbox, но перестаёт быть единственной записью об агенте.

Что выигрывает платформа

Быстрый старт и высокая плотность

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

Независимая идентичность

Identity можно связать с ActorTemplate, tenant, пользователем и версией агента. Перемещение между Worker не меняет эту связь. Но такую модель ещё предстоит аккуратно состыковать с Kubernetes RBAC и внешними identity provider.

Pause и resume

Логический run способен пережить процесс. Состояние сохраняется отдельно, Worker освобождается, а продолжение назначается позже. Для Human-in-the-Loop это естественнее, чем держать Pod в ожидании несколько часов.

Наблюдаемость на уровне задачи

Trace и audit trail получают стабильный actor_id или run_id. Иначе один логический агент распадается по нескольким Pod, а один Worker смешивает телеметрию нескольких задач.

Какие сложности новый слой не решает автоматически

Дополнительный control plane — это не бесплатная оптимизация. Он создаёт собственные задачи распределённой системы:

  • scheduler должен учитывать ресурсы и совместимость Actor с Worker;
  • состояние pause/resume нужно хранить надёжно и версионировать;
  • потерю Worker необходимо отличать от завершения Actor;
  • policy должна проверяться при каждом новом размещении;
  • observability обязана сохранять причинную связь между Actor, Worker и инструментами;
  • обновление ActorTemplate не должно незаметно менять уже одобренный run.

Особенно опасно считать Worker изолированным только потому, что он работает в Pod. Если несколько Actor последовательно используют один runtime, нужно гарантировать очистку filesystem, процессов, environment, browser profile и сетевых credential. В противном случае повышение плотности превращается в канал утечки контекста.

Когда отдельный Pod всё ещё правильный ответ

Новый слой нужен не каждому агенту. Отдельный Pod проще и надёжнее, если:

  • задача выполняется долго и потребляет предсказуемые ресурсы;
  • требуется сильная изоляция на уровне VM или sandbox-контейнера;
  • агент имеет выделенный ServiceAccount и стабильную сетевую политику;
  • число одновременных запусков невелико;
  • скорость старта не критична;
  • команда не готова эксплуатировать ещё один scheduler.

Для production-платформы простота сама по себе остаётся преимуществом. Сначала стоит измерить cold-start, среднюю продолжительность задач, долю времени ожидания approval и стоимость простаивающих Pod. Без этих данных substrate может оказаться архитектурой ради архитектуры.

Практический контракт для agent runtime

Независимо от выбранной единицы исполнения, логический run полезно сделать явным:

  1. стабильный run_id, переживающий рестарт и перенос;
  2. типизированные action с preconditions;
  3. approval, привязанный к точному payload;
  4. append-only события выполнения;
  5. bounded retry и reconciliation после неизвестного результата;
  6. отдельные identity пользователя, агента и worker;
  7. очистка состояния перед повторным использованием sandbox.

Тогда Pod, Worker или microVM становятся сменяемой реализацией execution layer. Пользовательский контракт остаётся стабильным.

Что важно проверить у kagent сейчас

kagent — активно развивающийся CNCF-проект, а описанный substrate представляет новое направление, а не зрелый стандарт Kubernetes. В примерах исходной статьи используются ранние API v1alpha1 и конкретные версии sandbox-компонентов. Перед пилотом нужно сверить текущую документацию, threat model и ограничения runtime.

Самая полезная мысль проекта не в том, что «Pod больше не нужен». Наоборот, Pod остаётся хорошим worker. Но логический агент, его identity, история решений и pause/resume уже не обязаны совпадать с жизнью одного Pod.