RAG — это конвейер, а не память внутри модели

Retrieval-augmented generation переводится как генерация с дополнением найденными материалами. Базовая модель не получает ваши документы в веса при каждом запросе. Приложение ищет релевантные фрагменты во внешнем индексе, вставляет их в ограниченный prompt и просит сформировать ответ. Источник можно обновить без переобучения модели, но качество зависит от всего конвейера.

Такой подход полезен, когда знания часто меняются, имеют локальный доступ или должны цитироваться. Он не превращает документ в истину и не гарантирует отсутствие выдумки. Если нужной страницы нет, индекс устарел или retrieval ошибся, генератор не получает необходимого evidence. Если evidence найден, модель всё равно может его исказить.

Чтобы диагностировать систему, разделите offline ingestion и online query path. Первый строит и обновляет searchable corpus. Второй обрабатывает вопрос конкретного пользователя. У них разные latency, permissions, тесты и failure recovery. Смешивание приводит к совету «смените модель» при сломанном parser.

Архитектурная диаграмма и разбор ограничений

Переход

Что происходит

Типичная ошибка

Проверка

Источник → parser

Извлечение текста, таблиц и metadata

Потеря страницы, OCR или структуры

Coverage и sample diff с оригиналом

Parser → chunks

Разделение и добавление контекста

Исключение оторвано от правила

Chunk review и boundary cases

Chunks → index

Embeddings, lexical terms, filters

Старая версия или неверные права

Freshness и permission tests

Question → candidates

Query transform и hybrid retrieval

Нужный фрагмент не вошёл в top-k

Recall@k на размеченных вопросах

Candidates → context

Reranking, deduplication, ordering

Дубликаты вытеснили evidence

Context relevance и diversity

Context → answer

Генерация, отказ и citations

Ответ противоречит фрагменту

Faithfulness и claim support

Answer → user

Access, formatting, feedback, log

Раскрыт недоступный документ

Authorization и audit scenarios

Диаграмма — не конкретный стек. Keyword index может быть отдельным или встроенным, reranker — моделью либо правилом, генератор — hosted или local. Граница важнее названий: у каждого перехода должны быть вход, версия, наблюдаемая метрика и способ воспроизвести ошибку.

Ingestion: сделайте документы пригодными для поиска

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

Parser должен извлекать не только сплошной текст. Заголовки, номера разделов, таблицы, подписи, сноски и страницы нужны для смысла и citation. Проверьте scanned PDFs, merged cells, columns и hidden text. Случайный OCR-дефект в коде продукта часто важнее разницы между embedding models.

Chunking определяет единицу retrieval. Слишком короткий фрагмент теряет условие, субъект и исключение. Слишком длинный смешивает темы и расходует context budget. Начинайте с естественных границ документа, затем измеряйте. Overlap помогает на стыке, но создаёт дубликаты и не исправляет плохую структуру.

Добавьте к chunk короткий локальный контекст: документ, раздел, тема, дата действия и access label. Contextual retrieval использует этот подход, чтобы самостоятельный фрагмент сохранял значение. Metadata не должна быть выдумана моделью при ingestion без проверки, особенно для прав, сроков и владельца.

Индексируйте версии атомарно: пользователь не должен видеть половину нового corpus. После сборки прогоните canary queries, сравните количество документов и orphan chunks, затем переключите alias. Сохраните rollback на предыдущую версию. Это обычная эксплуатация данных, а не свойство LLM.

Retrieval: ищите и смысл, и точные признаки

Dense retrieval полезен при перефразировании: вопрос и passage могут не иметь одинаковых слов. Lexical search важен для артикулов, фамилий, аббревиатур и точных фраз. Hybrid retrieval объединяет кандидатов, но веса нельзя выбирать по одному удачному вопросу. Разметьте реальные запросы и ожидаемые evidence chunks.

Query rewriting может раскрыть сокращение, выделить сущность или создать несколько вариантов. Оно же может незаметно изменить намерение. Сохраняйте исходный и преобразованный запрос, ограничивайте число веток и оценивайте случаи, где rewrite ухудшил поиск. Пользовательские права применяются до возврата candidates, а не после генерации.

Reranker смотрит на вопрос и кандидата совместно и может поднять более точный passage. Он добавляет latency и новую модель ошибок. Проверяйте recall до reranking и precision после него: иначе невозможно понять, потерялся ли evidence на первом поиске или при перестановке.

Top-k — не показатель качества сам по себе. Большое значение повышает шанс найти ответ и одновременно добавляет шум, дубликаты и противоречия. Контекст имеет предел; даже внутри него положение информации способно влиять на результат. Отбирайте минимальный достаточный набор и сохраняйте provenance каждого фрагмента.

Context assembly: сформируйте пакет доказательств

