sidebar_position: 7 title: "Subagent Delegation" description: "Spawn isolated child agents for parallel workstreams with delegate_task" lang: ru


Делегирование субагента

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

Одна задача

delegate_task(
    goal="Debug why tests fail",
    context="Error: assertion in test_foo.py line 42",
    toolsets=["terminal", "file"]
)

Параллельная партия

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

delegate_task(tasks=[
    {"goal": "Research topic A", "toolsets": ["web"]},
    {"goal": "Research topic B", "toolsets": ["web"]},
    {"goal": "Fix the build", "toolsets": ["terminal", "file"]}
])

Как работает контекст субагента

:::Внимание Критическое: Субагенты ничего не знают Субагенты начинают с совершенно нового разговора. Они ничего не знают об истории разговоров родителя, предыдущих вызовах инструментов или обо всем, что обсуждалось перед делегированием. Единственный контекст субагента исходит из полей goal и context, которые родительский агент заполняет при вызове delegate_task.

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

# BAD - subagent has no idea what "the error" is
delegate_task(goal="Fix the error")

# GOOD - subagent has all context it needs
delegate_task(
    goal="Fix the TypeError in api/handlers.py",
    context="""The file api/handlers.py has a TypeError on line 47:
    'NoneType' object has no attribute 'get'.
    The function process_request() receives a dict from parse_body(),
    but parse_body() returns None when Content-Type is missing.
    The project is at /home/user/myproject and uses Python 3.11."""
)

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

Практические примеры

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

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

delegate_task(tasks=[
    {
        "goal": "Research the current state of WebAssembly in 2025",
        "context": "Focus on: browser support, non-browser runtimes, language support",
        "toolsets": ["web"]
    },
    {
        "goal": "Research the current state of RISC-V adoption in 2025",
        "context": "Focus on: server chips, embedded systems, software ecosystem",
        "toolsets": ["web"]
    },
    {
        "goal": "Research quantum computing progress in 2025",
        "context": "Focus on: error correction breakthroughs, practical applications, key players",
        "toolsets": ["web"]
    }
])

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

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

delegate_task(
    goal="Review the authentication module for security issues and fix any found",
    context="""Project at /home/user/webapp.
    Auth module files: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py.
    The project uses Flask, PyJWT, and bcrypt.
    Focus on: SQL injection, JWT validation, password handling, session management.
    Fix any issues found and run the test suite (pytest tests/auth/).""",
    toolsets=["terminal", "file"]
)

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

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

delegate_task(
    goal="Refactor all Python files in src/ to replace print() with proper logging",
    context="""Project at /home/user/myproject.
    Use the 'logging' module with logger = logging.getLogger(__name__).
    Replace print() calls with appropriate log levels:
    - print(f"Error: ...") -> logger.error(...)
    - print(f"Warning: ...") -> logger.warning(...)
    - print(f"Debug: ...") -> logger.debug(...)
    - Other prints -> logger.info(...)
    Don't change print() in test files or CLI output.
    Run pytest after to verify nothing broke.""",
    toolsets=["terminal", "file"]
)

Подробности пакетного режима

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

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

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

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

# In ~/.hermes/config.yaml
delegation:
  model: "google/gemini-flash-2.0"    # Cheaper model for subagents
  provider: "openrouter"              # Optional: route subagents to a different provider

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

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

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

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

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

Макс. итераций

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

delegate_task(
    goal="Quick file check",
    context="Check if /etc/nginx/nginx.conf exists and print its first 10 lines",
    max_iterations=10  # Simple task, don't need many turns
)

Дочерний тайм-аут

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

delegation:
  child_timeout_seconds: 600   # default

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

💡 Tip

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

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

TUI предоставляет наложение /agents (псевдоним /tasks), которое превращает рекурсивное разветвление delegate_task в первоклассную поверхность аудита:

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

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

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

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

delegate_task(
    goal="Survey three code review approaches and recommend one",
    role="orchestrator",  # Allows this child to spawn its own workers
    context="...",
)

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

Срок службы и долговечность

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

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

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

Делегирование против выполнения_кода

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

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

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

# In ~/.hermes/config.yaml
delegation:
  max_iterations: 50                        # Max turns per child (default: 50)
  # max_concurrent_children: 3              # Parallel children per batch (default: 3)
  # max_spawn_depth: 1                      # Tree depth (1-3, default 1 = flat). Raise to 2 to allow orchestrator children to spawn leaves; 3 for three levels.
  # orchestrator_enabled: true              # Disable to force all children to leaf role.
  model: "google/gemini-3-flash-preview"             # Optional provider/model override
  provider: "openrouter"                             # Optional built-in provider

# Or use a direct custom endpoint instead of provider:
delegation:
  model: "qwen2.5-coder"
  base_url: "http://localhost:1234/v1"
  api_key: "local-key"

:::совет Агент автоматически осуществляет делегирование в зависимости от сложности задачи. Вам не нужно явно просить его о делегировании — он сделает это, когда это имеет смысл.