1. Фраза «перевір це» дає туманний результат
Коли люди вперше починають працювати з агентами, рука сама тягнеться до коротких команд: «перевір diff», «подивися тести», легендарне «review this». Здається, що розумний агент сам усе зрозуміє. Розбирається він, на жаль, не в тому, що вам потрібно, а в тому, що простіше видати переконливим текстом.
Уявіть типову сцену в Commerce OS. Ви чіпаєте refund flow, де логіка повернень завʼязана на суми, статуси замовлення та обмеження за часом. Віддаєте reviewer-агенту: «перевір поточний diff». У відповідь: «Код загалом виглядає нормально, можливо, варто додати кілька тестів і перевірити граничні випадки». Агент не дурний — ви не задали йому форму результату. Він не знає, повертати чи зауваження за severity, указувати чи file:line, відокремлювати чи гіпотези від фактів, чи можна редагувати код і що робити, якщо diff накрив половину модуля.
Подивіться на різницю між двома запитами:
Погано:
Перевір цей diff.
Краще:
Перевір поточний diff в auth і billing flows.
Код не редагуй.
Сфокусуйся на пропущених тестах, сумісності API та граничних випадках.
Поверни зауваження за severity з file:line, evidence і запропонованими перевірками.
Якщо diff більший за 500 рядків — зупинися й попроси розбити change.
У другому варіанті агенту вже нікуди розпливатися, і важливо це не лише для нього, а й для вас — саме вам потім вирішувати, брати результат у роботу чи гнати на доопрацювання.
Агент без output contract дуже схожий на колегу, який на запит «ну як там review?» відповідає: «загалом нормально, але є нюанси». Формально розмова відбулася, а користі приблизно як від прогнозу погоди у стилі «десь буде щось середнє між сонцем і апокаліпсисом».
2. Output contract проти Session Handoff Note
Щоб не змішувати різні артефакти, корисно відразу розвести два документи, схожі за духом, але різні за метою: в одному ви передаєте далі стан задачі, в іншому — приймаєте результат делегованої ролі.
Output contract — це договір про результат, який агент має повернути. Не про особистість, не про «стиль роботи», не про красивий текст — саме про результат. Ви заздалегідь вирішуєте, що обовʼязково має бути у відповіді, де докази, як позначається невизначеність, що вважається порушенням меж і коли агент зобовʼязаний зупинитися.
Для порівняння зручно дивитися так:
| Артефакт | Головне запитання | Коли використовується | Що в ньому головне |
|---|---|---|---|
| HANDOFF_NOTE.md / Session Handoff Note | «Що відбувається із задачею зараз?» | Коли ви передаєте роботу іншій сесії або людині | Поточний стан, рішення, відкриті питання, наступний крок |
| Output contract агента | «Чи можна прийняти цей результат?» | Коли subagent завершив свою роль і повернув output | Формат результату, evidence, scope, uncertainty, stop conditions |
Session Handoff Note ви вже зустрічали раніше — він потрібен, щоб не втратити контекст довгої задачі між сесіями. Output contract потрібен для іншого: подивитися на результат reviewer- або tester-агента і сказати одне з трьох — «беру в роботу», «повернися й уточни», «межі порушено, не приймаю».
Ця різниця особливо корисна в Workflow Kit. agents/reviewer.md і agents/tester.md — не просто файли з роллю, а артефакти, що мають повертати результат у передбачуваному форматі. Якщо reviewer пише вільне есе, а tester — «тести додано», у вас не інженерний процес, а літературний гурток з елементами shell-скриптів.
3. З чого складається хороший output contract
Сильний контракт не зобовʼязаний бути великим — навпаки, чим він коротший і ясніший, тим краще працює. Але без кількох секцій ви знову скочуєтеся в ситуацію, коли агент щось сказав, а ви вгадуєте, чи можна на це спиратися.
Ось зручна структура, яка підходить і reviewer, і tester, якщо підкрутити деталі під роль:
| Секція | Навіщо вона потрібна | Що ви перевіряєте |
|---|---|---|
| summary | Дає коротку рамку результату | Чи зрозумів агент задачу і scope |
| findings | Містить зауваження або пропозиції | Чи мають зауваження severity і привʼязку до коду |
| evidence | Доводить кожне важливе твердження | Чи є file:line, команда, лог, diff |
| tests/checks run | Показує, що реально запускалося | Чи є команди і exit codes, а не «нібито запускав» |
| uncertainty | Відокремлює факти від припущень | Чи є позначки [hypothesis] |
| changed files | Показує, чи порушив агент межі ролі | Для reviewer — має бути порожньо |
| next step | Робить результат придатним до застосування | Чи зрозуміло, що робити далі |
| stop conditions | Обмежує шкоду за нештатної ситуації | Чи зупинився агент там, де мав |
На практиці це може виглядати так:
## Формат виводу
- summary: 3–5 речень, без води
- findings: severity, file:line, evidence, recommendation
- tests/checks run: команда + exit code
- uncertainty: окремий блок з [hypothesis]
- changed files: список або none
- next step: одна зрозуміла дія для розробника
Точні назви розділів і синтаксис agent file у поточній версії Claude Code можуть відрізнятися — це нормально. Важливо не поле summary саме по собі, а принцип: результат влаштований так, щоб його можна було перевірити, а не лише прочитати.
Ще один корисний спосіб дивитися на контракт — розділити поля на жорсткі і мʼякі.
| Тип поля | Приклад | Чим добре |
|---|---|---|
| Жорстке | orders/refund/RefundPolicy.java:87, ./gradlew test, exit code 1, changed files: none | Його можна перевірити майже механічно |
| Мʼяке | severity: major, risk: regression in refund flow, recommendation: add integration test | Потребує людського судження |
Жорсткі поля захищають вас від красивої риторики, а мʼякі роблять результат корисним. Якщо в контракті лише мʼякі поля, агент перетворюється на дуже впевненого коментатора; якщо лише жорсткі — він видає сухий протокол без змісту. Інженерно хороший контракт тримає баланс між цими двома шарами.
4. Запит агенту під контракт
Навіть хороший контракт марний, якщо ви ставите задачу в стилі «ну подивися». Він спрацьовує лише тоді, коли запит сам сформульовано як інженерне завдання: межі, фокус, заборона на зайве, очікуваний формат.
З reviewer-агентом це видно особливо наочно. Погано:
Перевір код після моїх змін.
Нормально:
Перевір поточний diff по refund flow в Commerce OS.
Код не редагуй.
Сфокусуйся на regressions, пропущених тестах і сумісності API.
Поверни findings за severity з file:line, evidence і suggested checks.
Якщо diff більший за 500 рядків — зупинися й попроси розбити change.
Чому це працює краще? Тому що тут зафіксовано одразу пʼять речей. По-перше, scope: refund flow, не весь проєкт. По-друге, межі ролі: не редагувати код. По-третє, фокус уваги: regressions, tests, API. По-четверте, формат результату: severity, file:line, evidence. По-пʼяте, умова зупинки: diff надто великий — не геройствувати.
З tester-агентом картина схожа, але акценти інші: йому мало просто сказати «перевір тести» — краще сформулювати запит так, щоб було зрозуміло, що він пише лише тести, а production-код не чіпає.
Підготуй тестове покриття для поточного diff в auth flow.
Production-код не змінюй.
Якщо потрібні зміни, обмежся файлами в tests/**.
Поверни список сценаріїв, команди запуску, exit codes і позначені [hypothesis].
Якщо падають більше пʼяти нерелевантних тестів — зупинися й відзвітуй.
Зверніть увагу: хороший запит майже завжди спирається на вже наявний output contract, навіть не цитуючи його повністю. Ви не вигадуєте формат заново, а активуєте заздалегідь описану роль. У цьому й полягає сила Workflow Kit: контракт живе в agents/reviewer.md або agents/tester.md, а сесійне формулювання лише приземляє його в конкретний diff.
5. Приймання або відхилення результату
Найдоросліша частина роботи починається не в момент делегування, а в момент повернення результату. Саме тут видно, побудували ви інженерний процес чи просто завели ще один чат з дуже самовпевненим співрозмовником.
Приймання делегованої роботи зазвичай зводиться до трьох рішень:
| Рішення | Коли підходить | Що робите далі |
|---|---|---|
| Прийняти | Є evidence, scope дотримано, межі ролі не порушено, наступний крок зрозумілий | Берете findings у роботу або фіксуєте відсутність проблем |
| Повернути на уточнення | Ідея корисна, але бракує доказів, ясності або маркування гіпотез | Просите переформатувати output за контрактом |
| Відхилити | Немає evidence, були неочікувані edits, порушено stop conditions або межі ролі | Не використовуєте результат і збираєте задачу заново |
Хороший reviewer-output у Commerce OS може виглядати приблизно так:
### знахідки
- major — orders/refund/RefundPolicy.java:87
evidence: умова допускає amount == 0, а тесту на нульовий refund немає
recommendation: додати regression test на zero-amount case
### прогнані тести/перевірки
- ./gradlew test --tests RefundPolicyTest → exit code 0
### змінені файли
- none
Тут майже все на місці: severity, конкретний рядок, evidence, рекомендація, команда, підтвердження, що reviewer нічого не змінював. Такий результат можна приймати.
А ось приклад, який варто повернути:
### знахідки
- Можливо, тут є проблеми з refund flow.
- Варто ще подивитися тести.
- Загалом код виглядає ризикованим.
Чому повернути, а не відразу викинути? Тому що, можливо, агент справді щось помітив, але не оформив результат за контрактом. Немає file:line, немає evidence, немає severity, незрозуміло, що запускалося. У роботу як є — не можна.
А якщо reviewer раптом повернув changed files з production-кодом, хоча роль була read-only, — це вже привід не «уточнювати», а відхиляти результат як порушення меж.
Наглядно весь процес виглядає так:
flowchart TD
A[Агент повернув результат] --> B{Є evidence?}
B -- ні --> C[Повернути на уточнення або відхилити]
B -- так --> D{Дотримано scope і role boundaries?}
D -- ні --> E[Відхилити]
D -- так --> F{Гіпотези позначені явно?}
F -- ні --> G[Повернути на уточнення]
F -- так --> H{Наступний крок зрозумілий?}
H -- так --> I[Прийняти в роботу]
H -- ні --> G
Сенс цієї схеми простий: ви приймаєте не розумне враження, а структурований артефакт.
6. Гіпотези позначаємо, а не ховаємо в упевненому тоні
Одна з найнеприємніших пасток під час роботи з агентами — не явна помилка, а непозначена невизначеність. Агент пише дуже впевнено, і лише потім виявляється, що половина висновків була здогадкою. Тому в контракті є окремий блок uncertainty, а гіпотези позначаються явно — маркером [hypothesis].
Поганий варіант виглядає так:
- major: refund flow ламається через stale cache в billing service
Проблема в тому, що це звучить як встановлений факт. А де доказ — лог, трасування виклику, тест? Можливо, агент просто побачив схожий патерн і добудував картину.
Набагато чесніше так:
- [hypothesis] possible regression in refund flow
evidence: прямого підтвердження в diff не знайдено
why suspect: billing cache читається до перевірки refund status
needed check: прогнати integration test на stale status
У другому варіанті агент не став «менш розумним» — він став придатним для інженерної роботи. Видно, що підтверджено, що поки лише припускається і який крок потрібен, щоб гіпотезу підтвердити або відкинути.
Особливо це важливо для tester-агента. Він часто працює на стику наявного тестового набору, нових сценаріїв і неповного знання про проєкт. Якщо він не вміє чесно сказати «тут я припускаю» — він почне закріплювати свої здогадки в тестах. А це вже той рідкісний випадок, коли автоматизація ламає систему не гучно, а дуже ввічливо й документовано.
7. У Workflow Kit: reviewer і tester
Щоб усе це не залишилося на рівні абстракції, давайте приземлимо тему в артефактах Workflow Kit — саме там контракт перестає бути красивою ідеєю і стає частиною підтримуваного файлу agents/reviewer.md або agents/tester.md.
Для reviewer контракт може бути таким:
## Формат виводу
- summary: 3–5 речень
- findings: severity, file:line, evidence, recommendation
- tests/checks run: команда + exit code
- uncertainty: позначати як [hypothesis]
- changed files: none
- next step: одна зрозуміла дія
А для tester — трохи іншим:
## Формат виводу
- summary: яке поведінку покрито
- proposed tests: файл + сценарій
- commands run: команда + exit code
- changed files: лише tests/**
- uncertainty: позначати як [hypothesis]
- stop conditions: за масових нерелевантних падінь зупинитися
Різниця між ними не косметична. Reviewer за роллю має залишатися read-only, тому changed files у нього мають бути порожніми. Tester може змінювати тестові файли, але саме тестові, а не production-логіку. Інакше вийде класичний сюжет: «агент полагодив тести», переписавши поведінку системи під тест, а не навпаки.
Тут особливо добре видно, навіщо контракт узагалі потрібен. Він не лише допомагає приймати результат — він ще й дисциплінує саму роль. Поки контракт не зафіксовано, reviewer і tester відрізняються лише словами в заголовку файлу; щойно він зʼявляється, їхня поведінка стає вимірюваною та передбачуваною.
Точні назви розділів, поля frontmatter і формат agent file можуть змінюватися від версії до версії Claude Code — це не страшно. Страшне інше: коли в агента немає явного договору про результат, а отже, немає і нормального інженерного приймання. Коли reviewer і tester повертають однаково влаштований, читабельний, перевірний output, питання «чи можна це прийняти» вирішується за полями контракту, а не за тим, наскільки впевнено написано відповідь. Договір про результат — це те, що перетворює делегування зі ставки на удачу на передбачувану операцію з чітким прийманням.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