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

Субагенты

Субагенты — это фоновые запуски агента, создаваемые из уже существующего запуска. Они работают в собственной сессии (agent:<agentId>:subagent:<uuid>) и по завершении объявляют свой результат обратно в чат запрашивающей стороны.

Слеш-команда

Используйте /subagents, чтобы просматривать и управлять запусками субагентов в текущей сессии:
  • /subagents list
  • /subagents kill <id|#|all>
  • /subagents log <id|#> [limit] [tools]
  • /subagents info <id|#>
  • /subagents send <id|#> <message>
/subagents info показывает метаданные запуска (статус, временные метки, id сессии, путь к транскрипту, очистка). Основные цели:
  • Параллелить «исследование / длительные задачи / медленные инструменты», не блокируя основной запуск.
  • Держать субагентов изолированными по умолчанию (разделение сессий + опциональная песочница).
  • Минимизировать риск неправильного использования инструментов: субагенты не получают session-инструменты по умолчанию.
  • Поддерживать настраиваемую глубину вложенности для оркестраторных паттернов.
Примечание о стоимости: каждый субагент имеет собственный контекст и расход токенов. Для тяжёлых или повторяющихся задач задавайте более дешёвую модель для субагентов, а основной агент оставляйте на более качественной модели. Это настраивается через agents.defaults.subagents.model или переопределения на уровне агента.

Инструмент

Используйте sessions_spawn:
  • Запускает субагента (deliver: false, глобальная очередь: subagent)
  • Затем выполняет шаг announce и публикует announce-ответ в чат запрашивающей стороны
  • Модель по умолчанию: наследуется от вызывающего агента, если не задано agents.defaults.subagents.model (или agents.list[].subagents.model); явный sessions_spawn.model имеет приоритет.
  • Thinking по умолчанию: наследуется от вызывающего агента, если не задано agents.defaults.subagents.thinking (или agents.list[].subagents.thinking); явный sessions_spawn.thinking имеет приоритет.
Параметры инструмента:
  • task (обязательно)
  • label? (необязательно)
  • agentId? (необязательно; запустить под другим agent id, если разрешено)
  • model? (необязательно; переопределяет модель субагента; недопустимые значения игнорируются, и субагент запускается на модели по умолчанию с предупреждением в результате инструмента)
  • thinking? (необязательно; переопределяет уровень thinking для запуска субагента)
  • runTimeoutSeconds? (по умолчанию 0; если задано, запуск субагента будет прерван через N секунд)
  • cleanup? (delete|keep, по умолчанию keep)
Список разрешённых агентов:
  • agents.list[].subagents.allowAgents: список agent id, которые можно указывать через agentId (["*"] — разрешить любые). По умолчанию: только агент-инициатор.
Обнаружение:
  • Используйте agents_list, чтобы увидеть, какие agent id сейчас разрешены для sessions_spawn.
Автоархивация:
  • Сессии субагентов автоматически архивируются через agents.defaults.subagents.archiveAfterMinutes (по умолчанию: 60).
  • Архивация использует sessions.delete и переименовывает транскрипт в *.deleted.<timestamp> (в той же папке).
  • cleanup: "delete" архивирует сразу после announce (транскрипт сохраняется через переименование).
  • Автоархивация выполняется по принципу best-effort; ожидающие таймеры теряются при перезапуске gateway.
  • runTimeoutSeconds не архивирует автоматически; он только останавливает запуск. Сессия остаётся до автоархивации.
  • Автоархивация одинаково применяется к сессиям глубины 1 и глубины 2.

Вложенные субагенты

По умолчанию субагенты не могут создавать собственных субагентов (maxSpawnDepth: 1). Вы можете разрешить один уровень вложенности, установив maxSpawnDepth: 2, что позволяет использовать паттерн оркестратора: основной → субагент-оркестратор → суб-субагенты-воркеры.

Как включить

{
  agents: {
    defaults: {
      subagents: {
        maxSpawnDepth: 2, // разрешить субагентам создавать дочерние (по умолчанию: 1)
        maxChildrenPerAgent: 5, // макс. активных дочерних на сессию агента (по умолчанию: 5)
        maxConcurrent: 8, // глобальный лимит конкурентности очереди (по умолчанию: 8)
      },
    },
  },
}

Уровни глубины

DepthSession key shapeRoleCan spawn?
0agent:<id>:mainОсновной агентВсегда
1agent:<id>:subagent:<uuid>Субагент (оркестратор при depth 2)Только если maxSpawnDepth >= 2
2agent:<id>:subagent:<uuid>:subagent:<uuid>Суб-субагент (воркер)Никогда

Цепочка announce

Результаты поднимаются вверх по цепочке:
  1. Воркер глубины 2 завершает работу → объявляет родителю (оркестратору глубины 1)
  2. Оркестратор глубины 1 получает announce, синтезирует результаты, завершает работу → объявляет основному агенту
  3. Основной агент получает announce и доставляет результат пользователю
