Гайд · TNWS AI

Как собрать проверяемый RAG-промпт в Haystack PromptBuilder

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

Шаблон с вопросом и документами, обязательные переменные, безопасный отказ при пустом контексте и проверка рендеринга.

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

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

PromptBuilder форматирует строковый шаблон Jinja2. В Haystack 3.1 required_variables по умолчанию равен *, то есть отсутствующая переменная приводит к ошибке. Если пометить переменную необязательной, она может превращаться в пустую строку; это риск незаметной генерации без контекста.

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

  1. Отделите системную задачу от внешних документов и определите переменные query, documents.
  2. Составьте шаблон с явным условием для пустого списка документов и запретом придумывать факты вне контекста.
  3. Оставьте query и documents обязательными, чтобы не выдавать пустой контекст за корректную сборку.
  4. Запустите PromptBuilder.run локально и распечатайте полученный prompt до вызова LLM.
  5. Проверьте положительный документ, пустой список и пропущенную переменную, затем отдельно измерьте бюджет токенов.

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

from haystack import Document
from haystack.components.builders import PromptBuilder

template = """Ответь на вопрос только по материалам ниже.
Если материалы пусты или не содержат ответа, скажи: Нет данных.
Материалы:
{% for doc in documents %}[{{ loop.index }}] {{ doc.content }}
{% endfor %}
Вопрос: {{ query }}
Ответ с номером материала: """
builder = PromptBuilder(template=template,
                        required_variables=["query", "documents"])
rendered = builder.run(query="Каков срок возврата?",
                       documents=[Document(content="Возврат 14 дней.")])
print(rendered["prompt"])

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

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

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

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

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

Шаблон не является механизмом защиты от инъекций, если текст документа содержит команды вроде «игнорируй прежние инструкции». Внешний фрагмент следует трактовать как данные, не как новую системную инструкцию. При длинной подборке документов проверяйте, что важное исключение не отрезается ограничением контекста; сначала ранжируйте или сокращайте набор, не обрезайте конец вслепую. Если извлечение ничего не нашло, приложение может вообще не вызывать генератор и вернуть честный отказ; условие в шаблоне полезно как второй уровень. Индексы [1], [2] должны быть привязаны к фактическому порядку documents при данном вызове. Храните соответствие с исходными ID отдельно, иначе номер в ответе станет неоткрываемой «ссылкой». Проверка required_variables особенно важна при рефакторинге pipeline: исчезнувший documents не должен молча сделать модель общим чат-ботом.

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

Создайте набор случаев: один документ с ответом, два противоречащих документа разных редакций, один документ с похожей темой без ответа, пустой список и документ с инструкцией-вредителем. Для противоречия предусмотрите источник актуальной редакции и правило разрешения конфликта до генерации; промпт не знает автоматически, какой документ юридически действителен. Убедитесь, что ожидаемые URL или ID действительно поступили вместе с документами, а не сочинены моделью. Запуск PromptBuilder сам по себе не подтверждает качество LLM: тест рендеринга и тест ответа должны быть разными. Сохраняйте снимок шаблона и набора документов, чтобы регрессии после редактирования текста можно было воспроизвести.

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

  • Собранный prompt содержит вопрос и документ.
  • Пропущенная обязательная переменная приводит к ошибке.
  • Пустой контекст не превращается в вымышленный ответ.

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

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

  • Не считать шаблон защитой от prompt injection.
  • Не делать documents необязательной переменной без причины.
  • Не путать индекс [1] с постоянным ID источника.

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

FAQ

Какой язык шаблонов?

Jinja2.

Что возвращает builder?

Строку prompt в результате run.

Гарантирует ли шаблон честный ответ модели?

Нет, проверка генератора нужна отдельно.

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

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

Какой язык шаблонов?

Jinja2.

Что возвращает builder?

Строку prompt в результате run.

Гарантирует ли шаблон честный ответ модели?

Нет, проверка генератора нужна отдельно.

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

Комментарии

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