Делегирование подагентам

Инструмент delegate_task обеспечивает дочерние экземпляры AIAgent с изолированным контекстом, ограниченными наборами инструментов и собственными сессиями терминала. Каждый дочерний агент получает новый разговор и работает независимо — только его окончательная сводка выводится в контекст родителя.

Одиночная задача

delegate_task(
    goal="Отладить, почему падают тесты",
    context="Ошибка: assertion в test_foo.py строка 42",
    toolsets=["terminal", "file"]
)

Параллельный пакет

До 3-х одновременных подагентов по умолчанию (на предупреждение, без жёсткого ограничения):

delegate_task(tasks=[
    {"goal": "Исследовать тему A", "toolsets": ["web"]},
    {"goal": "Исследовать тему B", "toolsets": ["web"]},
    {"goal": "Исправить сборку", "toolsets": ["terminal", "file"]}
])

Как работает контекст подагента:::предупреждение Критически: подагенты ничего не знают

Подагенты проводят с полностью новым разговором. У них нет никаких знаний об истории разговора родителя, предыдущих вызовах инструментов или чего-либо, обсуждаемого до рассмотрения дела. Ни один контекстный подагент получается из полей goal и context, которые родительский агент выполняет при вызове delegate_task.

Это означает, что родительский агент должен передать все, что нужно подагенту, в вызове:

# ПЛОХО - подагент понятия не имеет, что такое "ошибка"
delegate_task(goal="Исправить ошибку")

# ХОРОШО - подагент имеет весь необходимый контекст
delegate_task(
    goal="Исправить TypeError в api/handlers.py",
    context="""Файл api/handlers.py содержит TypeError на строке 47:
    'NoneType' object has no attribute 'get'.
    Функция process_request() получает dict от parse_body(),
    но parse_body() возвращает None, когда отсутствует Content-Type.
    Проект находится в /home/user/myproject и использует Python 3.11."""
)

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

Практические образцы

Параллельное исследование

Исследуйте несколько тем одновременно и соберите сводки:

delegate_task(tasks=[
    {
        "goal": "Исследовать текущее состояние WebAssembly в 2025 году",
        "context": "Сосредоточиться на: поддержка браузеров, среда выполнения вне браузера, поддержка языков",
        "toolsets": ["web"]
    },
    {
        "goal": "Исследовать текущее состояние внедрения RISC-V в 2025 году",
        "context": "Сосредоточиться на: серверные чипы, встраиваемые системы, экосистема ПО",
        "toolsets": ["web"]
    },
    {
        "goal": "Исследовать прогресс квантовых вычислений в 2025 году",
        "context": "Сосредоточиться на: прорывы в коррекции ошибок, практические применения, ключевые игроки",
        "toolsets": ["web"]
    }
])

Проверка кода + исправление

Делегируйте рабочие проверки и исправления процессов в новом контексте:

delegate_task(
    goal="Проверить модуль аутентификации на наличие проблем безопасности и исправить найденные",
    context="""Проект в /home/user/webapp.
    Файлы модуля аутентификации: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py.
    Проект использует Flask, PyJWT и bcrypt.
    Сосредоточиться на: SQL-инъекции, проверка JWT, обработка паролей, управление сессиями.
    Исправить все найденные проблемы и запустить тестовый набор (pytest tests/auth/).""",
    toolsets=["terminal", "file"]
)

Многофайловый рефакторинг

Делегируйте крупную задачу рефакторинга, которая засорила контекст родителя:

delegate_task(
    goal="Выполнить рефакторинг всех Python-файлов в src/, заменив print() на правильное логирование",
    context="""Проект в /home/user/myproject.
    Используйте модуль 'logging' с logger = logging.getLogger(__name__).
    Замените вызовы print() на соответствующие уровни логирования:
    - print(f"Error:...") -> logger.error(...)
    - print(f"Warning:...") -> logger.warning(...)
    - print(f"Debug:...") -> logger.debug(...)
    - Остальные print -> logger.info(...)
    Не меняйте print() в тестовых файлах или выводе CLI.
    Запустите pytest после, чтобы убедиться, что ничего не сломалось.""",
    toolsets=["terminal", "file"]
)

Детали пакетного режима

Когда вы обеспечиваете массив «задач», подагенты выполняются параллельно с использованием пула потоков:

Делегирование одной задачи напрямую без накладных расходов пула потоков.

Переопределение модели

Вы можете настроить другую модель для подагентов через config.yaml — полезно для решения простых задач на более дешёвых/быстрых моделях:

# В ~/.hermes/config.yaml
delegation:
  model: "google/gemini-flash-2.0"    # Более дешёвая модель для подагентов
  provider: "openrouter"              # Опционально: направить подагентов к другому провайдеру

Если опущено, подагенты используют ту же модель, что и спонсор.

Советы по выбору набора инструментов

Параметр toolsets определяет, каким инструментам будет доступен подагент. В зависимости от задачи:

Инструменты для выкройки Сценарий использования
["терминал", "файл"] Работа с кодом, отладка, редактирование файлов, сборка
["паутина"] Исследование, проверка фактов, поиск документации
["терминал", "файл", "сеть"] Полноценные задачи (по умолчанию)
["файл"] Анализ только для чтения, проверка кода без выполнения
["терминал"] Системное администрирование, управление процессами

