English translation is not available yet. Showing Russian content.

Как вы дебажите агента, который делает неправильные действия?

Краткий тезис

Дебаг агента — это систематический процесс, основанный на прозрачности каждого шага. Ключевые приёмы: логирование всех решений (input, thought, action, observation), визуализация графа вызовов (LangSmith), тестирование инструментов изолированно, снижение temperature для воспроизводимости, human-in-the-loop для критичных действий и упрощение промпта для устранения перегрузки. Без этих шагов агент остаётся «чёрным ящиком», а ошибки — мистикой.

1. Термин: Agent (агент)

Агент — это LLM, который в цикле получает запрос, «думает» (генерирует рассуждение), выбирает инструмент (функцию) и аргументы, выполняет его, получает наблюдение (observation) и решает, нужно ли продолжить или вернуть ответ пользователю. Агент может ошибаться на каждом этапе: неверно интерпретировать запрос, выбрать неподходящий инструмент, передать невалидные аргументы или неправильно обработать наблюдение.

2. Почему агенты делают неправильные действия?

Основные источники ошибок:

ИсточникПример
Промпт – неясная инструкция, противоречивые примерыАгент решает, что «калькулятор» — это «поиск в интернете»
Инструменты – некорректное описание, скрытые багиAPI калькулятора не обрабатывает отрицательные числа
Состояние – забытый контекст, неверная памятьАгент «забыл» результат предыдущего шага
Окружение – нестабильность LLM (разные ответы при одинаковом промпте)При temperature > 0 один и тот же запрос даёт разные действия
Перегрузка – слишком сложный промпт, много инструментовАгент «теряется» среди 15 описаний функций

3. Логирование каждого шага (input, thought, action, observation)

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

  • input (входной запрос + история)
  • thought (рассуждение LLM до вызова — если агент типа ReAct)
  • action (имя инструмента и аргументы)
  • observation (сырой результат инструмента)
  • final (финальный ответ, если есть)

Пример на Python с использованием декоратора для логирования:

import json, time
from functools import wraps

