Workflow — это JS-скрипт, который детерминированно управляет роем субагентов: кого поднять, сколько, в каком порядке и с каким промптом у каждого. Не «много агентов ради количества», а control flow — циклы, ветвления, fan-out — зашитый в код. Именно это держит точность там, где объём убивает и обычный скрипт, и одного агента.
Напиши ту же инструкцию как ТЗ в markdown — на 3–5 агентах сработает. Но на объёме модель-драйвен подход рассыпается: у Клода нет жёсткой памяти состояния между шагами, он интерпретирует ТЗ «как по кайфу» и часть шагов теряет по дороге. Workflow снимает это: control flow исполняет движок, а не модель. Хоть 8, хоть 200 задач — каждая проходит ровно тот путь, что прописан в скрипте.
Важное, что теряют в комментариях: workflow не запускается сам «потому что задача большая». Он может поднять десятки агентов и сжечь много токенов, поэтому включается только по явному запросу — когда ты прямо просишь оркестрацию/workflow. Просто крупная задача — недостаточный повод.
Разложить задачу и параллельно покрыть широкий фронт — файлы, разделы, сущности.
Несколько независимых мнений + состязательная проверка перед тем, как принять результат.
Объём, который не влезает в один контекст: миграции, аудиты, сплошные проходы.
Скрипт — обычный JS. Начинается с блока meta (имя, описание, фазы), дальше — тело с примитивами:
Поднять субагента. Со schema вернёт валидированный объект — без парсинга строк.
Каждый элемент проходит все стадии независимо. Без барьера — элемент A уже на стадии 3, пока B на стадии 1.
Запустить пачку и дождаться всех. Только когда стадии реально нужны все результаты сразу.
export const meta = { name: 'extract-docs', description: 'Распознать документы и свести в таблицу', phases: [{ title: 'Извлечение' }, { title: 'Сведение' }], } // по субагенту на документ — но конкурентно бежит ~16, остальные в очереди const rows = await parallel(files.map(f => () => agent(`Извлеки из ${f} тип, номер, дату, сумму, контрагента, договор`, { schema: DOC_SCHEMA }) // вернёт объект, не текст ))
По умолчанию бери pipeline: он не ставит барьер между стадиями, поэтому wall-clock = самая долгая цепочка одного элемента, а не сумма самых долгих стадий. parallel нужен только когда следующая стадия обязана видеть все результаты предыдущей — дедуп, слияние, ранний выход по нулю.
Задача из видео: сопоставить акты и счёт-фактуры (PDF, Word, картинки, разное качество), найти расхождения, дубли и пропуски. Обычный скрипт не разберёт форматы; один агент не влезет 400 файлов в контекст. Workflow — да. Но с одной поправкой, которую часто упускают.
// 1. Извлечение: fan-out, каждый агент — свой файл, строгая schema const docs = (await parallel(files.map(f => () => agent(`Распознай ${f}: тип, номер, дата, сумма, контрагент, договор`, { schema: DOC_SCHEMA, phase: 'Извлечение' }) ))).filter(Boolean) // 2. Сведение: детерминированно, БЕЗ агентов const acts = docs.filter(d => d.type === 'акт') const invoices = docs.filter(d => d.type === 'счёт') const table = acts.map(a => { const match = invoices.find(i => i.contract === a.contract && i.sum === a.sum) return { act: a.num, invoice: match?.num ?? '—', contract: a.contract, sum: a.sum, status: match ? 'ок' : 'нет пары' } }) // дубли/пропуски — тоже обычными группировками по номеру
Собрал один раз — workflow лёг в .claude/workflows/ отдельной сущностью. Прилетела новая
партия — ничего не переписываешь, запускаешь по имени одной командой (можно параметризовать через args).
Главное заблуждение: «200 агентов сразу». Нет — одновременно крутится порядка 16, остальные ждут очереди и идут волнами.
| Параметр | Реальность | Частый миф |
|---|---|---|
| Конкурентность | ~16 одновременно (min(16, ядра−2)) | «сто-двести параллельно» |
| Всего за прогон | 1000 агентов суммарно (не одновременно) | «1000 в параллель» |
| Один вызов | 4096 элементов на pipeline/parallel | безлимитный вход |
| 200 документов | ≈ 13 волн по 16 — не мгновенно | «всё сразу за секунды» |
| Токены/лимит | агенты жгут тот же общий лимит | «бесплатное ускорение» |
Версия из видео, но с двумя правками: сопоставление — детерминированным JS, а не агентами, и явная точка проверки человеком.
Собери и запусти workflow. В папке ./docs лежат счёт-фактуры и акты в разных форматах (PDF, Word, картинки). 1) Извлечение (агенты): подними по одному субагенту на каждый документ, пусть распознает тип, номер, дату, сумму, контрагента и номер договора и вернёт СТРОГО по schema (валидированный объект, не текст). 2) Сопоставление (обычный JS, без агентов): сведи акты со счёт-фактурами по договору и сумме, найди несовпадения, дубли и пропуски детерминированной логикой поверх извлечённых данных — не гоняй matching через LLM. 3) Свод: одна таблица — акт, фактура, договор, сумма, статус (ок / расхождение / дубль / нет пары). 4) Приёмка: пометь строки с низкой уверенностью извлечения и выведи их отдельно на проверку человеком — это черновик для бухгалтера, не финальный вердикт. Заверни в переиспользуемый именованный workflow в .claude/workflows/, чтобы я гонял его на следующих партиях одной командой (партию передавать через args).