Retrieval-Augmented Generation, citation prompting, grounding, lost-in-the-middle проблема
Языковые модели обладают знаниями, зафиксированными на момент обучения. Они не знают, что произошло вчера, не имеют доступа к вашей внутренней документации и не могут обратиться к корпоративной базе данных. RAG (Retrieval-Augmented Generation) решает эту проблему, не требуя переобучения модели.
RAG — это архитектурный паттерн, при котором перед генерацией ответа система извлекает релевантные фрагменты из внешнего хранилища и вставляет их в промпт. Модель отвечает уже не из памяти весов, а опираясь на предоставленный контекст.
Зачем это нужно:
Классический пример: чат-бот технической поддержки. Документация компании меняется каждую неделю. Переобучать модель еженедельно нереально. RAG извлекает нужную статью и даёт модели работать с ней.
Стандартный пайплайн состоит из трёх этапов.
Этап 1 — Retrieval (Извлечение)
Запрос пользователя превращается в вектор-эмбеддинг. Система ищет ближайшие векторы в базе (Pinecone, Weaviate, pgvector). Возвращаются топ-K наиболее похожих фрагментов (chunks).
Этап 2 — Context Injection (Вставка контекста)
Найденные фрагменты форматируются и помещаются в промпт как "контекст". Здесь начинается работа промпт-инженера: как именно подать эти фрагменты, в каком порядке, с какими разделителями.
Этап 3 — Generation (Генерация)
Модель получает промпт с контекстом и вопросом, генерирует ответ. Если промпт составлен правильно, модель использует контекст, а не выдумывает.
Структура RAG-промпта имеет значение. Рассмотрим типичный шаблон:
Ты — ассистент технической поддержки компании.
Ниже приведены релевантные фрагменты из документации:
--- ДОКУМЕНТ 1 ---
Заголовок: Настройка двухфакторной аутентификации
Источник: docs.company.com/2fa
Текст: Двухфакторная аутентификация включается в разделе...
-----------------
--- ДОКУМЕНТ 2 ---
Заголовок: Сброс пароля
Источник: docs.company.com/password-reset
Текст: Для сброса пароля перейдите в...
-----------------
На основе только этой документации ответь на вопрос пользователя.
Если информации недостаточно — честно скажи об этом.
Вопрос: Как подключить Google Authenticator?
Ключевые принципы форматирования:
---, ===, XML-теги)Citation prompting — техника, при которой мы явно инструктируем модель ссылаться на документы при составлении ответа. Это повышает доверие к ответу и позволяет пользователю проверить информацию.
Пример инструкции:
При ответе обязательно указывай, из какого документа взята информация.
Используй формат: [Источник: <название документа>].
Если делаешь вывод на основе нескольких документов — укажи все.
Результат такого промпта:
Для подключения Google Authenticator зайдите в Настройки > Безопасность > 2FA
и выберите "Приложение-аутентификатор" [Источник: Настройка двухфакторной аутентификации].
Затем отсканируйте QR-код в приложении Google Authenticator [Источник: Настройка двухфакторной аутентификации].
Продвинутый вариант — numbered citations по аналогии с академическими статьями:
Предоставь ответ в следующем формате:
- В тексте используй номера ссылок в квадратных скобках: [1], [2]
- В конце добавь раздел "Источники:" со списком документов
Исследование "Lost in the Middle" (Liu et al., 2023) показало, что языковые модели хуже используют информацию из середины длинного контекста. Модель лучше всего "видит" начало и конец промпта.
Практическое следствие: если у вас 10 retrieved документов и наиболее релевантный оказался пятым — вы можете получить менее точный ответ, чем если бы он был первым или последним.
Решения:
Векторный поиск не идеален. Среди топ-5 документов может оказаться один, семантически похожий, но фактически нерелевантный. Этот "шум" сбивает модель.
Пример: вопрос о настройке Redis кэширования может извлечь документ о Redis pub/sub (семантически близко, но не по теме). Модель начнёт смешивать информацию.
Борьба с шумом:
Иногда предоставленный документ противоречит тому, что модель "знает" из обучения. Например, в документации написано "функция deprecated с версии 3.1", но модель обучена на данных где эта функция ещё активна.
По умолчанию модели склонны доверять собственным параметрическим знаниям. Это приводит к игнорированию контекста.
Чтобы явно приоритизировать контекст:
ВАЖНО: Если информация в документах противоречит твоим знаниям —
доверяй документам. Они содержат актуальную информацию.
Обратная ситуация — когда контекст содержит ошибку — требует другого подхода:
Ответь на основе документов. Если видишь явное противоречие с
общеизвестными фактами — укажи на него отдельно.
Когда релевантных документов много, они не помещаются в контекстное окно. Три стратегии:
Chunking (Разбивка)
Документы разбиваются на небольшие перекрывающиеся фрагменты (например, 512 токенов с перекрытием 50 токенов). Плюс: точный поиск. Минус: фрагмент может потерять контекст целого документа. Решение — добавлять в каждый chunk метаданные родительского документа.
Summarization (Суммаризация)
Для каждого документа заранее создаётся краткое резюме. При retrieval сначала ищутся резюме (быстро и дёшево), затем при необходимости подгружается полный текст. Иерархический RAG: сначала резюме для навигации, затем детали.
Hybrid (Гибридный поиск)
Комбинация векторного поиска (семантика) и BM25 (ключевые слова). Векторный поиск хорош для концептуальных запросов, BM25 — для точных названий функций или кодов ошибок. Результаты объединяются через Reciprocal Rank Fusion (RRF). Это значительно повышает качество retrieval, особенно для технических тематик.
Grounding — это техника принудить модель отвечать исключительно на основе предоставленного контекста, не привлекая "внешние" знания.
Базовый grounding промпт:
Отвечай ТОЛЬКО на основе предоставленных документов.
Не используй знания, которые не содержатся в документах выше.
Если документы не содержат достаточно информации для ответа —
ответь: "В доступных документах нет ответа на этот вопрос."
Продвинутый grounding через роль:
Ты — информационная система, которая имеет доступ только к указанным документам.
Тебе технически недоступны другие источники информации.
Grounding особенно важен в:
Первичный векторный поиск возвращает приближённо похожие документы. Reranking — второй проход, более точная оценка релевантности конкретно для данного запроса.
Cross-encoder reranking: специализированная модель оценивает пару (запрос, документ) совместно, давая балл релевантности. Это медленнее, чем vector search, но точнее. Типичный pipeline: ANN-поиск находит топ-50, cross-encoder переранжирует, в промпт идут топ-5.
Prompt-based relevance scoring: можно попросить саму LLM оценить документы перед ответом:
Оцени релевантность каждого из следующих документов
для ответа на вопрос: "<вопрос>".
Для каждого документа дай оценку от 0 до 10.
Используй только документы с оценкой >= 7.
Этот подход дороже по токенам, но эффективен при сложных запросах.
Maximal Marginal Relevance (MMR): выбор документов с балансом релевантности и разнообразия. Если первые два документа почти идентичны — лучше взять третий, менее похожий на первые, но содержащий новую информацию.
| Критерий | RAG | Fine-tuning |
|---|---|---|
| Знания обновляются часто | Да | Нет |
| Нужны источники/цитаты | Да | Сложно |
| Специфический стиль/формат | Сложно | Да |
| Сложные рассуждения по домену | Так себе | Да |
| Бюджет на инфраструктуру | Средний | Высокий |
| Нужно быстро запустить | Да | Нет |
RAG выигрывает, когда знания динамичны или нужна проверяемость. Fine-tuning выигрывает, когда нужно изменить поведение модели (стиль, формат, способ рассуждения) или когда задача требует глубокой специализации в узкой области.
Часто оптимальное решение — RAG + Fine-tuning: fine-tuning учит модель формату и стилю ответов, RAG предоставляет актуальные факты. Например, fine-tuning на корпусе юридических документов учит модель правильной терминологии, RAG предоставляет конкретные нормативные акты.
Ключевой вопрос при выборе: "Что мне нужно изменить — знания или поведение?" Если знания — RAG. Если поведение — fine-tuning.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.