4.2 · Как устроен RAG: обзор архитектуры
Неделя 4 · RAG · ⏱ ~2–3 ч · Теория
Зачем это AI-инженеру
Заголовок раздела «Зачем это AI-инженеру»RAG (Retrieval-Augmented Generation) — самый частый паттерн в продуктах на LLM: чат по документации, база знаний компании, поддержка, поиск по договорам. На собеседовании просят нарисовать RAG-систему на доске и объяснить, где она ломается. В главе 4.1 мы научились одному звену — искать тексты по смыслу через эмбеддинги. Здесь видим цепочку целиком, и каждую следующую задачу недели (chunking, индекс, гибридный поиск, цитаты) мы кладём на своё место, а не изучаем изолированно.
Проблема, которую решает RAG
Заголовок раздела «Проблема, которую решает RAG»У LLM три ограничения: знания заморожены на дате обучения, модель не видит наших приватных данных и уверенно выдумывает, когда не знает. База знаний магазина меняется постоянно: новые тарифы доставки, другие сроки возврата, новые товары с собственной гарантией. Спросить модель «можно ли вернуть вскрытый чай в магазине „Полка“» без контекста — получить правдоподобную выдумку.
Идея RAG: перед генерацией найти релевантные куски наших документов и положить их в промпт. Найти их помогает поиск по смыслу из прошлой главы. Модель отвечает не «из головы», а по предоставленному тексту — как студент на открытом экзамене с конспектом.
Альтернативы и когда они лучше:
| Подход | Когда подходит |
|---|---|
| Положить всё в контекст (long context) | Документов мало (десятки страниц), они помещаются в окно модели; с prompt caching это бывает дешевле и проще RAG |
| Fine-tuning | Нужно изменить стиль/формат/поведение, а не добавить факты; факты через fine-tuning учатся плохо и устаревают |
| RAG | Документов много, они меняются, нужны ссылки на источник |
Статья Anthropic про Contextual Retrieval прямо говорит: если база меньше ~200 тысяч токенов, сначала стоит просто положить её в промпт. Эту планку полезно помнить — это хороший ответ на собеседовании. Наша учебная база знаний (30–50 страниц, которые мы соберём в главах 4.3–4.4) под неё, скорее всего, попадает, и мы честно держим вариант «всё в промпт» как baseline. RAG строим ради ссылок на точный раздел и ради умения, которое нужно на базах в тысячи страниц: там «всё в промпт» уже не работает.
Две фазы: индексация и запрос
Заголовок раздела «Две фазы: индексация и запрос» ИНДЕКСАЦИЯ (офлайн, по расписанию / при обновлении доков) ┌─────────┐ ┌───────┐ ┌──────────┐ ┌───────────┐ ┌─────────────┐ │загрузка │──►│ чистка│──►│ chunking │──►│эмбеддинги │──►│ индекс │ │HTML/PDF │ │→ MD │ │+метаданные│ │ (+BM25) │ │ (вектор БД) │ └─────────┘ └───────┘ └──────────┘ └───────────┘ └─────────────┘
ЗАПРОС (онлайн, на каждый вопрос) ┌──────┐ ┌─────────────┐ ┌─────────┐ ┌───────────┐ ┌────────┐ ┌───────┐ │вопрос│─►│переформули- │─►│ поиск │─►│ реранкинг │─►│ промпт │─►│ LLM → │ │ │ │ровка+фильтры│ │ top-50 │ │ top-5 │ │+ куски │ │ответ+ │ └──────┘ └─────────────┘ └─────────┘ └───────────┘ └────────┘ │ссылки │ └───────┘Это похоже на обычный бэкенд: есть фоновая работа (cron, очереди, прогрев кэша) и горячий путь (запрос пользователя → ответ). Индексация может быть медленной и дорогой, запрос должен быть быстрым.
Каждый этап: что делает и что может сломаться
Заголовок раздела «Каждый этап: что делает и что может сломаться»Разберём этапы на примере нашего проекта. Его корпус — папка kb/: справочный центр «Полки» в виде Markdown-файлов (delivery.md, returns.md, warranty.md, страницы товаров в products/…). Каждый файл начинается с front matter — блока метаданных между строками --- (title, category, updated, у старой редакции правил — archived: true). Страницы напишем в главе 4.3.
1. Загрузка (ingestion). Скачать или прочитать HTML, PDF, Markdown, Confluence… Сломается: JS-рендеринг (страница пустая без браузера), навигация и футеры, попавшие в текст, устаревшие версии страниц. В нашем проекте основной источник — Markdown-файлы kb/ на диске, так что половина этих проблем снимается; веб-страницы — опционально.
2. Чистка. Превратить HTML в чистый Markdown: убрать меню, cookie-баннеры, сохранить заголовки, таблицы и блоки кода. Сломается: таблицы превращаются в кашу, код теряет отступы. Для базы знаний магазина таблицы тарифов доставки и сроков гарантии — самое ценное.
3. Chunking. Нарезать документы на куски, которые потом ищутся по отдельности. Слишком большой кусок — эмбеддинг «размыт», в промпт попадает лишнее; слишком маленький — теряется контекст («этот товар» — какой?). Подробно — гл. 4.3.
4. Метаданные. У каждого чанка: категория (category: доставка, возврат, гарантия…), путь к файлу с якорем раздела, раздел (заголовки-предки), дата обновления, признак архивной страницы (archived). Они нужны для фильтров («только returns», «без архивных») и для ссылок в ответе.
5. Эмбеддинги. Каждый чанк → вектор (гл. 4.1). Плюс обычно параллельно строят лексический индекс (BM25), чтобы точно находить артикулы, названия товаров и промокоды (гл. 5.2).
6. Индекс. Векторная БД или расширение к обычной (sqlite-vec, pgvector, Qdrant). Хранит векторы, текст, метаданные; умеет искать ближайших соседей с фильтром. гл. 4.4.
7. Обработка запроса. Покупатель пишет «а чай-то вскрытый можно сдать обратно?». Это стоит переписать в поисковые запросы («возврат вскрытого чая», «какие товары не подлежат возврату»), определить категорию и поставить фильтр: category = returns, архивные страницы исключить. гл. 5.1.
8. Поиск (retrieval). Векторный поиск и BM25 дают две выдачи, их объединяют (RRF, Reciprocal Rank Fusion — слияние по местам в выдачах, гл. 5.2) → кандидаты, обычно 20–100.
9. Реранкинг. Более точная, но медленная модель (cross-encoder: читает вопрос и кусок вместе и выдаёт оценку релевантности, а не сравнивает готовые векторы) пересортировывает кандидатов, оставляем 3–10. гл. 5.2.
10. Сборка промпта. Инструкция + пронумерованные куски с источниками + вопрос. Правила: отвечать только по кускам, ставить ссылки [1], [2], честно говорить «не нашёл» (в нашем проекте — и передавать вопрос человеку). гл. 5.3.
11. Генерация и пост-обработка. Ответ, ссылки на разделы (kb/returns.md#opened-tea-returns), проверка, что ссылки ссылаются на реально выданные куски.
Где теряется качество
Заголовок раздела «Где теряется качество»Ошибка RAG почти всегда в retrieval, а не в генерации. Если нужного куска нет в контексте, лучшая модель не ответит правильно (или выдумает). Поэтому метрики делятся на две группы:
- Retrieval: hit rate@k (попал ли нужный кусок в топ-k), recall@k (какая доля всех нужных кусков попала в топ-k), MRR (насколько высоко стоит первый нужный кусок).
- Generation: faithfulness (ответ опирается на куски, а не выдуман), answer relevance (отвечает ли на вопрос), корректность ссылок.
Начинаем с первой группы: она дешёвая (не нужен LLM), детерминированная и показывает, где болит. Весь путь недель 4–5 построен на одной идее — маленький набор вопросов с известными ответами (golden set) и цифра hit rate после каждого улучшения. Систематические evals будут дальше в плане, здесь — их минимальная форма.
Contextual Retrieval: зачем читать вводную часть уже сейчас
Заголовок раздела «Contextual Retrieval: зачем читать вводную часть уже сейчас»Одна из частых причин промахов retrieval сидит ещё в индексации — в том, как кусок оторван от своего документа. Anthropic описывает эту проблему: чанк, вырванный из документа, теряет контекст. Кусок «Гарантия — 12 месяцев со дня покупки» без указания товара почти бесполезен: это лампа «Свет» или «Свет мини»? Решение — перед эмбеддингом приписать к каждому чанку короткое пояснение, сгенерированное LLM по всему документу («Этот фрагмент со страницы товара „Лампа «Свет»“, раздел „Гарантия“, описывает срок гарантии»). Плюс BM25 рядом с эмбеддингами и реранкинг. Сейчас нужно понять проблему, решение будет в гл. 5.2. Для документов с заголовками есть дешёвый вариант того же: приписывать к чанку хлебные крошки заголовков (Товары > Лампа «Свет» > Гарантия) — это мы сделаем уже в гл. 4.3.
Архитектурные решения, которые надо принять заранее
Заголовок раздела «Архитектурные решения, которые надо принять заранее»Этапы понятны; для каждого нужен конкретный инструмент. Часть решений проще принять один раз сейчас, чем менять посреди проекта.
| Вопрос | Варианты | Решение для нашего проекта (по умолчанию) |
|---|---|---|
| Язык проекта | Python / другой язык (JS, Go…) | Python: самая богатая экосистема RAG, и весь курс на нём |
| Эмбеддинги | API / локально | Локально (Ollama или Sentence Transformers): у DeepSeek эмбеддингов нет; конкретная модель — по итогам сравнения в гл. 4.1 |
| Хранилище | sqlite-vec / pgvector / Qdrant | sqlite-vec: один файл, знакомый SQLite |
| Лексический поиск | BM25 в памяти / FTS5 в SQLite | Начинаем с rank_bm25, FTS5 — как улучшение |
| Генерация | Любая LLM с API | DeepSeek (deepseek-flash), офлайн-вариант — Ollama; Claude/OpenAI для сравнения; имя модели и base_url из .env |
| Реранкер | API / локальный cross-encoder | Локальный cross-encoder (Sentence Transformers) |
| Интерфейс | CLI / Streamlit / Telegram | CLI для отладки, потом Streamlit или бот |
| Обновление | Полная переиндексация / инкрементальная | Хэш содержимого чанка → не дублировать (гл. 4.4) |
Чем RAG по базе знаний магазина особенный
Заголовок раздела «Чем RAG по базе знаний магазина особенный»Общая схема подходит любому RAG, но у нашего корпуса есть свои ловушки — именно на них будут построены проверки в следующих главах.
- Точные идентификаторы: артикулы, промокоды, названия вроде «Свет» и «Свет мини», коды отказа оплаты. Чистые эмбеддинги их плохо различают → нужен гибридный поиск.
- Похожие разделы на разных страницах: раздел «Гарантия» есть на каждой странице товара, правила возврата — в
returns.mdи в архивномreturns-2025.md→ фильтры поcategoryиarchivedобязательны, иначе ответ про одну лампу склеится с гарантией другой, а действующие правила — со старыми. - Версии: старая редакция правил возврата лежит рядом с новой. В метаданных храним
archivedи дату обновления; архив по умолчанию из поиска исключаем. - Таблицы тарифов и гарантий — ключевой контент; не резать их пополам. Отдельно — числа, которые расходятся между страницами (порог бесплатной доставки в
delivery.mdи вpromo.md), и вопросы, ответ на которые собирается из двух разделов. - Безопасность: проект работает только с публичной базой знаний. Ему не нужны данные клиентов, он не открывает базы магазина и ничего не меняет в заказах.
DeepSeek и Ollama: как это сделать у нас
Заголовок раздела «DeepSeek и Ollama: как это сделать у нас»Архитектура RAG от провайдера не зависит. Меняется только то, кто стоит в двух «модельных» квадратиках схемы: эмбеддинги и генерация. К генерации относятся ещё переписывание запроса и, по желанию, contextual-пояснения к чанкам.
ИНДЕКСАЦИЯ: ... ─► chunking ─► [эмбеддинги: Ollama bge-m3 / Sentence Transformers] ─► sqlite-vec ЗАПРОС: вопрос ─► [rewrite: DeepSeek или Ollama] ─► поиск ─► реранкер (локальный cross-encoder) ─► [ответ: DeepSeek; Ollama для приватного; Claude/OpenAI для сравнения] ─► ответ + ссылки- Эмбеддинги — локально. На ноябрь 2026 у DeepSeek нет эндпоинта эмбеддингов, подробно — в главе 4.1 · Эмбеддинги руками на numpy. Берём Ollama (
/api/embed) или Sentence Transformers. - Генерация — DeepSeek. На ноябрь 2026 по странице Models & Pricing в API две модели:
deepseek-flash(сейчас это DeepSeek-V4.1-Flash-1017) иdeepseek-v4-pro. У обеих окно 1M токенов, JSON-вывод и tool calls, и у обеих по умолчанию включён режим рассуждения (thinking). Базовый URL для OpenAI SDK —https://api.deepseek.com. Имена моделей и цены меняются: имя модели держим в.envи проверяем страницу. - Реранкер — локально. Эндпоинта реранкинга на ноябрь 2026 нет ни у DeepSeek, ни у Ollama (в их документации его не найти). Cross-encoder запускается через Sentence Transformers, подробно — в гл. 5.2.
- Безопасность. База знаний магазина публична (это его справочный центр), поэтому куски базы и вопросы о ней отправлять в облачные модели, включая DeepSeek, можно. Нельзя подмешивать в вопросы или в индекс что-то из приложения магазина: заказы, данные клиентов, журнал событий, ключи платёжного провайдера. Настоящие сообщения покупателей (имена, телефоны, номера заказов) в облако не уходят: для тестов на сообщениях клиентов берём выдуманные тексты или локальную модель. Серверы DeepSeek в Китае, но правило касается любого облачного провайдера. Если позже понадобится RAG по приватным данным, вся цепочка (эмбеддинги + генерация) — только на Ollama.
Что это меняет в решении «RAG или всё в контекст»
Заголовок раздела «Что это меняет в решении «RAG или всё в контекст»»Планка «меньше ~200K токенов — попробовать положить всё в промпт» из статьи Anthropic зависит от окна и цены. У DeepSeek окно 1M, а кэширование контекста включено автоматически для всех (гайд Context Caching): повторяющийся префикс запроса берётся с диска и стоит в десятки раз дешевле. На 13.11.2026 у deepseek-flash в непиковое время вход при попадании в кэш стоит $0.003 за 1M токенов, при промахе $0.15, выход $0.60. В пиковые часы (01:00–04:00 и 06:00–10:00 UTC в будни) цены вдвое выше. Кэш best-effort: попадание не гарантировано, а неиспользуемый кэш очищается через часы или дни.
Весь kb/ «Полки» почти наверняка влезет в 1M, так что вариант «вся база знаний в промпт» на DeepSeek — дешёвый и честный baseline: держим его в голове и сравниваем с ним. RAG всё равно нужен: ответ должен ссылаться на конкретный раздел, архивные правила нельзя показывать модели наравне с действующими, а база знаний настоящей компании быстро дорастает до тысяч страниц и миллионов токенов, которые не влезут и в 1M. Наша маленькая база — полигон, на котором видна каждая ошибка retrieval.
Сравнение провайдеров для RAG
Заголовок раздела «Сравнение провайдеров для RAG»| Что нужно RAG | Claude | OpenAI | DeepSeek | Ollama |
|---|---|---|---|---|
| Эмбеддинги | Своих нет (рекомендован Voyage AI) | Есть | Нет → Ollama / Sentence Transformers | Есть, локально |
| Эндпоинт реранкинга | Нет (у партнёров вроде Voyage, Cohere) | Нет | Нет → локальный cross-encoder | Нет → Sentence Transformers |
| Генерация ответа | Да | Да | Да, deepseek-flash / deepseek-v4-pro |
Да; качество зависит от размера модели и памяти компьютера |
| Окно контекста | Смотри документацию модели | Смотри документацию модели | 1M токенов | Ограничено моделью и памятью; задаётся num_ctx |
| Кэш длинного префикса | Явный, через cache_control |
Автоматический (смотри гайд OpenAI) | Автоматический; поля prompt_cache_hit_tokens / prompt_cache_miss_tokens в usage |
Платы нет — платим временем своего компьютера |
| Встроенные цитаты (Citations) | Да | В Chat Completions нет (что есть в других API OpenAI — смотри документацию) | Нет; Anthropic-совместимый эндпоинт DeepSeek поле citations игнорирует |
Нет |
| Куда уходят данные | США | США | Китай | Никуда |
Вывод для проекта: цитаты делаем вручную ([n] + проверка кодом, глава 5.3), эмбеддинги и реранкер — локально, генерация — DeepSeek. Ollama — полностью офлайн-вариант и путь для всего приватного.
Ограничение железа. Эмбеддинг-модели маленькие (bge-m3 ~1.2 GB), а размер локального генератора упирается в память: при 8 GB RAM — модели класса 3–4B (qwen3:4b, ~2.5 GB), при 16 GB — 7–8B, при 32 GB и больше — 14B и крупнее. Эмбеддинги, реранкер и генератор, загруженные одновременно, складываются по памяти, плюс всё, что ещё работает на машине. Это ещё одна причина, почему генерация здесь на DeepSeek: база знаний публичная, и отправлять её можно.
Что использовать в практике
Заголовок раздела «Что использовать в практике»Практика этой главы — схема и решения, провайдеры здесь только подписи на квадратиках. Подписываем их честно: «эмбеддинги: Ollama bge-m3 (локально)», «генерация: DeepSeek deepseek-flash, имя модели из .env», «реранкер: Sentence Transformers (локально)», «Claude/OpenAI — опционально, для сравнения». На будущее запомним правило для evals: судья (LLM-as-judge) должен быть сильнее модели, которую он оценивает. Например, ответы deepseek-flash или локальной модели проверяет deepseek-v4-pro или Claude.
Маршрут изучения
Заголовок раздела «Маршрут изучения»- Открываем Eugene Yan: Patterns for Building LLM-based Systems → читаем введение и раздел «Retrieval-Augmented Generation» (≈45 мин). Обратим внимание на: почему retrieval важнее генерации, гибридный поиск (BM25 + эмбеддинги), ANN-индексы, пример с тем, как классический поиск помогает там, где эмбеддинги промахиваются. Раздел про evals — бегло, он пригодится позже.
- Открываем Anthropic: Contextual Retrieval → читаем вводную часть до раздела с реализацией контекстных эмбеддингов, плюс заметку про базы меньше 200K токенов (≈20 мин). Выписываем формулировку проблемы «чанк теряет контекст» и цифры улучшения retrieval из статьи — к ним вернёмся в гл. 5.2.
- Открываем DeepLearning.AI short courses → находим в каталоге курс по RAG (там их несколько, набор меняется; искать по слову «RAG» или «Retrieval») и смотрим первые 2–3 урока на 1.5x (≈45 мин). Цель — увидеть, как кто-то другой рисует ту же цепочку; все ноутбуки проходить не нужно.
- Сравниваем три источника с диаграммой из «Теории» этой главы: какие этапы у кого есть, у кого нет (≈15 мин). Записываем расхождения — это вопросы, которые прояснятся в следующих главах.
- Открываем DeepSeek: Models & Pricing и Context Caching (≈20 мин). Выписываем текущие имена моделей, окно контекста, цены входа с попаданием и с промахом кэша, пиковые часы, как работает автоматический кэш и какие поля
usageего показывают. - Открываем DeepSeek: Anthropic API → таблицу совместимости (≈10 мин). Ищем, что происходит с
cache_controlиcitations(на ноябрь 2026 оба игнорируются). Это пример того, что «совместимый API» ≠ «те же возможности». - Если страница ещё не прочитана в главе 4.1, открываем Ollama: Embeddings (≈10 мин), чтобы подписать квадратик «эмбеддинги» на своей схеме.
На что обратить внимание
Заголовок раздела «На что обратить внимание»- «Подключим RAG — и галлюцинаций не будет». Нет: если retrieval нашёл не то, модель уверенно ответит по неправильному куску. RAG снижает, а не устраняет выдумки; цитаты и отказ «не нашёл» — обязательная часть.
- Улучшать генерацию, когда сломан поиск. Типичная ошибка — неделю тюнить промпт, хотя нужного куска просто нет в топ-5. Сначала hit rate.
- Нет golden set. Без 20 вопросов с известными ответами любое «стало лучше» — ощущение. Собираем его с первого дня.
- Устаревший индекс. База знаний обновилась, индекс — нет. Храним дату загрузки и хэш страницы.
- Смешение страниц в одном ответе: без фильтров по метаданным легко получить «гибрид» из гарантии двух похожих ламп или из старых и новых правил возврата.
- Слишком много контекста. 30 чанков в промпте — дорого, медленно и модель теряет важное в середине. Лучше 5 хороших после реранкинга.
- Фреймворк как чёрный ящик. LlamaIndex/LangChain собирают RAG в 10 строк, но отлаживать их сложнее. Поэтому сначала руками, а фреймворк — в гл. 5.4 для сравнения.
Практика
Заголовок раздела «Практика»- Создаём
projects/02-support-kb-rag/notes/rag.md. - Рисуем схему своего RAG по базе знаний магазина (ASCII в Markdown, или Mermaid — GitHub его рендерит; или картинка из Excalidraw, сохранённая рядом). Обе фазы: индексация и запрос. Для каждого этапа подписываем:
- Ниже схемы — таблица метаданных чанка: поле, тип, пример, зачем нужно. Минимум:
category,archived,url(путь к файлу с якорем, напримерkb/returns.md#opened-tea-returns),section,chunk_key,doc_hash,loaded_at. - Раздел «Риски»: 5 вещей, которые могут пойти не так именно с базой знаний магазина (архивные правила, похожие товары, расходящиеся числа…), и что мы с ними сделаем.
- Раздел «Golden set (черновик)»: первые 10 вопросов, на которые система должна отвечать, с ожидаемой категорией и страницей. Примеры: «Можно ли вернуть вскрытый чай?» (
kb/returns.md), «Сколько стоит доставка 3 кг в другой город?» (kb/delivery.md), «Какая гарантия на лампу „Свет“?» (kb/products/lamp-light.md), «Почему не прошла оплата?» (kb/payment.md), «Действует ли промокод вместе со скидкой?» (kb/promo.md). Плюс 3 вопроса, на которые ответа в базе нет («Какая служба доставки самая надёжная?») — для проверки отказа и передачи человеку в гл. 5.3. - Раздел «Решения»: заполненная таблица архитектурных решений из теории с нашими выборами. В строках «Эмбеддинги», «Генерация», «Реранкер» указываем провайдера и причину (основной путь: Ollama/Sentence Transformers + DeepSeek; Claude/OpenAI — для сравнения).
- Раздел «Данные и провайдеры»: таблица «какой текст куда уходит» (куски базы знаний → DeepSeek; вопросы → DeepSeek; эмбеддинги → только локально) и правило «ничего из приложения магазина и никаких настоящих сообщений клиентов в этот проект».
Пример фрагмента в Mermaid:
flowchart LR A[Load kb/ Markdown] --> B[Front matter + anchors] --> C[Chunk by headings] --> D[Embed] --> E[(sqlite-vec)] Q[Question] --> R[Rewrite + detect category] --> S[Vector + BM25] --> T[Rerank] --> P[Prompt with sources] --> L[LLM answer with citations] E --> S
Готово, когда
Заголовок раздела «Готово, когда»- В
notes/rag.mdесть схема обеих фаз, где у каждого этапа подписаны вход/выход, инструмент (с провайдером) и задача плана. - Есть таблица метаданных, список рисков, черновик golden set из 10+3 вопросов и таблица решений.
- Можем за 3 минуты устно провести кого-то по схеме и сказать, где чаще всего ломается RAG.
Тест для самопроверки
Заголовок раздела «Тест для самопроверки»Вопрос 1
Какие три ограничения LLM решает (или смягчает) RAG?
Знания заморожены на дате обучения; модель не видит приватных/специфичных данных; модель выдумывает, когда не знает. RAG даёт актуальный контекст и позволяет ссылаться на источник.
Вопрос 2
Документация на 60 страниц (~80K токенов), меняется раз в год. Что попробовать первым?
c). Документы маленькие и стабильные — проще и надёжнее положить их целиком в промпт; RAG — лишняя сложность, fine-tuning плохо учит факты.
Вопрос 3
Какие этапы у фазы индексации, по порядку?
Загрузка → чистка → chunking (с метаданными) → эмбеддинги (и лексический индекс) → запись в индекс.
Вопрос 4
Почему в RAG по базе знаний магазина нужна фильтрация по метаданным?
Одинаковые разделы («Гарантия», «Возврат») есть на многих страницах, а рядом с действующими правилами возврата лежит архивная редакция; без фильтра по category и archived в контекст попадут куски чужой страницы или старых правил, и ответ смешает их.
Вопрос 5
Где чаще всего ломается RAG — в retrieval или в генерации? Как это проверить дёшево?
В retrieval. Дёшево проверить hit rate@k на golden set: попал ли нужный кусок в топ-k — без вызова LLM.
Вопрос 6
Что такое hit rate@k?
Доля вопросов, для которых хотя бы один правильный кусок оказался в первых k результатах поиска.
Вопрос 7
Какую проблему описывает статья Anthropic про Contextual Retrieval?
Чанк, вырезанный из документа, теряет контекст (о каком товаре, разделе, редакции правил речь), поэтому плохо находится и плохо понимается; предлагают приписывать к чанку сгенерированное пояснение и сочетать эмбеддинги с BM25 и реранкингом.
Вопрос 8
Что не так в этом промпте?
Вот документы: {chunks}Ответь на вопрос пользователя максимально полно, используя свои знания: {question}«Используя свои знания» прямо разрешает отвечать не по документам — это открывает дорогу галлюцинациям. Нет требования ссылок, нет инструкции говорить «не нашёл», куски не пронумерованы и без источников.
Вопрос 9
Чем реранкинг отличается от первичного поиска?
b). Первичный поиск быстрый и грубый по всей базе, реранкер (cross-encoder) медленнее, но точнее, и пересортировывает 20–100 кандидатов.
Вопрос 10
Зачем хранить у чанка doc_hash и loaded_at?
Хэш страницы — чтобы при повторной загрузке пропускать неизменённые страницы и переэмбеддить только изменившиеся (дубликаты чанков отсекает chunk_key); дата — чтобы понимать актуальность и показывать её пользователю.
Вопрос 11
Почему fine-tuning — плохой способ «научить» модель актуальным правилам доставки и возврата магазина?
Fine-tuning плохо запоминает конкретные факты, не даёт ссылок на источник и устаревает при каждом изменении базы знаний — переобучать дорого, а RAG-индекс обновляется загрузкой.
Вопрос 12
Какие этапы RAG в стеке «DeepSeek + Ollama» выполняются локально и почему?
b). На ноябрь 2026 у DeepSeek нет ни эмбеддингов, ни реранкера. Эмбеддинги делает Ollama или Sentence Transformers, реранкинг — локальный cross-encoder, а DeepSeek отвечает за генерацию и переписывание запроса.
Вопрос 13
Код переводят с Claude на Anthropic-совместимый эндпоинт DeepSeek и рассчитывают на встроенные Citations и cache_control. Что произойдёт?
По таблице совместимости DeepSeek оба поля игнорируются. Цитат с гарантией не будет, а кэш у DeepSeek работает сам, автоматически по префиксу. Цитаты придётся делать вручную: [n] + проверка кодом.
Вопрос 14
Почему куски базы знаний магазина можно отправлять в DeepSeek, а выгрузку заказов и переписки с клиентами для «RAG по истории обращений» нельзя?
База знаний — публичный справочный центр магазина, утекать там нечему. Заказы и переписка содержат персональные данные клиентов (имена, телефоны, адреса), а такие данные не уходят ни в одну облачную модель; у DeepSeek к тому же серверы в Китае. Такой RAG строится целиком на Ollama, локально.
Что дальше
Заголовок раздела «Что дальше»Теперь режем базу знаний на куски: 4.3 · Chunking: сравнить 3 стратегии, затем строим полноценный индекс в 4.4 · Векторная БД + загрузка базы знаний.