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

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

Инструмент 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"]}
])

Мультизадача на ходу (Mid-run Multitask)​

Когда вам нужна параллельная работа, пока родительский ход ещё идёт (как Cursor /multitask), используйте продуктовую поверхность — не новый core-инструмент:

ДействиеЭффект
/multitask <цель> / /mtСейчас запустить фонового leaf-субагента
Desktop Alt/⌥+EnterТо же из composer, пока агент busy
Plan tab Build parallelПервая готовая волна чекбоксов плана → до 3 детей
Plan tab ReviseMid-run [PLAN REVISE] steer — родитель перечитывает план

Обёртка над delegate_task(..., background=True) с лимитами и safety:

  • Cap: delegation.max_concurrent_children × delegation.multitask.max_prompts_per_dispatch (по умолчанию 3)
  • Предупреждение о пересечении путей (опционально блок)
  • Мягкий бюджет символов промпта
  • Leaf-дети не могут рекурсивно мультитаскить
# ~/.vibeos/config.yaml
delegation:
multitask:
enabled: true
max_prompts_per_dispatch: 3
warn_on_write_overlap: true
block_on_write_overlap: false
max_estimated_prompt_chars: 12000
use_worktrees: false
worktree_sync: true
cleanup_worktrees_on_complete: true

При use_worktrees: true у каждого ребёнка свой checkout (хелперы vibeos -w) и cwd pin. После завершения дерево удаляется, если нет незапушенных коммитов (cleanup_worktrees_on_complete). Тумблеры — Desktop Settings → Advanced.

Очередь vs Steer vs Multitask
  • Очередь — потом, после текущего хода
  • Steer (/steer / ⌘Enter) — шепот в тот же run после следующего tool batch
  • Multitask — вторая пара рук сейчас (отдельный контекст; назад приходит summary)

Offline smoke: scripts/smoke-multitask-midrun.sh и scripts/smoke-plan-build-parallel.sh.

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

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

Субагенты начинают с совершенно нового разговора. Они ничего не знают об истории разговоров родителя, предыдущих вызовах инструментов или обо всем, что обсуждалось перед делегированием. Единственный контекст субагента поступает из полей 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, субагенты работают параллельно, используя пул потоков:

  • Максимальный параллелизм: 3 задачи по умолчанию (настраивается через delegation.max_concurrent_children или переменную окружения DELEGATION_MAX_CONCURRENT_CHILDREN; этаж 1, без жесткого потолка). Пакеты, превышающие лимит, возвращают ошибку инструмента, а не автоматически усекаются.
  • Пул потоков: использует ThreadPoolExecutor с настроенным пределом параллелизма в качестве максимального количества рабочих процессов.
  • Отображение хода выполнения. В режиме CLI в виде дерева отображаются вызовы инструментов от каждого субагента в режиме реального времени со строками завершения каждой задачи. В режиме шлюза прогресс группируется и передается обратному вызову родительского процесса.
  • Упорядочение результатов. Результаты сортируются по индексу задачи, чтобы соответствовать порядку ввода, независимо от порядка завершения.
  • Распространение прерываний: прерывание родительского элемента (например, отправка нового сообщения) прерывает работу всех активных дочерних элементов.

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

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

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

# In ~/.vibeos/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
)

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

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

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

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

delegation:
child_timeout_seconds: 0 # default: 0 = no timeout
# child_timeout_seconds: 1800 # opt-in hard cap (floor 30s)

Положительное значение устанавливает жесткий лимит настенных часов для каждого дочернего элемента; 0 или отрицательное значение отключает его.

Диагностический дамп при тайм-ауте нулевого вызова

При настроенном жестком ограничении, если у субагента истекло время ожидания нулевых вызовов API (обычно: недоступен поставщик, сбой аутентификации или отклонение схемы инструмента), delegate_task записывает в ~/.vibeos/logs/subagent-timeout-&lt;session&gt;-&lt;timestamp&gt;.log структурированную диагностику, содержащую снимок конфигурации субагента, трассировку разрешения учетных данных и любые ранние сообщения об ошибках. Гораздо проще выявить первопричину, чем в предыдущем случае с тайм-аутом.

