Multi-agent workflow

За два вебінари ви найняли reviewer і tester, надали їм права, ізоляцію та contract результату. Сьогодні - питання рівнем вище: кілька виконавців мають не просто стартувати, а завершити роботу передбачувано.

Спойлер: найчастіше найкраща відповідь - як і раніше, один Claude. Але коли паралельність справді виправдана, потрібно вміти три речі: побачити справжній fork/join, спостерігати за потоками й не втратити результат, якщо один із них зламався. Розберемо всі три - і навчимося говорити "паралель не потрібна" без почуття провини.

Сьогодні у фокусі:

Головна навичка - не запустити більше агентів, а довести, що паралельність окупилася й завершилася результатом, який можна перевірити.

Спочатку один Claude

Після skills, MCP і hooks хочеться одразу зібрати AI-оркестр. Але одна сесія вже вміє досліджувати, змінювати й перевіряти код.

Баг сортування refund inbox проходить ланцюжком reproduce -> cause -> fix, тому залишається в одній сесії.

Спочатку один agent і паралельні tools. Fan-out потрібен, коли незалежним гілкам корисні окремі contexts, а коротка розвідка вже показала межі.

Чотири моделі координації

Головне питання - хто тримає план і приймає наступне рішення.

МодельХто тримає планКоли використовувати
subagentslead sessionнезалежний research або review із поверненням результату
agent viewлюдинакілька незалежних повних сесій
agent teamslead і shared task listteammates обмінюються findings у процесі
dynamic workflowsJavaScript scriptповторювана orchestration багатьох subagents

worktree ізолює зміни, а /batch поєднує subagents і worktrees. /tasks, claude agents та /workflows допомагають спостерігати за обраною моделлю.


Спочатку розвідка, потім split

На старті межі часто нечіткі. Спочатку одна сесія збирає evidence, потім checkpoint вирішує, чи з'явився чесний split.

Для orders filter спочатку фіксуємо API contract - формат запитів і відповідей, про який домовилися backend і frontend. Лише після цього backend, frontend і tests можуть працювати одночасно.

Відповідь "ні" іноді виправляється меншою кількістю потоків, read-only роллю або contract freeze. Після першої хвилі перегляньте план: продовжити, звузити, замінити worker або зупинити гілку.

Fork/join наживо

Дві ролі на схемі ще не означають паралельну роботу. Потрібні одночасний старт і явна точка join.

> Запусти два read-only subagent паралельно.
> api-owner: знайди поточний orders API contract.
> ui-owner: знайди, де UI будує status filter.
> Поверни RESULT або BLOCKED + files + evidence.
> Після обох результатів збережи join у CONTRACT.md.
> Source code не змінюй.

