Почему тестировать агентов сложнее, чем кажется
Вы запускаете своего первого Deep Agent. Он умеет искать в интернете, анализировать PDF, вызывать API. В демо выглядит блестяще. Вы показываете коллегам — все в восторге. Потом выходите в продакшн, и начинается ад.
Агент зависает в бесконечных циклах. Делает не те запросы. Теряет контекст после пятого шага. Возвращает ответы, которые формально правильные, но по сути бесполезные.
Проблема в том, что классическое тестирование здесь не работает. Юнит-тесты проверяют функции, интеграционные — взаимодействия. Но агент — это не функция. Это система, которая принимает решения в условиях неопределенности. Которая учится на ходу. Которая может пойти по непредсказуемому пути.
Большинство команд тестируют агентов как обычные API: дали запрос — получили ответ. Это примерно как тестировать шахматную программу, проверяя только первый ход. Бесполезно.
Три уровня сложности: от простого к хаосу
В 2026 году сформировалась четкая иерархия тестирования агентов. Нельзя прыгать сразу на третий уровень. Нужно идти последовательно, иначе вы потратите месяцы на отладку того, что должно было быть отлажено за неделю.
Single-step: проверяем кирпичики
Представьте, что ваш агент — это конструктор. Single-step тестирование проверяет каждый кирпичик отдельно. Не весь дом, а именно кирпич: правильно ли он сделан, выдерживает ли нагрузку.
В контексте агентов это значит: тестируем каждую функцию (tool), каждый промпт, каждый парсер ответов по отдельности.
| Что тестируем | Как тестируем | Критерий успеха |
|---|---|---|
| Функция поиска в интернете | Даем конкретный запрос, проверяем структуру ответа | Возвращает список ссылок с заголовками |
| Промпт для анализа статьи | Подаем статью, смотрим на вывод | Выделяет ключевые тезисы без галлюцинаций |
| Парсер JSON ответов | Кормим broken JSON, смотрим на обработку ошибок | Не падает, возвращает понятную ошибку |
Звучит очевидно, правда? Но я видел десятки команд, которые пропускали этот этап. Они сразу бросались тестировать сложные сценарии, а потом неделями искали, почему агент возвращает мусор. Оказывается, проблема была в парсере, который не обрабатывал null значения.
Full-turn: проверяем цепочки
Теперь собираем кирпичи в стены. Full-turn тестирование проверяет полный цикл агента от запроса пользователя до финального ответа. Но с одним важным ограничением: мы фиксируем путь исполнения.
Допустим, у нас агент для исследования рынка. Полный цикл: получить запрос → найти компании → собрать финансовые данные → проанализировать → выдать отчет.
В full-turn тесте мы говорим: "Используй именно этот путь. Сначала функция A, потом B, потом C". Мы не даем агенту выбирать. Мы проверяем, что если он идет по заранее определенному маршруту, то достигает цели.
# Пример full-turn теста для research agent
def test_research_agent_happy_path():
# Фиксируем последовательность действий
expected_steps = [
"web_search",
"extract_company_info",
"fetch_financial_data",
"generate_report"
]
agent = ResearchAgent()
result = agent.run(
query="Анализ рынка электромобилей в Европе",
forced_sequence=expected_steps # Заставляем идти по этому пути
)
# Проверяем, что прошел все шаги
assert agent.execution_trace == expected_steps
# Проверяем качество результата
assert "европ" in result["report"].lower()
assert "электромобил" in result["report"].lower()
assert len(result["sources"]) >= 3
Зачем это нужно? Чтобы отсечь проблемы взаимодействия между компонентами. Может быть, каждая функция работает идеально, но когда они объединяются в цепочку, возникают конфликты форматов, потери контекста, race conditions.
В статье "Как построить систему оценки AI-агентов" я подробно разбирал, как отслеживать эти цепочки и анализировать, где именно теряется качество.
Multiple-turn: выпускаем в дикую природу
А вот здесь начинается самое интересное. Multiple-turn тестирование — это когда мы отпускаем агента в свободное плавание. Даем задачу и говорим: "Решай как хочешь. Используй любые инструменты в любом порядке. Главное — достигни цели".
Это максимально приближенно к реальным условиям. И максимально сложно для тестирования.
Проблема в том, что multiple-turn тесты недетерминированы. Сегодня агент пошел одним путем и решил задачу за 3 шага. Завтра — другим путем за 7 шагов. Послезавтра — зациклился и никогда не закончил.
Не пытайтесь сделать multiple-turn тесты полностью детерминированными. Это бессмысленно. Вместо этого определите метрики успеха, которые не зависят от конкретного пути.
Практика: строим тестовый стенд в 2026
Теория — это хорошо, но давайте перейдем к конкретике. Вот как выглядит современный пайплайн тестирования агентов в 2026 году.
1 Создаем воспроизводимые среды
Первое правило тестирования агентов: изолируй их от реального мира. Никаких живых API, никакого реального интернета, никаких случайных данных.
Используйте:
- VCR.py или pytest-recording для записи и воспроизведения HTTP-запросов
- Local LLM вместо облачных API (Qwen2.5-32B, Llama 3.2 11B, Gemma 3 4B отлично подходят)
- Тестовые базы данных с фиксированными данными
- Моки для внешних сервисов, которые эмулируют реальное поведение, но детерминированы
# Пример настройки изолированной среды
import pytest
from unittest.mock import Mock
from your_agent import WebSearchTool, DatabaseTool
@pytest.fixture
def isolated_agent_environment():
# Мок для поиска в интернете
mock_search = Mock(spec=WebSearchTool)
mock_search.execute.return_value = {
"results": [
{"title": "Тестовая статья 1", "url": "http://test.com/1", "snippet": "Тестовый сниппет"},
{"title": "Тестовая статья 2", "url": "http://test.com/2", "snippet": "Еще один сниппет"}
]
}
# Мок для базы данных
mock_db = Mock(spec=DatabaseTool)
mock_db.query.return_value = [
{"id": 1, "name": "Тестовая компания", "revenue": 1000000}
]
return {
"search": mock_search,
"database": mock_db
}
2 Определяем критерии успеха для каждого уровня
Критерии должны быть измеримыми, объективными и релевантными бизнес-целям.
| Уровень тестирования | Критерии успеха (примеры) | Инструменты для оценки |
|---|---|---|
| Single-step | Функция возвращает данные в правильном формате; промпт дает стабильные результаты; обработка ошибок работает | pytest, unittest, стандартные assertions |
| Full-turn | Агент проходит весь заданный путь; конечный результат соответствует ожиданиям; нет потерь данных между шагами | LangSmith Evals, DeepEval, custom evaluators |
| Multiple-turn | Агент достигает цели (success rate); делает это эффективно (шаги, время); не зацикливается; качество результата высокое | A/B тесты, человеческая оценка, LLM-as-a-judge (GPT-4.5, Claude 3.7) |
Для multiple-turn тестов особенно важен success rate. Не perfection rate, а именно success rate. Агент может сделать ответ неидеальным, с небольшими ошибками, но если он решает задачу — это успех.
3 Настраиваем автоматическую оценку с LangSmith
LangSmith в 2026 году — это не просто инструмент для отслеживания, а полноценная платформа для оценки агентов. Вот как ее использовать для multiple-turn тестирования.
from langsmith import Client
from langsmith.evaluation import evaluate
from langsmith.schemas import Example, Run
# 1. Создаем датасет тестовых сценариев
client = Client()
dataset = client.create_dataset(
dataset_name="agent_multiple_turn_tests",
description="Тесты для research agent в различных сценариях"
)
# 2. Добавляем примеры с ожидаемыми результатами
client.create_examples(
dataset_id=dataset.id,
inputs=[
{"query": "Найди последние исследования по квантовым вычислениям"},
{"query": "Сравни Tesla и BYD по финансовым показателям за 2025"},
{"query": "Какие тренды в AI ожидаются в 2026-2027?"}
],
outputs=[
{"expected_topics": ["квантовые", "вычисления", "исследование"]},
{"expected_companies": ["Tesla", "BYD"], "expected_metrics": ["revenue", "profit"]},
{"expected_years": ["2026", "2027"], "min_sources": 5}
]
)
# 3. Создаем evaluator для автоматической оценки
def agent_success_evaluator(run: Run, example: Example) -> dict:
"""Оценивает успешность выполнения задачи агентом."""
# Извлекаем результат
result = run.outputs.get("final_answer", "")
# Проверяем критерии из example
score = 0
feedback = []
expected_topics = example.outputs.get("expected_topics", [])
for topic in expected_topics:
if topic.lower() in result.lower():
score += 1
else:
feedback.append(f"Не найден topic: {topic}")
# Нормализуем score
normalized_score = score / max(len(expected_topics), 1)
return {
"key": "topic_coverage",
"score": normalized_score,
"feedback": ", ".join(feedback) if feedback else "Все темы покрыты"
}
# 4. Запускаем оценку
results = evaluate(
lambda inputs: your_agent.run(inputs["query"]),
data=dataset,
evaluators=[agent_success_evaluator],
experiment_prefix="multiple_turn_test"
)
Прелесть этого подхода в том, что вы можете запускать оценку автоматически после каждого коммита. Видите, что success rate упал с 85% до 70% — сразу понимаете, что что-то сломалось.
Типичные ошибки и как их избежать
Я видел эти ошибки в десятках проектов. Не повторяйте их.
Ошибка 1: Тестировать только happy path
Все тестируют, как агент работает, когда все идеально. Никто не тестирует, что происходит, когда:
- API внешнего сервиса возвращает 500 ошибку
- Интернет-поиск не находит ничего по запросу
- Модель генерирует невалидный JSON
- Пользователь меняет задачу посередине выполнения
Решение: создайте отдельный датасет "adversarial examples" и тестируйте на них обязательно.
Ошибка 2: Использовать production LLM для тестов
GPT-4.5 стоит денег. Claude 3.7 тоже. Если вы запускаете тысячи тестов каждый день, счета будут астрономическими.
Решение: используйте локальные модели для тестирования. Современные 4B-7B модели вроде Qwen2.5-Coder-7B или Gemma 3 4B отлично справляются с тестовыми сценариями. Они быстрые, бесплатные и детерминированные (с temperature=0).
В статье "DeepMath: математический агент" я показывал, как даже небольшие модели могут выполнять сложные задачи в контролируемой среде.
Ошибка 3: Игнорировать стоимость выполнения
Ваш агент может решать задачу идеально. Но если он делает 15 запросов к GPT-4.5 и 20 вызовов платных API, чтобы ответить на простой вопрос — это провал.
Решение: добавьте метрики стоимости и эффективности в тесты. Отслеживайте:
- Количество шагов до решения
- Количество токенов, потраченных на промпты
- Количество вызовов платных инструментов
- Общее время выполнения
Ошибка 4: Не тестировать на edge cases
Edge cases — это не только технические крайности. Это еще и:
- Запросы на редких языках
- Очень длинные контексты (100K+ токенов)
- Задачи с противоречивыми требованиями
- Мультимодальные запросы (текст + изображение)
Решение: выделите 20% тестового времени на edge cases. Они выявят проблемы, которые не проявляются в обычных сценариях.
Инструменты 2026 года: что действительно работает
Экосистема тестирования агентов сильно выросла за последние два года. Вот что стоит использовать в 2026:
| Задача | Инструмент | Почему |
|---|---|---|
| Single-step тесты | pytest + pytest-asyncio | Золотой стандарт, отличная интеграция, асинхронная поддержка |
| Моки и изоляция | pytest-mock, vcr.py | Позволяют создавать полностью детерминированные тесты |
| Full-turn оценка | LangSmith Evals | Готовые evaluators, интеграция с трассировкой, облачная платформа |
| Multiple-turn бенчмарки | AgentBench 2.0, SWE-bench | Стандартизированные задачи, сравнение с другими агентами |
| Локальные LLM для тестов | Ollama, vLLM, llama.cpp | Бесплатные, быстрые, детерминированные с temperature=0 |
| Визуализация трассировок | LangSmith UI, Weights & Biases | Понятные графики, анализ цепочек, поиск паттернов ошибок |
Особенно рекомендую обратить внимание на AgentBench 2.0 — это обновленная версия бенчмарка, которая включает задачи из 8 разных доменов: программирование, математика, поиск, планирование и другие. Идеально для multiple-turn тестирования.
Что будет дальше: прогноз на 2027
Тестирование агентов станет еще сложнее. И еще важнее.
К 2027 году мы увидим:
- Автономные тестировщики агентов — агенты, которые тестируют других агентов, генерируют edge cases, ищут уязвимости
- Симуляции реального мира — не просто моки API, а полноценные симуляции пользователей, конкурентов, изменяющихся условий
- Тестирование мультиагентных систем — когда взаимодействуют десятки агентов, нужны новые методологии оценки
- Формальную верификацию — математические доказательства того, что агент никогда не пойдет по опасному пути
Уже сегодня в проектах вроде "State-of-the-Art Research Agent" используются продвинутые техники тестирования, которые завтра станут стандартом.
Мой совет: начните с single-step. Доведите его до совершенства. Потом переходите к full-turn. И только когда будете уверены в обоих уровнях — выпускайте агента в multiple-turn тесты.
И помните: хороший тест не тот, который всегда проходит. Хороший тест тот, который падает, когда что-то идет не так. И падает с понятным сообщением, которое говорит вам, где именно искать проблему.
Ваш агент может быть гениальным. Но без правильного тестирования он останется гениальным только в демо. В продакшне он будет просто еще одной buggy фичей, которую ненавидят пользователи и которую боятся поддерживать разработчики.
Не дайте этому случиться.