JavaRush /Курси /Claude code /Контракт результату агента

Контракт результату агента

Claude code
Рівень 12 , Лекція 3
Відкрита

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, питання «чи можна це прийняти» вирішується за полями контракту, а не за тим, наскільки впевнено написано відповідь. Договір про результат — це те, що перетворює делегування зі ставки на удачу на передбачувану операцію з чітким прийманням.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