КЛАСТЕР 05 · RAG ИНДЕКСАЦИЯ ~18 МИНУТ
День 22 · из 35

Эмбеддинги
и чанкинг

Как текст превращается в точку в многомерном пространстве. Почему «оплата картой» и «билинг» становятся близкими. Что такое чанкинг и почему от его выбора зависит, найдёт RAG ответ или нет.

Суть урока

Эмбеддинг — это превращение куска текста в вектор из сотен-тысяч чисел. Эти числа подобраны так, чтобы тексты с близким смыслом давали близкие векторы. Это позволяет искать «по смыслу», а не по буквам. Чанкинг — это разбиение твоих документов на куски подходящего размера, которые будут индексироваться отдельно. Эти два этапа — фундамент любого RAG: ошибся тут — никакая хитрость дальше не поможет.

Что такое эмбеддинг

Эмбеддинг — это превращение текста в вектор (массив чисел фиксированной длины). Например, «как настроить SSO» может стать таким вектором:

Эмбеддинг как массив чисел · упрощённо
"как настроить SSO"
[0.234, -0.891, 0.523, 0.014, -0.667, 0.918, ..., 0.103]
"настройка авторизации"
[0.245, -0.873, 0.589, 0.021, -0.612, 0.901, ..., 0.121]
"как испечь пирог"
[-0.123, 0.456, -0.789, 0.234, 0.567, -0.123, ..., 0.890]
У первых двух — близкие числа. У третьего — совсем другие.

Размерность вектора — обычно от 384 до 3072 чисел (зависит от модели). Это и есть «многомерное пространство»: тексты — точки в этом пространстве, и близкие по смыслу — реально близкие как точки (по евклидову расстоянию или косинусу).

Почему это работает

Эмбеддинг-модели обучены на огромных корпусах текстов так, чтобы тексты в похожих контекстах получали похожие векторы. Когда в обучающих данных «SSO», «авторизация», «вход в систему» постоянно встречаются в схожих контекстах — модель учится размещать их близко.

Эмбеддинг — это математическое выражение смысла. Не идеальное, не абсолютное, но достаточное, чтобы построить поиск, который работает по смыслу, а не по буквам.

Как работает поиск через эмбеддинги

  1. Индексация (один раз): каждый документ из базы прогоняется через эмбеддинг-модель → получается вектор → сохраняется в специальную БД (векторную).
  2. Поиск (при каждом запросе): запрос пользователя прогоняется через ту же модель → получается вектор → ищется N документов в БД с самыми близкими векторами.
  3. Возвращаем top-N документов, кладём в контекст.

Поиск ближайших векторов в БД работает быстро — векторные БД (Pinecone, Weaviate, Chroma, Qdrant, pgvector) специально оптимизированы под эту задачу. На 1 миллион документов поиск занимает миллисекунды.

i
Главное практическое следствие
Пользователь спрашивает «как авторизоваться через корпоративный аккаунт», в документации написано «настройка SSO с identity provider» — обычный keyword search ничего не найдёт. RAG через эмбеддинги — найдёт. Это и есть его главное преимущество.

Эмбеддинг-модели и их различия

Эмбеддинг-моделей много. От выбора зависят: качество поиска, цена, скорость, размер вектора. Разделить их можно так:

Облачные эмбеддинг-API

OpenAI text-embedding-3-small / text-embedding-3-large, Cohere embed-v3, Voyage AI. Платный API, простой вызов.

Когда выбрать: на старте, для прототипов, когда не хочешь возиться с инфраструктурой. Очень дёшево: ~$0.02 за 1M токенов на маленьких моделях.

Минусы: зависишь от провайдера, данные уходят в облако (важно для приватных), плата за каждый запрос (накапливается при больших базах).

Стандарт по умолчанию: для большинства проектов хватает text-embedding-3-small от OpenAI. Хорошее качество, очень дёшево.

Open-source модели

BGE, E5, GTE, Nomic-embed, Jina. Бесплатные, можно запустить локально или у себя на сервере. Размеры — от 100M до 7B параметров.

Когда выбрать: приватные данные (нельзя в облако), большая база (миллионы документов — облако дорого), нужна полная независимость.

Минусы: своя инфраструктура (GPU/CPU нужен), обновление модели — твоя забота, выбор сложнее (моделей десятки).

Если выбираешь: смотри MTEB Leaderboard на HuggingFace — там реальные сравнения моделей по задачам.

Многоязычные модели

Большинство эмбеддинг-моделей преимущественно обучены на английском. Если у тебя русские документы — нужны специальные многоязычные.

Что есть: multilingual-e5, BGE-M3, jina-embeddings-v2-multilingual. Облачные — text-embedding-3-large от OpenAI хорошо работает с русским, Cohere multilingual.

