RAG по своим конспектам строится из пяти частей: очистка файлов, разбиение на смысловые чанки, embeddings, поиск похожих фрагментов и ответ модели только на найденном контексте. Для доверия сохраняйте имя файла и заголовок каждого чанка, а при недостатке данных просите модель честно отказать.
RAG не обучает модель заново и не гарантирует истину. Он подбирает фрагменты перед генерацией ответа. Если поиск вернул не тот конспект, сильная модель всё равно получит плохую основу. Поэтому сначала проверяют retrieval отдельно: для набора вопросов смотрят, попал ли правильный фрагмент в top-k. Только затем оценивают формулировку ответа и ссылки.
Фрагмент заметки с метаданными и законченным смыслом.
Числовой вектор для сравнения близости текста.
Несколько наиболее похожих фрагментов для контекста.

RAG по своим конспектам: начните с качественных чанков
Не режьте текст строго каждые 500 символов посреди предложения. Для заметок удобно сначала делить по заголовкам и абзацам, затем собирать блоки до лимита. Пример ниже использует только стандартный Python и сохраняет целые абзацы. В production дополнительно учитывают токены, таблицы, код и перекрытие там, где мысль продолжается между блоками.
def split_notes(text: str, max_chars: int = 700) -> list[str]:
paragraphs = [part.strip() for part in text.split("\n\n") if part.strip()]
chunks: list[str] = []
current: list[str] = []
for paragraph in paragraphs:
candidate = "\n\n".join([*current, paragraph])
if current and len(candidate) > max_chars:
chunks.append("\n\n".join(current))
current = [paragraph]
else:
current.append(paragraph)
if current:
chunks.append("\n\n".join(current))
return chunks- Абзацы остаются целыми, пока блок не превышает целевой размер
- Каждый chunk можно связать с именем файла и заголовком
После chunking передайте список текстов в embedding-модель. Ollama рекомендует embeddinggemma, qwen3-embedding и all-minilm. Векторы документа и вопроса должны создаваться одной моделью. Храните рядом source, heading, дату и порядковый номер. При смене embedding-модели переиндексируйте всю коллекцию, потому что пространства векторов несовместимы.
Что проверять в RAG отдельно
| Элемент | Что означает | Что делать |
|---|---|---|
| Очистка | Нет меню, дублей и мусорных страниц | Просмотреть случайные 20 фрагментов |
| Chunking | Мысль не обрывается | Вопрос понятен по одному chunk |
| Retrieval | Правильный источник в top-k | Набор из 30 контрольных вопросов |
| Generation | Ответ опирается на контекст | Цитаты ведут к найденным фрагментам |
| Отказ | Нет ответа без данных | Вопрос вне коллекции |
Большой top-k не всегда лучше. Лишние фрагменты размывают контекст и могут противоречить друг другу. Начните с 3-5 результатов и показывайте их пользователю. Если точный термин не находится семантически, добавьте гибридный поиск по ключевым словам. Для сложных вопросов полезен reranker, который повторно сортирует кандидатов.

