Построение индекса: качество чанков решает всё

Собираем индексацию воедино и формулируем главный закон RAG: garbage in — garbage out.

Построение индекса — финальный шаг: каждый чанк превращается в вектор и записывается в векторную БД вместе с текстом и метаданными.

Конвейер индексации целиком

документ
  -> парсинг (чистый текст)
  -> чанкинг (фрагменты + overlap)
  -> эмбеддинг каждого чанка (вектор)
  -> запись в векторную БД (вектор + текст + метаданные)
  -> построение ANN-индекса (HNSW/IVF)

После этого база готова отвечать на запросы. Индексацию запускают офлайн и повторяют при изменении документов.

Псевдокод индексации (для чтения)

for doc in load_documents(folder):
    for chunk in split(doc.text, size=400, overlap=50):
        vector = embed(chunk)               # модель эмбеддингов
        db.add(vector=vector,
               text=chunk,
               metadata={"source": doc.name})
db.build_index(metric="cosine")

Почему чанки важнее модели

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

Проиллюстрируем: запрос ищет точный факт, но он «размазан» между двумя плохо нарезанными чанками — и ни один не отвечает на вопрос полностью.

bad_chunks = [
    "Гарантия на технику",            # факт оборвался
    "составляет 24 месяца со дня покупки",  # продолжение без темы
]
good_chunks = [
    "Гарантия на технику составляет 24 месяца со дня покупки.",
]

def answers(chunk, q_words):
    return q_words.issubset(set(chunk.lower().split()))

q = {"гарантия", "месяца"}
print("Плохие чанки отвечают:", any(answers(c, q) for c in bad_chunks))
print("Хороший чанк отвечает:", any(answers(c, q) for c in good_chunks))

Вывод:

Плохие чанки отвечают: False
Хороший чанк отвечает: True

Ни один из «плохих» чанков не содержит и «гарантия», и «месяца» одновременно — факт распался. Хорошо нарезанный чанк держит мысль целиком, и поиск находит её. Вот почему чанкинг — не формальность, а ключевое решение.

Когда переиндексировать

  • Изменились или добавились документы.
  • Сменили модель эмбеддингов (обязательно — пространство другое).
  • Поменяли стратегию или размер чанков.

Итог

  • Индексация: парсинг → чанкинг → эмбеддинг → запись + ANN-индекс.
  • Поиск возвращает только то, что лежит в индексе — потолок задаёт чанкинг.
  • Смена модели эмбеддингов или стратегии чанков требует переиндексации.
Проверьте себя
1. Что происходит на шаге построения индекса?
AДокументы переводятся на другой язык
BЧанки эмбеддятся в векторы и записываются в БД вместе с текстом и метаданными
CМодель дообучается
DТекст шифруется
2. Почему говорят, что качество чанков задаёт потолок качества ответов?
AПотому что модель не важна
BПоиск может вернуть только то, что лежит в индексе; плохие чанки = плохой контекст
CПотому что чанки шифруются
DПотому что overlap всегда вреден
3. В каком случае индекс обязательно нужно перестроить?
AПри смене цвета интерфейса
BПри смене модели эмбеддингов — у неё другое векторное пространство
CКаждый час по расписанию
DНикогда не нужно
Поддержать проект