Перед prompt удалите byte-identical и semantic duplicates, сгруппируйте версии и явно отметьте даты. Не смешивайте документы разных пользователей или уровней доступа. При конфликте не просите модель молча выбрать победителя: покажите расхождение и правило приоритета либо верните его на review.

Назначьте каждому passage внутренний immutable citation ID, связанный с source ID, версией, страницей и offsets. Модель может ссылаться только на эти IDs. После ответа приложение проверяет, что ID существовал в переданном контексте и доступен пользователю. Это предотвращает несуществующие ссылки, но ещё не доказывает entailment.

Инструкции системы должны отделять evidence от commands: текст источника нельзя выполнять как указание. Но prompt formatting — лишь один слой. Retrieved content остаётся недоверенным; tool use ограничивается allowlist, аргументы валидируются, а внешнее действие требует дополнительного контроля.

Generation: разрешите системе не знать

Задайте контракт ответа: прямой вывод, citations на каждое проверяемое утверждение, обозначение конфликта и UNKNOWN при недостаточном evidence. Не заставляйте модель отвечать на любой вопрос. Низкая retrieval confidence не является доказательством отсутствия факта, поэтому формулировка должна говорить «в доступных источниках не найдено».

Для критичных полей полезнее структурированный output со schema validation, чем свободный убедительный текст. Валидная схема также не доказывает истинность. После parsing выполните claim-level verification: поддерживает ли конкретный cited passage именно эту фразу, не содержит ли более узкого условия и не устарел ли.

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

Оценивайте RAG по слоям

Создайте test set из настоящих информационных потребностей: простой lookup, multi-hop, вопрос без ответа, конфликт версий, точный код, длинная таблица, закрытый документ и вредоносная инструкция. Для каждого укажите допустимые evidence chunks, свойства ответа и access expectation. Не используйте production secrets в наборе.

На retrieval измеряйте, попал ли нужный evidence в top-k, какое место занял и сколько нерелевантных chunks вытесняет контекст. На generation отдельно оценивайте faithfulness, answer relevance, completeness, citation correctness и правильный отказ. Общий процент успешности скрывает место дефекта.

ARES показывает ценность раздельных context relevance, answer faithfulness и answer relevance. Автоматический evaluator ускоряет повторные прогоны, но валидируйте его на человечески размеченном поднаборе. Особенно проверяйте русский язык, таблицы, отрицания и условные правила.

Сохраняйте результаты по версии corpus, parser, chunker, embedding, lexical index, reranker, prompt и generator. Любое изменение может улучшить один сегмент и сломать другой. Добавляйте реальные ошибки в regression set и не обновляйте golden evidence автоматически вместе с системой.

Безопасность и права — часть retrieval

Фильтрация доступа после генерации слишком поздняя: закрытый passage уже мог повлиять на ответ или попасть в log. ACL пользователя применяются при формировании candidates и повторно перед показом citations. Cache и conversation memory также должны включать identity и policy version в ключ.

Защитите ingestion: разрешённые источники, проверка типа и размера, malware scan, sanitization и provenance. Веб-страница или загруженный PDF может содержать indirect prompt injection. Не позволяйте retrieval автоматически расширять allowlist URL по тексту найденного документа.

Логи нужны для диагностики, но могут содержать запросы и passages. Минимизируйте их, задайте retention, роли и redaction. Для инцидента сохраните IDs и hashes, достаточные для воспроизведения в защищённой среде. Метрика без source version не объяснит, почему вчера ответ был другим.

Практический пилот за один узкий corpus

  • Выберите один документный набор с владельцем, версиями и понятными правами.

  • Составьте 30–50 реальных вопросов, включая UNKNOWN, конфликт и access-denied сценарии.

  • Разметьте ожидаемые evidence chunks до настройки retrieval.

  • Проверьте parsing и chunk boundaries на таблицах, исключениях и длинных разделах.

  • Сравните lexical, dense и hybrid candidates; добавьте reranker только при измеримой пользе.

  • Введите immutable citation IDs и claim-level verification.

  • Настройте отказ при недостаточном evidence и запрет tool actions из retrieved text.

  • Запишите версии всех компонентов и прогоните regression set перед изменением alias.

Пилот считается полезным не тогда, когда дал красивый ответ на сцене, а когда команда может объяснить каждый сбой. Если evidence отсутствует в index, исправляйте ingestion. Если он есть, но не найден, retrieval. Если он в prompt, но искажён, generation или context assembly. Эта карта экономит месяцы случайного тюнинга.

Начните с базовой системы: понятный parser, lexical search, несколько chunks, строгий ответ с citations. Зафиксируйте метрики, затем добавляйте embeddings, rewrite и reranker по одному. Сложность оправдана только наблюдаемым улучшением на собственном test set без ухудшения прав и отказов.

Что читать дальше