Что важно: проверяй именно на своём языке. «Multilingual» в названии — не гарантия одинакового качества на всех языках. Бывает что модель хорошо работает на испанском и плохо на русском.

Главная грабля: взять английскую модель для русских документов. Будет работать, но плохо — все смысловые связки будут «через английский».

Специализированные

Модели, дообученные под конкретный домен: код, медицинские тексты, юридические документы, научные статьи.

Когда нужны: когда твоя база очень узкоспециализирована и общие модели плохо ловят оттенки смысла. Например, CodeBERT для эмбеддингов кода, BioBERT для медицины.

Когда не нужны: в большинстве бизнес-случаев. Общие модели от OpenAI и Cohere покрывают 90% задач. Не лезь сюда раньше времени.

Что критично при выборе

01

Поддержка твоего языка

Главный фильтр на старте. Если работаешь на русском — бери модель, в которой русский явно поддержан.

02

Размерность вектора

Больше — обычно лучше качество, но дороже хранить и медленнее искать. Для большинства задач 768-1536 — оптимум.

03

Максимальная длина входа

Сколько токенов модель принимает на вход. Влияет на чанкинг: чанки не должны превышать этот предел.

04

Стабильность

Если меняешь модель — нужно переиндексировать всю базу (старые векторы несовместимы). Выбирай надолго.

Чанкинг — разбиение на куски

Вторая половина индексации — что именно мы эмбеддим. У тебя 4000 страниц документации — нельзя сделать один огромный эмбеддинг (превысит max input у модели, потеряет специфику). Нельзя сделать один на абзац (потерян широкий контекст). Где середина?

Это и есть чанкинг — разбиение документов на куски (chunks) подходящего размера, каждый из которых индексируется отдельно.

Размер чанка

Типичные размеры — от 200 до 1000 токенов. Балансирует две противоположные силы:

  • Чанки маленькие (~200 токенов): точно ловят смысл, но теряют контекст. Один абзац без окружающих может быть бесполезен.
  • Чанки большие (~1500 токенов): сохраняют контекст, но «разбавляют» смысл. Эмбеддинг страницы — слабее, чем эмбеддинг конкретного раздела.

Эмпирически: 400-800 токенов — хороший дефолт для большинства типов документов. Для длинных формальных текстов (юридические, технические) — ближе к 800-1000. Для коротких диалогов, FAQ — ближе к 200-400.

Стратегии разбиения

Плохо

Fixed-size chunking — режем по N символов

Тупо берём документ и режем каждые N символов или токенов. Простейший подход, но часто рвёт смысл посередине предложения.

«...для настройки SSO нужно открыть кон||| {ОБРЫВ} ||| фигурацию идентити-провайдера в админ-панели...»

Эмбеддинг такого «куска» получается странный — модель видит обрезанный текст и плохо ловит смысл.

Лучше

Semantic chunking — режем по смысловым границам

Разбиваем по естественным границам: абзацам, разделам, заголовкам. Каждый чанк — это законченная смысловая единица.

Чанк 1: «# Настройка SSO\n\nЧтобы настроить SSO, нужно...»
Чанк 2: «## Настройка identity provider\n\nВ админ-панели...»

Эмбеддинг такого чанка — точный, потому что текст — целостный. На markdown / HTML структурированных документах работает отлично.

Ещё лучше

Recursive chunking — иерархическое разбиение

Начинаем с крупных границ (главы → разделы), если чанк выходит большой — режем дальше по более мелким (абзацы → предложения). Сохраняем смысл везде, где можно.

Это стандарт в библиотеках типа LangChain (RecursiveCharacterTextSplitter). На разнотипных документах работает лучше всего.

Overlap (перекрытие)

Распространённый приём — делать чанки с перекрытием: следующий чанк начинается на 50-100 токенов раньше, чем закончился предыдущий. Это значит, что какой-то фрагмент текста попадает в два чанка.

Зачем: важная информация на границе между чанками не «теряется». Если ответ требует одновременно конца одного раздела и начала следующего — он будет в обоих чанках, и хотя бы один из них найдётся.

Цена: индекс растёт на 10-15%, дублирование в результатах. На практике овэрлап в 10-20% от размера чанка — норма.

Метаданные чанков

Помимо самого текста и эмбеддинга, в чанк полезно записывать метаданные:

  • Источник: из какого документа этот чанк (для цитирования)
  • Раздел: заголовок раздела/секции (даёт контекст модели)
  • Дата: когда документ обновлён (можно отсекать старое)
  • Тип: FAQ / руководство / changelog / политика (можно фильтровать)
  • Аудитория: для разработчиков / для пользователей / внутреннее (контроль доступа)