/tasks
api-owner   Working   Read src/api/orders/*
ui-owner    Working   Grep src/web/orders/*

Два worker працюють одночасно. Join починається після двох результатів і збирає CONTRACT.md.

Якщо другий worker залежить від першого, це serial pipeline. Не маскуйте стрілками звичайну чергу.

Join - це складання спільного результату, а не збір повідомлень

Два агенти можуть дати правильні локальні відповіді, які суперечать одна одній. Тому join будує новий спільний artifact, а не склеює повідомлення.

Verifier перевіряє підсумковий artifact після join: спільний contract, повноту, конфлікти та непідтверджені claims.


Agent view: не втратити сесії

З окремими background sessions проблема швидко стає операційною: хто працює, хто чекає на рішення, чий результат уже готовий.

$ claude --bg --name "refund-investigation" "знайди причину падіння тесту"
backgrounded · 7c5dcf5d · refund-investigation

$ claude agents
Needs input  refund-investigation  fix test or sorting?  2m
Working      orders-filter-api     inspect contract      4m

Space відкриває peek і reply, Enter підключає повну сесію.

Background session перед записом сама переходить у .claude/worktrees/. Draft PR з'явиться, якщо є git remote, ізоляція відбулася й ви не заборонили PR.

Agent team: peers, а не дерево звітів

Team потрібен, коли teammates мають обмінюватися findings і брати завдання зі спільної черги.

flowchart TD H["Ви"] --> L["Team lead"] L --> A["Teammate A"] L --> B["Teammate B"] A --> M["Mailbox"] M --> A B --> M M --> B A --> T["Shared task list"] B --> T T --> L

Mailbox передає повідомлення. Teammate бачить project context і spawn brief, але не історію розмови lead.

Вартість зростає з кількістю активних teammates. Почніть із невеликої команди; ризик і merge залиште checkpoint людини.

Роль не дорівнює агенту

Симетрична схема "по агенту на роль" виглядає красиво, але часто лише збільшує handoff.

Три приклади поділу ролей:

Роль може виконати plan mode, main session, subagent, fresh session або людина. Швидкий тест: приберіть слово agent - роль залишилася змістовною? Так - ви проєктуєте процес. Ні - інтерфейс.

Це приклади поділу ролей, а не команди Claude Code. Не потрібно використовувати всі три - обирайте варіант під конкретне завдання.

Planner, executor, verifier

Для послідовного refund bug ролі корисні, але три одночасні агенти не потрібні.

flowchart LR P["Plan mode"] -->|"PLAN.md"| E["Main session"] E -->|"diff + test output"| V["Fresh verifier"] V -->|"VERIFIED or REWORK"| H["Рішення людини"]

Перший verifier pass повертає REWORK: sorting виправлено, але падає archived-refunds test. Executor отримує failing command, evidence і scope, а не "подивися ще раз".

Якщо перевірка дорога або неоднозначна, роль verifier бере на себе людина. Патерн залишається тим самим.

Цикл має три користувацькі виходи

У цьому workflow ми самі задаємо contract повернення. VERIFIED, REWORK і BLOCKED - не вбудовані стани /goal.

StatusЩо означаєЩо далі
VERIFIEDchecks пройшлирішення людини
REWORKє failing check і спробиобмежена ітерація
BLOCKEDнемає даних або ліміт вичерпаноevidence і запитання
Stop when: tests green + diff in scope
Limits: max 3 attempts or 15 minutes
Return: VERIFIED | REWORK | BLOCKED + evidence
/goal <condition> просить модель після кожного ходу оцінити умову. Він сам не запускає tests і не читає files: evidence має отримати основна сесія. Для детермінованої зупинки використовуйте test script або command-based Stop hook.
"Працюй, доки не вийде" без ліміту - не autonomy, а нескінченна витрата часу й токенів.

Один write-owner на кожну межу

Читати спільний contract можуть усі ролі. А одночасний запис в один файл перетворює виграш на merge conflict.

Читати можуть усі, записувати у file або module має один owner. Shared DTO отримує owner до fan-out.

Межа виявилася хибною - worker повертає NEEDS_INPUT: той самий blocked-вихід - evidence і мінімальне запитання замість мовчазного розширення scope.

Delegation brief: чотири опори

Потрібна коротка інженерна записка: точніша за "зроби backend", легша за сторінку регламенту.

Scope: src/api/orders/*
Boundaries: preserve public API; don't touch UI or migrations
Done: contract test green + changed files in scope
Return: result + evidence + risks
If blocked: NEEDS_INPUT + reason + smallest question

Чотири опори: scope, boundaries, done/evidence, return/escalation. Розмір diff - сигнал переглянути scope, а не умова успіху.

Повний brief потрібен паралельному потоку, який вносить зміни. Для read-only розвідки часто достатньо одного точного запитання та формату відповіді.

Справжній parallel pipeline

Паралельність починається після одного shared decision - фіксації API contract.

flowchart TD P["Planner"] --> C["Зафіксувати API contract"] C --> BE["Backend owner"] C --> FE["Frontend owner"] C --> TT["Test owner"] BE --> J["Join"] FE --> J TT --> J J --> M["Merge owner"] M --> V["Integration verifier"] V --> H["Рішення людини про merge"]

Backend, frontend і tests працюють одночасно в різних write-зонах. Так виглядає чесний fork: один merge-owner збирає clean state, потім verifier запускає спільний contract і full test suite.

Якщо contract продовжує змінюватися, незалежності немає. Спочатку уточніть його або чесно серіалізуйте роботу.

Один worker упав - що далі?

Failure path проєктують заздалегідь, інакше join нескінченно чекає на один потік або втрачає вже готову роботу.

news-owner:    VERIFIED  24 records
company-owner: BLOCKED   HTTP 429, retry-after 60s
join:          PARTIAL   company claims are unverified

Правила timeout -> retry -> replacement або partial join задають до старту. Прогалина залишається видимою в підсумковому artifact.


Практика: ідея та мета

Після вебінару зберіть невеликий research-workflow: два незалежні collectors беруть дані з різних публічних джерел і зводять їх в один дайджест.

Це практика для закріплення. Нічого здавати не потрібно, перевірки й оцінки немає.

Мета - навчитися проєктувати процес, а не просто запускати кілька агентів:

Головний експеримент: спочатку виконайте те саме завдання одним Claude, потім паралельно. Порівняйте підсумкову повноту, помилки, час, token cost і human review effort.

Один A/B-запуск дає приблизний сигнал, а не доказ. Якщо один Claude виявився кращим, практика теж вдалася.

Практика: особливості реалізації

Workflow працює, коли кожен етап можна перевірити й безпечно завершити під час збою.

  1. оберіть вузьку тему та два різні публічні джерела;
  2. зробіть single-agent baseline: час, токени й ручна перевірка;
  3. запустіть два collector: один source - один owner - один artifact;
  4. задайте DONE, BLOCKED, schema та ліміт часу;
  5. зберіть digest: dedup, conflicts і partial result; verifier перевіряє source кожного claim;
  6. запишіть verdict: чи допомогла паралельність.

Кожен запис зберігає provenance: URL, час публікації та завантаження, stable ID, verification status.

Текст сторінки - недовірені дані. Collector не виконує знайдені інструкції, не читає secrets і не вигадує результат при BLOCKED.

Практика: допомога з реалізацією

Не починайте із запуску агентів. Спочатку попросіть Claude спроєктувати короткий план і дочекайтеся вашого підтвердження.

Допоможи спроєктувати навчальний research-workflow.
Спочатку лише план:
1. вузька тема та два різні публічні джерела;
2. goal кожного collector з результатами DONE і BLOCKED;
3. вихідний файл і schema записів;
4. single-agent baseline і parallel run.
Не запускай збір, доки я не підтверджу план.

Опорна структура, якщо хочете повторити практику буквально:

Немає Firecrawl - беріть будь-який read-only web tool. Немає одночасного запуску - використовуйте дві сесії. Джерело недоступне - фіксуйте BLOCKED і робіть partial result.