Практика: RAG на десяти конспектах с проверкой попадания в top-3
Возьмите десять своих заметок и соберите на них минимальный поиск с ответом. Нужны три части: функция split_notes для чанков, embeddings одной моделью и выдача трёх фрагментов вместе с source и heading. Успехом считается такое: на контрольный вопрос нужный конспект попадает в top-3, а ответ модели ссылается именно на него.
- Чистка десяти заметок. Сложите десять файлов в одну папку, уберите меню, навигацию и дубли, а для PDF откройте извлечённый текст и прочитайте его глазами. Просмотрите 20 случайных фрагментов: обрывков вёрстки и склеенных слов в них быть не должно.
- Чанки по абзацам. Прогоните тексты через split_notes с max_chars=700 и распечатайте длины полученных блоков. Абзацы обязаны остаться целыми, а разрыв посреди предложения считайте браком чанкинга.
- Метаданные source и heading. Для каждого chunk сохраните source, heading, дату и порядковый номер в списке словарей. Проверьте выборочно: по одному фрагменту должно быть понятно, из какого файла и какого раздела он взят.
- Векторы одной моделью. Постройте embeddings всех чанков одной моделью, например all-minilm, и той же моделью векторизуйте вопрос. Имя модели запишите рядом с индексом, иначе через месяц будет непонятно, чем считались векторы.
- Top-3 и ответ с источниками. Задайте вопрос, выведите на экран три ближайших фрагмента с их source и heading, и только потом отдайте их модели как контекст. В ответе должны остаться имена файлов, по которым его можно открыть и проверить.
Сломайте условие намеренно: посчитайте вектор вопроса другой embedding-моделью, оставив старые векторы документов. Код не упадёт, ответ будет звучать уверенно, но выдача станет случайной, потому что пространства векторов несовместимы. Отдельно задайте вопрос по теме, которой в ваших десяти заметках нет: модель должна честно отказать, а не сочинить абзац. Верните исходную модель и переиндексируйте коллекцию целиком.
Дальше добавьте гибридный поиск по ключевым словам: точные термины, номера и редкие названия семантика часто теряет. Потом попробуйте reranker, который пересортирует кандидатов перед отправкой в модель, и сравните долю попаданий до и после. Держите top-k в диапазоне 3-5: лишние фрагменты размывают контекст и начинают противоречить друг другу. Перекрытие между чанками включайте точечно, только там, где мысль переходит в следующий абзац.
Частые ошибки и почему они появляются
Частая ошибка состоит в оценке только красивого ответа. Модель может угадать из общих знаний, хотя ваш конспект не найден. Вторая ошибка: индексировать PDF без проверки извлечённого текста. Третья: менять embedding-модель и оставлять старые векторы. Такой индекс выглядит рабочим, но близость теряет смысл.
Поиск получает слишком общий вектор, а модель тратит контекст на лишнее.
Без метаданных пользователь не может открыть исходный абзац и проверить ответ.
Качество нельзя оценить по двум удачным примерам. Соберите вопросы с ожидаемыми источниками.
Самопроверка
Обучает ли RAG модель на моих конспектах?
RAG не обучает веса модели и не заменяет дообучение. Он находит подходящие фрагменты заметок и подкладывает их в контекст перед генерацией ответа. Поэтому новую заметку достаточно проиндексировать, трогать саму модель не нужно.
Почему embedding-модель для документов и вопроса должна совпадать?
Embedding-модель должна быть одна, потому что разные модели строят разные векторные пространства. Близость между вектором вопроса от одной модели и векторами чанков от другой не означает смысловое сходство. При смене модели переиндексируйте всю коллекцию заново.
Что проверять первым, если RAG отвечает неправильно?
Первым проверяют retrieval: какие chunks вернул поиск и есть ли среди них правильный источник. Если нужного фрагмента в top-k нет, править промт бесполезно, основа ответа уже плохая. Разбирать формулировку и ссылки имеет смысл только при верной выдаче.
Какого размера делать чанки для заметок?
Чанки для заметок удобнее собирать по заголовкам и абзацам с лимитом порядка 700 символов, а не резать текст каждые 500 символов посреди предложения. Главный критерий: по одному chunk понятно, на какой вопрос он отвечает. Один огромный фрагмент даёт слишком общий вектор и съедает контекст модели.
Сколько фрагментов брать в top-k?
В top-k разумно начинать с 3-5 фрагментов. Большой top-k не улучшает ответ сам по себе: лишние куски размывают контекст и могут спорить друг с другом. Показывайте найденные фрагменты пользователю, чтобы он видел, на чём построен ответ.
Зачем хранить имя файла и заголовок рядом с чанком?
Имя файла и заголовок нужны, чтобы читатель открыл исходный абзац и проверил ответ сам. Без метаданных ссылку подставить некуда, и остаётся верить модели на слово. Рядом полезно держать дату и порядковый номер фрагмента, тогда видно, откуда пришёл каждый кусок контекста.
Что делать дальше
Возьмите десять заметок и тридцать вопросов, для каждого заранее укажите ожидаемый файл. Сначала измерьте попадание источника в top-3, затем подключайте генерацию. Реализацию загрузчика и тестов можно собрать после курса GenAI. Выбор модели уточните в статье про Ollama и память, а формат запросов в материале про промты.