Метаданные не используются в эмбеддинге (не влияют на похожесть), но огромно важны на этапе фильтрации и реранкинга. Об этом — День 24.

Решения AI-инженера

Развилка 1. Облачные vs локальные эмбеддинги

На старте — облачные. text-embedding-3-small от OpenAI или Cohere embed v3. Это бесплатно по эффорту (одна функция API), почти бесплатно по деньгам (~$0.02 за миллион токенов).

На локальные переходишь, когда: (а) приватные данные нельзя в облако, (б) база огромна и облачный счёт начинает кусаться, (в) нужно low-latency и сетевой запрос за эмбеддингом слишком дорог.

Никогда не начинай с локальных «потому что круче». 80% проектов остаются на облачных и это окей.

Развилка 2. Какого размера чанки

Не существует «правильного» размера. Подход — экспериментировать на своих данных:

  1. Стартуй с 500 токенов + overlap 50.
  2. Сделай 20 типичных запросов пользователей, проверь топ-3 результата для каждого.
  3. Если в чанках «обрывки без контекста» — увеличивай (700-1000).
  4. Если в чанках «много мусора, ответ теряется» — уменьшай (300-400).
  5. Итеративно подбирай. На разных типах документов оптимум разный.

Готового ответа нет, и это нормально. Эта эмпирика — часть инженерной работы с RAG.

Концептуальные грабли

«Переключусь с small на large для лучшего качества». Векторы от разных моделей несовместимы. Меняешь модель → нужно переиндексировать всю базу. Для маленькой это окей. Для миллиона документов это часы работы и заметные деньги на эмбеддингах.

Выбирай модель надолго. Если вынужден менять — закладывай миграцию: переиндексация ночью, версионирование эмбеддингов в БД, плавный переход.

Запрос пользователя должен пройти через ту же модель, что индексировала документы. Иначе их векторы — в разных пространствах, поиск не работает.

Это очевидно, но часто ломается при «случайных» переходах: разработчик A проиндексировал, разработчик B читает старый код, добавляет фичу, использует более новую модель в search. RAG разом перестаёт работать.

«Режу по 2000 символов». На русском это ~500-700 токенов, на английском — ~400-500, на коде ещё иначе. Чанки получаются разной «информационной плотности».

Хороший подход — резать по токенам через ту же токенизацию, что используется в эмбеддинг-модели. Большинство библиотек (LangChain, LlamaIndex) умеют это из коробки.

«Сохраню только текст и вектор, остальное потом». Через 3 месяца понимаешь, что нужны фильтры: «только из политик», «только за последний год», «только для разработчиков». А метаданные не сохранены — переиндексируй всё заново.

Привычка с первого дня: каждый чанк сохраняем с метаданными — источник, дата, тип, аудитория, разделы. Это копейки места, и спасает от больших переделок потом.

Практика

Эксперимент 01 · Поиграйся с эмбеддингами

Открой OpenAI Embeddings или Cohere Playground

В OpenAI Playground есть Embeddings, в Cohere — Embed. Введи 5-10 коротких фраз: половину про одно (например, «настройка авторизации», «как залогиниться», «вход в систему»), половину про другое («рецепт пирога», «как испечь хлеб», «кулинарные советы»). Получи эмбеддинги. Посчитай косинусное расстояние (или просто посмотри глазами на числа). Заметишь: первые пять близки между собой, вторые — между собой, две группы — далеки. Это и есть «поиск по смыслу» в действии.

Эксперимент 02 · Чанкинг своих заметок

На реальном тексте

Возьми любой свой длинный документ (заметку, статью, доку). Раздели его в уме на чанки тремя способами: (а) каждые 500 символов; (б) по абзацам; (в) по подзаголовкам. Сравни — какой из вариантов даёт осмысленные куски, каждый из которых имеет ценность по отдельности? Это покажет, почему semantic chunking почти всегда лучше fixed-size.

Эксперимент 03 · Audit потенциальной базы

Сколько токенов и какая структура

Если у тебя есть документация, по которой ты хочешь сделать RAG — посчитай: сколько в ней документов? средняя длина в токенах? есть ли заголовки/разделы (значит подходит semantic chunking) или сплошной текст (потребуется fixed-size с overlap)? есть ли метаданные (дата, автор, тип)? Этот аудит — то, что определит твой выбор стратегий на следующих шагах.

Что в Дне 23
Знаем, как индексировать. Завтра — обратная половина: что происходит, когда пользователь задаёт вопрос. Pipeline запроса: эмбеддинг → поиск → топ-N → в контекст → ответ. И почему первый прогон чаще всего разочаровывает — типичные провалы базового RAG.