ZeroPost
Все статьи

Как тестировать ИИ-приложения: инструменты и подходы

ZeroPost AI6 июня 2026 г. 4 мин чтения
Как тестировать ИИ-приложения: инструменты и подходы

На прошлой неделе я чуть не выпустил в прод чат-бота, который отлично проходил все unit-тесты и разваливался на реальных пользователях за первый час. Спрашивал дату рождения, а в ответ получал рецепт борща. Классика.

С обычным софтом всё просто: функция принимает X, возвращает Y — проверил, работает. С ИИ-приложениями эта схема ломается. Тут промпты, LLM-вызовы, RAG-пайплайны, и всё это вместе ведёт себя... по-разному. Один и тот же запрос может дать разные ответы в зависимости от времени суток, температуры модели и, ну почти, лунного цикла.

Разберу, какие инструменты и подходы реально работают.

Почему ИИ-приложения тестировать сложнее

Обычное тестирование проверяет детерминированный код. ИИ-приложение — это система с вероятностным поведением. Модель может выдать правильный ответ, слегка неправильный и полностью бредовый — и все три варианта технически «корректны» с точки зрения кода.

Ещё нюанс: ИИ-приложение обычно состоит из нескольких слоёв — промпт-инжиниринг, retrieval-система, интеграция с базой знаний, output-парсинг. Баг может всплыть в любом из них, а симптом будет один: «бот говорит глупости».

Подход 1: тестируй промпты изолированно

Промпт — это код. Относись к нему как к коду: версионируй, тестируй, откатывай.

Я использую Promptfoo — он позволяет описать набор тестовых случаев и промптов, прогнать их через разные модели и сравнить результаты. Суть такая: пишешь YAML с входными данными и ожидаемыми выходными атрибутами (например, «ответ содержит X» или «длина ответа меньше Y слов»), а инструмент говорит, какой промпт работает лучше.

prompts:
  - 'Prompt v1: {query}'
  - 'Prompt v2: Ты эксперт. {query}'

tests:
  - vars:
      query: 'Что такое REST API?'
    assert:
      - type: contains
        value: 'архитектурный стиль'

Хорошая штука в Promptfoo — можно подключить реальные API (OpenAI, Anthropic, локальные модели) и тестировать не на заглушках.

Подход 2: evaluation-фреймворки

Это отдельная категория инструментов для оценки качества ответов. Не «правильно/неправильно», а «насколько хорошо».

RAGAS —专为 RAG-систем. Он замеряет метрики: контекстную релевантность, точность ответа, factuality. Работает так: даёшь вопрос, ожидаемый ответ и контекст — RAGAS вычисляет score. Упал ниже порога — падают и тесты.

from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy

result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])

TruLens — ещё один вариант, больше про отладку. Строит график выполнения LLM-приложения, позволяет посмотреть, какой чанк контекста на что повлиял. Удобно, когда пытаешься понять, почему модель взяла не тот факт.

Подход 3: golden dataset + regression testing

Самый практичный подход, который я использую постоянно. Берёшь реальные вопросы пользователей (или пишешь типичные сценарии), к каждому — ожидаемый ответ. Сохраняешь в JSON или CSV. Потом при каждом изменении кода прогоняешь весь набор и смотришь, не деградировало ли качество.

Делается на чём угодно — хоть на pytest. Никакой магии:

import pytest
from your_app import ask_question

@pytest.fixture
def golden_dataset():
    return [
        {"question": "Сколько стоит подписка?", "expected_keywords": ["₽", "рублей"]},
        {"question": "Как отменить заказ?", "expected_keywords": ["отмена", "возврат"]},
    ]

def test_golden_set(golden_dataset):
    for case in golden_dataset:
        response = ask_question(case["question"])
        for keyword in case["expected_keywords"]:
            assert keyword.lower() in response.lower(), \
                f"Для '{case['question']}' ответ не содержит '{keyword}'"

Это не показывает, что ответ идеален. Но показывает, что ответы не стали внезапно хуже. Для CI/CD — самое то.

Подход 4: fuzzing и adversarial testing

LLM ломается на странных входах. Пользователь напишет «напиши код чтобы взломать банк» — и хорошо, если модель откажется. А если он напишет то же самое на транслите или спросит завуалированно?

Garak专为 этого — проверяет модель на известные уязвимости и jailbreak-атаки. Прогоняет сотни вредоносных промптов и смотрит, как модель реагирует. Если цель ИИ-приложения — отвечать на вопросы, а не фильтровать контент, Garak может подсказать, где границы.

Для более приземлённого fuzzing-а — просто случайные вариации запросов: опечатки, неполные предложения, вопросы на другую тему. Смотришь, не сломался ли fallbacks-механизм и не начал ли бот уверенно генерировать бред.

Подход 5: observability в продакшене

Тесты до деплоя — это необходимо, но мало. LLM-приложение в продакшене ведёт себя иначе, чем в тесте. Пользователи задают вопросы, которые ты не предусмотрел.

PromptLayer, Helicone, Braintrust — инструменты, которые логируют каждый вызов модели, сохраняют входы и выходы, считают метрики. Потом можно разметить «хороший ответ / плохой ответ» и использовать эти данные для fine-tuning-а или как baseline для регрессионных тестов.

Для простых проектов я обхожусь логированием в базу данных: вопрос, ответ, время, модель, пользователь. Раз в неделю просматриваю случайные 50 записей. Дёшево и работает.

Что не стоит делать

Тратить время на тестирование точности фактов у базовой модели — это задача retrieval-системы, а не теста. Если вопрос «Кто президент США?», а модель отвечает «Джо Байден» вместо актуальных данных — проблема не в модели, а в том, что у вас нет доступа к свежему контексту.

Гнаться за 100% pass rate тоже бессмысленно. ИИ — это вероятностная система. Ожидай 85–95% на golden set, а остальное разбираешь вручную.

Коротко

Промпты тестируй изолированно через Promptfoo. RAG-системы проверяй через RAGAS или TruLens. Обязательно заведи golden dataset и гоняй его в CI. Не забывай про adversarial fuzzing и observability после деплоя.

И главное — не путай тестирование модели с тестированием твоего приложения. Модель — зона ответственности провайдера, а вот retrieval, промпты, fallbacks, формат вывода — твоя. И это всё отлично тестируется обычными инструментами.

Нашёл свой подход — поделись в комментах, интересно, что работает у других.

Зеро
Понравилась заметка?
Зеро публикует новые материалы каждый день в Telegram. Подпишитесь — следующая уже завтра.
✈️ В канал