Некоторые наборы инструментов заблокированы для подагентов независимо от того, что вы указываете: - делегирование — заблокировано для листовых подагентов (по умолчанию). Сохраняется для дочерних агентов с role="orchestrator", ограниченным max_spawn_length — см. Ограничение глубины и вложенная оркестрация ниже. - «уточнить» — подагенты не могут взаимодействовать с пользователем - память — нет записи в постоянную память - code_execution — дочерние агенты должны обдумать пошаговое руководство. - send_message — нет кросс-платформенных переключателей (например, отправка сообщений Telegram)

Максимальное количество итераций

Каждый подагент имеет лимит итераций (по умолчанию: 50), который контролирует, сколько шагов с помощью инструмента вызова он может выполнить:

delegate_task(
    goal="Быстрая проверка файла",
    context="Проверить, существует ли /etc/nginx/nginx.conf, и вывести первые 10 строк",
    max_iterations=10  # Простая задача, не нужно много шагов
)

Тайм-аут дочернего агента

Подагенты убиваются как зависшие, если они молчат, продолжая delegation.child_timeout_секунды секунд реального времени. По умолчанию 600 (10 минут) — увеличено с 300 с в более ранних версиях, потому что модели с постоянным распределением нетривиальных исследовательских задач убивались в середине размышления. Настройте под свою установку:

delegation:
  child_timeout_seconds: 600   # по умолчанию

Уменьшите для быстрых локальных моделей; Увеличьте для более медленных моделей рассуждения о сложных задачах. Таймер сбрасывается каждый раз, когда дочерний агент делает API-вызов или инструмент вызова — только бездействующие рабочие вызывают убийство.

💡 Tip

Диагностический дамп при тайм-ауте с нулевыми вызовами Если подагент истекает по тайм-ауту, выполняется ноль API-вызовов (обычно: провайдер недоступен, ошибка аутентификации или инструмент схемы отклонения), delegate_task записывает структурированную оценку в ~/.hermes/logs/subagent-timeout-<session>-<timestamp>.log, содержащую образ конфигурации подагента, трассировку разрешения учётных данных и любые сообщения об ошибках. Это значительно упрощенный поиск корневой причины по сравнению с поведением молчаливого тайм-аута.

Мониторинг запущенных подагентов (/agents)

TUI вызывает с применением /agents (псевдоним /tasks), преобразует рекурсивное развёртывание delegate_task в первую поверхность аудита:

Классический CLI просто выводит /agents как текстовую сводку; TUI — это место, где наложение сияет. См. TUI — Слэш-команды.

Ограничение силы и вложенная оркестрация

По умолчанию делегирование плоское: доля (глубина 0) блокчейна дочерних агентов (глубина 1), и эти дочерние агенты не могут гировать дальше. Это собственная неконтролируемая рекурсивная делегация.

Для многоэтапных рабочих процессов (исследование → синтез, или параллельная оркестрация под задачи) руководитель может породить дочерних агентов-оркестраторов, которые могут делегировать свои собственные рабочие процессы:

delegate_task(
    goal="Изучить три подхода к проверке кода и рекомендовать один",
    role="orchestrator",  # Позволяет этому дочернему агенту порождать свои собственные рабочие процессы
    context="...",
)

Предупреждение о затратах: При max_spawn_depth: 3 и max_concurrent_children: 3 дерево может достичь 3×3×3 = 27 одновременных листовых агентов. Каждый дополнительный уровень умножает расходы — увеличивайте max_spawn_depth осознанно.

Время жизни и долговечность

⚠️ Warning

delegate_task синхронен — не долговечен

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

Для долговечной длительной работы, которая должна пережить прерывания или выходить за рамки текущего шага, используйте:

Ключевые свойства

Делегирование vs execute_code

Фактор delegate_task execute_code
Рассуждение Полный цикл рассуждения LLM Только выполнение Python-кода
Контекст Новый изолированный разговор Нет разговора, только скрипт
Доступ к инструментам Все неблокированные инструменты с рассуждением 7 инструментов через RPC, без рассуждения
Параллелизм 3 одновременных подагента по умолчанию (настраивается) Один скрипт
Лучше всего для Сложных задач, требующих суждения Механических многошаговых конвейеров
Стоимость токенов Выше (полный цикл LLM) Ниже (возвращается только stdout)
Взаимодействие с пользователем Нет (подагенты не могут уточнять) Нет

Правило большого пальца: Используйте delegate_task, когда подзадача требует рассуждения, суждения или многошагового решения проблем. Используйте execute_code, когда вам нужна механическая обработка данных или скриптовые рабочие процессы.

Конфигурация

```yaml

В ~/.hermes/config.yaml

delegation: max_iterations: 50 # Максимум шагов на дочернего агента (по умолчанию: 50) # max_concurrent_children: 3 # Параллельных дочерних агентов на пакет (по умолчанию: 3) # max_spawn_depth: 1 # Глубина дерева (1-3, по умолчанию 1 = плоское). Увеличьте до 2, чтобы разрешить дочерним агентам-оркестраторам порождать листовых; до 3 для трёх уровней. # orchestrator_enabled: true # Отключите, чтобы принудительно установить всем дочерним агентам роль leaf. model: "google/gemini-3-flash-preview" # Опциональное переопределение провайдера/модели provider: "openrouter" # Опциональный встроенный провайдер

Или используйте прямую пользовательскую конечную точку вместо провайдера:

delegation: model: "qwen2.5-coder" base_url: "http://localhost:1234/v1" api_key: "local-key" ```:::совет Агент обрабатывает делегирование автоматически в зависимости от сложности задачи. Вам не нужно явно просить его делегировать — он сделал это, когда это имеет смысл.