Команды агентов
#1. Цель
Ввести команду агентов как first-class сущность Temporality: переиспользуемое, версионированное определение состава и порядка совместной работы нескольких агентов над задачей.
Механика совместной работы в ядре уже есть — инструменты delegate и plan с DAG, acceptance gates и rework-циклами (docs/agent-delegation.md). Команда не заменяет её, а накрывает переиспользуемым определением:
- один раз описать устойчивую композицию (реализация → ревью → QA; фан-аут исследований → синтез);
- версионировать и сравнивать составы и протоколы по результатам реальных запусков;
- измерять композицию целиком: токены, стоимость, rework-циклы, споры;
- эволюционировать состав на основе evidence — по той же модели, что skills и агенты.
Ключевое требование к UX: пользователь описывает команду естественным языком и редактирует обычной формой. Внутренний манифест team.yaml — артефакт системы, а не пользовательский интерфейс (тот же принцип, что у skill.yaml и определений агентов).
#2. Проблематика текущего состояния
- Порядок совместной работы задаётся ad hoc: ведущий агент каждый раз заново изобретает декомпозицию в промпте вызова
plan/delegate. - Единственный пример команды (LeadCoderReviewerQA) захардкожен отдельным Temporal-workflow вне ядра — его нельзя изменить без пересборки.
- Повторяющиеся композиции нельзя сохранить, переиспользовать, измерить и улучшить.
- Метрики есть только на уровне отдельного рана: стоимость и токены не сворачиваются по композиции в целом.
- Пользователь не видит «какие команды существуют и как они устроены» — команды не существуют как сущность.
- Связка «задача → подходящий состав» держится в голове пользователя или в промпте, а не в системе.
#3. Основные понятия
#3.1 Team (команда)
Определение совместной работы: название, описание, ролевые слоты, протокол, дефолты, привязка к оргструктуре.
Команда — это определение, а не постоянно работающий процесс. Экземпляр команды существует только внутри запуска и распускается по его завершении.
#3.2 Role Slot (ролевой слот)
Роль в команде. Слот описывает:
id, название (Coder, Reviewer, QA);- ответственность — за что слот отвечает (в терминах docs/evaluable-agent.md, не стиль общения);
- требования — capabilities и skills, необходимые агенту для этой роли;
- контракт выхода — что слот обязан вернуть, чтобы следующий этап мог начаться;
- привязку — конкретный агент (
fixed) или требования для подбора (role).
Слот переживает смену агентов: пока агент удовлетворяет требованиям слота, команда работает. Это позволяет заменить QA-агента на другого, не трогая определение команды.
#3.3 Protocol (протокол)
Типовая топология совместной работы. Небольшой словарь:
pipeline— последовательные стадии, контракт каждой стадии подаётся на вход следующей;lead_workers— ведущий агент получает цель и сам декомпозирует её черезplan/delegate;fan_out— параллельные исполнители + сводящий слот;review_gate— исполнитель + ревьюер с циклом доработки (механика acceptance gates);dag— общий случай: шаги с зависимостями и ревью-воротами.
Протоколы компилируются в существующие механизмы plan/delegate, а не исполняются отдельным движком.
#3.4 Team Run (командный запуск)
Экземпляр работы команды: снапшот определения версии, привязанные слоты, цель. Порождает обычные дочерние AgentRun-ы; события дополнительно помечаются team_id и версией.
#3.5 Roster (ростер)
Множество агентов, доступных для привязки с учётом эффективной видимости вызывающего (docs/org-structure.md). Определения агентов у нас уже роле-ориентированы — ростер это они и есть; отдельной сущности «роль» не требуется.
#4. Принципы
#Определение постоянно, экземпляр эфемерен
Команда-определение версионирована и переиспользуется. Команда-экземпляр живёт только внутри запуска. Нет «постоянно работающего отдела» с фоновым общением.
#Слот — это ответственность и контракт, а не промпт
Слот задаёт, за что роль отвечает и что обязана вернуть. Как в docs/evaluable-agent.md — роль определяет ответственность, а не стиль.
#Малый словарь топологий
Произвольные графы общения запрещены осознанно: свободный N-агентный чат доказанно дорог, дрейфует и не отлаживается (анти-паттерн ранних AutoGen GroupChat). Расширение словаря протоколов — продуктовое решение, а не рантайм-свобода агентов.
#Контекст передаётся явно
Дочерние раны не делят память неявно. Всё, что нужно слоту, передаётся ему: цель, контракты предыдущих слотов, командный scratch. Соответствует принципу «делегированный запуск — настоящий run» из docs/agent-delegation.md.
#Детерминированный скелет, агентные решения в точках
Порядок, зависимости и ворота задаёт протокол. Агентские решения допускаются только в определённых точках: декомпозиция (в lead_workers), выполнение задачи, вердикт ревью.
#Права не складываются
Команда не расширяет права участников. Каждый дочерний ран работает с правами и политиками своего агента; командное взаимодействие не является способом эскалации (наследует принцип «ребёнок работает только со своими правами»).
#Команда наблюдаема как целое
Дерево вызовов, DAG, события, знания, споры — всё видно в существующих панелях, плюс rollup-метрики уровня команды.
#5. Модель определения
Внутренний манифест (пользователь его не видит):
id: squad-code-delivery
version: 3
name: Code Delivery
description: Доставка изменения кода: реализация, ревью, проверка качества.
org_unit_id: null # null = вся инсталляция, иначе узел + поддерево
protocol:
kind: pipeline # pipeline | lead_workers | fan_out | review_gate | dag
max_rework: 2 # лимит доработок на ворота (DefaultMaxRework ядра)
slots:
- id: coder
title: Coder
responsibility: Реализует изменение и проверяет его выполнимым кодом.
requirements:
capabilities: [read_files, modify_files, run_commands]
contract:
output: список изменённых файлов и доказательства проверки
binding:
mode: role # role | fixed
preferred_agent_id: coder # подсказка подбору, не обязательство
- id: reviewer
title: Reviewer
responsibility: Находит дефекты и оценивает достаточность доказательств.
requirements:
capabilities: [read_files, run_commands]
contract:
output: verdict accept | rework + список замечаний
binding:
mode: fixed
agent_id: reviewer
defaults:
max_turns: 40
budget_usd: 5.0
parallel_limit: 4 # одновременных дочерних ранов
#Версионирование
Каждое изменение определения создаёт новую версию (как у skills и агентов). Версия хранит: описание, слоты, протокол, дефолты, автора, дату. Запуск фиксирует снапшот версии — изменение определения во время запуска не влияет на него.
#6. Протоколы
Каждый протокол — компиляция в терминах существующих инструментов:
| Протокол | Компиляция | Что обобщает |
|---|---|---|
pipeline |
последовательные дочерние раны; контракт слота N — вход слота N+1 | пример LeadCoderReviewerQA |
lead_workers |
один ран ведущего агента с правом delegate/plan; слоты = ростер для его декомпозиции |
обычное делегирование, но с фиксированным составом кандидатов |
fan_out |
plan с независимыми задачами (depends_on: []) + сводящая задача, зависящая от всех |
параллельные исследования → синтез |
review_gate |
plan c review_of и max_rework |
текущие acceptance gates |
dag |
явный список шагов с depends_on/review_of; слоты подставляются как исполнители шагов |
прямой аналог tool-спеки plan, но в терминах слотов |
Правила, общие для всех протоколов:
- запускам шагов назначаются агенты через привязку слотов (см. §7), а не
agent_idиз промпта; - ворота ревью — это ворота протокола; policy-подтверждения (docs/approval-model.md) применяются к каждому дочернему рану как обычно и воротами не заменяются;
- инструменты
plan/delegateостаются доступны агентам и вне команд: команда — переиспользуемая обёртка, а не единственный способ совместной работы;
#Ограничения протоколов
- циклы в
dagзапрещены (валидация как вplan— reject до запуска,effect: none); - глубина делегирования ограничена
MaxDelegationDepthядра; parallel_limitограничивает одновременные дочерние раны.
#7. Привязка слотов
Привязка выполняется при запуске (launch-time binding):
- слот
fixed→ указанный агент; если агент невидим в скоупе запуска (ростер вызывающего + проектный скоуп) — команда не стартует с осмысленной ошибкой; - слот
role→ подбор из ростера по требованиям: capabilities (семантика карточек ростера: незаданная capability = разрешена, явныйfalseотсекает;delegation— только явная выдача) и skills;preferred_agent_idиспользуется как тай-брейк при нескольких кандидатах, а не как обязательство; однозначный кандидат привязывается автоматически; - несколько равных кандидатов без preferred → запуск отклоняется (409) со списком кандидатов для явного выбора; ноль кандидатов → отклонение (422) с перечнем требований;
- пользователь при запуске может зафиксировать привязки в
bindings(они обязаны попадать в ростер) или предварительно посмотреть разрешение черезGET /v1/agent/teams/{id}/resolve; - ни одного кандидата → честная ошибка до старта, без частичного запуска (effect=none).
Подбор не пытается быть умнее пользователя: он либо находит однозначного кандидата, либо показывает короткий список на подтверждение.
#8. Создание команды (Formation)
Wizard по образцу Skill Builder:
Пользователь описывает задачу команды естественным языком:
«Нужна команда, которая реализует фичи: один кодер пишет, ревьюер проверяет, QA прогоняет тесты».
Team Builder Agent:
- интерпретирует описание;
- выбирает протокол;
- определяет слоты, ответственность, требования и контракты;
- подтягивает доступных агентов и их capabilities из системы;
- формирует черновик определения.
Происхождение значений визуально различается (как у skills): из инструкции / предложено агентом / из доступных агентов / подтверждено / требует уточнения.
Уточняющие вопросы задаются прямо в wizard:
«Ревьюер может отклонять работу кодера. Сколько кругов доработки допускаем?»
Результат открывается в обычной форме редактирования (CRUD): название, описание, протокол, слоты, дефолты. Пользователь правит то, что агент понял неточно.
Обязательный опрос не проводится: если значение разумно выводится — оно выводится и помечается.
#Режим «Переформировать»
При существенном изменении описания пользователь может переформировать определение. Перед заменой показывается diff и затронутые ручные правки; ничего не теряется молча (как у агентов, docs/evaluable-agent.md §13).
#Шаблоны команд
Продукт поставляется с шаблонами («Code Delivery», «Research Fan-out», «Delivery + QA gate»), а не с предсозданными командами — по уроку встроенных агентов: шаблон хороший, создавать сущность под себя — пользователь.
#9. Командный запуск
POST /v1/agent/teams/{team_id}/runs
{ project, goal, bindings?: { slot_id: agent_id }, version?: 3 }
Порядок в ядре:
- загрузить определение (указанную или последнюю версию);
- снапшотировать его в контекст запуска;
- разрешить привязки слотов (§7) — все до старта;
- скомпилировать протокол в последовательность
plan/delegateвызовов; - исполнять как обычные дочерние AgentRun-ы с существующими гарантиями (каузальность, отмена вниз по дереву, бюджеты).
#События
Существующие delegation.* и plan.* сохраняются без изменений. Добавляются:
team.started—{ team_id, version, goal, bindings };slot.bound—{ slot_id, agent_id, mode: fixed | matched };team.completed—{ status, total_tokens, cost_usd, rework_rounds }(по образцуrun.completedс итогами);team.failed— с причиной и указанием слота/шага.
Таким образом существующие панели (DelegationTree, PlanGraph, трейс) работают для командных запусков без переделки.
#10. Командный контекст
#Team scratch
Общее персистентное хранилище в рамках командного запуска (префикс в существующем workspace storage):
- скоуп —
team run id, доступ на чтение/запись у всех слотов; - очищается по TTL после завершения запуска;
- путь передаётся каждому дочернему рану явно.
#Артефакты контрактов
Контракт выхода слота записывается в team scratch (файлом), а зависимые слоты получают и текст в промпте, и ссылку на артефакт. Длинные результаты (логи, диффы, отчёты) не раздувают промпты.
#Scoped hints
Знания, сформированные внутри командного запуска (knowledge.proposed → confirmed), доступны подсказками всем слотам этого запуска — команда учится в рамках задачи. Глобальные знания — как обычно, через эффективную видимость.
#11. Наблюдаемость
- Дерево вызовов и DAG — существующие компоненты, работают из коробки.
- Rollup уровня команды: токены, стоимость, длительность, число rework-циклов, споры (RunDisputes). Эндпоинт стоимости:
GET /v1/agent/cost/team-run. - В панели Runs — группировка по команде: «Code Delivery · 214 запусков за неделю» с подсвеченными паттернами (частые отклонения, дорогие шаги).
- Точка «где агенты друг друга сбили с толку» — цепочка
plan.task.rejected→reopened: видно, чей вердикт отправил чью работу на доработку и с каким фидбеком.
#12. Эволюция команды
На вкладке «Эволюция» карточки команды — сопоставление версий определения с результатами:
v3 ● текущая
↑ 214 запусков
↑ accept-first-try 71% (+9 к v2)
↑ средние rework-циклы 0.6 (−0.4)
↑ 1 предложение изменения
──────────────────────────────────────────
Изменение v2 → v3: добавлен слот QA, max_rework 3 → 2
Причина: 12% запусков v2 упирались в лимит доработок
[Посмотреть доказательства]
Метрики по версии определения:
- accept-first-try — доля задач, принятых ревью с первой попытки;
- среднее число rework-циклов на задачу;
- стоимость/длительность запуска;
- доля споров, разрешённых доработкой.
Evolution proposals — по модели docs/living-skills.md: система обнаруживает устойчивые паттерны из evidence запусков (например, «ревьюер отклоняет 70% работ слота coder → предложить добавить шаг self-check или сменить пару») и предлагает изменение определения; человек смотрит доказательства и принимает или отклоняет. Проваливание в первоисточник сохраняется: proposal → evidence → executions → trajectories → knowledge → версия определения.
#13. Видимость и доступ
team.org_unit_id— как у агентов, skills и MCP-серверов:NULL= вся инсталляция, иначе узел оргструктуры + поддерево;- слот привязывается только к агенту, видимому в скоупе команды;
- списки команд фильтруются по эффективной видимости вызывающего;
- роли на узлах действуют как обычно (docs/org-structure.md §13).
#14. Безопасность
- Права дочерних ранов — собственные права их агентов; команда не эскалирует.
- Policy-подтверждения применяются к каждому слоту как к обычному агенту; командные ворота — не замена policy-гейтам.
- HITL-запросы уходят по каналам инициатора запуска (docs/triggers-and-escalations.md); командный запуск можно поставить на паузу целиком.
- Бюджет команды — сумма бюджетов шагов (заявлено; сейчас принуждаются
per-run бюджеты политик и
parallel_limit, командныйbudget_usdхранится и показывается, но не останавливает запуск).
#15. API
GET/POST/PUT/DELETE /v1/workspace/teams— CRUD (+org_unit_id);GET /v1/workspace/teams/{id}/versions— история версий;POST /v1/agent/teams/{id}/runs— запуск (goal, bindings, version);GET /v1/agent/teams/{id}/resolve?project=&version=— предпросмотр привязок для UI (кто будет выбран и почему);- Статус и дерево — через общие run-вью и события
team.*в журнале; POST /v1/agent/teams/{teamID}/runs— запуск,GET /v1/agent/teams/{teamID}/resolve— резолв слотов;GET /v1/agent/cost/team-run?run_id=— rollup стоимости/токенов;POST /v1/workspace/teams/builder— formation (описание → черновик определения).
Списки фильтруются по эффективной видимости; для admin-токенов ядра — без фильтра (как у остальных ресурсов).
#16. UI
- Раздел «Команды»: список с фильтром (по аналогии с агентами и skills).
- Карточка команды, вкладки:
- Основное — название, описание, протокол, дефолты;
- Состав — слоты: ответственность, требования, контракт, привязка; для
role— подсказки подходящих агентов; - Запуски — история с rollup-метриками;
- Эволюция — версии, метрики, предложения (§12).
- Запуск: выбор проекта, цель, подтверждение привязок
role-слотов. - Командный запуск визуализируется существующими DelegationTree + PlanGraph + сводкой (токены / стоимость / rework).
- Formation wizard (§8) с индикацией происхождения значений.
- Поля «Доступность» (org unit) — как у остальных ресурсов.
#17. Связь с существующими механизмами
| Механизм | Отношение |
|---|---|
plan / delegate |
двигатели; команда компилируется в них, отдельный оркестратор не вводится |
| Acceptance gates | ворота протоколов review_gate/dag — это они |
| DelegationTree / PlanGraph | работают для командных запусков без переделки |
| RunDisputes | споры агрегируются в метрики команды |
| Cost accounting | rollup поверх существующего per-run учёта |
| Knowledge / hints | scoped hints внутри командного запуска (§10) |
| Org structure | модель видимости переиспользуется целиком |
| Approval model | применяется к каждому слоту без изменений |
| Пример LeadCoderReviewerQA | мигрирует в шаблон команды pipeline; код примера удаляется |
#18. Анти-паттерны (зафиксировано осознанно)
- N-агентный свободный чат как протокол.
- Команда как постоянно работающий «отдел» с фоновым общением.
- Слот, навсегда прибитый к одному агенту.
team.yamlкак пользовательская форма.- Новый движок оркестрации вместо компиляции в
plan/delegate. - Неявный общий контекст «все видят всё».
- Скрытие структуры команды от пользователя.
#19. Фазы реализации
- Фаза 1 — Модель и API:
workspace_team+ версии, слоты и протоколы как данные, CRUD, org-видимость, тесты эффективной видимости. - Фаза 2 — Рантайм: компиляция
pipeline,review_gate,dagвplan/delegate; событияteam.*; снапшот определения; запуск и отмена; сквозные Go-тесты (порядок событий, снапшот при изменении определения, бюджеты). - Фаза 3 — Привязка слотов:
fixedиrole-подбор, подтверждение/замена в UI, ошибки unresolved-slot, тесты матчинга на capabilities и видимость. - Фаза 4 — UI команд: раздел, карточка с вкладками, запуск, rollup-сводка, группировка в Runs.
- Фаза 5 — Formation: Team Builder Agent, wizard, происхождение значений, «Переформировать» с diff.
- Фаза 6 — Командный контекст: team scratch, артефакты контрактов, scoped hints.
- Фаза 7 — Телеметрия и эволюция: метрики версий, evolution proposals, вкладка «Эволюция».
- Фаза 8 — Миграция примера: LeadCoderReviewerQA → шаблон
pipeline; поставка шаблонов команд.
#20. Критерии готовности (MVP, фазы 1–4)
- Команду можно создать формой, сохранить, отредактировать (новая версия), удалить.
- Запуск
pipeline-команды выполняется как дерево дочерних ранов; событияteam.*иplan.*/delegation.*в журнале в правильном порядке. review_gate-команда проходит полный цикл: работа → отклонение → доработка → принятие.- Слот
roleнаходит агента по capabilities либо команда не стартует с понятной ошибкой. - В Runs видно дерево, DAG и rollup токенов/стоимости командного запуска.
- Изменение определения после старта не влияет на идущий запуск (тест).
- Команда не расширяет права участников (тест на эскалацию).
- Список команд и кандидатов на привязку фильтруется org-видимостью (тест).
- Пользователь ни в одном сценарии не видит
team.yaml.
#21. Открытые вопросы
- Подбор для
role-слотов: только capabilities или также skills и история успеха агента на этой роли? - Нужны ли командам расписания/триггеры (связка с docs/triggers-and-escalations.md)?
- Допускать ли вложение команд (команда как слот другой команды) — пока осознанно нет, глубина делегирования и так ограничена.
- Нужен ли аудит привязок «кто кого назначил» — предположительно да, в журнале изменений команды (фаза 7).