AI-агенты и автоматизация Собрать руками

Как тестировать AI-агента

Тестирование AI-агента — это не про «работает или нет», а про надёжность, безопасность и предсказуемость в реальных сценариях. Разбираем инструменты, пайплайны и типичные ловушки.

Что тестировать у AI-агента?

AI-агент — это не просто API-вызов. Он состоит из цепочки: намерение → контекст → выбор инструмента → вызов инструмента → обработка результата → ответ пользователю. Тестировать нужно каждый этап: корректность парсинга намерений, правильность вызова инструментов, обработку ошибок, fallback-логику и итоговую релевантность ответа. Отсутствие тестов на этом уровне приводит к «тихим сбоям»: агент не падает, но делает неправильные действия.

Структура тестового пайплайна

flowchart TD
    A[Сценарий: «Заказать кофе»] --> B[Unit-тесты инструментов]
    B --> C[Mocked-вызов LLM с фиксированным контекстом]
    C --> D[Проверка выбора инструмента]
    D --> E[Интеграционный вызов реального инструмента]
    E --> F[Валидация результата]
    F --> G[Evals: релевантность, безопасность, юзабилити]
    G --> H[Fallback: если инструмент недоступен]

Unit-тест инструмента (пример)

// test/tools/test_order_coffee.js
test('orderCoffee: возвращает ID заказа при валидных данных', () => {
  const mockDB = { saveOrder: jest.fn().mockResolvedValue('order_123') };
  const result = await orderCoffee({
    user_id: 'u_777',
    drink: 'latte',
    size: 'm',
    mockDB
  });
  
  expect(mockDB.saveOrder).toHaveBeenCalledWith({
    drink: 'latte',
    size: 'm',
    status: 'pending'
  });
  expect(result).toEqual({ order_id: 'order_123' });
});

Важно: тестируйте инструменты как чистые функции — без LLM, без внешних зависимостей. Это гарантирует, что ошибка не в инструменте, а в его вызове.

Mocked-тест LLM-логики

Используйте фикстуры для имитации ответа LLM. Это позволяет проверить, как агент реагирует на разные формулировки и ошибки.

// test/agent/plan_step.js
test('агент выбирает orderCoffee при запросе «заказать латте»', () => {
  const mockLLM = jest.fn().mockResolvedValue({
    tool_name: 'orderCoffee',
    tool_args: { drink: 'latte', size: 'm' }
  });

  const agent = new Agent({ tools: [orderCoffee], llm: mockLLM });
  const plan = await agent.plan('Закажи, пожалуйста, латте среднего размера');

  expect(plan.tool_name).toBe('orderCoffee');
  expect(plan.tool_args.drink).toBe('latte');
});

Такие тесты ловят ошибки в промптах, парсинге JSON и логике выбора инструментов.

Типичные ошибки при тестировании

  • Тестируем только «счастливый путь» — агент должен корректно обрабатывать: неясные запросы, недоступные инструменты, невалидные аргументы, таймауты.
  • Игнорируем логи — без структурированных логов (trace_id, tool_call_id, confidence_score) невозможно отследить, где именно агент «сбился».
  • Тестируем только на одном LLM — разные модели (GPT-4o, Claude 3.5 Sonnet) по-разному интерпретируют инструкции и возвращают JSON. Проверяйте на 2+ моделях.
  • Нет тестов на fallback — если инструмент недоступен, агент должен либо переспросить, либо передать человеку. Это критично для безопасности.

Чеклист тестирования AI-агента

  • ✅ Unit-тесты всех инструментов (включая edge-кейсы: пустой ID, отрицательная сумма)
  • ✅ Mocked-тесты выбора инструмента и парсинга JSON
  • ✅ End-to-end сценарии: «заказать кофе», «отменить заказ», «узнать статус»
  • ✅ Тесты fallback: инструмент недоступен, LLM вернул невалидный JSON, таймаут
  • ✅ Evals: релевантность ответа (LLM-as-a-judge), безопасность (prompt injection), юзабилити (ясность формулировок)
  • ✅ Логирование: trace_id, timestamp, tool_call_id, confidence_score, error_type

Следующий шаг: evals-пайплайн

После unit- и интеграционных тестов запускайте автоматические evals на реальных или синтетических данных:

flowchart LR
    A[Сценарий: 100 запросов] --> B[Запуск агента]
    B --> C[Сохранение trace_id + логов]
    C --> D[Evals-движок]
    D --> E1[Релевантность]
    D --> E2[Безопасность]
    D --> E3[Tool-accuracy]
    D --> E4[Latency]
    E1 & E2 & E3 & E4 --> F[Отчёт: score, failure cases]

Пример инструментов: langfuse (трейсы), ragas (релевантность), guardrails-ai (безопасность), pytest-asyncio (авто-тесты).