Мониторинг работающих субагентов (/agents)​

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

  • Живое древовидное представление запущенных и недавно завершенных субагентов, сгруппированных по родительскому элементу.
  • Стоимость каждого филиала, токен и объединение файлов.
  • Элементы управления убийством и паузой — отмените конкретный субагент в процессе выполнения, не прерывая его братьев и сестер.
  • Последующий обзор: просматривайте пошаговую историю каждого субагента даже после того, как он вернулся к родительскому агенту.

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

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

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

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

delegate_task(
goal="Survey three code review approaches and recommend one",
role="orchestrator", # Allows this child to spawn its own workers
context="...",
)
  • role="leaf" (по умолчанию): дочерний элемент не может дальше делегировать — идентично поведению с плоским делегированием.
  • role="orchestrator": дочерний элемент сохраняет набор инструментов delegation. Закрыто delegation.max_spawn_depth (по умолчанию 1 = плоский, поэтому role="orchestrator" по умолчанию не работает). Увеличьте значение max_spawn_depth до 2, чтобы позволить дочерним элементам оркестратора создавать дочерние элементы листьев; 3+ для более глубоких деревьев. Верхнего потолка нет — практический предел — стоимость.
  • delegation.orchestrator_enabled: false: глобальный переключатель уничтожения, который заставляет каждого дочернего элемента использовать leaf независимо от параметра role.

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

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

Delegate_task является синхронным — ненадежным

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

  • Если родительский элемент прерывается (пользователь отправляет новое сообщение /stop, /new), все активные дочерние элементы отменяются и возвращаются status="interrupted". Их незавершенная работа отбрасывается.
  • Дети не продолжают бежать после окончания родительского хода.
  • Отмененные дочерние элементы возвращают структурированный результат (status="interrupted", exit_reason="interrupted"), но поскольку родительский элемент тоже был прерван, этот результат часто никогда не превращается в видимый пользователю ответ.

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

  • cronjob (action=create) — планирует отдельный запуск агента; невосприимчив к прерываниям родительского хода.
  • terminal(background=True, notify_on_complete=True) — долго выполняемые команды оболочки, которые продолжают выполняться, пока агент выполняет другие действия.

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

  • Каждый субагент получает свой собственный терминальный сеанс (отдельный от родительского).
  • Вложенное делегирование не является обязательным — только дочерние элементы role="orchestrator" могут делегировать дальше, и только тогда, когда max_spawn_depth повышается со значения по умолчанию, равного 1 (плоское). Отключите глобально с помощью orchestrator_enabled: false.
  • Конечные субагенты не могут вызывать: delegate_task, clarify, memory, send_message, execute_code. Субагенты оркестратора сохраняют delegate_task, но по-прежнему не могут использовать остальные четыре.
  • Распространение прерываний — прерывание родителя прерывает всех активных дочерних элементов (включая внуков под оркестраторами)
  • Только окончательная сводка входит в контекст родительского объекта, что обеспечивает эффективное использование токенов.
  • Субагенты наследуют родительский ключ API, конфигурацию поставщика и пул учетных данных (включение ротации ключей при ограничениях скорости).

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

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

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

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

# In ~/.vibeos/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 (floor 1, no ceiling, default 1 = flat). Raise to 2 to allow orchestrator children to spawn leaves; 3+ for deeper trees.
# 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
api_mode: anthropic_messages # optional; auto-detected from base_url for anthropic_messages endpoints

# Or use a direct custom endpoint instead of provider:
delegation:
model: "qwen2.5-coder"
base_url: "http://localhost:1234/v1"
api_key: "local-key"
# api_mode: "anthropic_messages" # Optional. Wire protocol override for base_url ("chat_completions", "codex_responses", or "anthropic_messages"). Empty = auto-detect from URL (e.g. /anthropic suffix). Set explicitly for endpoints the heuristic can't classify (Azure AI Foundry, MiniMax, Zhipu GLM, LiteLLM proxies, …).

Когда base_url указывает на Anthropic-совместимую конечную точку (например, путь, заканчивающийся на /anthropic, маршрут Azure Foundry Claude или прокси-сервер MiniMax /anthropic), api_mode автоматически определяется как anthropic_messages, поэтому субагент использует правильный формат передачи без каких-либо настроек. Установите api_mode явно, если предположение автоопределения неверно (редко).

подсказка

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