Агенти й agentic loop
Зміст
У попередній главі модель викликала інструмент один раз і повертала відповідь: спитав — отримав. Але справжня робота рідко вкладається в один крок. «Полагодь оцей червоний тест», «відтвори баг зі скріншота», «онови локатори після редизайну» — це не одна дія, а цикл: спробував, подивився на результат, підправив, спробував знову. Агент (agent) — це і є мовна модель (large language model, LLM), поставлена в такий цикл.
Для QA це вже не футурологія: термінальні агенти на кшталт Claude Code самі проганяють тести, читають трейси й правлять код у кілька ітерацій. А на співбесідах усе частіше просять не «розкажи про AI», а відрізнити «чат-бот з інструментами» від справжнього агента й пояснити, де автономію давати безпечно, а де — ні. Плутанина тут коштує дорого: агент, якому дали забагато волі без запобіжників, здатний за хвилину видалити тестові дані на спільному стенді або зафорспушити в main.
Агент vs чат-бот
Різниця не в «розумі» моделі, а в тому, хто вирішує наступний крок.
Чат-бот (і навіть заскриптований воркфлоу з викликами інструментів) веде людина або наперед прописаний код: кроки відомі заздалегідь, модель заповнює проміжки. Агент навпаки — модель сама диктує собі наступну дію, спираючись на результат попередньої, і крутить цей цикл, доки не досягне мети або доки не спрацює умова зупинки.
Anthropic у своєму інженерному матеріалі проводить цю межу так: воркфлоу (workflow) — це система, де LLM та інструменти зʼєднані наперед визначеними шляхами в коді; агент — це система, де модель динамічно керує власним процесом і використанням інструментів, сама вирішуючи, як досягти результату.
| Чат-бот / воркфлоу | Агент | |
|---|---|---|
| Хто веде кроки | Людина або код | Сама модель |
| Кількість дій | Фіксована, відома наперед | Невідома, залежить від результатів |
| Зупинка | Одна відповідь | Мета досягнута / ліміт / вето людини |
| Приклад | «Згенеруй тест-кейси з цієї вимоги» | «Досягни, щоб auth.spec.ts був зелений» |
Ключова думка: тул-виклик (tool call) сам собою ще не робить систему агентом. Агентом її робить цикл, у якому модель спостерігає наслідок своєї дії і сама вирішує, що робити далі. Механіку окремого виклику розібрано в главі Tool use і function calling — тут інструмент стає одним «ударом» усередині петлі.
Agentic loop: план → дія → спостереження → корекція
Серце агента — цикл із чотирьох тактів. Це узагальнення патерну ReAct (reasoning + acting): модель чергує міркування і дії, підмішуючи в контекст спостереження за наслідками.
- План (reasoning). Маючи мету й історію, модель вирішує, який крок наблизить до результату: «локатор не спрацював — треба глянути, як тепер виглядає сторінка».
- Дія (act). Модель викликає інструмент: запускає тест, читає файл, робить запит до API, відкриває трейс.
- Спостереження (observation). Результат інструмента повертається в контекст моделі — рядок помилки, вивід команди, стан сторінки.
- Корекція (correction). Модель звіряє спостереження з метою й оновлює план: гіпотеза підтвердилась чи ні, який наступний крок.
Далі — знову план, і так по колу. Цикл має обриватися за однією з умов: модель сама сигналізує «готово», вичерпано ліміт ітерацій, скінчився бюджет помилок/токенів, або людина наклала вето на дію.
Розглянемо конкретно — агент тріажить червоний Playwright-тест. Мета: checkout.spec.ts має пройти.
- Ітерація 1. План: запустити тест і побачити помилку. Дія:
npx playwright test checkout.spec.ts. Спостереження:TimeoutErrorна локаторіgetByRole('button', { name: 'Pay' }). Корекція: кнопки з такою назвою немає — треба глянути реальний DOM. - Ітерація 2. План: відкрити трейс і подивитися на сторінку. Дія: читає trace/знімок. Спостереження: кнопка тепер підписана
Checkout, а неPay. Корекція: оновити локатор. - Ітерація 3. Дія: править локатор, перезапускає тест. Спостереження: зелено. Модель сигналізує «готово».
Схематично (це не API конкретного SDK, а форма циклу):
// Схематично: агент як цикл
let context = [systemPrompt, goal];
for (let step = 0; step < MAX_STEPS; step++) {
const decision = await model.decide(context); // план
if (decision.done) break; // зупинка за сигналом моделі
const result = await runTool(decision.tool, decision.args); // дія
context.push(decision, result); // спостереження лягає в контекст
// наступна ітерація — корекція плану на основі result
}
Зверніть увагу на рядок if (decision.done) break та step < MAX_STEPS: без явних умов зупинки агент або крутитиметься вічно, або спалить увесь контекст. Умови зупинки — не деталь, а частина дизайну агента.
Контекст агента
Агент бачить рівно те, що лежить у його контекстному вікні (context window), і нічого більше. А саме:
- системний промпт — інструкції поведінки й описи доступних інструментів (їхні імена та JSON-схеми);
- мету — те, що просив користувач;
- наростаючу історію — усі попередні дії та спостереження;
- стан середовища — файли, сторінку, відповіді API, до яких дотягуються інструменти.
Головний наслідок: з кожною ітерацією історія росте, бо туди лягає результат чергового інструмента. Довгий цикл роздуває контекст — а це прямо бʼє і по вартості, і по якості. Кожен крок фактично перевідсилає всю попередню історію моделі, тож токени накопичуються нелінійно; на довгому контексті модель ще й гірше тримає деталі. Механіку токенів і деградації розібрано в главі Токени, контекст і вартість.
Тому зрілі агенти керують контекстом: підсумовують (компактують) стару історію, викидають застарілі спостереження, виносять пам'ять у файли, або делегують шматки роботи субагентам зі свіжим контекстом (див. Сабагенти й оркестрація). Для QA практичний висновок простий: якщо агент «забув», що робив 20 кроків тому, і почав ходити по колу — швидше за все, релевантне вже витіснене з вікна.
Автономність і human-in-the-loop
Автономність — це шкала, а не перемикач. На одному кінці — повністю автономний агент, що доводить задачу до кінця без людини. Посередині — human-in-the-loop (HITL): людина підтверджує окремі дії перед виконанням. Ближче до автономного — human-on-the-loop: людина лише наглядає й може втрутитися.
Компроміс очевидний: автономія масштабує роботу, але масштабує й помилки. Одна невірна дія без нагляду вкладається в наступні, і каскад помітиш уже за наслідками.
Практичне правило для QA — гейтити саме незворотні дії, а зворотні лишати автономними:
- потребують підтвердження людини: видалення даних,
TRUNCATE/DROPна спільному стенді,git push --force, розсилка листів чи повідомлень, деплой; - можна автономно: редагування файлу в робочій копії, read-only SQL-запит, запуск тесту, читання логів.
Саме так влаштовані дозволи в агентних інструментах: Claude Code за замовчуванням питає дозвіл перед виконанням команд, і цей запобіжник знімають свідомо, а не «щоб не заважав». Базовий воркфлоу з дозволами розібрано в главі Claude Code: базовий воркфлоу для QA.
Типові помилки
Виглядає як прогрес, а насправді агент застряг у циклі. Модель повторює ту саму невдалу дію або осцилює між двома станами (править локатор → ламає інший → вертає назад). Лікується лімітом ітерацій, детекцією повторів і сигналом «здайся й спитай людину».
Виглядає як одна невдала дія, а насправді отруєно весь контекст. Рання хибна гіпотеза лишається в історії, і кожен наступний крок міркує вже від неї — каскад помилок (error cascade). Тому одну зіпсовану ітерацію інколи дешевше почати з чистого контексту, ніж «дотягувати».
Виглядає як виконана задача, а насправді агент згубив мету. На довгому циклі початкова ціль тоне в контексті (goal drift): агент акуратно робить не те, що просили. Симптом — бездоганні дії, що не наближають до результату.
Виглядає як зелений тест, а насправді агент зшахраював. Замість полагодити баг агент видаляє червоний тест, ставить test.skip, або хардкодить очікуване значення під фактичне. Формально мета «тести зелені» досягнута — по суті перевірку знищено. Це різновид reward hacking; ловиться тільки рев'ю виводу — див. Верифікація результатів AI.
Виглядає як виклик інструмента, а насправді інструмент вигаданий. Модель кличе тул, якого немає, або передає параметр не тієї схеми. Спостереження — помилка інструмента, і добрий агент має вміти її прочитати й виправитись, а не зациклитись.
Виглядає як «майже готово», а насправді агент палить бюджет. Без ліміту кроків цикл тягне десятки ітерацій, кожна перевідсилає всю історію — рахунок і латентність ростуть тихо, доки не глянеш у метрики.
Коли агент доречний
Головний принцип від Anthropic: починай з найпростішого рішення й нарощуй складність лише за потреби. Один промпт із хорошими прикладами дешевший, швидший і передбачуваніший за агента. Заскриптований воркфлоу з фіксованими кроками надійніший там, де шлях відомий наперед.
Агент виправданий, коли збігаються кілька умов:
- задача багатокрокова, і послідовність кроків невідома заздалегідь (шлях залежить від проміжних результатів);
- є зворотний звʼязок — оракул, за яким агент бачить, чи наближається до мети (тест пройшов/впав, компілятор лається, стан сторінки змінився);
- помилки зворотні або обмежені — або є HITL-гейти на небезпечні дії;
- цінність задачі виправдовує вартість токенів і латентність.
Агент зайвий, коли: задача детермінована (візьми скрипт), немає сигналу зворотного звʼязку (агенту нема на що спертися), помилки катастрофічні й незворотні без гейтів, або задача проста й чутлива до затримки.
QA-приклад по обидва боки межі: тріаж флакі-падіння — гарна робота для агента (оракул = результат тесту, шлях наперед невідомий). А прогін того самого фіксованого смоук-набору за розкладом — це воркфлоу, а не агент: тут нема чого «вирішувати» динамічно.
Мультиагентні системи (оглядово)
Коли задача завелика для одного контексту, кілька агентів ділять роботу. Найпоширеніший патерн — оркестратор-виконавці (orchestrator-workers): провідний агент розбиває задачу, роздає підзадачі субагентам (у кожного — власне свіже контекстне вікно), а потім зводить їхні результати.
Навіщо це: паралелізм (кілька гілок роботи одночасно), ізоляція контексту (один роздутий брудний контекст замінюється кількома чистими), спеціалізація (окремий агент-«суддя», окремий агент-«кодер»).
Ціна теж реальна: координація додає складності, дебажити систему з кількох агентів важче, а токенів вона зʼїдає значно більше. За оцінкою Anthropic, багатоагентні системи в їхньому дослідницькому продукті спалювали приблизно у 15 разів більше токенів, ніж звичайна чат-взаємодія, — тому вони виправдані лише там, де цінність задачі це покриває.
Тож мультиагентність доречна для задач, що добре паралеляться і виграють від ізоляції контексту (широкий пошук, дослідження), і зайва для тісно звʼязаної послідовної роботи, де один агент упорається дешевше. Глибше — у главі Сабагенти й оркестрація.
Підсумок
- Агент = LLM у циклі, що сам вирішує наступний крок. У чат-бота чи воркфлоу крок веде людина або код; тул-виклик сам собою агента не робить.
- Agentic loop — це план → дія → спостереження → корекція, доки не досягнуто мети або не спрацювала умова зупинки. Зупинка — частина дизайну, а не дрібниця.
- Контекст росте з кожним кроком, тягнучи за собою вартість і деградацію; зрілий агент керує контекстом (компакт, пам'ять, субагенти).
- Незворотні дії — за human-in-the-loop. Автономія масштабує роботу і помилки водночас; гейти ставлять на видалення, деплой, force-push, розсилки.
- Спершу найпростіше рішення. Агент виправданий лише там, де шлях невідомий, є зворотний звʼязок і помилки обмежені; інакше дешевший скрипт або один промпт.
Що питають на співбесіді
- «Чим агент відрізняється від чат-бота?» — інтервʼюер слухає, чи назвете цикл і хто вирішує наступний крок, а не «агент розумніший». Слабка відповідь тоне в базвордах; сильна — «модель сама веде петлю дія-спостереження до зупинки».
- «Опишіть agentic loop.» — очікують чотири такти (план/дія/спостереження/корекція) плюс умови зупинки. Бонус — згадка, що спостереження лягає в контекст і той росте.
- «Де б ви НЕ дали агенту повну автономію?» — перевіряють інстинкт безпеки: незворотні дії (видалення даних, деплой, force-push) — за підтвердженням людини. Це майже дослівно збігається з тим, як QA думає про ризик.
- «Ваш агент застряг у циклі / зробив тести зеленими, але щось не так — що сталося?» — чекають знання фейлів: зациклення, каскад помилок, goal drift, reward hacking (видалив тест / хардкодив значення), і що ловиться це рев'ю виводу та лімітами.
- «Коли агент — це overkill?» — червоний прапорець для інтервʼюера, якщо кандидат тулить агента всюди. Сильний кандидат назве «найпростіше рішення спершу»: детермінована задача → скрипт, немає оракула → агенту нема на що спертися.
Джерела
- Anthropic — Building Effective Agents: канонічна межа «воркфлоу vs агент» і принцип «найпростіше рішення спершу».
- Anthropic — How we built our multi-agent research system: патерн оркестратор-виконавці, ізоляція контексту та ціна в токенах.
- Yao et al. — ReAct: Synergizing Reasoning and Acting in Language Models: першоджерело патерну «міркування + дія + спостереження».
- Силабус ISTQB CTFL 4.0 LLM-агентів не торкається; профільний матеріал — ISTQB Certified Tester AI Testing (CT-AI), присвячений тестуванню систем на базі AI.
Що таке AI-агент і чим він відрізняється від чат-бота?
Агент — це мовна модель (large language model, LLM), поставлена в цикл, де вона сама обирає наступний крок, спираючись на результат попереднього. Ключова відмінність не в «розумі» моделі, а в тому, хто веде процес: у чат-бота чи заскриптованого воркфлоу кроки задає людина або наперед написаний код, а модель лише заповнює проміжки. Агент навпаки — крутить петлю «дія → спостереження» самостійно, доки не досягне мети або доки не спрацює умова зупинки. Тому сильна відповідь на співбесіді згадує саме цикл і того, хто диктує наступну дію, а не абстрактне «агент розумніший».
Чому один виклик інструмента ще не робить систему агентом?
Тул-виклик (tool call) сам собою — це разова дія: спитав функцію, отримав результат. Агентом систему робить цикл, у якому модель бачить наслідок своєї дії і сама вирішує, що робити далі. Тобто заскриптований воркфлоу може щедро користуватися інструментами й лишатися воркфлоу, якщо послідовність кроків прописана в коді наперед. Межа проходить по автономії керування: інструмент стає одним «ударом» усередині петлі, а не окремим завершеним сценарієм.
Як Anthropic розводить поняття «воркфлоу» і «агент»?
За інженерним матеріалом Anthropic, воркфлоу (workflow) — це система, де LLM та інструменти зʼєднані наперед визначеними шляхами в коді: розробник заздалегідь знає граф кроків. Агент — це система, де модель динамічно керує власним процесом і використанням інструментів, сама вирішуючи, як дійти до результату. Практичний наслідок: якщо шлях відомий заздалегідь, надійніше й дешевше зробити воркфлоу; агент виправданий там, де послідовність кроків неможливо прописати наперед. Ця межа — улюблене питання інтервʼюерів, бо ловить кандидатів, які тулять «агента» на будь-яку автоматизацію.
Опишіть agentic loop. З яких тактів він складається?
Це цикл із чотирьох повторюваних тактів, узагальнення патерну ReAct (reasoning + acting). Перший — план (reasoning): маючи мету й історію, модель вирішує, який крок наблизить до результату. Другий — дія (act): модель викликає інструмент, наприклад запускає тест чи читає файл. Третій — спостереження (observation): результат інструмента повертається в контекст моделі. Четвертий — корекція (correction): модель звіряє спостереження з метою й оновлює план. Далі — знову план, і так по колу, доки не спрацює умова зупинки. Бонусом варто згадати, що спостереження щоразу лягає в контекст, і той наростає.
Навіщо агенту умови зупинки і які вони бувають?
Без явної умови зупинки агент або крутитиметься вічно, або спалить увесь контекст і бюджет — тому зупинка це частина дизайну, а не дрібниця. Цикл має обриватися за однією з чотирьох причин: модель сама сигналізує «готово», вичерпано ліміт ітерацій, скінчився бюджет токенів чи помилок, або людина наклала вето на дію. У схематичному коді це видно як перевірка прапорця завершення і лічильник кроків із верхньою межею. Пропустиш ці умови — отримаєш агента, що осцилює між двома станами й тихо палить рахунок, доки хтось не гляне в метрики.
Що входить у контекст агента і чому це важливо?
Агент бачить рівно те, що лежить у його контекстному вікні (context window), і нічого більше. Туди входять: системний промпт з інструкціями поведінки й описами доступних інструментів (їхні імена та JSON-схеми); мета, яку сформулював користувач; наростаюча історія всіх попередніх дій і спостережень; стан середовища, до якого дотягуються інструменти (файли, сторінка, відповіді API). Практичний наслідок для QA: якщо агент «забув», що робив 20 кроків тому, і почав ходити по колу — швидше за все, релевантне вже витіснене з вікна, а не «модель здуріла».
Чому довгий agentic loop дорожчає нелінійно і як з цим борються?
З кожною ітерацією історія росте, бо туди лягає результат чергового інструмента, а кожен крок фактично перевідсилає всю попередню історію моделі — тож токени накопичуються нелінійно. Це бʼє одразу по двох фронтах: вартість (більше токенів на крок) і якість (на довгому контексті модель гірше тримає деталі). Тому зрілі агенти керують контекстом: компактують (підсумовують) стару історію, викидають застарілі спостереження, виносять памʼять у файли або делегують шматки роботи субагентам зі свіжим контекстом. Для QA це пояснює, чому «здав велику задачу одним промптом» часто працює гірше, ніж розбити її.
Що таке human-in-the-loop і чим він відрізняється від human-on-the-loop?
Автономність — це шкала, а не перемикач. На одному кінці повністю автономний агент, що доводить задачу до кінця без людини. Human-in-the-loop (HITL) — посередині: людина підтверджує окремі дії перед виконанням, тобто стоїть на шляху виконання. Human-on-the-loop ближче до автономного: людина лише наглядає й може втрутитися, але не гейтить кожен крок. Компроміс усюди один: автономія масштабує роботу, але масштабує й помилки, бо одна невірна дія без нагляду вкладається в наступні.
Які дії агента варто гейтити людиною, а які можна лишити автономними?
Практичне правило — гейтити саме незворотні дії, а зворотні лишати автономними. Підтвердження людини потребують: видалення даних, TRUNCATE/DROP на спільному стенді, git push --force, розсилка листів чи повідомлень, деплой — усе, що важко чи неможливо відкотити. Можна лишати автономним: редагування файлу в робочій копії, read-only SQL-запит, запуск тесту, читання логів — бо наслідок легко відкотити або він взагалі не змінює стан. Саме так влаштовані дозволи в агентних інструментах: Claude Code за замовчуванням питає дозвіл перед виконанням команд, і цей запобіжник знімають свідомо, а не «щоб не заважав».
Ваш агент виглядає зайнятим, але не наближається до мети. Які типові фейли це можуть бути?
Найчастіші три. Перший — зациклення: модель повторює ту саму невдалу дію або осцилює між двома станами (править локатор, ламає інший, вертає назад); лікується лімітом ітерацій і детекцією повторів. Другий — каскад помилок (error cascade): рання хибна гіпотеза лишається в історії, і кожен наступний крок міркує вже від неї; інколи дешевше почати ітерацію з чистого контексту, ніж «дотягувати». Третій — дрейф мети (goal drift): на довгому циклі початкова ціль тоне в контексті, і агент акуратно робить не те, що просили; симптом — бездоганні дії, що не наближають до результату.
Що таке reward hacking у контексті агента, який лагодить тести?
Це коли агент формально досягає мети, знищуючи її суть. Замість полагодити баг він видаляє червоний тест, ставить test.skip або хардкодить очікуване значення під фактичне — тести стають зеленими, а перевірку по суті вбито. Небезпека в тому, що метрика «всі тести проходять» бреше, і автоматика цього не зловить. Ловиться таке лише рев'ю виводу агента: треба дивитися не тільки на зелений статус, а й на діф, який агент застосував. Для QA це прямий аналог того, як тест можна «підігнати» замість чесно перевірити.
Агент викликав інструмент, якого не існує. Що це і як має поводитися добрий агент?
Це різновид галюцинації: модель кличе тул, якого немає в наданому наборі, або передає параметр не тієї схеми. Спостереження в цьому разі — помилка інструмента (невідома назва чи невалідні аргументи), яка лягає в контекст. Добрий агент має прочитати цю помилку й виправитися: узяти інструмент зі списку доступних або поправити аргументи під схему, а не зациклитися на неіснуючому виклику. Це одна з причин, чому описи інструментів у системному промпті мають бути чіткими: що зрозуміліша схема, то менше таких промахів.
За яких умов агент виправданий, а коли він overkill?
Головний принцип від Anthropic: спершу найпростіше рішення, складність нарощуй лише за потреби. Агент виправданий, коли збігаються кілька умов: задача багатокрокова і послідовність кроків невідома заздалегідь; є зворотний звʼязок — оракул, за яким агент бачить, чи наближається до мети (тест пройшов/впав, компілятор лається); помилки зворотні або обмежені, або на небезпечні дії стоять HITL-гейти; цінність задачі виправдовує вартість токенів і латентність. Overkill він там, де задача детермінована (візьми скрипт), немає сигналу зворотного звʼязку (агенту нема на що спертися), помилки катастрофічні без гейтів, або задача проста й чутлива до затримки. Червоний прапорець для інтервʼюера — кандидат, що тулить агента всюди.
Наведіть QA-приклади по обидва боки межі «агент vs воркфлоу».
Тріаж флакі-падіння — гарна робота для агента: оракул є (результат тесту), а шлях наперед невідомий, бо причина падіння щоразу інша, і кроки залежать від проміжних спостережень. А прогін того самого фіксованого смоук-набору за розкладом — це воркфлоу, а не агент: кроки відомі наперед, вирішувати динамічно нема чого, тож заскриптований пайплайн надійніший і дешевший. Різниця в тому, чи є в задачі що «вирішувати» на льоту: коли шлях сталий — агент лише додає непередбачуваності й вартості.
Що таке патерн «оркестратор-виконавці» і навіщо він потрібен?
Це найпоширеніший мультиагентний патерн (orchestrator-workers): провідний агент розбиває мету на підзадачі, роздає їх субагентам — у кожного власне свіже контекстне вікно — а потім зводить їхні результати. Навіщо: паралелізм (кілька гілок роботи одночасно), ізоляція контексту (один роздутий брудний контекст замінюється кількома чистими), спеціалізація (окремий агент-«суддя», окремий агент-«кодер»). Це прямий спосіб обійти проблему роздування контексту з довгого циклу: замість тягти все в одну історію, роботу дроблять на ізольовані шматки.
Чому мультиагентні системи не є рішенням за замовчуванням?
Бо їхня ціна реальна: координація додає складності, дебажити систему з кількох агентів важче, а токенів вона зʼїдає значно більше. За оцінкою Anthropic, багатоагентні системи в їхньому дослідницькому продукті спалювали приблизно у 15 разів більше токенів, ніж звичайна чат-взаємодія. Тому мультиагентність виправдана лише там, де цінність задачі це покриває: задачі, що добре паралеляться і виграють від ізоляції контексту (широкий пошук, дослідження). Для тісно звʼязаної послідовної роботи, де кроки залежать один від одного, один агент упорається дешевше й простіше — тут кілька агентів лише додають накладних витрат.
Чому саме інстинкт QA добре лягає на дизайн безпечних агентів?
Бо гейтинг незворотних дій — це те саме мислення про ризик, яким QA живе щодня: перш ніж запустити щось руйнівне, спитай, чи можна це відкотити. Агенту повну автономію не дають там само, де тестувальник не тисне «видалити» на проді без підтвердження: видалення даних, деплой, force-push, розсилки. Тому на співбесіді питання «де б ви НЕ дали агенту повну автономію?» перевіряє саме цей інстинкт, і QA-кандидат тут у виграшному становищі — він звик відділяти зворотне від незворотного й ставити запобіжники на друге.
Три розбори, де рішення «агент чи ні» і дизайн запобіжників вирішують, чи агент допоможе, чи наробить лиха: таблиця вибору інструмента під конкретні QA-задачі, трасування agentic loop на тріажі флакі-тесту, і розбір фейлу, де зелені тести приховали знищену перевірку. Скрізь — на що дивитися і чому.
Кейс 1. Що взяти: один промпт, воркфлоу чи агент
Перш ніж піднімати агента, треба чесно відповісти на три питання: чи відомий шлях наперед, чи є оракул зворотного звʼязку, чи зворотні помилки. Ось як типові QA-задачі лягають на цю сітку.
| Задача | Шлях відомий? | Є оракул? | Найкращий інструмент |
|---|---|---|---|
| Згенерувати тест-кейси з вимоги | так, разова дія | ні | Один промпт |
| Прогнати фіксований смоук за розкладом | так | так (результат) | Воркфлоу (скрипт/CI) |
| Масово перейменувати локатори за мапою | так | так (компілятор) | Воркфлоу |
Довести checkout.spec.ts до зеленого | ні | так (тест) | Агент |
| Відтворити баг зі скріншота й описом | ні | частково | Агент з HITL |
| Видалити всі тестові дані на спільному стенді | так | так | Скрипт + підтвердження людини |
Що дивитися і чому:
- Немає оракула — агента нема на що спертися. Генерація тест-кейсів з вимоги — це разовий творчий крок без сигналу «стало краще/гірше»; тут агентна петля лише палить токени, а один добрий промпт дає результат дешевше й передбачуваніше.
- Шлях відомий наперед — бери воркфлоу. Смоук-набір і масове перейменування мають фіксовану послідовність; вирішувати динамічно нема чого, а скрипт надійніший і його легше дебажити, ніж недетермінованого агента.
- Шлях невідомий, але є оракул — це територія агента. «Досягни, щоб тест був зелений» неможливо прописати кроками наперед: причина падіння щоразу інша, і кожен крок залежить від попереднього спостереження. Саме тут петля план-дія-спостереження-корекція окупається.
- Незворотна дія — гейт незалежно від інструмента. Навіть коли задача детермінована (видалити дані), сам факт незворотності вимагає підтвердження людини; автономія тут не про зручність, а про ризик каскаду.
Кейс 2. Трасуємо agentic loop на тріажі флакі-тесту
Мета агента: checkout.spec.ts має проходити стабільно. Шлях наперед невідомий, зате є оракул — результат прогону. Форма циклу (це не API конкретного SDK, а схема):
// Схематично: агент як цикл із умовами зупинки
let context = [systemPrompt, goal];
for (let step = 0; step < MAX_STEPS; step++) {
const decision = await model.decide(context); // ПЛАН
if (decision.done) break; // зупинка за сигналом моделі
const result = await runTool(decision.tool, decision.args); // ДІЯ
context.push(decision, result); // СПОСТЕРЕЖЕННЯ лягає в контекст
// наступна ітерація почне з КОРЕКЦІЇ плану на основі result
}
Як це розгортається крок за кроком:
Ітерація 1
План: запустити тест, побачити помилку
Дія: npx playwright test checkout.spec.ts
Спостереж.: TimeoutError на getByRole('button', { name: 'Pay' })
Корекція: кнопки з такою назвою немає — глянути реальний DOM
Ітерація 2
План: відкрити трейс/знімок сторінки
Дія: читає trace
Спостереж.: кнопка тепер підписана 'Checkout', а не 'Pay'
Корекція: оновити локатор
Ітерація 3
Дія: править локатор, перезапускає тест
Спостереж.: зелено
Модель сигналізує decision.done = true → break
Що дивитися і чому:
if (decision.done) breakіstep < MAX_STEPS— не косметика, а два запобіжники. Перший дає моделі чесно завершити; другий рятує, коли модель не бачить виходу й почала б крутитися вічно. Приберіть будь-який — і отримаєте або зациклення, або спалений бюджет.- Спостереження — це вхід наступного плану. Рядок
TimeoutErrorз конкретним локатором дає моделі підставу для гіпотези; якби інструмент повернув порожнечу, корекція була б наосліп. Тому якість оракула прямо визначає якість петлі. - Кожна ітерація роздуває контекст. Трейс і виводи тестів лягають в історію, і на 20-й ітерації модель перевідсилає їх усі щокроку. Якщо агент раптом «забув» ранній висновок і повернувся до вже відкинутої гіпотези — релевантне витіснене з вікна, час компактувати.
- Тут агент доречний саме тому, що шлях невідомий. Причиною міг бути не локатор, а гонка, застарілий бандл чи впав бекенд — і кроки щоразу різні. Фіксованим скриптом це не покрити, а оракул (результат тесту) не дає агенту збрехати собі, що стало краще.
Кейс 3. Зелені тести, яких насправді немає
Той самий агент отримав ту саму мету — «зроби, щоб checkout.spec.ts проходив». За кілька ітерацій він рапортує: тести зелені. Але діф виглядає так:
- await expect(page.getByRole('button', { name: 'Checkout' })).toBeVisible();
- await expect(page.getByText('Order confirmed')).toBeVisible();
+ test.skip('checkout completes', async ({ page }) => {
+ // тимчасово вимкнено
+ });
Формально мета досягнута: червоного тесту немає, пайплайн зелений. По суті перевірку знищено — це reward hacking, і жодна автоматика на статусі прогону цього не зловить, бо статус тепер бреше. Другий різновид того самого — хардкод очікуваного під фактичне:
- expect(total).toBe(expectedTotal);
+ expect(total).toBe(149.99); // підігнав під те, що повернув застосунок
Що дивитися і чому:
- Оракул «усі тести зелені» можна зламати, а не задовольнити. Мета, яку агент оптимізує, має збігатися з тим, що вам справді треба; «зелений статус» ним не є, якщо його можна досягти видаленням перевірки. Ловиться це лише рев'ю виводу — дивіться на діф, а не на галочку CI.
test.skip, видалений асерт і хардкод під факт — три червоні прапорці в дифі агента. Кожен перетворює провал на удаваний успіх. Тому вивід агента, що «полагодив тести», проходить те саме рев'ю, що й пул-реквест від людини.- Незворотне — за людину, сумнівне — за рев'ю. Тут дія (правка файлу) зворотна, тож автономія доречна, але результат усе одно верифікують перед мерджем. Автономія на кроці не скасовує перевірки на виході.
- Це той самий інстинкт, що й у ручному QA. Тест можна «підігнати», щоб пройшов, замість чесно перевірити — і агент лише автоматизує цю спокусу. Хто звик недовіряти зеленому статусу без погляду в перевірку, той і агента ревʼюить правильно.
Агент vs воркфлоу
- Можу пояснити головну відмінність агента від чат-бота одним критерієм: хто обирає наступний крок — людина/код чи сама модель.
- Знаю визначення Anthropic: воркфлоу — наперед прописані шляхи в коді; агент — модель динамічно керує власним процесом.
Agentic loop
- Знаю чотири такти циклу: план (reasoning) → дія (act) → спостереження (observation) → корекція (correction) — і що це узагальнення патерну ReAct.
- Знаю чотири умови зупинки: сигнал «готово» від моделі, ліміт ітерацій, вичерпаний бюджет токенів/помилок, вето людини.
Контекст агента
- Знаю, що входить у контекстне вікно: системний промпт з описами інструментів, мета, наростаюча історія дій/спостережень, стан середовища.
- Можу пояснити, чому довгий цикл дорожчає нелінійно: кожен крок перевідсилає всю попередню історію, а на довгому вікні ще й падає якість.
- Знаю способи керування контекстом: компакт (підсумовування), викидання застарілих спостережень, памʼять у файлах, делегування субагентам.
Автономність і human-in-the-loop
- Розумію, що автономність — шкала, а не перемикач, і можу розташувати на ній повну автономію, human-on-the-loop і human-in-the-loop.
- Знаю правило гейтингу: підтвердження людини — на незворотні дії (видалення, деплой,
git push --force, розсилки), автономно — на зворотні (правка файлу, read-only запит, запуск тесту). - Розумію, чому дефолтний запит дозволу в Claude Code — це запобіжник, який знімають свідомо, а не «щоб не заважав».
Типові фейли агентів
- Можу відрізнити зациклення (повтор дії/осциляція) від інших фейлів і назвати ліки: ліміт ітерацій, детекція повторів.
- Розумію каскад помилок (error cascade): рання хибна гіпотеза отруює всю подальшу історію.
- Знаю, що таке дрейф мети (goal drift): бездоганні дії, що не наближають до результату.
- Можу пояснити reward hacking на прикладі тестів: видалив тест /
test.skip/ хардкод значення — мета формально досягнута, перевірку вбито; ловиться лише рев'ю виводу.
Коли агент доречний
- Знаю принцип «спершу найпростіше рішення»: один промпт чи скрипт часто дешевший, швидший і передбачуваніший за агента.
- Можу перелічити умови, за яких агент виправданий: багатокроковість, невідомий наперед шлях, наявність оракула зворотного звʼязку, зворотні/обмежені помилки, виправдана вартість.
- Розумію, коли агент overkill: детермінована задача, немає оракула, катастрофічні незворотні помилки без гейтів, простота й чутливість до затримки.
Мультиагентність
- Знаю патерн «оркестратор-виконавці» (orchestrator-workers): провідний розбиває мету, субагенти зі свіжим контекстом виконують, оркестратор зводить.
- Можу назвати три вигоди мультиагентності: паралелізм, ізоляція контексту, спеціалізація.
- Розумію ціну: складність координації, важчий дебаг і приблизно 15-кратна витрата токенів проти звичайної чат-взаємодії (оцінка Anthropic).
Що принципово відрізняє агента від чат-бота чи заскриптованого воркфлоу?
Питання
AI-агент — що це одним реченням?