Гайд · TNWS AI

Как привязать ответ RAG к документам через Haystack AnswerBuilder

Haystack 3.1Python#Haystack#RAG#Python
4 мин—

GeneratedAnswer, reference_pattern и проверка номеров цитат против фактических документов без ложной атрибуции.

Применимость и задача

Поисковый запрос: «как добавить ссылки на источники Haystack AnswerBuilder». Материал сверён с официальной документацией Haystack 3.1 19 сентября 2026 года. Примеры рассчитаны на Python и пакет haystack-ai; для векторного примера дополнительно нужен пакет sentence-transformers-haystack. Демонстрационное InMemoryDocumentStore не рекомендовано разработчиком для production. Интерфейс командной строки ниже — Python API, а не названия пунктов графического меню.

AnswerBuilder преобразует query и replies генератора в GeneratedAnswer; можно дополнительно передать documents и метаданные генератора. Параметр reference_pattern — regex для номеров документов в ответе; индексация документов начинается с 1. Без reference_pattern в объекте перечисляются все переданные документы, а не только действительно процитированные.

Нумерованный порядок работы

  1. Подайте генератору пронумерованные фрагменты и сохраните список документов в том же порядке.
  2. В промпте запросите ссылку вида [1] рядом с проверяемым утверждением.
  3. Настройте reference_pattern на один номер в квадратных скобках.
  4. Передайте replies, query и исходные documents в AnswerBuilder и просмотрите answers.
  5. Проверьте каждое утверждение по фактическому документу; номер ссылки — не доказательство корректного вывода.

Готовый шаблон

from haystack import Document
from haystack.components.builders import AnswerBuilder

docs = [Document(id="R7", content="Возврат 14 дней."),
        Document(id="D9", content="Доставка по будням.")]
answer = AnswerBuilder(reference_pattern=r"\[(\d+)\]")
result = answer.run(query="Срок возврата?",
                    replies=["Возврат возможен 14 дней [1]."],
                    documents=docs)
for item in result["answers"]:
    print(item.data, [doc.id for doc in item.documents])

Пример предназначен для контролируемого теста на своих данных. Установите зависимости в отдельном окружении и зафиксируйте версии; при использовании локальной embedding-модели отдельно проверьте её доступность и разрешённость для вашего проекта. Код был проверен на синтаксис Python, но его вызовы Haystack в данном материале не выдаются за выполненный runtime-тест.

Вход и ожидаемый результат

Вход: два фрагмента R7 и D9, ответ «Возврат возможен 14 дней [1]». Ожидается объект ответа с текстом и ссылкой на R7, но не на D9. Если модель напишет [2] у срока, синтаксически ссылка будет разобрана, а фактически опровергнется содержимым документа D9.

Помимо положительного кейса записывайте отрицательный: отсутствие факта, чужой документ, пустой файл или несовместимая редакция правила в зависимости от задачи. Храните ожидаемые ID и смысл результата отдельно от вывода программы. Если пример не прошёл, выясните, на каком шаге данные впервые разошлись: загрузка, обработка, извлечение или построение ответа. Нельзя исправлять результат одной только формулировкой ответа, если нужный факт никогда не поступил в контекст.

Разбор ограничений и ошибок

Нумерованные ссылки возникают в тексте генератора, а AnswerBuilder разбирает их структуру; компонент не доказывает, что предложение действительно следует из указанного фрагмента. Для важного RAG-ответа проверяйте три уровня: ID найденного документа, точную цитируемую фразу и соответствие утверждения этой фразе. При изменении порядка retrieved documents сохранённый в старом кеше ответ [1] может начать указывать на другой источник; кэшируйте весь контекст вместе с ответом или привязывайте постоянные ID. Если не задать reference_pattern, все документы попадут в поле references и интерфейс может ошибочно назвать их использованными. Regex должен находить именно те обозначения, которые вы инструктировали модель выводить, а не любые цифры в сроке или артикуле. Возвращаемые references не должны обходить проверку доступа: прямой переход по URL документа тоже проверяется сервером.

Проверочный сценарий на реальном корпусе

Негативный тест включает ответ без ссылок, несуществующий номер [9], противоречивый срок [1] и цитату на документ другого пользователя. Первый случай лучше пометить непроверенным, второй — ошибкой атрибуции, третий — фактической ошибкой, четвёртый — инцидентом контроля доступа. Эти категории нельзя сводить к одной метрике «ответ со ссылкой». При нескольких фрагментах одного документа объединяйте ссылки на исходный документ только после проверки, что они относятся к той же редакции. Для генераторов Chat и non-Chat структура replies может различаться, но компонент поддерживает оба вида согласно документации. Число цитат не является оценкой качества; иногда честный ответ «нет данных» с нулём цитат предпочтительнее красивого вымышленного ответа.

Критерии приёмки

  • [1] сопоставлен с R7.
  • Доставка D9 не объявлена источником срока.
  • Фактический срок подтверждён текстом R7.

Не принимайте демонстрационный вывод за статистику качества. Для рабочего приложения повторите эти проверки на обезличенном наборе документов, измерьте результат после изменения версии корпуса и запретите доступ к источникам вне полномочий пользователя. Корректный ответ HTTP вашего сервиса не означает корректный ответ RAG-системы; последнее устанавливается сопоставлением факта с разрешённым источником.

Типичные ошибки: чего не делать

  • Не считать наличие ссылки доказательством истинности.
  • Не оставлять reference_pattern пустым, если нужны только процитированные документы.
  • Не кешировать ответ отдельно от порядка retrieved документов.

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

FAQ

Что если pattern не задан?

В ответ добавляются все переданные документы.

С какого номера начинаются ссылки?

С 1.

Проверяет ли AnswerBuilder факты?

Нет, он разбирает и связывает данные ответа.

Официальные источники

Частые вопросы

Что если pattern не задан?

В ответ добавляются все переданные документы.

С какого номера начинаются ссылки?

С 1.

Проверяет ли AnswerBuilder факты?

Нет, он разбирает и связывает данные ответа.

Читайте также

Комментарии

Пока тихо. Скажите первое слово