JavaRush /Курси /Claude code /Довгі задачі без безкінечного чату

Довгі задачі без безкінечного чату

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

1. Довга задача ламається не в коді, а в процесі

Довга задача ламається не через те, що модель «погано кодить», а тоді, коли процес втрачає форму: контекст розростається, гіпотези перемішуються, ви обговорюєте три проблеми одночасно, diff не читається.

Візьмімо AI Commerce Growth OS. Треба винести refund-логіку з RefundController у RefundService: не зламати API, не чіпати платіжного провайдера, зберегти поведінку. Дайте Claude запит «відрефактори refund-flow і зроби код нормальним» — і корисність без меж розповзеться: через пів години обговорюєте DTO, exception handler, логи й pagination у сусідньому модулі. Не задача, а клубок задач.

Якщо працювати «одним заходом» Якщо працювати як інженерний процес
Один великий запит
task spec + milestones
Безіменна сесія Іменована сесія під конкретну задачу
Правки «раз уже ми тут» Жорсткий scope і заборона на unrelated work
Один коміт наприкінці Малі коміти на межах етапів
Зупинка через втому Stop points за планом
Пам’ять тільки в діалозі Summary і decision log

Довга AI-assisted задача — це не великий prompt, а маленький інженерний процес. Не спроєктуєте його — задача попливе раніше, ніж зламається код.

2. Каркас довгої задачі: spec і milestones

Щоб задача не розповзалася, їй потрібен каркас на три питання: що робимо, чого не робимо, де зупиняємося перевіряти стан. Перетворюйте task spec одразу на скелет процесу — мета, обмеження, поділ на етапи:

# TASK_SPEC: refund-flow refactor

## Мета
Винести refund decision logic з RefundController у RefundService.

## Область змін
Лише refund-flow.

## Не-цілі
Не змінювати payment provider integration.
Не змінювати публічний API.
Не змінювати схему БД.

## Обмеження
Зберегти поточну поведінку та зелені тести.

## Майлстоуни
M1 — зафіксувати поточну поведінку тестами
M2 — винести логіку в RefundService
M3 — зробити контролер тонким і ще раз перевірити інтеграційні тести

## Точки зупинки
Після кожного milestone: summary + checks + commit

Задача отримала форму: Claude не блукає «ще покращу пару місць», а йде коридором.

flowchart TD
    A[TASK_SPEC] --> B[Named session]
    B --> C[Milestone 1]
    C --> D[Summary + checks + small commit]
    D --> E[Milestone 2]
    E --> F[Summary + checks + small commit]
    F --> G[Milestone 3]
    G --> H[Stop point / finish]

Milestones роблять задачу переносною та перевірюваною. Без них незрозуміло, де вона, і будь-яка пауза стає болем.

3. Іменована сесія: у задачі має бути ім’я

Задача живе довше за десять хвилин — безіменна сесія працює проти вас. Скоро у вас «та довга про refunds», «ще одна схожа, але там тести» і «якась, де Claude пропонував util-клас». Пам’ять підводить уже не модель, а вас.

Дайте задачі ім’я, що збігається з workstream, branch і змістом task spec:

Що іменуємо Приклад
Задача
refund-refactor
Branch
feature/refund-refactor
Session
refund-refactor

Тоді у вас не три сутності, а один маршрут: задача, гілка, сесія, зміни. До першої перерви — дрібниця, після першого обіду — порятунок.

Відновлення:

# точна назва команди і прапорця залежить від версії Claude Code
claude --resume refund-refactor

Важлива не команда, а звичка: сесія прив’язана до задачі, а не висить як «ще один чат». Назва на кшталт new chat, session-12 або test2-final-final — сигнал, що процес іде в хаос.

4. Milestone summary і decision log

Історії діалогу мало: пам’ять виносять назовні короткими висновками. Milestone summary — «де ми зараз», decision log — «які рішення ухвалено, щоб через пів години не сперечатися знову».

Мінімальний summary після етапу:

## Підсумок етапу: M1

Готово:
- додані тести на поточну refund-поведінку
- зафіксовані кейси partial refund і approval > $100

Відкриті питання:
- кейс refund > $1000 поки не покритий

Ризики:
- integration path з payment provider ще не перевірено

Далі:
- винести decision logic у RefundService

Decision log:

## Лог рішень
- threshold $100 залишаємо у властивості конфігурації
- payment provider integration у цьому refactor не чіпаємо
- не переносимо exception mapping у цю саму задачу

Жити в одному «правильному» файлі ці нотатки не зобов’язані: поруч із задачею, у нотатці до гілки, у markdown. З них складається handoff для fresh session або reviewer.

Без журналу сесія живе в режимі «здається, ми це вже обговорювали»: Claude знову пропонує відхилений варіант, а ви згадуєте про це через кілька повідомлень. Добрий summary — це знімок стану, а не звіт для начальства.

5. Stop points: зупинятися за планом

Задачі псуються через невдалу зупинку. Найчастіший stop point: «Гаразд, втомився, завтра продовжу». Втома — поганий критерій: задача кинута в випадковій точці.

Добрий stop point — кінець осмисленого шматка: додали characterization tests; винесли логіку в сервіс і прогнали перевірки; зробили контролер тонким і подивилися diff. Це місце, де задачу можна безпечно передати навіть собі майбутньому: зрозуміло, що зроблено, чого немає, які перевірки запускалися, який наступний крок.

Малий commit на межі етапу зменшує ціну продовження:

git commit -m "test(refund): characterize approval rules"
git commit -m "refactor(refund): extract RefundService"

Summary пояснює зміст етапу, commit фіксує стан файлів. Лише commit — не видно рішень за ним; лише текст — нічого продовжувати.

