Гайд · TNWS AI
Как проверить формат ответа нейросети собственным scorer в MLflow
Создаём @scorer для проверяемого префикса и проводим оценку без LLM-судьи и без внешнего API.
Задача и применимость
Поисковый запрос: «как написать свой deterministic scorer для ответа в MLflow genai evaluate». Автоматически ловить регрессию обязательного формата ответа, не выдавая это за оценку фактической правильности. Инструкция применима к Python-клиенту и Tracking Server актуальной ветки MLflow GenAI, проверенной по официальной документации 20 сентября 2026 года. Для конкретной установки сначала посмотрите mlflow.__version__: при отличии интерфейса от приведённого руководства закрепите совместимую версию и проверьте её документацию. Учебные данные вымышлены; ни один описанный пример не является запросом к реальному магазину.
Что происходит в системе
Официальный quickstart показывает декоратор @scorer и возможность оценивать результат функции по outputs. Такой детерминированный тест удобен там, где правило можно выполнить кодом: наличие префикса, JSON-схема, длина, непустой список ссылок. Он не делает внешнего вызова LLM-судьи и поэтому отделяет механику оценивания от поведения конкретной платной модели. Функция predict в примере — детерминированная заглушка, которую позже можно заменить настоящей AI-функцией с тем же аргументом question.
Пошаговое выполнение
- Зафиксируйте формальное требование: каждый ответ начинается с «Источник:».
- Подготовьте отдельные синтетические примеры правильного и неправильного вывода.
- Напишите @scorer, получающий outputs, и вызовите mlflow.genai.evaluate с предсказателем.
- Посмотрите в результатах оценку каждой записи, отдельно от ожидаемого ответа.
- Добавьте негативные варианты с пустой строкой, пробелом и ложной ссылкой; не считайте префикс проверкой реальности источника.
Для локального опыта нужен Python 3.10+, установленный пакет mlflow и запущенный отдельно командой mlflow server локальный сервер. Адрес http://localhost:5000 из примеров справедлив при стандартном локальном запуске; в контейнере и удалённом окружении задайте настоящий доступный URI. Вызовы реальной модели выполняйте только с подходящими ключами и подтверждённой доступностью модели. Фрагмент ниже — готовый шаблон контроля конкретной операции:
import mlflow
from mlflow.genai import scorer
mlflow.set_tracking_uri("http://localhost:5000")
mlflow.set_experiment("Проверка формата ответа")
def predict(question: str) -> str:
return ("Источник: FAQ-7. Заявка нужна." if "возврат" in question.lower()
else "Не знаю источника.")
@scorer
def has_source_prefix(outputs: str) -> bool:
return outputs.startswith("Источник: ")
cases = [
{"inputs": {"question": "Как оформить возврат?"}},
{"inputs": {"question": "Как узнать цену?"}},
]
result = mlflow.genai.evaluate(data=cases, predict_fn=predict,
scorers=[has_source_prefix])
print(result)
Пример входа и ожидаемого результата
Вход — вопрос о возврате и вопрос о цене. Первый демонстрационный ответ начинается с «Источник: » и должен пройти проверку формата, второй — нет. Это намеренно не сравнение с истинным документом: строка FAQ-7 придумана как учебный идентификатор и не подтверждает, что такой документ существует.
Как интерпретировать измерение
Слабость условия startswith очевидна: «Источник: выдуманный-URL» тоже пройдёт. Поэтому для окончательной проверки RAG-ответа дополните тест сверкой идентификатора источника с документами, фактически возвращёнными retrieval, или отдельной человеческой оценкой. Полезен отрицательный случай, в котором модель отказалась отвечать из-за отсутствия материалов: у такого ответа отсутствие префикса может быть корректным поведением. В этом случае правило нужно уточнить: разрешён ли специальный отказ. Иначе scorer будет наказанием за честность.
Границы решения и особые случаи
Встроенный Correctness из той же документации использует LLM-as-a-Judge; без подходящего доступа к judge-модели его нельзя подставить как бесплатную замену условию. Чтобы оценка была повторяемой, храните одинаковые кейсы и неизменную версию функции. Анализируйте оценки построчно: средняя доля соответствия может скрыть один критический сценарий. Именованный scorer лучше безымянной лямбды, поскольку на панели результатов легче понять, какое именно требование не выполнилось.
Дополнительный контрольный случай
Когда базовое условие работает, оформите отдельные случаи для корректной ссылки, пустого идентификатора и маркера отказа. Сначала определите договорённость редакции: требуется ли ссылка у ответа «не знаю», если источника действительно нет. Затем внесите это правило в scorer и контрольную выборку одновременно, как новую версию критериев, а не задним числом меняйте результат прошедшей оценки. Даже идеально соблюдаемый формат не заменяет сверку содержания с документом.
Критерии проверки результата
- Первый тест проходит формальное правило, второй — нет.
- Не утверждается, что наличие префикса подтверждает реальность ссылки.
- Функция получает аргумент question из одноимённого ключа inputs.
Если критерий не выполняется, сохраните номер версии пакета, безопасный входной пример и фактический результат. Затем меняйте по одной переменной: адрес сервера, параметры вызова, конфигурацию эксперимента либо редакцию шаблона. Такой подход помогает установить причину отличия без предположений о том, что модель «обязана» отвечать строго одной строкой. После успешного теста на заглушке повторите проверку на малом наборе разрешённых рабочих данных; обучающий пример сам по себе не является нагрузочным, приватностным или качественным аудитом.
Типичные ошибки и что не делать
- Не называйте формальный scorer проверкой достоверности.
- Не забывайте о допустимом отказе без источника.
- Не добавляйте LLM-судью без отдельной настройки доступа и затрат.
Учитывайте, что трассировка и оценка могут сохранять содержимое входа и выхода. До подключения клиентов организуйте контроль доступа и обработку персональных данных. Не помещайте секреты API в промпты, параметры функций, журналы или опубликованные скриншоты. Если пример использует детерминированную функцию, его успешная проверка подтверждает корректность механики MLflow и теста, но не качество какой-либо нейросети.
FAQ
Вызывает ли этот scorer другую модель?
Нет, это обычная Python-функция.
Проверяет ли он факт из документа?
Нет, только строковый формат.
Нужно ли expectations в каждом кейсе?
Для этого scorer по outputs — нет.
Официальные источники
Частые вопросы
Вызывает ли этот scorer другую модель?
Нет, это обычная Python-функция.
Проверяет ли он факт из документа?
Нет, только строковый формат.
Нужно ли expectations в каждом кейсе?
Для этого scorer по outputs — нет.
Читайте также
Как найти ошибочные и медленные запросы AI-приложения в MLflow Traces
Фильтруем статус ERROR и длительность через search_traces, сверяя результат с искусственными успешным и аварийным вызовами.
Как разделить поиск и сборку ответа RAG на спаны MLflow Tracing
Размечаем вручную поиск фрагмента и формирование ответа; проверяем вложенные спаны без вызова платной модели.
Как скрыть email в трассе MLflow до её записи на сервер
Настраиваем span_processors для удаления email из входов спана и проверяем, что исходный текст не ушёл в backend.
Комментарии
Пока тихо. Скажите первое слово