Гайд · TNWS AI
Как разделить поиск и сборку ответа RAG на спаны MLflow Tracing
Размечаем вручную поиск фрагмента и формирование ответа; проверяем вложенные спаны без вызова платной модели.
Задача и применимость
Поисковый запрос: «как отследить отдельные шаги RAG пайплайна через mlflow trace». Найти шаг, на котором RAG-приложение потеряло опорный документ, вместо того чтобы гадать по итоговому ответу. Инструкция применима к Python-клиенту и Tracking Server актуальной ветки MLflow GenAI, проверенной по официальной документации 20 сентября 2026 года. Для конкретной установки сначала посмотрите mlflow.__version__: при отличии интерфейса от приведённого руководства закрепите совместимую версию и проверьте её документацию. Учебные данные вымышлены; ни один описанный пример не является запросом к реальному магазину.
Что происходит в системе
Декоратор @mlflow.trace автоматически захватывает имя функции, аргументы, результат, время выполнения и ошибки; при вложенных вызовах появляется отношение родитель–дочерний спан. Поэтому при ошибочном ответе можно проверить, вернул ли retrieval пустую строку или потеря произошла при сборке ответа. В промышленном RAG замените словарь своим поиском, но оставьте одинаковый контрольный набор вопросов и известные ID фрагментов. Иначе сравнение старой и новой версии не будет осмысленным.
Пошаговое выполнение
- Запустите локальный MLflow Tracking Server и привяжите приложение к отдельному эксперименту.
- Разметьте функцию поиска и функцию формирования ответа декоратором @mlflow.trace.
- Вызовите обёртку с контрольным вопросом и выведите итог в консоль.
- Откройте эксперимент и вкладку Traces, раскройте дерево спанов.
- Проверьте содержимое каждого шага и повторите опыт с запросом без подходящего документа.
Для локального опыта нужен Python 3.10+, установленный пакет mlflow и запущенный отдельно командой mlflow server локальный сервер. Адрес http://localhost:5000 из примеров справедлив при стандартном локальном запуске; в контейнере и удалённом окружении задайте настоящий доступный URI. Вызовы реальной модели выполняйте только с подходящими ключами и подтверждённой доступностью модели. Фрагмент ниже — готовый шаблон контроля конкретной операции:
import mlflow
mlflow.set_tracking_uri("http://localhost:5000")
mlflow.set_experiment("RAG Проверка спанов")
DOCS = {"возврат": "Возврат оформляют после подтверждения заявки."}
@mlflow.trace(name="retrieve")
def retrieve(question: str) -> str:
return DOCS.get("возврат", "") if "возврат" in question.lower() else ""
@mlflow.trace(name="compose_answer")
def compose_answer(fragment: str) -> str:
return fragment or "В базе нет подтверждённого ответа."
@mlflow.trace(name="rag_request")
def rag_request(question: str) -> str:
return compose_answer(retrieve(question))
print(rag_request("Как оформить возврат?"))
Пример входа и ожидаемого результата
Вход — «Как оформить возврат?». Ожидаемая строка — «Возврат оформляют после подтверждения заявки.». Внутри одной трассы должны быть дочерние retrieve и compose_answer; для «Как проверить доставку?» ответ должен сообщить отсутствие подтверждённого ответа. Это демонстрационная база из одной записи, а не проверка способности нейросети рассуждать.
Как интерпретировать измерение
Представьте, что в базе есть и политика обмена, и политика возврата. Если ответ описал обмен, а спан retrieve действительно вернул фрагмент об обмене, виноваты поиск либо данные индекса. Если retrieve отдал правильный фрагмент, а compose_answer его исказил, проверять надо шаблон генерации или модель. Для больших документов разумнее журналировать идентификаторы и короткие безопасные фрагменты, чтобы трассы не превратились в склад персональных данных. Декоратор по умолчанию сохраняет входы и выходы, так что в примере используются вымышленные данные.
Границы решения и особые случаи
Не вызывайте каждый шаг отдельно вне родительской функции, ожидая одного связанного дерева. Не называйте весь процесс LLM-вызовом: поиск не становится генерацией только потому, что обслуживает нейросеть. У конкретного провайдера может быть автоматическая инструментализация; ручные спаны полезны для собственного кода между вызовами. При переходе на настоящий LLM сравнивайте trace с фактическим пользовательским результатом, но не принимайте существование спана за доказательство точности ответа.
Критерии проверки результата
- Одна трасса содержит оба вложенных шага с читаемыми входами и выходами.
- Запрос без документа даёт проверяемый отказ, а не придуманное правило.
- После смены поиска можно локализовать ошибку по результату retrieve.
Если критерий не выполняется, сохраните номер версии пакета, безопасный входной пример и фактический результат. Затем меняйте по одной переменной: адрес сервера, параметры вызова, конфигурацию эксперимента либо редакцию шаблона. Такой подход помогает установить причину отличия без предположений о том, что модель «обязана» отвечать строго одной строкой. После успешного теста на заглушке повторите проверку на малом наборе разрешённых рабочих данных; обучающий пример сам по себе не является нагрузочным, приватностным или качественным аудитом.
Типичные ошибки и что не делать
- Не загружайте реальные частные документы в учебный эксперимент.
- Не путайте время поиска с общим временем запроса.
- Не считайте успешный статус спана мерой фактической достоверности.
Учитывайте, что трассировка и оценка могут сохранять содержимое входа и выхода. До подключения клиентов организуйте контроль доступа и обработку персональных данных. Не помещайте секреты API в промпты, параметры функций, журналы или опубликованные скриншоты. Если пример использует детерминированную функцию, его успешная проверка подтверждает корректность механики MLflow и теста, но не качество какой-либо нейросети.
FAQ
Нужен ли ключ модели?
Нет, этот учебный сценарий не обращается к модели.
Что означает родительский спан?
Он объединяет дочерние операции одного вызова.
Где смотреть результат?
В Traces выбранного эксперимента.
Официальные источники
Частые вопросы
Нужен ли ключ модели?
Нет, этот учебный сценарий не обращается к модели.
Что означает родительский спан?
Он объединяет дочерние операции одного вызова.
Где смотреть результат?
В Traces выбранного эксперимента.
Читайте также
Как найти ошибочные и медленные запросы AI-приложения в MLflow Traces
Фильтруем статус ERROR и длительность через search_traces, сверяя результат с искусственными успешным и аварийным вызовами.
Как проверить формат ответа нейросети собственным scorer в MLflow
Создаём @scorer для проверяемого префикса и проводим оценку без LLM-судьи и без внешнего API.
Как скрыть email в трассе MLflow до её записи на сервер
Настраиваем span_processors для удаления email из входов спана и проверяем, что исходный текст не ушёл в backend.
Комментарии
Пока тихо. Скажите первое слово