Гайд · TNWS AI
Как привязать ответ RAG к документам через Haystack AnswerBuilder
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] рядом с проверяемым утверждением.
- Настройте reference_pattern на один номер в квадратных скобках.
- Передайте replies, query и исходные documents в AnswerBuilder и просмотрите
answers. - Проверьте каждое утверждение по фактическому документу; номер ссылки — не доказательство корректного вывода.
Готовый шаблон
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 факты?
Нет, он разбирает и связывает данные ответа.
Читайте также
Как ограничить поиск документами одного клиента в Haystack
Фильтр meta.tenant в retriever, тест на утечку чужого документа и границы серверной авторизации.
Как настроить смысловой поиск в Haystack InMemoryEmbeddingRetriever
Индексируем документы и запрос одной embedding-моделью, проверяем размерность, top_k и качество на перефразировках.
Как избежать дублей документов в Haystack через DocumentWriter и DuplicatePolicy
Повторная индексация без случайных дублей: стабильные ID, режимы OVERWRITE, SKIP и FAIL и проверка числа записей.
Комментарии
Пока тихо. Скажите первое слово