Содержание
Большая языковая модель не «читает файлы» и не хранит вашу документацию как папку на диске. Она работает с токенами и векторами, держит выученные закономерности в весах, а свежие факты получает только если вы сами положили их в окно контекста. RAG — это как раз способ найти нужный фрагмент снаружи и подставить его в этот контекст на время ответа, не переобучая модель.
Ниже — сквозная карта: от строки текста до поиска по базе знаний на Markdown. Цель не перечислить инструменты, а развести слои, которые в разговорах постоянно сливают в одно слово «ИИ».
Ключевые выводы
Обучение меняет модель, RAG — нет. Обучение корректирует веса. RAG находит внешний текст и добавляет его в контекст конкретного запроса. Это разные рычаги, и путать их дорого.
Слово «эмбеддинг» означает две разные вещи. Внутри Transformer это вектор токена, с которым считает механизм внимания. В RAG это вектор фрагмента документа, по которому ищут похожий смысл. Связь концептуальная, задачи разные.
Transformer не превращает текст в цифры. Токенизатор даёт идентификаторы, слой эмбеддингов — векторы, блоки модели обрабатывают контекст, выходная голова считает вероятности следующего токена.
Векторная база данных — не сам RAG. RAG = найти → положить в контекст → сгенерировать. На старте хватает Markdown, оглавления и поиска по словам. Векторный индекс — производный слой, его можно заменить.
Хорошая структура документов — инвестиция. Заголовки, смысловые блоки и метаданные одновременно помогают человеку, модели в контексте и будущему поиску. Эмбеддинги и агенты надстраиваются поверх того же источника истины.
LLM не равна базе знаний
Модель хранит не файлы python.md или регламент отдела, а параметры: миллиарды чисел, которые настроили на предсказании следующего токена. В этих весах сжаты статистические закономерности языка и мира на момент обучения. Это не каталог с версиями документов и не система прав доступа.
Внешняя документация живёт отдельно: в Git, вики, тикетах, PDF, таблицах. RAG не «вшивает» её в модель. Он в момент ответа находит релевантные куски и кладёт их рядом с вопросом. Модель видит их как обычный текст в контексте — так же, как видит системную инструкцию и историю чата.
Имеет смысл держать в голове четыре разных механизма:
| Слой | Что это |
|---|---|
| Знания в модели | Закономерности в весах после обучения |
| Знания вовне | Документы, код, таблицы, которые вы контролируете |
| Поиск | Как выбрать, что показать модели |
| Генерация | Как модель продолжает текст по выбранному контексту |
Текст, токены и два вида эмбеддингов
Токенизатор: строка ещё не смысл
Модель не получает символы Unicode как человек. Сначала токенизатор режет строку на куски из своего словаря и заменяет каждый кусок номером.
"Привет, как дела?"
↓
Tokenizer
↓
["Привет", ",", " как", " дела", "?"]
↓
[18432, 11, 927, 4812, 30]
Номера условные: у каждой модели свой словарь. Важно другое. Идентификатор токена — это индекс, а не «смысл предложения». Одно русское слово может стать несколькими токенами; пробел иногда приклеивается к слову; код и редкие термины дробятся сильнее, чем кажется.
Отсюда три практических следствия. Окно контекста считают в токенах, не в словах. Цена многих API тоже от токенов. Нарезка документов «по 500 слов» плохо стыкуется с тем, как модель потом увидит тот же текст.
Слой эмбеддингов внутри модели
Номер токена сам по себе для нейросети бесполезен. Его пропускают через таблицу эмбеддингов: каждой позиции словаря соответствует вектор фиксированной длины.
token ID
↓
embedding
↓
[0.12, -0.73, 0.44, ...]
Это и есть первое значение слова «эмбеддинг»: внутреннее представление токена, с которым дальше работает Transformer. Близкие по употреблению токены после обучения часто оказываются рядом в этом пространстве, но цель слоя — дать сети числа для математики, а не построить поисковый индекс вашей вики.
Эмбеддинги документов для поиска
Второе значение появляется в RAG. Отдельную модель (часто меньшую и другую) просят свернуть фрагмент текста в один вектор. Похожие по смыслу абзацы должны лежать близко, даже если не повторяют одни и те же слова.
chunk
↓
embedding model
↓
[0.12, -0.03, 0.88, ...]
Путаница начинается, когда оба смысла называют одним словом. Внутренние эмбеддинги токенов живут внутри LLM и меняются от слоя к слою благодаря вниманию. Эмбеддинги документов живут в индексе поиска и сравниваются с вектором вопроса. Корпоративный взгляд на смысловой поиск, гибрид с точными идентификаторами и права доступа — в почему эмбеддинги изменили поиск.
Как модель обрабатывает контекст и генерирует ответ
Механизм внимания на простом примере
Возьмём фразу: «Маша положила книгу на стол, потому что она устала». Местоимение «она» для человека почти наверняка относится к Маше, а не к книге. Модель не «понимает персонажей». На каждом слое каждый токен пересчитывает своё представление, глядя на другие токены последовательности — сильнее на те, которые статистически полезны для предсказания.
каждый токен
↓
учитывает другие токены контекста
↓
получает более информированное представление
Это идея механизма внимания (self-attention): не словарь синонимов, а взвешенный обмен информацией внутри окна. Математику здесь можно не разворачивать. Достаточно помнить, что смысл токена зависит от соседей и что далеко за пределами окна модель этих соседей не видит.
Практический разбор маленького Transformer с обучением на узком корпусе — в истории про модель на 6,4 млн параметров. Для инженера приложения важнее следствие: качество ответа упирается в то, что попало в последовательность, а не в магическое «понимание файлов».
Один блок модели — не «переводчик в цифры»
Упрощённо один блок выглядит так:
Input
↓
Self-Attention
↓
Normalization
↓
Feed Forward Network
↓
Normalization
↓
Output
Модель — стопка таких блоков. Распространённое заблуждение: «Transformer переводит текст в цифры». Цепочка другая:
- токенизатор превращает текст в идентификаторы;
- слой эмбеддингов превращает идентификаторы в векторы;
Transformerобрабатывает эти представления в контексте;- выходная голова считает распределение вероятностей следующего токена.
Цифры появляются на шаге 2. Transformer работает уже с представлениями.
Авторегрессия: токен за токеном
Генерация — не один «ответ целиком», а цикл. Модель смотрит на текущий контекст, считает вероятности следующего токена, выбирает один (жадно или со случайностью), приписывает его к контексту и повторяет.
Я хочу выпить
↓
воду 0.61
кофе 0.18
чай 0.11
...
↓
воду
Я хочу выпить воду
↓
сейчас 0.31
и 0.27
...
Отсюда два свойства, которые потом объясняют и RAG, и галлюцинации. Во-первых, каждый новый токен зависит от того, что уже сгенерировано: ошибка в начале тянет за собой правдоподобное продолжение. Во-вторых, модель не отделяет «факты из документов» от «статистически частого текста», пока вы явно не положили документ в контекст и не потребовали на него опираться.
Обучение меняет веса, контекст — нет
Откуда берётся «знание» в параметрах
Упрощённая учебная задача: по префиксу предсказать продолжение.
"Париж — столица ___"
↓
"Франции"
Модель выдаёт распределение, сравнивает с правильным токеном, считает ошибку, чуть двигает веса. После триллионов таких шагов в параметрах оказываются сжатые регулярности: язык, факты, которые часто встречались в корпусе, шаблоны рассуждений. Это не файловая система. Нельзя открыть «статью про Париж» внутри весов и заменить дату.
Дообучение дополнительно подкручивает веса под формат, стиль или узкую задачу. RAG этого не делает. Сводка уровней — предобучение, контролируемое дообучение, LoRA, инструменты — в уже упомянутой карте обучения. Здесь нужна одна строка:
| Механизм | Что происходит с моделью |
|---|---|
| Обучение | Меняются веса |
| Дообучение | Веса дополнительно адаптируются |
| RAG | Веса не меняются, в контекст добавляют найденный текст |
| Промпт | Меняется инструкция и содержимое этого запроса |
Окно контекста
У модели конечное окно. В него обычно пытаются уместить системную инструкцию, историю диалога, вопрос, найденные фрагменты и результаты инструментов.
System instructions
+
Conversation
+
User question
+
Retrieved documents
+
Tool results
↓
LLM
Всё, что не влезло, для этого вызова не существует. Отсюда необходимость поиска: нельзя каждый раз отправлять десять миллионов токенов документации. Нужно выбрать несколько фрагментов, которые с высокой вероятностью помогут ответить.
Роль модели как интерфейса к знаниям, а не как корпоративной памяти, разобрана в почему появились LLM.
Зачем нужен RAG
Представьте внутреннюю документацию на миллионы токенов. Её нельзя целиком класть в каждый запрос: дорого, медленно, и модель всё равно потеряет нужную страницу в середине. Нужен отбор.
10 000 000 tokens документации
↓
retrieval
↓
5–20 релевантных chunks
↓
LLM
RAG — генерация, усиленная поиском: найти внешнюю информацию, добавить её в контекст, ответить с опорой на найденное. Это не «умная модель, которая помнит вики». Это конвейер из поиска и генерации.
На демонстрации конвейер кажется коротким. В продукте ломается обычно поиск, а не «недостаточная креативность» модели: плохая нарезка, устаревший индекс, только семантика там, где нужен точный код ошибки, отсутствие повторного ранжирования. Производственный контур — разбиение, гибридный поиск, переранжирование, оценка — собран в промышленной инженерии RAG, платформенный взгляд — в архитектуре промышленного RAG.
Документы как источник истины
Физически база знаний для прототипа и для многих команд — обычные файлы.
knowledge/
├── README.md
├── python/
│ ├── functions.md
│ ├── objects.md
│ └── classes.md
├── ai/
│ ├── llm.md
│ ├── embeddings.md
│ └── rag.md
└── programming/
└── algorithms.md
RAG не требует секретного формата. Учебник, внутренние инструкции, этот блог, навыки агента в SKILL.md — всё это может быть первичным источником. Удобство Markdown в том, что его читает человек, его версионирует Git, из него собирают сайт, и тот же текст можно нарезать для поиска.
Структура файла важнее, чем кажется. Сравните документ с осмысленными заголовками и «простыню» без якорей. Первому проще: человеку читать, модели ориентироваться в контексте, нарезчику резать по границам смысла, поиску прикреплять метаданные, позже — строить эмбеддинги.
# Python Functions
## Definition
...
## Arguments
...
## Mutable arguments
...
## Common mistakes
...
## Related concepts
- references
- mutability
- objects
Один источник истины может питать и сайт, и индекс:
Markdown
│
source of truth
│
┌─────────┴─────────┐
↓ ↓
Website RAG index
│
┌────────┴────────┐
↓ ↓
keyword search embeddings
↓
vector DB
Эмбеддинги здесь производные. Индекс можно пересобрать. Модель можно сменить. Поиск можно улучшить, не переписывая смысл документов. И наоборот: красивый векторный стек не спасёт путаницу в исходниках.
Нарезка документов и метаданные
Документ целиком редко годится и как единица поиска, и как единица контекста. Его режут на фрагменты.
document
↓
chunk 1
chunk 2
chunk 3
...
Плохая нарезка рвёт мысль посередине:
...can be modified after
creation. This means that when a list is...
Лучше резать по смысловой границе и тащить заголовок с собой:
## Mutable objects
Lists can be modified after creation...
На практике важны размер фрагмента, перекрытие соседних кусков, сохранение заголовка, связь с исходным файлом и поля описания. Слишком короткий кусок теряет контекст («список изменяем» — зачем это сказано?). Слишком длинный плохо ищется и съедает окно. Перекрытие спасает мысль на границе, но размножает дубли. Заголовок в каждом фрагменте даёт модели и человеку якорь: это не «абзац из середины python.md», а раздел про изменяемые объекты.
Метаданные позволяют сочетать смысл с фильтрами:
---
title: Изменяемые и неизменяемые объекты
topic: python
level: intermediate
concepts:
- mutability
- references
- functions
---
Или в индексе:
{
"source": "chapter-03.md",
"section": "Mutable arguments",
"topic": "python",
"level": "intermediate"
}
Семантический поиск находит близкий смысл. Фильтры отсекают чужой раздел, уровень или источник. Для точных имён API одного смысла мало. Экспериментальный взгляд на разбиение с сохранением структуры — в экспериментах с нарезкой для RAG.
Поиск: векторы, гибрид и повторное ранжирование
Поиск по близости векторов
Вопрос тоже превращают в вектор той же моделью эмбеддингов и сравнивают с векторами фрагментов. Часто берут косинусное сходство: чем ближе направление векторов, тем выше оценка.
Вопрос:
"Почему функция может изменить список?"
↓
embedding model
↓
query vector
↓
similarity search
↓
chunk A → 0.94
chunk B → 0.91
chunk C → 0.87
chunk D → 0.31
Верхние фрагменты попадают в промпт. Это не доказательство истинности: это близость в пространстве данной модели эмбеддингов. Короткие вопросы, смесь языков, код и редкие идентификаторы ломают картину чаще, чем маркетинговые слайды признают.
Векторная база — не сам RAG
Векторная база хранит примерно идентификатор, текст, вектор и метаданные.
{
"id": 1837,
"text": "Lists are mutable...",
"embedding": [0.12, -0.73, 0.44],
"metadata": {
"topic": "python",
"section": "mutable objects",
"source": "python.md"
}
}
Технологий много: PostgreSQL с pgvector, Qdrant, Weaviate, Milvus, Chroma, Pinecone, Elasticsearch / OpenSearch. На этапе эксперимента векторы можно держать в JSON. База нужна, когда появляются объём, фильтры, обновления и задержка. Она не заменяет ни документы, ни нарезку, ни промпт. Обзор слоя индекса — в векторных базах данных.
Гибридный поиск и повторное ранжирование
Семантика плохо ловит точные имена функций, коды ошибок, номера версий и редкие термины. Их лучше искать словами (классический полнотекстовый поиск, BM25) и пересекать с векторной выдачей, плюс фильтры по метаданным.
keyword search / BM25
+
semantic search
+
metadata filtering
↓
better retrieval
В продакшене часто не отдают модели сразу «топ-5 из десяти тысяч». Сначала дешёвый поиск набирает десятки кандидатов, затем отдельная модель повторно оценивает пару «вопрос + фрагмент» и оставляет лучшие.
10000 documents
↓
vector / hybrid search
↓
50 candidates
↓
reranker
↓
5 best chunks
↓
LLM
Как смешивать BM25 и векторы — в гибридном поиске с reciprocal-rank fusion. Как держать переранжирование в бюджете задержки и стоимости — в переранжировании в промышленном RAG.
Найденное всё равно остаётся текстом в промпте:
SYSTEM:
Ты отвечаешь на вопросы по Python.
CONTEXT:
Lists are mutable objects...
A function receives a reference to the list...
QUESTION:
Почему функция может изменить список?
RAG не вкладывает знание в веса. Он временно занимает часть окна контекста. Если фрагменты неверны, модель уверенно ошибётся «со ссылкой на источник».
От файлового прототипа к агенту
Простой поиск без векторной базы
Первый рабочий контур может быть скучным и от этого полезным:
Markdown
↓
INDEX.md
↓
metadata
↓
keyword / структурный поиск
↓
relevant chunks
↓
LLM
Оглавление, поиск по словам, фильтр по topic в YAML, несколько файлов целиком в контекст, если база маленькая. Так проверяют качество исходников до выбора Qdrant. RAG ≠ векторная база.
Навыки как операционное знание
В агентах для разработки «база знаний» часто выглядит как навык: инструкция, процедуры, примеры, иногда инструменты.
Skill
├── instructions
├── knowledge
├── procedures
├── tools
└── examples
На диске это снова Markdown:
skills/
├── SKILL.md
├── concepts/
│ ├── embeddings.md
│ ├── chunking.md
│ └── retrieval.md
├── procedures/
│ └── build-rag.md
└── examples/
└── example.md
Модель использует навык как операционное знание: не «факт о Париже», а «как в этом репозитории публикуют статью». Тот же текст удобен человеку. Позже поверх него можно включить эмбеддинги, если навыков станет слишком много для окна. Слой инструментов в проде, когда агент вызывает внешние API, — в MCP в продакшене.
Инструменты и цикл агента
RAG даёт знания. Инструменты дают действия: поиск, файловая система, база, калькулятор, HTTP API.
LLM
↓
решает, что нужно сделать
↓
Tool
├── search
├── database
├── filesystem
├── calculator
└── API
↓
результат
↓
LLM
Агент связывает рассуждение, поиск и инструменты в цикл. Это следующий слой оркестрации, а не «ещё один индекс». Имеет смысл включать его, когда одного прохода поиска не хватает: нужно сопоставить релиз-заметки, код ошибки и инструкцию. Для короткого справочного вопроса лишний цикл только увеличит задержку.
Поэтапная эволюция
Имеет смысл расти слоями, а не начинать с «платформы».
Этап 1 — Markdown. Папка knowledge/ с INDEX.md, понятиями, руководствами и примерами.
Этап 2 — смысловые фрагменты. Заголовки, блоки, YAML, связи между понятиями.
Этап 3 — простой поиск. Оглавление, слова, фильтры по полям.
Этап 4 — эмбеддинги. Фрагменты → модель эмбеддингов → например embeddings.json.
Этап 5 — векторный поиск. Появляется база или расширение СУБД.
Этап 6 — гибрид и повторное ранжирование. Слова + смысл + метаданные + переранжирование.
Этап 7 — агент. Инструменты и право модели выбирать следующее действие.
Каждый этап оставляет предыдущий источник истины на месте. Меняется способ находить, не способ хранить смысл.
Частые ошибки
Смешивать обучение и RAG: «зальём PDF в дообучение, и модель запомнит регламент». Регламент изменится в пятницу, веса — нет.
Считать Transformer «переводчиком текста в векторы поиска». Поисковые эмбеддинги — отдельная модель и отдельный индекс.
Нарезать документы по числу символов без заголовков и связей. Потом удивляться, что модель цитирует обрубок.
Ставить знак равенства между RAG и Qdrant. Без корпуса, нарезки, промпта и проверки качества индекс бесполезен.
Полагаться только на семантику там, где нужны имя функции и номер версии.
Класть в контекст слишком много «похожих» кусков: модель тонет, цена растёт, нужный абзац теряется.
Путать агента с поиском. Несколько вызовов инструментов не создадут отсутствующую страницу в базе знаний.
Четыре понятия, которые стоит повесить над монитором:
| Понятие | Что делает |
|---|---|
| Обучение | Изменяет веса модели |
| Эмбеддинг | Представляет текст (токен или фрагмент) вектором |
| RAG | Находит внешние знания и добавляет их в контекст |
| Векторная БД | Хранит и ищет эмбеддинги |
| Агент | Связывает модель, знания и инструменты в цикл задач |
Частые вопросы
LLM уже «знает» мою документацию после обучения?
Нет. Она знает статистику публичного и учебного корпуса на дату отсечки. Ваши внутренние файлы она видит только если вы передали их в контекст или нашли через RAG.
Нужна ли векторная база, чтобы сделать RAG?
Нет. RAG — это поиск плюс генерация. Для маленькой базы на Markdown достаточно оглавления и поиска по словам. Векторный индекс появляется, когда семантическая близость и объём этого требуют.
Чем эмбеддинг токена отличается от эмбеддинга документа?
Первый — внутренний вектор идентификатора в LLM, вход для внимания. Второй — свёртка фрагмента для поиска похожего смысла. Их считают разные компоненты системы.
Почему семантический поиск не находит имя функции?
Потому что редкий идентификатор слабо связан со «смыслом абзаца» в пространстве эмбеддингов. Для имён, кодов ошибок и версий нужен поиск по словам или гибрид.
Можно ли заменить RAG дообучением на тех же файлах?
Обычно нельзя разумно. Дообучение меняет поведение и формат, плохо обновляет факты и почти не даёт цитат. Факты с версиями оставляют снаружи. Когда дообучение всё же нужно — в карте обучения LLM.
Что класть в контекст: файл целиком или фрагменты?
Пока база крошечная — файл. Как только тексты перестают влезать или мешают друг другу, режьте по заголовкам, тащите метаданные и заголовок в каждый кусок.
Зачем повторное ранжирование, если векторный поиск уже вернул топ-5?
Первый поиск оптимизирован на скорость и полноту кандидатов, не на тонкое соответствие вопросу. Переранжирование перечитывает пару «вопрос + текст» и часто поднимает нужный абзац, который был на 12-м месте.
Чем навык агента отличается от статьи в базе знаний?
Статья отвечает «что такое». Навык отвечает «как делать в этом репозитории»: шаги, запреты, формат выхода, инструменты. Оба могут быть Markdown. Навык ближе к процедуре, статья — к справке.
Когда подключать агента с инструментами?
Когда одного поиска мало: нужно открыть файл, вызвать API, сопоставить несколько источников. Для вопроса «какой порт слушает сервис» достаточно RAG или даже одного фрагмента.
Почему модель выдумывает, хотя RAG подключен?
Чаще всего в контекст попали не те куски, куски устарели, инструкция не требует опираться только на них, или ответа нет в базе, а модель всё равно обязана «быть полезной». Лечится поиском, промптом отказа и оценкой, а не новой температурой.
Что почитать дальше
Эта статья — карта механики. Соседние материалы разбирают отдельные слои глубже.
Архитектурный выбор «веса или внешние знания» — как обучают LLM. Зачем модели быть интерфейсом, а не памятью предприятия — почему появились LLM и почему предприятиям нужен RAG. Смысловой поиск в корпоративном контуре — почему эмбеддинги важны. Как довести конвейер до продакшена — промышленная инженерия RAG. Нарезка, гибрид и переранжирование — эксперименты с разбиением, гибридный поиск, переранжирование.
Заключение
Современная ИИ-система — не «умная модель», а несколько независимых слоёв: токенизация, представления, Transformer, окно контекста, база знаний, поиск, инструменты и оркестрация. Хорошая база на Markdown может быть полноценным источником истины. Эмбеддинги, векторная база и переранжирование не заменяют её: они помогают находить нужное по мере роста.
Практический шаг на этой неделе: взять одну папку документов, привести заголовки к смысловым границам, собрать INDEX.md и проверить, находится ли ответ поиском по словам до выбора векторной базы. В лаборатории кода это выглядит как сборка контура с понятными стыками, а не как покупка «платформы знаний» в первый день.

