Архитектура RAG — как дать модели свои данные
От загрузки документов до выдачи ответа со ссылками — разбираем пайплайн RAG по слоям и где он ломается.
Что такое RAG
Retrieval-Augmented Generation — подход, где модель отвечает не из памяти, а на основе документов, которые мы ей подсунули в нужный момент. Вместо того чтобы дообучать модель на своих данных (дорого, долго, быстро устаревает), мы оставляем модель как есть, а нужные куски знаний достаём в момент запроса и кладём прямо в контекст.
Полный разбор с примерами кода и шаблонами промптов — по подписке Pro. Сюда можно вставить любой свой текст.
Зачем это нужно
Большая языковая модель знает только то, что видела на обучении. Она не в курсе вашей внутренней документации, вчерашних тикетов и базы знаний компании. RAG закрывает этот разрыв, не трогая саму модель.
- Свежесть. Данные обновляются в индексе, а не переобучением модели.
- Прозрачность. Можно показать, из каких источников собран ответ.
- Контроль. Модель отвечает по вашим документам, а не фантазирует.
Когда RAG не нужен
Если задача — переписать текст, перевести или порассуждать на общую тему, никакие внешние данные не требуются. RAG оправдан там, где ответ обязан опираться на конкретные документы, которых нет в памяти модели.
Пайплайн по слоям
Любой RAG раскладывается на два конвейера: индексация (готовим данные заранее) и запрос (отвечаем в реальном времени). Разберём по шагам.
Загрузка и нарезка
Документы режем на куски (chunks) — обычно 200–500 токенов. Слишком крупные куски размывают смысл при поиске, слишком мелкие теряют контекст.
def chunk(text: str, size: int = 400, overlap: int = 40) -> list[str]:
words = text.split()
chunks = []
for i in range(0, len(words), size - overlap):
chunks.append(" ".join(words[i : i + size]))
return chunks
Перекрытие (overlap) между кусками спасает мысль, которая иначе оборвалась бы ровно на границе чанка.
Эмбеддинги
Каждый кусок превращаем в вектор — числовое представление смысла — и кладём в векторную БД. Похожие по смыслу тексты получают близкие векторы.
Модель эмбеддингов и модель-генератор — это РАЗНЫЕ модели. Эмбеддинги дешёвые и быстрые, их гоняют на всю базу.
Поиск
На вопрос пользователя считаем вектор запроса и ищем ближайшие по смыслу куски в базе. Обычно берут top-k (например, 4–8 самых релевантных).
Генерация
Найденное кладём в контекст модели вместе с вопросом и инструкцией «отвечай только по этим данным, со ссылками». На выходе — ответ, опирающийся на источники.
Где это ломается
Красивая схема на практике спотыкается на каждом слое. Вот типичные места.
Плохая нарезка
Кусок обрывается на полуслове, заголовок отрывается от тела, таблица рвётся пополам — и смысл теряется ещё до поиска.
Шумный поиск
Векторный поиск выдаёт «похожее, но не то»: синонимичные формулировки без нужного факта. Лечится re-ranking и гибридным поиском (вектор + ключевые слова).
Переполнение контекста
Суём слишком много кусков «на всякий случай» — модель тонет в шуме и отвечает хуже, чем с тремя точными. Больше контекста ≠ лучше ответ.
Частая ошибка новичка: top-k = 20 «чтобы наверняка». На деле качество падает, а счёт за токены растёт.
Практика
Начинай с простого: фиксированная нарезка + один проход поиска + top-k = 4. Усложняй только когда упрёшься в качество и сможешь это измерить.
С чего начать
- Загрузка. Режем документы на куски 300–400 токенов с перекрытием.
- Эмбеддинги. Один прогон всей базы через модель эмбеддингов.
- Поиск. top-k ближайших по косинусной близости.
- Генерация. Куски + вопрос + строгая инструкция со ссылками.
Что мерить
Без метрик улучшения превращаются в гадание. Минимум — отвечает ли система на набор контрольных вопросов и ссылается ли на верные источники.
Сначала измеримая база, потом оптимизации. Re-ranking и гибридный поиск добавляй, когда видишь на цифрах, что простой пайплайн упёрся.
Куда расти дальше
Когда база работает — на очереди re-ranking найденного, гибридный поиск, сжатие контекста и кэширование частых запросов. Но это уже следующая статья.