Loop engineering: як спроєктувати цикл агента, що знає, коли зупинитися
Як працює цикл ШІ-агента: від циклів «спостерігай — дій» і стану до умов зупинки, лімітів ретраїв, контролю витрат і метрик, плюс порівняння некерованого й керованого дизайну.
Довкола будь-якої ШІ-моделі є набір допоміжних частин, і одна з найважливіших серед них — цикл агента. Тут ми придивимося саме до нього і до того, як його спроєктувати, щоб агент поводився передбачувано, не розоряв і розумів, коли час закінчувати.
Від одного виклику до циклу
Звичайний чат-бот здебільшого йде одним прямим шляхом:
User → LLM → Response
В агента завдання складніше. Щоб завершити одну задачу, може знадобитися кілька кроків, і після кожного модель дивиться, що вийшло:
User
↓
Understand the task
↓
Decide what to do
↓
Use a tool
↓
Observe the result
↓
Decide what to do next
↓
Use another tool
↓
Evaluate the result
↓
Finish
Саме цим повторенням і займається loop engineering.
Цикл агента — це коло, в якому ШІ-агент раз у раз робить таке:
- Отримує інформацію.
- Обирає, що робити.
- Виконує дію.
- Дивиться на результат.
- Вирішує, чи потрібна ще одна дія.
- Зрештою зупиняється.
У спрощеному вигляді цикл виглядає так:
┌───────────┐
│ Observe │
└─────┬─────┘
↓
┌───────────┐
│ Decide │
└─────┬─────┘
↓
┌───────────┐
│ Act │
└─────┬─────┘
↓
┌───────────┐
│ Observe │
│ Result │
└─────┬─────┘
↓
Finished?
/ \
No Yes
↓ ↓
Decide Stop
Головне тут те, що один виклик моделі не мусить одразу видати фінальну відповідь. Агент може діяти, вчитися на тому, що повернулося, і продовжувати.
Невеликий приклад: погода в Бристолі
Припустімо, користувач питає: «Яка погода в Бристолі і чи брати парасольку?» Агент може впоратися за кілька ходів. Він отримує питання й розуміє, що потрібні поточні дані. Потім викликає погодний API, і той повертає ось що:
Temperature: 16°C
Condition: Heavy rain
Тепер агент має все потрібне й відповідає, що в Бристолі дощ, тож парасольку краще взяти. Навіть такий крихітний запит потребував більше ніж однієї операції.
Бувають і прості задачі. Питанню на кшталт «Скільки буде 15 × 20?» вистачає однієї операції. Запит важчий: «Знайди три британські університети з магістратурою з Data Science і порівняй вартість навчання та вимоги до вступу». Тут може знадобитися приблизно така послідовність:
Search University A
↓
Read information
↓
Search University B
↓
Read information
↓
Search University C
↓
Read information
↓
Compare results
↓
Generate answer
Жодна окрема відповідь мовної моделі надійно все це не покриє. Цикл дає агентові змогу розбити велику задачу на маленькі дії.
Агент як скінченний автомат
Ситуацію агента можна описати як стан. Нехай s_t — стан у момент t. На кожному такті агент отримує спостереження o_t, обирає дію a_t, і світ переходить у наступний стан:
У цьому виразі s_t — поточний стан, o_t — поточне спостереження, a_t — дія, f — функція переходу станів, а s_{t+1} — наступний стан. Вибір дії теж можна записати компактно:
Тут грецька літера пі позначає політику ухвалення рішень. В агенті на базі LLM модель є частиною цієї політики. Знімок стану може виглядати так:
State:
"We need the current weather."
Observation:
"Weather tool is available."
Action:
"Call weather(location='Bristol')"
А після відповіді інструмента:
New observation:
"16°C, heavy rain"
Next action:
"Generate final response"
Дивитися на агента так, як на систему, що змінює стан, корисніше, ніж вважати його чат-ботом із зайвими кроками.
Коли зупинитися
Мабуть, найважче питання в проєктуванні циклу — як агент розуміє, що закінчив. Уявіть агента, який застряг ось так:
Call search
↓
Get result
↓
Call search again
↓
Get result
↓
Call search again
↓
...
Без правила виходу це може тривати вічно. Тому продакшн-агентові потрібні умови завершення. Поширених кілька.
Перша — щасливий шлях, коли задачу виконано:
Task completed → STOP
Друга — бюджет кроків, наприклад максимум п'ять:
Maximum steps = 5
Якщо агент дійшов до п'яти кроків і не закінчив, він зупиняється:
STOP
Третя — повторювані збої інструмента, після яких прогін треба завершити або передати комусь іншому:
Tool failed repeatedly → STOP / ESCALATE
Четверта — ризикована дія, коли людина має схвалити її, перш ніж щось станеться:
High-risk action → STOP → Ask human
Вартість, затримка й надійність
Вважайте кожен крок чимось, що коштує грошей. Припустімо, ціна одного кроку така:
Тоді звичайний прогін із 10 кроків коштує приблизно стільки:
Баг, через який кроків стає 1000, різко змінює підсумок:
Для одного запиту це вже може бути неприємно.
Помножте на тисячі користувачів, і проблема очевидна. Тому loop engineering стосується вартості, затримки й надійності не менше, ніж функціональності.
Обробка збоїв
Реальні системи ламаються. Уявіть, що погодний виклик повернув ось це:
Error: API unavailable
Погано спроєктований агент просто падає. Кращий цикл реагує на помилку:
Tool call
↓
Error
↓
Retry?
┌─┴─┐
Yes No
↓ ↓
Retry Escalate
Ретраям теж потрібні ліміти. Наприклад, після двох збоїв система може зупинитися, а не надсилати той самий приречений запит знову й знову.
Де трапляються цикли
Цикли агентів є в багатьох галузях. Ось п'ять типових.
Дослідження:
Search → Read → Compare → Search again → Summarise
Програмування:
Read code → Modify code → Run tests → Observe errors → Fix → Test again
Аналіз даних:
Inspect data → Run analysis → Observe result → Create visualisation → Explain
Підтримка клієнтів:
Understand issue → Search knowledge base → Check customer data → Respond
Керування комп'ютером:
Observe screen → Decide action → Click/type → Observe new screen → Continue
Спільна нитка проста: дій, дивись на результат, потім вирішуй, що далі.
Некеровані й керовані цикли
Порівняймо два варіанти. Перший дає моделі інструмент і відпускає її:
LLM
↓
Tool
↓
LLM
↓
Tool
↓
LLM
↓
Tool
↓
...
Тут ніщо нічого не контролює. Другий варіант додає контрольні точки довкола кожного кроку:
Task
↓
Observe
↓
Decide
↓
Validate action
↓
Execute
↓
Observe result
↓
Evaluate
↓
┌───────────────┐
│ Goal complete?│
└───────┬───────┘
Yes│ No
↓ ↓
Stop Continue
Другий варіант запроваджує контроль, і в цьому суть loop engineering.
Як вимірювати цикл
Про успіх не можна судити лише з того, чи з'явилася зрештою відповідь. Ось кілька корисних метрик:
Ще варто відстежувати:
- скільки триває задача (затримка)
- скільки витрачено токенів
- у що обходиться кожна завершена задача
- як часто виклики повторюються
- частку завершених задач
- як часто доводиться втручатися людині
Разом ці показники кажуть, чи агент справді стає кращим.
Компроміс щодо кількості кроків
Додаткові кроки дають агентові змогу братися за складніші задачі. Але вони ж приносять зростання витрат, довше очікування, більше шансів помилитися, більше збоїв інструментів і менш передбачувану поведінку. Тож мета не в тому, щоб агент крутився якомога довше. Мета — виконати задачу за найменшу кількість кроків, за якої все ще працює надійно.
Що потрібно надійному циклу
Loop engineering — це проєктування й контроль повторюваного циклу виконання ШІ-агента. Базовий шаблон такий:
Він повторюється, доки задачу не виконано або система не вирішить зупинитися. Надійному агентові потрібні:
- чітко визначені дії
- ітерації, які хтось контролює
- явні умови зупинки
- обробка помилок
- ліміти на ретраї
- керований стан
- обмеження на витрати
- постійне оцінювання
Автономність не означає нескінченного виконання. Добрий агент знає не лише, що робити далі, а й коли зупинитися.
Сильна модель і продуманий цикл усе одно можуть помилитися, якщо агентові подають не ту інформацію. Звідси наступне питання: що агент має отримувати на кожному кроці? Відповідь лежить у царині context engineering, яка дбає про те, щоб агенти отримували потрібну інформацію в потрібний момент.