Каждый уровень видит announce только от своих прямых дочерних сессий.

Политика инструментов по глубине

  • Depth 1 (оркестратор, когда maxSpawnDepth >= 2): получает sessions_spawn, subagents, sessions_list, sessions_history, чтобы управлять дочерними. Остальные session/system-инструменты остаются запрещены.
  • Depth 1 (лист, когда maxSpawnDepth == 1): без session-инструментов (текущее поведение по умолчанию).
  • Depth 2 (воркер): без session-инструментов — sessions_spawn всегда запрещён на глубине 2. Не может создавать дальнейших дочерних.

Лимит дочерних на агента

Каждая сессия агента (на любой глубине) может иметь не более maxChildrenPerAgent (по умолчанию: 5) активных дочерних одновременно. Это предотвращает неконтролируемый fan-out от одного оркестратора.

Каскадная остановка

Остановка оркестратора глубины 1 автоматически останавливает всех его дочерних глубины 2:
  • /stop в основном чате останавливает всех агентов глубины 1 и каскадно их дочерних глубины 2.
  • /subagents kill <id> останавливает конкретного субагента и каскадно его дочерних.
  • /subagents kill all останавливает всех субагентов инициатора и каскадирует остановку.

Аутентификация

Аутентификация субагента определяется по id агента, а не по типу сессии:
  • Ключ сессии субагента — agent:<agentId>:subagent:<uuid>.
  • Хранилище auth загружается из agentDir соответствующего агента.
  • Профили auth основного агента добавляются как fallback; профили агента имеют приоритет при конфликте.
Примечание: объединение аддитивное, поэтому профили основного агента всегда доступны как fallback. Полная изоляция auth на уровне агента пока не поддерживается.

Announce

Субагенты отчитываются через шаг announce:
  • Шаг announce выполняется внутри сессии субагента (не в сессии инициатора).
  • Если субагент отвечает ровно ANNOUNCE_SKIP, ничего не публикуется.
  • В противном случае announce-ответ публикуется в чат инициатора через follow-up вызов agent (deliver=true).
  • Announce-ответы сохраняют маршрутизацию тредов/тем, где это поддерживается (Slack threads, Telegram topics, Matrix threads).
  • Announce-сообщения нормализуются к стабильному шаблону:
    • Status: определяется по результату выполнения (success, error, timeout или unknown).
    • Result: краткое содержание из шага announce (или (not available), если отсутствует).
    • Notes: детали ошибок и полезный контекст.
  • Status не выводится из ответа модели; он определяется сигналами выполнения.
Announce-пейлоады включают строку статистики в конце (даже если сообщение обёрнуто):
  • Время выполнения (например, runtime 5m12s)
  • Расход токенов (input/output/total)
  • Оценочная стоимость, если настроены цены моделей (models.providers.*.models[].cost)
  • sessionKey, sessionId и путь к транскрипту (чтобы основной агент мог получить историю через sessions_history или открыть файл на диске)

Политика инструментов (инструменты субагента)

По умолчанию субагенты получают все инструменты, кроме session-инструментов и системных инструментов:
  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn
Когда maxSpawnDepth >= 2, субагенты-оркестраторы глубины 1 дополнительно получают sessions_spawn, subagents, sessions_list и sessions_history, чтобы управлять своими дочерними. Переопределение через конфигурацию:
{
  agents: {
    defaults: {
      subagents: {
        maxConcurrent: 1,
      },
    },
  },
  tools: {
    subagents: {
      tools: {
        // deny wins
        deny: ["gateway", "cron"],
        // if allow is set, it becomes allow-only (deny still wins)
        // allow: ["read", "exec", "process"]
      },
    },
  },
}

Конкурентность

Субагенты используют выделенную очередь внутри процесса:
  • Имя очереди: subagent
  • Конкурентность: agents.defaults.subagents.maxConcurrent (по умолчанию 8)

Остановка

  • Отправка /stop в чат инициатора прерывает его сессию и останавливает все активные запуски субагентов, созданные из неё, включая вложенных дочерних.
  • /subagents kill <id> останавливает конкретного субагента и каскадно его дочерних.

Ограничения

  • Announce субагента выполняется по принципу best-effort. При перезапуске gateway ожидающие announce-задачи теряются.
  • Субагенты используют те же ресурсы процесса gateway; рассматривайте maxConcurrent как предохранитель.
  • sessions_spawn всегда неблокирующий: он немедленно возвращает { status: "accepted", runId, childSessionKey }.
  • Контекст субагента включает только AGENTS.md + TOOLS.md (без SOUL.md, IDENTITY.md, USER.md, HEARTBEAT.md или BOOTSTRAP.md).
  • Максимальная глубина вложенности — 5 (maxSpawnDepth диапазон: 1–5). Для большинства случаев рекомендуется глубина 2.
  • maxChildrenPerAgent ограничивает число активных дочерних на сессию (по умолчанию: 5, диапазон: 1–20).