Хаб / Материалы / Разбор
Разбор6 августа 20269 минут

Почему один вектор не находит: гибридный поиск в контуре ОКБ

Векторный поиск красиво выглядит на демо и тихо промахивается на реальных документах — там, где в вопросе номер приказа или артикул. Разбираем, из чего собран наш поиск: bge-m3, BM25, переранжирование и ссылка на раздел.

Почти любая демонстрация «ИИ по вашим документам» показывает один и тот же фокус: загрузили десять PDF, спросили своими словами, получили ответ. Фокус работает, потому что на десяти документах промахнуться сложно. На двадцати тысячах служебных записок, актов и регламентов начинается инженерия, и первым ломается ровно то, что в демо выглядело магией, — векторный поиск.

Что вообще делает вектор

Эмбеддинг — это способ превратить кусок текста в набор чисел так, чтобы близкие по смыслу куски оказались рядом в пространстве. Мы используем BAAI/bge-m3, 1024 измерения, и храним получившиеся векторы в Qdrant. Когда приходит вопрос, он превращается в такой же вектор, и система ищет ближайшие к нему фрагменты документов.

Сильная сторона очевидна: можно спросить «что делать, если поставщик сорвал сроки», и найдётся раздел, где написано «в случае нарушения контрагентом договорных обязательств». Ни одного общего слова, а документ тот самый.

Слабая сторона ровно там же. Вектор работает со смыслом, а не с написанием. Для него «приказ №117-од» и «приказ №171-од» — почти одна и та же точка: смысл идентичен, отличаются две цифры. Артикулы, номера ГОСТов, фамилии, серийники, аббревиатуры — всё это для эмбеддинга шум, который он честно усредняет.

Как это выглядит у заказчика

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

Зачем нужен BM25, которому сорок лет

BM25 — классический полнотекстовый поиск: он считает, насколько редкое слово из запроса встретилось в документе и сколько раз. Никакого понимания смысла, зато точное совпадение по строке. Ровно то, чего не умеет вектор.

Поэтому в контуре работают оба механизма сразу. Запрос уходит в два индекса: векторный и лексический. Результаты сводятся в один список с весом — в базовой конфигурации 0.5, то есть вклад обоих способов равный. Вес — не догма, а настройка: на юридической базе имеет смысл поднять лексическую часть, на переписке и заявках — векторную.

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

Переранжирование: второй, дорогой взгляд

После слияния списков у нас есть кандидаты — обычно несколько десятков фрагментов. Все они формально «похожи» на запрос, но релевантность у них разная, а в контекст модели влезет не всё. Тут включается переранжировщик BAAI/bge-reranker-v2-m3.

Разница с эмбеддингом принципиальная. Эмбеддинг кодирует запрос и документ независимо, и потом сравнивает числа — быстро, но грубо. Переранжировщик читает пару «запрос + фрагмент» целиком и выдаёт оценку соответствия. Это в разы дороже по вычислениям, поэтому его нельзя пустить на всю базу — но на сорока кандидатах он отрабатывает за доли секунды и заметно чистит верхушку списка.

В ответ модели уходит небольшая группа лучших фрагментов. Меньше мусора в контексте — меньше поводов у модели что-нибудь придумать.

Чем режем документы

Качество поиска определяется не только моделью, но и тем, на какие куски разрезан документ. Разрежете по 500 символов подряд — получите фрагменты, начинающиеся с середины предложения и заканчивающиеся в середине таблицы. Формально всё работает, практически — ответы будут рваными.

Мы режем структурно: по разделам и подразделам, с сохранением заголовков в теле фрагмента. За это отвечает связка Docling и собственный слой okb docling-shim — отдельный разбор про то, как это устроено, лежит здесь. Побочный, но важный эффект: раз фрагмент знает свой раздел, ответ может сослаться не просто на файл, а на «раздел 4.2 регламента».

Ссылка на источник — не украшение

Каждый ответ приходит со ссылками на файл и раздел, откуда взяты сведения. Это не про красоту интерфейса, а про единственный доступный способ проверки: человек открывает исходник и смотрит сам. Локальная модель ошибается не чаще и не реже облачной, разница в том, что здесь у вас есть быстрый способ поймать ошибку.

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

Где эта схема всё ещё промахивается

  • Вопрос без единой зацепки. «Что там по тому проекту, о котором говорили в мае» — не находит ни вектор, ни BM25, потому что искать нечего. Помогает переформулировка, а не архитектура.
  • Таблицы, где смысл в структуре. Сложные сводные таблицы разрезаются хуже текста: часть смысла живёт в объединённых ячейках и заголовках столбцов.
  • Опечатки в редких словах. BM25 не найдёт «Иванв», вектор пожмёт плечами. Частично спасает нечёткое сопоставление, полностью — нет.
  • Противоречащие друг другу документы. Если в базе лежат две редакции регламента, система покажет обе и сошлётся на обе. Решать, какая действует, будет человек.
Оговорка про настройку

Веса гибрида, количество кандидатов на переранжирование и размер фрагмента — это параметры, которые доводятся на ваших документах в первые недели работы. Универсальных значений не существует; всякий, кто называет их не глядя на базу, называет их наугад.

Коротко

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

Вопрос по этому материалу?
Напишите в бюро — отвечает тот же человек, который это собирал.
admin@heavylogic.su

Читать дальше

Все материалы →