🔎 RAG: генерация, дополненная поиском
RAG (Retrieval-Augmented Generation, генерация, дополненная поиском) — это схема, при которой модель перед ответом подгружает релевантные фрагменты из вашей базы знаний, а уже потом формулирует ответ, опираясь на них. Это самый распространённый и самый полезный паттерн в корпоративном AI: именно он превращает «умную, но не знающую ваших реалий» модель в систему, которая отвечает по вашим документам.
Одно предложение
RAG = «модель не пытается вспомнить ответ из головы, а сначала ищет нужное в вашей базе, читает найденное и только потом отвечает». Это и точнее, и дешевле, и безопаснее (08-gallyutsinatsii-i-nadezhnost).
Зачем нужен RAG
Модель «от производителя» знает то, что было в её обучающих данных, и не знает вашего. RAG решает сразу несколько проблем:
| Проблема | Что даёт RAG |
|---|---|
| Модель не знает ваши документы | Подтягивает фрагменты из вашей базы |
| Знания устарели | Базу обновляете вы — без переобучения модели |
| Нужны источники (аудит) | Можно показать, из какого фрагмента взят ответ |
| Высокий риск галлюцинаций | Заземляет модель в проверенных текстах (08-gallyutsinatsii-i-nadezhnost) |
| Контекст ограничен | Даёт только релевантное, а не весь архив (02-tokens-context-window) |
Полный конвейер RAG
RAG — это не «одна функция», а два процесса: разовая индексация (подготовка базы) и постоянный запрос (поиск + генерация).
flowchart TD subgraph IDX["🗄 Индексация (один раз + обновления)"] D["📄 Документы"] --> CH["✂ Чанкинг<br/>(нарезка на фрагменты)"] CH --> EM["🔢 Embedding-модель<br/>(текст → вектор)"] EM --> VDB[("🗃 Векторная база<br/>+ текст фрагмента<br/>+ метаданные")] end subgraph Q["🔍 Запрос (каждый раз)"] UQ["❓ Вопрос пользователя"] --> QEM["🔢 Embedding<br/>вопроса"] QEM --> RET["🔎 Поиск top-K<br/>похожих фрагментов"] VDB --> RET RET --> RR["📊 Реранжирование<br/>(уточнение порядка)"] RR --> GEN["🧠 LLM генерирует ответ<br/>по найденным фрагментам"] GEN --> ANS["✅ Ответ + источники"] end
Этап 1. Чанкинг (chunking)
Документы режутся на чанки — фрагменты, которые будут искаться и подаваться в модель целиком. Размер чанка — один из главных рычагов качества:
- Слишком мелкий — теряется контекст смысла.
- Слишком крупный — в модель попадает много шума, дороже, хуже точность.
- Часто используют 200–800 токенов с перекрытием (overlap), чтобы не разрезать мысль пополам.
Не режьте «по символам»
Умный чанкинг учитывает структуру документа: разделы договора, абзацы, заголовки. Для юридических текстов осмысленная нарезка (по пунктам/статьям) даёт заметный прирост качества поиска.
Этап 2. Embedding (эмбеддинг)
Каждый чанк пропускается через embedding-модель, которая превращает текст в вектор (02-tokens-context-window). Это отдельная, лёгкая и дешёвая модель — не та большая LLM, что генерирует ответ.
Этап 3. Векторная база (vector database)
Векторы вместе с исходным текстом чанка и метаданными (название документа, дата, раздел) складируются в векторной базе, оптимизированной под поиск «близких по смыслу» векторов.
| База | Особенность |
|---|---|
| Qdrant | Популярная, пишется на Rust, есть open-source и cloud |
| Milvus | Заточена под масштаб |
| pgvector | Расширение PostgreSQL — удобно, если БД уже есть |
| Pinecone / Weaviate / Chroma | Облочные и встраиваемые варианты |
Почему метаданные важны
Без метаданных поиск вернёт «похожий по смыслу» чанк, но вы не узнаете, из какого он документа и актуален ли. С метаданными можно фильтровать: «ищи только в действующих договорах 2026 года», «только в политике конфиденциальности». Фильтр по метаданным — дешёвый и сильный рычаг точности.
Этап 4. Поиск (retrieval)
Вопрос пользователя тоже превращается в вектор, и база возвращает top-K самых близких по смыслу чанков (K обычно 3–10).
Чистый векторный поиск — не всегда лучшее
Векторный поиск силён в смысле, но слаб в точных терминах: название «Приложение № 14» или номер дела он может не найти. Поэтому в production чаще используют гибридный поиск: векторный (по смыслу) + классический по ключевым словам (BM25) — и объединяют результаты.
Этап 5. Реранжирование (reranking)
Отобранные фрагменты прогоняют через реранкер — отдельную модель, которая точнее пересортировывает их уже с учётом пары «вопрос ↔ фрагмент». Это заметно повышает качество «того самого» фрагмента на вершине выдачи.
Этап 6. Генерация
Найденные фрагменты вставляются в промпт, и LLM формулирует ответ с опорой на них. Здесь же работает инструкция «не выдумывай, ссылайся на источник» (07-prompt-engineering, 08-gallyutsinatsii-i-nadezhnost).
RAG vs Fine-tuning vs Длинный контекст
Самый частый вопрос на архитектурных-review. Простое правило:
flowchart TD Q{"В чём задача?"} Q -->|«Модель не знает наши документы/нормы»| RAG["🔎 RAG<br/>(даёт знания в момент)"]:::good Q -->|«Модель не ведёт себя как надо:<br/>стиль, формат, роль»| FT["🏭 Fine-tuning<br/>(или промпт)"]:::good Q -->|«Документ небольшой и один,<br/>нужно прочесть целиком»| LC["📏 Длинный контекст<br/>(загрузить целиком)"]:::good classDef good fill:#e8f5e9,stroke:#4caf50;
Почему RAG обычно побеждает
- Знания обновляются без переобучения — просто перетрите базу.
- Можно показать источник (аудит, доверие).
- Дешевле, чем держать огромный контекст в каждом запросе (06-stoimost-i-ekonomika). Fine-tuning не «даёт знания» в смысле фактов — он подстраивает поведение. Длинный контекст хорош, но дорог и страдает «потерей середины» (02-tokens-context-window).
Продвинутые варианты
- Hybrid search — векторный + ключевый (BM25) поиск. Стандарт для production.
- Reranking — отдельный этап уточнения порядка. Часто даёт +10–20% к качеству.
- GraphRAG — поверх текста строится граф связей (сущности, отношения); полезно для сложных запросов «кто с кем связан через что». Дороже в индексации.
- Agentic RAG — поиском управляет агент: сам решает, нужен ли поиск, сколько раундов, в каких источниках; может уточнять запрос. Самый мощный, но и самый дорогой вариант.
- Multi-vector / parent-child — ищут по мелким чанкам, а в модель отдают более крупный родительский фрагмент (чтобы сохранить контекст).
Где RAG ломается
Типовые провалы
- Плохой чанкинг — смысл разрезан, поиск находит «не то».
- Слабая embedding-модель или не подходящая к языку/домену.
- Нет реранкера — релевантный фрагмент застрял на 5-м месте и не попал в выдачу.
- Устаревшая база — ответ по старой версии документа.
- Нет фильтров по метаданным — модель отвечает по черновику вместо действующего.
- Ошибки не измеряют — без RAG-eval (например, RAGAS) вы не знаете, что система работает плохо, пока не поздно.
Качество RAG — что мерить
| Метрика | Что показывает |
|---|---|
| Retrieval hit-rate / MRR | Нашёлся ли нужный фрагмент и насколько высоко |
| Faithfulness (точность по источнику) | Нет ли в ответе выдумок сверх найденного |
| Answer relevancy | Ответ по теме вопроса |
| Context precision / recall | Качество отобранного контекста |
RAGAS и аналоги
Существуют фреймворки (RAGAS и подобные), которые автоматически оценивают RAG-систему по этим метрикам, часто с помощью LLM-as-Judge (14-ocenka-kachestva). Не запускайте RAG в production без такой оценки.
📌 Что запомнить
- RAG = «сначала поиск по вашей базе, потом генерация с опорой на найденное».
- Конвейер: чанки → эмбеддинги → векторная база → поиск (гибридный) → реранжирование → генерация.
- Качество держится на: умном чанкинге, подходящей embedding-модели, метаданных, реранкере.
- RAG даёт знания, fine-tuning — поведение, длинный контекст — для разового чтения.
- Продвинутые варианты: hybrid search, GraphRAG, Agentic RAG.
- Не запускать без RAG-eval (RAGAS, LLM-as-Judge).
Дальше: 🤖 Архитектура AI-агентов → — что превращает LLM из «ответчика» в «деятеля».