中文翻译暂不可用,显示俄语原文。
Как вы дебажите агента, который делает неправильные действия?
Краткий тезис
Дебаг агента — это систематический процесс, основанный на прозрачности каждого шага. Ключевые приёмы: логирование всех решений (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 предложения, без лишних деталей.
- Разделяем роли – вместо одного агента со всем сразу делаем несколько агентов-подзадач.
- Добавляем явный приоритет – в системном сообщении пишем «Сначала используй калькулятор для вычислений, потом поиск для проверки».
Проверка: после упрощения прогоните те же тесты — если ошибка исчезла, значит промпт был перегружен.
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.
Шаги:
- Реализуйте агента с ReAct-промптом.
- Добавьте логирование каждого шага в JSON-файл.
- Подключите LangSmith (бесплатный аккаунт или локальный сервер).
- Снизьте temperature до 0.
- Напишите unit-тест для
calculator(обнаружьте баг с отрицательными числами). - Исправьте описание инструмента (уберите опечатку и добавьте обработку).
- Снова запустите агента — ошибка должна исчезнуть.
- Визуализируйте граф в LangSmith и найдите, где агент «задумался» неправильно до исправления.
Ожидаемый результат Вы сможете вручную и с помощью инструментов найти и устранить ошибку агента. Главная цель — понять, что без систематического подхода (логи + визуализация + unit-тесты) отладка агента превращается в гадание.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 48 | Архитектура агента и выбор парадигмы (ReAct, Plan-and-Execute) |
| 50 | Unit-тесты, mock-объекты для инструментов |
| 51 | Предотвращение опасных действий, HITL |
| 52 | Подробный разбор HITL и его реализация |
| 53 | Хранение и очистка контекста, долговременная память |
Навигация
- Предыдущий: 48
- Следующий: 50
- Индекс: 00. Индекс разборов