І ще: stop point не дає тягнути стороннє. «А зараз би ще заодно підправити формат логів» — запитайте: це частина milestone чи інша історія? У дев’яти випадках із десяти — інша.

6. Context rot: коли сесія пам’ятає зайве

Забруднення контексту ви вже бачили на коротких задачах. На довгій воно підступніше: контекст не просто переповнюється — він старіє. Це context rot: сесія тягне старі гіпотези та відхилені ідеї як живі.

Ви вирішили не виносити refund-логіку в RefundUtils — це розмиє межі відповідальності. Через сорок хвилин контекст розрісся, і Claude знову: «Можливо, варто винести спільну логіку в utility class». Не навмисно — стара гіпотеза сидить поруч із новими даними.

Мінісценка:

Ви: utility class не підходить, залишаємо сервісний шар
Claude: зрозумів, ідемо через RefundService
...
через 30 хвилин
Claude: щоб зменшити дублювання, можна винести логіку в RefundUtils

Проблема не у відповіді — сесія почала гнити. Інші ознаки: ходить колами по відхилених варіантах, змішує підходи, посилається на застарілі assumptions, лізе у файли поза scope.

Не дотискайте. Зупиніться, зберіть summary, зафіксуйте рішення, продовжуйте з чистого стану. Розпізнати context rot — не слабкість, а дисципліна.

7. Два режими задачі: покроковий і goal-driven

Каркас є — як вести задачу? Два режими: покроковий і goal-driven (робота до формально перевірюваної умови завершення). Питання — який безпечніший.

Порівняймо:

Покроковий режим Goal-driven режим
Після кожного кроку ви підтверджуєте, що робити далі Claude іде кілька ходів поспіль до досягнення умови завершення
Краще для ризикованих змін Краще для добре обмежених задач
Підходить, коли потрібно багато людських рішень Підходить, коли є детерміновані перевірки
Повільніше, але прозоріше Швидше, але потребує хорошого verification harness

Покроковий — класика для чутливих задач: крок, diff, перевірки, рішення, далі. Особливо там, де зачеплені гроші, зовнішні контракти або форма рішення ще не ясна.

Goal-driven добрий лише тоді, коли кінець перевіряє машина — є machine-checkable termination condition без ваших суб’єктивних оцінок.

Погані умови:

Погане формулювання Чому воно погане
«Зроби акуратно» Машина не знає, що таке «акуратно»
«Коли стане краще» Це суб’єктивно
«Коли код буде чистим» Так само суб’єктивно

Добрі умови:

Хороше формулювання Чому воно хороше
./gradlew test
завершується без помилок
Перевіряється машинно
./gradlew build
зелений
Перевіряється машинно
Потрібні тести проходять Перевіряється машинно

Приклад у task spec може виглядати так:

## Умова завершення
Задача вважається завершеною, коли:
- RefundControllerTest проходить
- RefundServiceTest проходить
- ./gradlew test завершується з code 0
- публічний API refund endpoint не змінено

Тут є тонкий, але важливий нюанс. Goal-driven режим безпечний лише за детермінованої верифікації. Якщо у вас немає надійних тестів, якщо перевірка суб’єктивна, якщо задача про «на око стало зручніше», запускати такий режим небезпечно. Це вже не інженерний автопілот, а гра в «сподіваюся, ми десь вчасно зупинимося». А надія, як відомо, не входить до офіційного стеку quality assurance.

8. Скрізний приклад: refund-flow у Commerce OS

Щоб усе це не висіло в повітрі, давайте зберемо один цілісний сценарій. Припустімо, у Commerce OS у нас є задача: refactor refund-flow так, щоб decision logic пішла з контролера в сервісний шар, а поведінка лишилася колишньою. Задача не на п’ять хвилин, але й не на два тижні. Класичний кандидат на акуратну довгу сесію.

Каркас може бути таким:

# TASK_SPEC: refund-flow refactor

Мета:
Винести refund decision logic з RefundController у RefundService.

Область:
Лише refund-flow.

Обмеження:
Не змінювати API, не чіпати payment provider integration, зберегти tests green.

Майлстоуни:
M1 — characterization tests
M2 — RefundService extraction
M3 — controller cleanup + verification

Точки зупинки:
Після кожного milestone: summary + checks + commit

Сесію ми називаємо refund-refactor. Branch — feature/refund-refactor. Після першого етапу фіксуємо короткий summary:

## Підсумок майлстоуна: M1
Готово:
- додані тести на approval threshold
- зафіксовано поведінку partial refund

Рішення:
- threshold не переносимо в БД
- payment integration поза scope

Далі:
- виділити RefundService без зміни API

Далі, на другому етапі, вам уже не потрібно знову згадувати, чому threshold не пішов у БД і навіщо ми не чіпаємо інтеграцію. Рішення записане. Контекст не зобов’язаний тягти це лише у своїй історії.

Якщо на другому етапі Claude починає знову пропонувати utility class або лізти в PaymentGatewayClient, ви не сперечаєтеся без кінця. Ви бачите: задача починає виходити за межі рамок. Отже, час зупинитися, подивитися summary і повернути процес у межі milestone. А якщо задача достатньо формалізована й тести надійні, можна задати машинно перевірювану умову завершення саме для цього етапу: наприклад, усі refund-тести зелені, а білд не падає.

У такому режимі довга задача перестає бути безкінечним чатом, який страшно закрити. Вона перетворюється на послідовність невеликих, зрозумілих станів. Кожен стан має ім’я, межі, short summary, зафіксовані рішення і ясний наступний крок. А це вже зовсім інший рівень контролю. І, що особливо приємно, тут Claude справді починає підсилювати розробника, а не тягнути його за собою в хаос із «ще однієї хорошої ідеї».

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