def log_agent_step(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        step = {
            "timestamp": time.time(),
            "function": func.__name__,
            "args": args,
            "kwargs": kwargs,
            "result": None,
        }
        try:
            result = func(self, *args, **kwargs)
            step["result"] = result
            return result
        finally:
            with open("agent_log.jsonl", "a") as f:
                f.write(json.dumps(step) + "\n")
    return wrapper

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

4. Визуализация графа решений (LangSmith, AgentOps)

Логи — это текст, а граф вызовов — наглядная картина. Инструменты:

ИнструментОсновная функция
LangSmithТрассировка цепочек и агентов, интерактивный просмотр дерева вызовов, метрики latency/tokens
AgentOpsСпециализированная платформа для мониторинга агентов, анализ циклов, повторяющихся ошибок
Weights & Biases (W&B) TracesЛёгкая интеграция с open-source, визуализация шагов

LangSmithмастхэв для дебага production агентов. Он автоматически захватывает каждый шаг агента: какой промпт отправлен LLM, какой ответ получен, какой инструмент вызван и с каким результатом. В UI можно кликнуть на любой узел и увидеть полные данные. Это сокращает время поиска ошибки с часов до минут.

5. Снижаем temperature до 0 для воспроизводимости

Temperature — параметр LLM, контролирующий случайность генерации. При высоком temperature (0.7–1.0) модель может каждый раз выбирать разные действия на один и тот же вход. Для дебага мы хотим детерминированных ответов, чтобы каждое изменение в промпте или коде давало один и тот же результат.

temperature = 0.0
top_p = 1.0

После отладки можно вернуть небольшую случайность (0.1–0.3) для разнообразия в production, но на этапе поиска ошибки — только 0.

6. Тестируем каждый инструмент изолированно

Агент вызывает инструменты — значит, сначала нужно проверить, что каждый инструмент сам по себе работает корректно. Пишем unit-тесты для инструментов:

# test_tools.py
import pytest

def test_calculator_add():
    result = calculator("2 + 2")
    assert result == 4.0

def test_calculator_negative():
    result = calculator("-5 + 3")
    assert result == -2.0

def test_calculator_invalid():
    with pytest.raises(ValueError):
        calculator("not a math expression")

Если инструмент падает с ошибкой, агент получит неожиданное observation и может пойти по неверному пути. Изолированные тесты — база.

7. Добавляем человека-в-петле (human-in-the-loop) для критичных действий

Human-in-the-loop (HITL) — механизм, при котором агент перед выполнением опасного или дорогостоящего действия запрашивает подтверждение человека. Это не только повышает безопасность, но и позволяет наблюдать за решением агента в реальном времени.

Реализация: после того как агент сгенерировал action (например, отправить email или списать деньги), вызывается ask_human_confirmation(action_description). Если человек отклоняет, агент возвращается к размышлению.

Так вы замечаете, что агент пытался сделать что-то не то, ещё до того, как произошла ошибка. Это особенно полезно в начале разработки.

8. Упрощаем промпт агента

Перегруженный промпт — частая причина ошибок. Если в системе 20 инструментов с многословными описаниями, LLM может запутаться. Стратегия упрощения:

  1. Удаляем неиспользуемые инструменты – оставляем только те, которые нужны для текущей задачи.
  2. Сокращаем описания – каждое описание должно быть 1–2 предложения, без лишних деталей.
  3. Разделяем роли – вместо одного агента со всем сразу делаем несколько агентов-подзадач.
  4. Добавляем явный приоритет – в системном сообщении пишем «Сначала используй калькулятор для вычислений, потом поиск для проверки».

Проверка: после упрощения прогоните те же тесты — если ошибка исчезла, значит промпт был перегружен.

9. Трассировка и метрики

Помимо логов, собирайте мета-информацию о каждом шаге:

  • Latency вызова LLM и инструмента
  • Количество токенов (input + output)
  • Количество шагов до завершения
  • Циклы – если агент повторяет одно и то же действие (например, вызывает один и тот же инструмент с теми же аргументами) — это явный признак зацикливания.

Такие метрики можно выводить в дашборд (Grafana, LangSmith dashboard) и вводить пороги: если число шагов > 10, агенту пора вмешаться.

10. Постепенное усложнение (incremental development)

Лучший способ избежать сложных ошибок — начинать с простого. Сначала сделайте агента с одним инструментом и temperature=0. Добейтесь, чтобы он стабильно работал на 5 тестовых запросах. Потом добавьте второй инструмент, снова протестируйте. Только после этого добавляйте третий, четвёртый и т.д. Каждый раз, видя новую ошибку, вы будете точно знать, что она вызвана последним изменением.

Пет-проект для закрепления

Задача Создайте простого агента на LangChain, который умеет использовать два инструмента: calculator (eval-функция) и search_wikipedia (упрощённый поиск). Внесите в описание инструмента calculator опечатку (например, «кальклятор») и уберите обработку отрицательных чисел. Запустите агента на запросы вида «сколько будет 5 минус 10?». Убедитесь, что агент ошибается.

Инструменты Python, LangChain (или bare LLM API), LangSmith (можно локально trace), pytest.

Шаги:

  1. Реализуйте агента с ReAct-промптом.
  2. Добавьте логирование каждого шага в JSON-файл.
  3. Подключите LangSmith (бесплатный аккаунт или локальный сервер).
  4. Снизьте temperature до 0.
  5. Напишите unit-тест для calculator (обнаружьте баг с отрицательными числами).
  6. Исправьте описание инструмента (уберите опечатку и добавьте обработку).
  7. Снова запустите агента — ошибка должна исчезнуть.
  8. Визуализируйте граф в LangSmith и найдите, где агент «задумался» неправильно до исправления.

Ожидаемый результат Вы сможете вручную и с помощью инструментов найти и устранить ошибку агента. Главная цель — понять, что без систематического подхода (логи + визуализация + unit-тесты) отладка агента превращается в гадание.

Связь с другими вопросами

ВопросТема
48Архитектура агента и выбор парадигмы (ReAct, Plan-and-Execute)
50Unit-тесты, mock-объекты для инструментов
51Предотвращение опасных действий, HITL
52Подробный разбор HITL и его реализация
53Хранение и очистка контекста, долговременная память

Навигация