Сначала план, потом fan-out
Каждый запуск начинается с Coordinator. LLM разбивает запрос на подзадачи, и эти подзадачи сохраняются в базу до того, как что-либо запустится, — поэтому запуск можно инспектировать, возобновлять и проверять. Только затем начинается fan-out: каждая подзадача получает свой AgentRuntime — либо как tokio-задачу внутри JoinSet (по умолчанию — один процесс, лёгкий), либо, с use_multiprocess = true, как отдельный OS-процесс, управляемый ProcessManager и общающийся через Unix domain sockets.
Флот намеренно неоднороден. Исследователи используют web_search, web_fetch и extract_contacts; аналитики — file_read и python_exec; персоны (hunter, analyst, validator или ваш собственный TOML-профиль) заранее настраивают промпты, модели и лимиты глубины. Каждый depth-0 агент также получает дайджест памяти в промпт, поэтому флот стартует со всем, что уже узнали прошлые запуски.
Собирать с бюджетами, а не транскриптами
Параллельный fan-out полезен настолько, насколько эффективен сбор результатов. Субагенты не возвращают полный контекст целиком — результаты агрегируются и сжимаются в компактные сводки в рамках бюджета. Это сохраняет контекст координатора чистым для управления всей группой, пока сырые данные надёжно сохраняются в SQLite. Порядок и авторство данных полностью сохраняются при передаче: каждая сводка привязана к подзадаче и выполнившему её агенту.
Рефлексия и LLM-судья
За сбором следует рефлексия. Для генерации лидов она основана на количестве: если квота контактов не набрана, координатор запускает раунды восполнения, пока цель не будет достигнута или попытки не иссякнут. Затем, если включён Goal Mode, LLM-судья сравнивает собранный результат с исходной целью — а не с планом. Где он называет конкретные пробелы, запускаются новые подзадачи восполнения; цикл идёт до replan_rounds раундов. Судья — то, что не даёт запуску «выполнить план», упустив суть.
Синтезировать, экспортировать, уведомить
Наконец координатор синтезирует: LLM объединяет находки в единый отчёт, записываемый как index.md, summary.md и каталог findings/. Сводка сессии и найденные контакты поглощаются в долговременную память — следующий fan-out стартует умнее. Затем экспорт (PDF, HTML, JSON, DOCX) и уведомление (webhook, email, Telegram), плюс опциональная синхронизация CRM. Один запрос на входе; готовый артефакт на выходе.
Отказ — часть дизайна
Флоты отказывают так, как одиночные агенты не могут, поэтому control plane это предполагает. DoomLoopDetector следит за тремя одинаковыми вызовами инструментов подряд и останавливает цикл до того, как тот сожжёт бюджет. Токены отмены распространяются по всему дереву агентов, поэтому отмена запуска отменяет каждого ребёнка; сбой shell каскадируется на соседние вызовы инструментов вместо того, чтобы оставить наполовину выполненные батчи. В multiprocess-режиме каждый воркер — изолированный OS-процесс с семантикой kill_on_drop — один краш никогда не положит флот, — а координатор следит за таймаутами зависания: предупреждение на 450 секунд, убийство на 1200.
Работа координатора — не запускать агентов. Это держать бюджет, удерживать цель и знать, когда остановиться, — всё остальное механика.
— Fathom, заметки об архитектуре
Тот же цикл, на уровень ниже
Каждый субагент выполняет стандартный автономный цикл: сборка промпта в три кеш-уровня, проверка на зацикливание (doom-loop), оценка токенов и компактификация, стриминг ответов LLM, фильтрация инструментов через шлюзы политик безопасности, пакетное выполнение вызовов (чтение параллельно, запись последовательно) до полного завершения. Fan-out — это масштабирование базового цикла под контролем координатора, гарантирующего согласованность параллельных результатов.