/
Вопросы и ответы
/
AI-агенты
/

Почему агент зацикливается и как это лечить

Почему агент зацикливается и как это лечить

12 часов назад

Никита Вихров

Ответы

0

Почему агент зацикливается и как это лечить

Агент зацикливается, когда попадает в ситуацию, из которой не видит выхода: инструмент возвращает одно и то же, задача не решается, но агент продолжает пробовать. Без ограничений это бесконечный цикл и бесконечные расходы на токены.

Причин несколько, и у каждой своё лечение.


Причина 1: Инструмент возвращает ошибку, агент не знает что делать

# Агент вызывает инструмент
tool_result = read_file("/config/database.yml")
# → FileNotFoundError: файл не найден

# Агент снова вызывает тот же инструмент
tool_result = read_file("/config/database.yml")
# → FileNotFoundError: файл не найден

# ... и так по кругу

Лечение: инструмент должен возвращать понятную ошибку, а не исключение. Модель умеет обрабатывать текстовые ошибки — она не умеет обрабатывать сырые stack trace.

def read_file(path: str) -> str:
    try:
        with open(path) as f:
            return f.read()
    except FileNotFoundError:
        return f"Ошибка: файл {path} не найден. Проверь путь или поищи файл в другом месте."
    except PermissionError:
        return f"Ошибка: нет прав на чтение {path}."

Причина 2: Задача сформулирована так, что у неё нет финала

«Мониторь логи и сообщай об ошибках» — агент будет делать это бесконечно, потому что задача никогда не завершается.

Лечение: задача должна иметь чёткий критерий завершения.

# Плохо
messages = [{"role": "user", "content": "Следи за логами и сообщай об ошибках"}]

# Хорошо
messages = [{"role": "user", "content": """Проверь логи за последний час.
Если есть ошибки уровня ERROR — перечисли их и остановись.
Если ошибок нет — скажи об этом и остановись."""}]

Причина 3: Нет лимита шагов

Даже с хорошими инструментами и задачей агент иногда уходит в петлю. Защита — жёсткий лимит итераций:

MAX_STEPS = 10

messages = [{"role": "user", "content": task}]

for step in range(MAX_STEPS):
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=2048,
        tools=tools,
        messages=messages
    )

    if response.stop_reason == "end_turn":
        print("Готово:", response.content[0].text)
        break

    if response.stop_reason == "tool_use":
        # выполняем инструмент, добавляем в историю
        ...

else:
    # Вышли по лимиту
    print(f"Агент не завершил задачу за {MAX_STEPS} шагов. Остановлен принудительно.")

Причина 4: Агент не замечает, что повторяет себя

Иногда агент вызывает один и тот же инструмент с теми же аргументами несколько раз подряд. Добавь детектор повторений:

from collections import Counter

tool_calls = []

for step in range(MAX_STEPS):
    response = client.messages.create(...)

    if response.stop_reason == "tool_use":
        tool_call = next(b for b in response.content if b.type == "tool_use")
        call_signature = f"{tool_call.name}:{tool_call.input}"
        tool_calls.append(call_signature)

        # Если один и тот же вызов встречается больше 2 раз — стоп
        if Counter(tool_calls)[call_signature] > 2:
            messages.append({
                "role": "user",
                "content": [{"type": "tool_result", "tool_use_id": tool_call.id,
                             "content": "Ты уже вызывал этот инструмент с теми же аргументами. Попробуй другой подход или сообщи, что задача не решаема."}]
            })

Три защиты вместе — понятные ошибки из инструментов, чёткий критерий завершения и лимит шагов — закрывают большинство случаев бесконечных циклов.

12 часов назад

Никита Вихров

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845