Как проверять AI-ассистента целыми диалогами

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

Опишите цель диалога и допустимый путь

Возьмём заявку на гостевой пропуск. Пользователь сообщает имя, выбирает дату, исправляет её и подтверждает параметры. Успех — подготовленная заявка с последней указанной датой и без преждевременного создания пропуска. Точное количество уточняющих вопросов может отличаться, если необходимые сведения собраны корректно.

Сценарий должен содержать стартовое состояние, реплики пользователя и ожидаемые условия после каждого значимого хода. Например, после исправления даты в рабочем состоянии стоит новое значение; до подтверждения не вызван инструмент записи. Это проверяет ход работы, а не только вежливость последней фразы.

Разделите реплики и события приложения

Текст бота «я изменил дату» не доказывает обновление. В тестовом прогоне сохраняйте состояние и журнал инструментов. Для каждого хода фиксируйте выбранные параметры, открытые вопросы и внешние действия. Тогда можно проверить, что модель действительно передала новую дату следующему этапу.

Для первого набора удобно использовать фиксированные пользовательские реплики. Они дают воспроизводимую проверку конкретных переходов. Позже можно добавить симулятора пользователя для вариативных формулировок, сохраняя сценарные условия. Симулятор тоже ошибается, поэтому результаты требуют разбора.

Проверьте важные условия траектории

В примере журнал представляет уже выполненный тестовый диалог. Функция проверяет дату созданной заявки и её совпадение с последним подтверждённым состоянием. Создание завершает этот сценарий: любые последующие события, включая вторую запись или изменение даты, считаются нарушением. Если продукт разрешает менять уже созданную заявку, это отдельный сценарий с новым подтверждением. Отрицательные примеры проверяют раннюю запись, старую дату, отсутствие создания, повтор создания и изменение после него.

def evaluate(events):
    state, confirmed_state, created = {}, None, None
    for event in events:
        if created is not None:
            return False
        if event["type"] == "update":
            state.update(event["values"])
            confirmed_state = None
        elif event["type"] == "confirm":
            confirmed_state = dict(state)
        elif event["type"] == "create":
            if confirmed_state is None or event["values"] != confirmed_state:
                return False
            created = dict(event["values"])
            confirmed_state = None
    return created is not None and created.get("date") == "2026-11-04"
trace = [{"type": "update", "values": {"date": "2026-11-03"}},
         {"type": "update", "values": {"date": "2026-11-04"}},
         {"type": "confirm"}, {"type": "create", "values": {"date": "2026-11-04"}}]
assert evaluate(trace)
assert not evaluate([{"type": "create", "values": {}}] + trace)
assert not evaluate(trace[:-1])
assert not evaluate(trace[:-1] + [{"type": "create", "values": {"date": "2026-11-03"}}])
assert not evaluate(trace + [dict(trace[-1])])
assert not evaluate(trace + [{"type": "update", "values": {"date": "2026-11-05"}}])
print({"scenario_pass": evaluate(trace)})

Соберите разные типы продолжения

Кроме изменения даты нужны отказ продолжать, ответ несколькими полями сразу, вопрос пользователя о правиле и возврат к незаконченной задаче. Отдельно проверьте, что отказ от одной заявки не меняет другую активную задачу. Сценарии удобно группировать по рабочей цели, чтобы видеть слабые переходы.

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

Сохраняйте версию модели, промпта и инструментов вместе с журналом. Когда после обновления сценарий перестанет проходить, инженер сможет сравнить одинаковые шаги. Если пользовательские правила изменились, сначала обновите ожидаемые условия и объясните изменение эталона.

Начните с нескольких диалогов, которые представляют самые частые задачи команды. Они дадут больше практической пользы, чем сотня несвязанных справочных вопросов. После пилота добавляйте сценарии из реальных затруднений, обезличивая данные и сохраняя существенную последовательность уточнений.

Продолжить проект на практике

Диалоговые сценарии полезно запускать при изменениях приложения. В платном курсе LLMOps & Evaluation вы спроектируете контур оценки агентных систем и quality-гейты перед релизом. Сохранённые траектории и ожидаемые условия станут материалом для проверки, что новая версия по-прежнему доводит пользователя до нужного результата.

Откройте программу курса и выберите следующий этап своего проекта.

По теме: Версия eval-датасета: почему одной папки с вопросами недостаточно.

Продолжить на практике

  • LLMOps & Evaluation: из песочницы в продакшн ↗

    Практический курс по LLMOps. Соберёте продакшн-контур для LLM: eval-фреймворк (LangSmith/Ragas/OpenAI Evals), quality-гейты в CI/CD, алёрты на дрейф, монитринг скорости и стоимости, управление промпт-версиями и безопасность. Плюс профессиональные блоки: synthetic data для тестов, LLM-based judges, отчётность для релиз-комитета и runbook’и инцидентов.