От транскрипта к typed action items: три LLM-агента параллельно

Типичный meeting summarizer запихивает резюме, action items и оценку тона в один LLM-промпт — и на выходе получает кашу из разнородных задач. Автор jackchenme на Dev.to показывает другой контур: три специализированных агента обрабатывают один транскрипт параллельно, два возвращают типизированный JSON через Zod, четвёртый агрегатор склеивает всё в единый Markdown-отчёт.
Почему монолитный промпт ломает оркестрацию LLM
Когда summary, извлечение задач и sentiment живут в одном вызове модели, промпт вынужден конкурировать за внимание: prose-резюме требует свободного текста, action items — структуры с владельцем и датой, sentiment — enum тона плюс цитату-доказательство.
Разделение ролей снимает этот конфликт: каждый агент получает свой systemPrompt и свою temperature под задачу. Summarizer пишет трёхабзацное prose-резюме (повестка, решения, риски) при temperature 0.3. Action-items агент работает строже — 0.1 — и извлекает конкретные задачи с владельцем. Sentiment оценивает тон по каждому участнику и обязан приложить поле evidence. Это уже не «TypeScript-утилита», а явная схема оркестрации нескольких LLM с разными инструкциями.
Схема three-parallel-plus-one
Архитектура названа явно: три параллельных специалиста плюс один последовательный агрегатор, а не «три агента на всё».
| Агент | Имя в коде | Выход |
|---|---|---|
| Summarizer | summary |
Prose-текст без Zod-схемы |
| Action items | action-items |
Typed JSON (ActionItemList) |
| Sentiment | sentiment |
Typed JSON (SentimentReport) |
| Aggregator | aggregator |
Markdown с фиксированными заголовками |
Три первых агента стартуют через Promise.all на одном транскрипте. AgentPool(3) ограничивает concurrency: per-agent lock не даёт одному имени выполниться дважды. Агрегатор запускается после параллельной фазы:
await pool.run('aggregator', aggregatorPrompt);
В промпт агрегатора попадают prose summary как текст, action items и sentiment как JSON.stringify(...). Системная инструкция фиксирует секции ## Summary, ## Action Items, ## Sentiment, ## Next Steps и запрещает «придумывать» задачи, которых нет во входных данных.
Typed output через Zod вместо парсинга наугад
Два специалиста объявляют outputSchema на базе Zod — ActionItemList и SentimentReport. Action-items агент извлекает задачи с владельцем и опциональной датой; sentiment возвращает enum (positive / neutral / negative / mixed) и обязательное поле evidence с цитатой.
Без typed output агрегатору пришлось бы гадать, где в свободном тексте заканчивается таблица и начинается тональность. Zod-схемы превращают выход LLM в контракт, который TypeScript и агрегатор читают без regex-магии.
Пост сопровождается развёрнутым примером — около 280 строк TypeScript на базе cookbook meeting-summarizer в репозитории open-multi-agent. Запуск из корня:
npx tsx packages/core/examples/cookbook/meeting-summarizer.ts
Пакет ставится как @open-multi-agent/core. Для запуска примера по умолчанию нужен ANTHROPIC_API_KEY; в конфигах указана модель claude-sonnet-4-6. Тот же код автор запускает с deepseek-v4-flash — меняется только идентификатор модели, AgentConfig остаётся прежним.
Параллельный fan-out: wall-clock, токены и self-check
Автор измеряет wall-clock вокруг Promise.all и сумму per-agent duration. В коде есть практический self-check: если parallelElapsed >= serialSum * 0.7, скрипт падает с ASSERTION FAILED — признак того, что fan-out деградировал в очередь, а не в параллель.
В тесте автора с DeepSeek зафиксированы конкретные цифры:
- speedup 2.21×
- wall time 11.7 s
- сумма последовательных вызовов 25.9 s
- token usage полного цикла (три специалиста + агрегатор): 3 225 input, 4 083 output
Fan-out экономит wall-clock, но не токены: добавляется четвёртый вызов агрегатора, а на коротком транскрипте overhead координации может съесть выигрыш.
Пример отчёта построен на 21-строчном синтетическом engineering standup (участники Raj, Priya, Dan, Maya); в посте отмечено, что транскрипт синтетический, а production validation проекта пока ранняя.
Где multi-agent fan-out уместен
В том же фреймворке автор противопоставляет hand-wired fan-out альтернативе runTeam(), где координатор строит task graph. Канонические сценарии fan-out в посте: meeting → {summary, actions, sentiment}; также PR → {security, style, test-coverage} и support ticket → {category, urgency, suggested reply}.
Контраиндикации тоже названы: pipeline-зависимости вроде research-then-write — не fan-out; дробить одну задачу ради параллелизма бессмысленно. Для разработчика, который собирает AI-assisted pipeline вокруг транскриптов, урок простой: параллель имеет смысл, когда подзадачи независимы и хотя бы часть выходов должна быть типизированной.
Материал на Dev.to опубликован 24 июня 2026; на момент публикации у поста было 4 публичные реакции и 2 комментария — обсуждение только начинается.
Источники
- From Transcript to Typed Action Items: Three Parallel Agents in TypeScript — jackchenme, Dev.to, 2026-06-24; дата доступа: 2026-06-25