Одинадцять способів перервати нескінченні цикли штучного інтелекту-агента
Виявляйте цикли з застряглим інструментом, додавайте умови зупинки та відновлюйте роботу за допомогою контрольних точок замість додаткових токенів.
Джерела: **Your AI Agent Is Stuck in a Loop. Here Are 11 Ways to Fix It**
Agent
↓
Tool
↓
Result
↓
Agent
↓
Same Tool
↓
Same Tool
↓
Same Tool
↓
💸
1. Чому штучні інтелектуальні агенти застрягають у циклах?
Search customer
→ Find customer
→ Check order
→ Check order again
→ Search customer again
→ Check order again
Bad tool selection
Ambiguous tool results
State not changing
Weak stopping conditions
Repeated failed attempts
Model choosing the same strategy again
track_package("12345")
Status: In transit
Estimated delivery: Tomorrow
2. Простий цикл агента
Необхідно встановити людський контроль над операціями, які спричиняють витрати грошей чи змінюють дані виробництва. Підключення на етапі компіляції не гарантує повноти бізнес-процесів.
while (!done) {
const action = await model.decide(context);
const result = await executeTool(action);
context.push(result);
}
Model
↓
Tool
↓
Result
↓
Model
↓
Tool
↓
Result
↓
...
Приклад з реального життя
Як приклад з реального світу, перед зміною коду необхідно визначити вхідні дані, власника кроку та критерії завершення. Оператори повинні мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Необхідно документувати як шлях успішного виконання, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Встановлюйте людське схвалення для тих кроків, які призводять до витрат грошей чи змінюють дані у продакшені. Підключення на етапі компіляції не є гарантією повності функціоналу продукту. Як приклад з реального світу, перед зміною коду необхідно визначити вхідні дані, власника кроку та критерії завершення. Оператори повинні мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цю стадію як контракт між вхідними даними та перевіреними результатами. Називайте елементи продукту, визначайте критерії успіху та не допускайте безповідомного часткового завершення роботи.
get_refund_status()
Refund pending
get_refund_status()
3. Визначте бюджет для агента
Під час виконання кроку 3. Визначте бюджет для агента спочатку запишіть умови контракту: необхідні дані, сигнал про успіх та наслідки часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Записуйте час виконання та витрати на токени або запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам під час переходу від демо-середовища до спільних середовищ. Робіть перевірки після дорогих кроків. Функція відновлення не повинна знову стягувати плату за один і той самий виклик LLM, коли оператор намагається знову виконати пізнішу операцію.
const MAX_STEPS = 12;
const MAX_TOOL_CALLS = 20;
const MAX_RUNTIME_MS = 30_000;
Чому використовувати кілька лімітів?
Під час роботи над питанням «Чому використовувати кілька лімітів?» спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретів та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Робіть контрольні точки після дорогих операцій. Функція відновлення не повинна знову стягувати плату за один і той самий виклик LLM, коли оператор перезапускає пізнішу ланку.
Steps → reasoning budget
Tool calls → external API budget
Time → latency budget
Tokens → model cost
Приклади
Під час роботи з прикладами спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Одночасно задокументуйте шлях успішного виконання та шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Робіть контрольні пункти після дорогих операцій. Система відновлення не повинна знову стягувати плату за той самий виклик LLM, коли оператор повторює спробу з пізнішого етапу. Під час роботи з прикладами спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Розглядайте цей етап як угоду між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.
Search restaurant
→ Search restaurant
→ Search restaurant
→ Check table
→ Check table
→ Check table
→ Search restaurant again
Maximum 8 actions
Maximum 15 seconds
Maximum 5 reservation checks
4. Виявлення повторних дій
- Виявлення повторюваних дій найефективніше працює, коли його розглядають як вимірювану характеристику. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Візуалізація витрат заздалегідь запобігає несподіваним рахункам під час переходу від демо-середовища до спільних. Зберігайте стан графа у випрямленому та типованому форматі. Вкладені блоки приховують інформацію про те, який вузол заповнив яке поле, та ускладнюють продовження роботи після перерв.
search_users(...)
search_users(...)
search_users(...)
const signature = `${toolName}:${JSON.stringify(args)}`;
if (seenActions.has(signature)) {
throw new Error("Repeated tool invocation detected");
}
seenActions.add(signature);
Але точне зіставлення недостатнє
Але точне зіставлення недостатнє — цей підхід працює найкраще, коли його розглядати як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, щоб оператори могли перевіряти їх, не читаючи весь граф. Зберігайте стан графа у вигляді плоскої структури з чіткими типами даних. Вкладені блоки приховують інформацію про те, який вузол записав яке поле, і ускладнюють продовження роботи після перерв.
search("Node.js latency")
search("nodejs latency")
search("Node latency")
5. Виявлення відсутності прогресу
- Виявлення відсутності прогресу найкраще функціонує, коли його розглядають як вимірювану характеристику. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Документуйте як успішний, так і відновлювальний сценарії роботи разом. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Зберігайте стан графа у простому та типованому вигляді. Вкладені структури приховують інформацію про те, який вузол заповнив яке поле, і ускладнюють продовження роботи після перерв.
- Виявлення відсутності прогресу найкраще функціонує, коли його розглядають як вимірювану характеристику. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення роботи.
Step 1 → Search customer
Step 2 → Search customer by email
Step 3 → Search customer by name
Step 4 → Search customer by phone
Step 1
Find customer → ✅
Step 2
Find order → ✅
Step 3
Check shipment → ✅
Step 4
Check shipment → same result
Step 5
Check shipment → same result
Корисна ментальна модель
Щоб мати корисну ментальну модель, визначте вхідні дані, виконавця кроку та критерії завершення ще до зміни коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Відображення витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних середовищ. У разі, коли наступним кроком є код чи виклик інструменту, віддавайте перевагу структурованим результатам із перевіркою схеми перед вільним текстом.
How many actions did the agent take?
What changed after each action?
6. Не намагайтеся перезапустити бездумно
Для пункту 6. Не намагайтеся перезапускати процес сліпо — спочатку визначте вхідні дані, відповідального за крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не здогадуючись про прихований стан. Зберігайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функціоналу мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Встановіть людське схвалення для кроків, які спричиняють витрати грошей або змінюють дані в продакшені. Підключення на етапі компіляції не є гарантією повноти бізнес-функціоналу.
charge_card()
→ timeout
Той самий принцип застосовується до агентів
Для агентів також діє той самий принцип: необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Необхідно документувати як шлях успішного виконання, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Встановлюйте людське схвалення для тих кроків, які призводять до витрат грошей чи змінюють дані у продакшені. Підключення елементів під час компіляції не є гарантією повності функціоналу продукту. Для агентів також діє той самий принцип: необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цю стадію як контракт між вхідними даними та перевіреними результатами. Називайте елементи продукту, визначайте критерії успіху та не допускайте безповідомного часткового завершення роботи.
for (let i = 0; i < 10; i++) {
await callTool();
}
Timeout
→ Retry may make sense
Invalid input
→ Retry with same arguments makes no sense
Permission denied
→ Try a different strategy
Same successful result
→ Stop
7. Надайте агенту стратегію відновлення
Під час роботи над пунктом 7. Надайте агенту стратегію відновлення спочатку запишіть умови контракту: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Запишіть час виконання та витрати на токени або запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних середовищ. Створюйте контрольні точки після дорогих кроків. Функція відновлення не повинна знову стягувати плату за один і той самий виклик LLM, коли оператор перезапускає пізнішу ланку.
search_invoices(customer_id)
→ No result
search_invoices(customer_id)
→ No result
→ search_invoices(customer_id)
→ No result
→ search_invoices(customer_id)
Search by customer ID
↓
No result
↓
Search by email
↓
Still no result
↓
Search archived invoices
if (isStuck(state)) {
return replan({
reason: "No progress detected",
previousActions
});
}
8. Уточніть, що завдання виконано
Під час роботи над пунктом 8 необхідно чітко визначити, що вже зроблено, спочатку записавши умови контракту: необхідні вхідні дані, сигнал про успіх та наслідки часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Робіть контрольні пункти після дорогих операцій. Система відновлення не повинна знову стягувати плату за один і той самий виклик LLM, коли оператор намагається знову виконати пізнішу операцію.
I found an order.
Done.
Task:
Find latest order
Done when:
- customer identified
- orders retrieved
- orders sorted by date
- latest order selected
- result returned
Аналогія з реального світу
Під час роботи з аналогією реального світу спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Одночасно задокументуйте шлях успішного виконання та шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Робіть контрольні пункти після дорогих кроків. Система відновлення не повинна знову стягувати плату за той самий виклик LLM, коли оператор повторює спробу з пізнішого етапу. Під час роботи з аналогією реального світу спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Розглядайте цей етап як угоду між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового виконання.
Destination reached
9. Додайте можливість спостереження ще до того, як вона стане необхідною
- Додавайте можливість спостереження ще до того, як вона стане необхідною — це найкраще працює, якщо її розглядати як вимірювану характеристику. Зберігайте один ідеальний запис діяльності, один випадок збою та примітки щодо скасування змін перед розширенням обсягу роботи. Фіксуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Тримайте стан графа простим та типованим. Вкладені структури приховують інформацію про те, який вузол заповнив яке поле, що ускладнює продовження роботи після перерв.
run_id
step
tool
arguments
duration
result size
retry count
token usage
termination reason
Run: abc123
Step 1
search_users
210ms
Step 2
get_user
130ms
Step 3
get_orders
180ms
Step 4
get_orders
175ms
Step 5
get_orders
172ms
Step 6
LOOP DETECTED
Reason: No state change
10. Більш безпечний цикл агента
- Більш безпечний цикл агентів працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь граф. Тримайте стан графа простим та типованим. Вкладені блоки приховують інформацію про те, який вузол заповнив яке поле, і ускладнюють відновлення роботи після перерв.
while (!done) {
if (steps >= MAX_STEPS) {
return terminate("Step budget exceeded");
}
if (Date.now() - startTime > MAX_RUNTIME_MS) {
return terminate("Time budget exceeded");
}
const action = await model.decide(context);
if (isRepeated(action)) {
return replan("Repeated action detected");
}
const previousState = snapshot(state);
const result = await executeTool(action);
state = updateState(state, result);
if (!hasProgress(previousState, state)) {
markNoProgress();
}
if (tooMuchNoProgress()) {
return replan("No meaningful progress");
}
if (isComplete(state)) {
done = true;
}
}
11. Модель приймає рішення. Система його виконує.
- Модель приймає рішення. Фреймворк його впроваджує. Система працює найкраще, коли її розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Документуйте як успішний, так і відновлювальний сценарії роботи разом. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки.
- Модель приймає рішення. Фреймворк його впроваджує. Система працює найкраще, коли її розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового виконання завдань.
What should I do next?
How many times can you act?
How long can you run?
Have you repeated yourself?
Are you making progress?
Did the state change?
Are you allowed to call this tool?
When should execution stop?
Speed limiter
Brake system
Fuel gauge
Navigation system
Collision warning
Мета не полягає у скасуванні циклів
Write code
→ Run tests
→ See failure
→ Fix code
→ Run tests
→ See failure
→ Fix code
→ Tests pass
→ Stop
Did the agent loop?
Did the agent make progress?
Чек-лист для виконання
☑ Is there a maximum step count?
☑ Is there a runtime limit?
☑ Is there a tool-call budget?
☑ Can repeated actions be detected?
☑ Can we detect lack of progress?
☑ Are retries failure-aware?
☑ Can the agent re-plan?
☑ Is "done" explicitly defined?
☑ Can we see every tool call in production?
☑ Do we know why an agent terminated?
Останні думки
Дякуємо, що ви є частиною спільноти
Чек-лист для операцій
Маркер переписування 1 для 3372f6d9932d: перефразуйте супутні твердження мовою оператора, залиште поле [[CODE_n]] недоторканим та уникайте повторення речень з вихідного тексту.
Маркер переписування 2 для 3372f6d9932d: перефразуйте супутні твердження мовою оператора, залиште поле [[CODE_n]] недоторканим та уникайте повторення речень з вихідного тексту.
Маркер переписування 3 для 3372f6d9932d: перефразуйте супутні твердження мовою оператора, залиште поле [[CODE_n]] недоторканим та уникайте повторення речень з вихідного тексту.
Перепишіть маркер 4 для 3372f6d9932d: перефразуйте супутні твердження мовою операторів, залиште слоти [[CODE_n]] недоторканими та уникайте повторення речень з вихідного тексту.
Перепишіть маркер 5 для 3372f6d9932d: перефразуйте супутні твердження мовою операторів, залиште слоти [[CODE_n]] недоторканими та уникайте повторення речень з вихідного тексту.
Перепишіть маркер 6 для 3372f6d9932d: перефразуйте супутні твердження мовою операторів, залиште слоти [[CODE_n]] недоторканими та уникайте повторення речень з вихідного тексту.
Перепишіть маркер 7 для 3372f6d9932d: перефразуйте супутні твердження мовою операторів, залиште слоти [[CODE_n]] недоторканими та уникайте повторення речень з вихідного тексту.