
Полная версия:
Вектор смысла: новый квадрант. Навигация в пространстве векторного поиска

Вектор смысла: новый квадрант
Навигация в пространстве векторного поиска
Сергей Кирницкий
Оформление обложки Created with Grok
© Сергей Кирницкий, 2026
ISBN 978-5-0069-2378-2
Создано в интеллектуальной издательской системе Ridero
Предисловие
Эта книга началась с вопроса, который задают все, кто сталкивается с векторным поиском впервые: как это работает? Не в смысле «какой метод вызвать» – это работа документации. А в смысле глубже: почему математика вдруг научилась ловить смысл? Почему «King минус Man плюс Woman» даёт «Queen»? Почему два изображения, не имеющие ни одного общего пикселя, оказываются «похожими»?
Я писал эту книгу для тех, кто хочет понять. Понять – не скопировать код из примера, не настроить по инструкции, не пройти собеседование. Потому что из понимания практика выводится сама. А из практики без понимания – только зависимость от чужих ответов на Stack Overflow, от готовых рецептов, от надежды, что кто-то уже решил твою задачу.
Есть разница между человеком, который знает, какие параметры выставить, и человеком, который понимает, почему именно эти параметры работают для его случая. Первый беспомощен, когда рецепт не срабатывает. Второй может думать сам. Документация молчит, Stack Overflow не знает, языковая модель разводит руками – а понимание остаётся. Вернись к основам. Подумай: что на самом деле происходит? Ответ придёт. Не потому что запомнил – потому что понял.
Разработчик, который слышал про векторные базы данных и хочет разобраться, подходит ли это для его задачи, найдёт здесь фундамент. Инженер, который уже использует Qdrant или Pinecone, но чувствует, что упускает что-то важное в настройках и компромиссах, – заполнит пробелы. Архитектор, которому нужно принять решение о технологии и объяснить его команде, получит язык для этого разговора. А любопытный человек, которому просто интересно, как устроен современный поиск, – добро пожаловать. Любопытство остаётся лучшей причиной читать о технологиях.
Общее у всех этих читателей одно: желание видеть за инструментом принцип. За настройкой – компромисс. За магией – механику. Такой взгляд не обесценивает технологию. Наоборот – делает её по-настоящему своей.
Книга не требует знания линейной алгебры. Не требует опыта работы с нейросетями. Не требует даже глубокого знания программирования – хотя оно поможет оценить некоторые примеры. Единственное, что требуется, – готовность думать. Готовность остановиться на сложном месте, перечитать, связать с тем, что было раньше.
Чего эта книга не даёт? Здесь нет полного описания API, списка всех параметров, примеров на каждый случай – документация справляется с этим лучше и всегда актуальнее. К моменту, когда вы читаете эти строки, какие-то методы уже изменились, какие-то параметры добавились. Синтаксис – ни Python, ни REST, ни gRPC – тоже за пределами этого разговора. Готовых решений для копирования в продакшен не будет. И превращения в эксперта по векторным базам данных – тоже не обещаю.
Зато после прочтения вы будете знать, какие вопросы задавать документации. Куда смотреть, когда что-то не работает. Как думать о проблеме, когда готового ответа нет.
Что она даёт? Понимание. Закончив эту книгу, вы будете знать, почему векторный поиск работает – и где он ломается. Вы поймёте, что стоит за аббревиатурами HNSW, ANN, RAG – не определения из глоссария, а суть идей. Вы увидите компромиссы, которые скрыты за каждой настройкой, и научитесь думать о них осознанно. Быстро, точно, дёшево – выбери два. Не ограничение конкретного продукта – фундаментальный закон. Понимание таких законов меняет способ принимать решения.
Вы перестанете воспринимать технологию как магию и начнёте видеть её как инструмент – со своими возможностями и границами. А инструмент, который понимаешь, служит лучше, чем магия, в которую веришь.
Такое понимание не устареет. Версии API меняются, появляются новые библиотеки, одни продукты вытесняют другие. Принципы остаются. Идея о том, что похожесть – про смысл, а не про байты, не изменится с выходом следующей версии. Знание того, почему приближённый поиск быстрее точного и чем за это приходится платить, останется актуальным и через десять лет.
Книга построена как путешествие. Мы начинаем с простого вопроса – как найти похожее? – и постепенно углубляемся.
Первая часть показывает проблему. Почему наивные подходы не работают? Почему нельзя просто сравнить пиксели или посчитать совпадающие слова? Что вообще значит «похоже» и как математика описывает сходство? Эта часть – фундамент. Она меняет способ думать о поиске.
Вторая часть – история. Откуда взялись эмбеддинги – числовые представления смысла? Как Word2Vec изменил всё в 2013 году? Почему поиск среди миллиардов векторов вообще возможен – ведь сравнить всё со всем нереально? Здесь есть момент красоты: когда «King минус Man плюс Woman» даёт «Queen», математика ловит смысл. Это стоит прочувствовать.
Третья часть – механика. Как устроены векторные базы данных изнутри? Какие решения они принимают за вас, какие оставляют вам? Что означают все эти параметры и почему нет «лучших настроек» – есть только подходящие для конкретной задачи?
Четвёртая часть – практика и границы. Семантический поиск: где он силён, где слаб. RAG: почему это костыль и почему он нужен. Масштабирование: что происходит, когда данных становится много. И наконец – выбор инструмента: когда нужна специализированная база, когда хватит pgvector, а когда векторный поиск вообще не нужен.
Можно читать последовательно – так задумано. Каждая глава опирается на предыдущие, каждая идея готовит следующую. Можно и прыгать. Знаете, что такое эмбеддинги? Вторая часть будет повторением. Интересует только RAG? Начните с десятой главы, хотя я рекомендую хотя бы пролистать девятую.
Одна просьба: не пропускайте первую часть. Даже если вам кажется, что вы всё это знаете. Первые две главы закладывают фундамент – не технический, а концептуальный. Они устанавливают способ думать о похожести, который пронизывает всю книгу. Без этого фундамента остальное рискует остаться набором фактов, а не пониманием.
Несколько слов о Qdrant. Эта книга выросла из работы с Qdrant, и примеры часто используют его терминологию. Она, однако, не реклама продукта и не руководство пользователя. Qdrant здесь – проводник, через которого видна территория. Принципы, о которых мы говорим, универсальны. Они работают в Pinecone, в Milvus, в Weaviate, в pgvector. Меняются детали реализации, но не суть. Работаете с другой базой? Книга всё равно для вас.
Ещё одно. Я старался писать честно. Без маркетингового восторга, без обещаний магии, без «это решит все ваши проблемы». Технология, о которой мы говорим, мощная и красивая. И у неё есть границы. Семантический поиск – поиск по смыслу, не по ключевым словам – не понимает отрицания. RAG, способ давать языковым моделям нужный контекст, ломается на неудачном разбиении текста. Квантизация – сжатие векторов – теряет информацию. HNSW – алгоритм быстрого поиска – иногда промахивается мимо настоящего ближайшего соседа. Не недостатки – свойства. Знать их важнее, чем верить в безграничные возможности.
Здесь показаны и сила подхода, и места, где он ломается. Одно без другого – неполная картина. Восторг без понимания границ – путь к разочарованию. Скептицизм без признания возможностей – упущенные решения. Честность требует и того, и другого.
Иногда я ставлю вопрос и не отвечаю сразу. Иногда оставляю связь неназванной – кто заметит, тот заметит.
Если что-то кажется сложным – это нормально. Остановитесь, перечитайте, свяжите с тем, что было раньше. Понимание не приходит мгновенно. Оно выстраивается. Именно поэтому книга – путешествие, а не справочник.
Последнее. Книга – это разговор. Не лекция, не инструкция, не проповедь. Разговор предполагает, что мы идём вместе. Я знаю эту территорию и покажу её вам. Но я не гуру и не претендую на истину в последней инстанции. Я делаю выборы – что важно, что второстепенно, что опустить – и эти выборы видны. Вы можете с ними не соглашаться.
Если после прочтения вы сможете самостоятельно разобраться в новой векторной базе данных, оценить, подходит ли RAG для вашей задачи, объяснить коллеге, почему «просто сравнить всё со всем» – плохая идея, и принять осознанное решение о том, нужен ли вообще векторный поиск, – книга выполнила свою задачу. Если при этом вы почувствуете красоту момента, когда математика поймала смысл, – тем лучше. Удивление и понимание не мешают друг другу. Они усиливают друг друга.
Добро пожаловать в пространство смыслов.
Часть I: Проблема
Прежде чем решать задачу, нужно её почувствовать. Не прочитать описание – а узнать. Примерить на себя. Понять, почему она вообще существует и почему не решается очевидными способами.
Эта часть – про боль. Про задачу, которая кажется простой, пока не попробуешь её решить. «Найти похожее» – что может быть проще? Оказывается, очень многое. Потому что «похожее» – это не про пиксели и не про буквы. Это про смысл. А смысл измерять куда сложнее, чем кажется на первый взгляд.
Читатель, который пропустит эту часть, потеряет фундамент. Всё остальное в книге – ответы на вопросы, которые здесь задаются. Без вопросов ответы повисают в воздухе.
Глава 1. Поиск похожего
Есть задачи, которые легко сформулировать и трудно решить. «Найти похожее» – одна из них. Мы делаем это постоянно: ищем товар, напоминающий тот, что понравился; документ, связанный с текущим; песню, похожую на любимую. Мозг справляется мгновенно. Компьютер – нет.
Почему? Потому что мозг сравнивает значения, а компьютер видит только данные. Байты. Пиксели. Символы. Между «данными» и «смыслом» – пропасть. Эта глава – о том, как выглядит эта пропасть и почему её нельзя перепрыгнуть наивными методами.
1.1. Миллион фотографий
Представьте: вы строите интернет-магазин. Каталог – миллион товаров. У каждого товара – фотография, название, описание, характеристики. Классический поиск работает: пользователь вводит «красные кроссовки Nike», система находит товары, где в названии или описании есть эти слова. Всё понятно, всё работает. Технология отлажена десятилетиями, инструменты зрелые, задача решена.
А теперь пользователь загружает фотографию. Кроссовки, которые он увидел на улице. Или в соцсети. Или на ком-то в метро. Он не знает бренд, не знает модель, не может описать словами – у него есть только картинка и желание «хочу такие же». Или хотя бы похожие. Что делать?
Можно, конечно, попросить пользователя описать товар текстом. Но попробуйте сами: опишите словами конкретную пару обуви так, чтобы поисковая система нашла именно её среди миллиона других. «Белые кроссовки с синей полосой и толстой подошвой» – сколько результатов вернёт такой запрос? Сотни. Тысячи. И нужный товар может оказаться на двадцатой странице, потому что в его описании написано «спортивная обувь ivory с декоративным элементом navy». Та же пара, другие слова.
Это не экзотический сценарий. Google Lens, Pinterest, Taobao, ASOS – все они решают эту задачу. Загрузи картинку, получи похожие. Для пользователя это выглядит как магия: навёл камеру, нажал кнопку, получил результат. Для инженера – как проблема, у которой нет очевидного решения. Проблема, над которой бились десятилетиями и решили только в последние годы.
Потому что как сравнить две фотографии? Что значит «похожи»?
Одинаковые пиксели? Нет, конечно – тот же товар под другим углом будет иметь совершенно другие пиксели. Сдвиньте камеру на сантиметр, измените освещение, положите товар на другой фон – и попиксельно это будет совершенно другое изображение. Ноль совпадений. При этом для человека – очевидно тот же предмет.
Одинаковые цвета? Ближе, но красная куртка и красный автомобиль – это не «похожие товары». Красный закат и красный перец – тем более.
Одинаковая форма? Уже теплее, но как формализовать «форму»? Как объяснить компьютеру, что кроссовки – это кроссовки, независимо от того, сфотографированы они сбоку, сверху или под углом?
Задача «найти похожее» обманчиво проста в формулировке и удивительно глубока в реализации. Каждый день миллионы людей ищут «что-то похожее на это» – и каждый раз за простым интерфейсом скрывается сложнейшая технологическая задача.
И фотографии – только начало. Та же проблема возникает везде, где нужно искать по смыслу, а не по точному совпадению. Везде, где пользователь знает что хочет, но не может это точно описать. Везде, где «похожее» важнее «точно такого же».
Возьмём документы. Юридическая фирма, архив на сотни тысяч договоров, накопленных за двадцать лет работы. Приходит новый контракт, нужно найти прецеденты – похожие договоры с похожими условиями, чтобы понять типичные формулировки, возможные риски, исторические решения. Поиск по ключевым словам? «Договор аренды» найдёт тысячи результатов, большинство нерелевантных. «Договор аренды нежилого помещения в Москве сроком на 5 лет с правом субаренды» – слишком специфично, можно пропустить релевантные документы, где формулировки чуть другие. «Помещение» в одном договоре, «площадь» в другом, «объект» в третьем – смысл тот же, слова разные. А ведь юристу нужны именно смысловые аналоги, не текстовые совпадения.
Возьмём службу поддержки. База знаний – десятки тысяч статей, инструкций, решений типичных проблем. Годы накопленного опыта, ответы на все возможные вопросы. Клиент пишет: «Приложение вылетает после обновления». Где искать ответ? По слову «вылетает»? Статья может называться «Проблемы совместимости версии 3.2 с iOS 17» – ни одного общего слова с запросом, но это именно то, что нужно. Или клиент напишет «приложение крашится», или «программа закрывается сама», или «не работает после апдейта» – всё это один и тот же вопрос, но для поиска по ключевым словам это четыре разных запроса с разными результатами.
Или рекомендации. Пользователь посмотрел фильм, понравилось. Что предложить дальше? Тот же жанр? Слишком грубо – «комедия» объединяет и лёгкие романтические истории, и чёрный юмор, и абсурдистские эксперименты. Фильм Уэса Андерсона и фильм Адама Сэндлера – оба комедии, но аудитории почти не пересекаются. Того же режиссёра? Может сработать, но ограничивает выбор и не всегда релевантно – режиссёр мог снять очень разные фильмы в разные периоды. С теми же актёрами? Ещё менее надёжно. Что-то с «похожим настроением», с похожей атмосферой, с похожим послевкусием? Отлично, только как измерить настроение? Как объяснить алгоритму, что «Амели» и «Королевство полной луны» – это похожий зрительский опыт, хотя один фильм французский, другой американский, разные жанры, разные годы, разные актёры?
Та же история с музыкой. Spotify и Apple Music каждый день решают эту задачу для сотен миллионов пользователей. Человек слушает песню и хочет «ещё что-нибудь такое». Тот же исполнитель – очевидно, но быстро закончится. Тот же жанр – слишком размыто, «рок» включает в себя тысячи непохожих направлений. Похожий темп, похожие инструменты, похожее настроение – всё это нужно как-то измерить и сравнить.
В науке – аналогично. Исследователь нашёл статью по своей теме и хочет найти связанные работы. Поиск по ключевым словам из заголовка? Пропустит статьи, где та же идея описана другими терминами. Поиск по авторам? Слишком узко. Поиск по цитированию? Ближе, но не учитывает недавние публикации, которые ещё не успели накопить цитаты. Нужен поиск по смыслу – «найди статьи, которые исследуют похожую проблему похожими методами».
Везде одна и та же структура: есть объект, есть коллекция, нужно найти в коллекции что-то «близкое» к объекту. Товар среди миллиона товаров. Документ среди сотен тысяч документов. Песня среди десятков миллионов треков. Статья среди бесконечного потока научных публикаций.
И везде – одна и та же проблема: «близость» определяется смыслом, а не формой. Два изображения похожи не потому, что у них совпадают пиксели, а потому что на них изображено одно и то же. Два документа связаны не потому, что в них одинаковые слова, а потому что они об одном и том же. Две песни воспринимаются как похожие не потому, что совпадают звуковые волны, а потому что они создают похожее ощущение.
Форма – это то, что видит компьютер. Смысл – это то, что видит человек. Между ними – пропасть.
Человек справляется с этим легко. Мы смотрим на две фотографии и мгновенно понимаем: это похожие товары или разные. Мы читаем два документа и чувствуем: об одном они или о разном. Мы слушаем две песни и знаем: это похожая музыка или совершенно разная. Мы не можем объяснить алгоритм – мы не знаем, как именно наш мозг это делает, – но результат выдаём надёжно и быстро.
Компьютер так не может. Компьютер видит массив чисел – яркости пикселей, коды символов, частоты звуковых колебаний. Для него фотография – это таблица из миллионов ячеек, в каждой – три числа от 0 до 255, красный, зелёный, синий. Текст – последовательность кодов Unicode. Музыка – график колебаний давления воздуха. Никакого «смысла», никакого «значения», никакого «похоже на». Только числа.
И вот тут возникает вопрос, который определяет всю дальнейшую историю: можно ли научить машину сравнивать смыслы? Можно ли превратить «это про одно и то же» в вычислимую величину?
Почему очевидные методы не работают – об этом дальше.
1.2. Почему это сложно
Первый рефлекс программиста – попробовать очевидное. Нужно сравнить две картинки? Сравним пиксели. Нужно сравнить два текста? Посчитаем общие слова. Нужно найти дубликаты? Вычислим хэш. Эти методы интуитивно понятны, легко реализуемы, хорошо изучены. Они работают – для других задач. Для поиска по смыслу они бесполезны. И понять почему – значит понять саму природу проблемы.
Начнём с изображений и попиксельного сравнения.
Фотография – это сетка пикселей. Каждый пиксель – три числа: красный, зелёный, синий. Сравнить две фотографии попиксельно – значит взять соответствующие пиксели и посчитать, насколько они различаются. Чем меньше различие – тем более «похожи» картинки. Звучит логично.
На практике это не работает почти никогда.
Возьмите одну и ту же чашку кофе. Сфотографируйте её дважды – один раз чуть левее, другой раз чуть правее. Сдвиг на пять сантиметров. Для человека это очевидно одна и та же чашка, тот же кофе, та же сцена. Для попиксельного сравнения – два совершенно разных изображения. Каждый пиксель сдвинулся, каждый пиксель изменился. Там, где был край чашки, теперь фон. Там, где был фон, теперь чашка. Совпадений почти нет. Алгоритм скажет: это разные картинки, похожесть близка к нулю.
Теперь сфотографируйте ту же чашку при другом освещении. Утром и вечером. При лампе и при свече. Та же чашка, тот же ракурс, та же композиция – но цвета другие. Тени другие. Блики другие. Каждый пиксель изменил свои RGB-значения. Для алгоритма – снова разные картинки.
А теперь сфотографируйте две разные белые чашки на одинаковом белом фоне при одинаковом освещении. Пиксели будут очень похожи – много белого там и тут. Алгоритм скажет: почти одинаковые изображения. Хотя это совершенно разные предметы.
Попиксельное сравнение измеряет не то. Оно отвечает на вопрос «насколько совпадают числа в массивах», а не на вопрос «насколько похоже то, что изображено». Это разные вопросы с разными ответами.
Есть чуть более умные методы. Можно искать не точное совпадение пикселей, а похожие структуры. Можно сравнивать гистограммы цветов – сколько красного, сколько синего, сколько зелёного на картинке в целом. Не попиксельно, а статистически. Можно искать характерные точки – углы, края, контрастные переходы – и сравнивать их расположение. Такие алгоритмы десятилетиями использовались в компьютерном зрении. Они лучше справляются со сдвигами и поворотами. Могут найти тот же объект под другим углом, если угол не слишком отличается.
Но они всё равно сравнивают визуальные свойства, а не смысл. Красное яблоко и красный мяч будут «похожи» по цвету и даже по форме. Фотография кошки анфас и фотография той же кошки в профиль будут «разными» по характерным точкам – точки-то в других местах. А главное – эти методы не понимают, что на картинке. Они видят пиксели, статистику, закономерности. Не видят объекты, не видят сцены, не видят смысл.
Форма – не смысл. Пиксели – не значение. Этот путь никуда не ведёт.
Теперь текст. Кажется, с текстом проще – слова же несут смысл напрямую, в отличие от пикселей. Посчитаем общие слова, и дело в шляпе.
Метод называется «мешок слов» – bag of words. Берём текст, разбиваем на слова, считаем, сколько раз встречается каждое слово. Получаем что-то вроде рецепта: этот документ содержит три слова «договор», два слова «аренда», одно слово «помещение». Другой документ содержит пять слов «договор», одно слово «аренда», три слова «собственность». Сравниваем эти «рецепты» – чем больше совпадений, тем документы «ближе».
Проблема первая: синонимы – разные слова с одинаковым значением. «Автомобиль» и «машина» – одно и то же, но для мешка слов это разные слова. Документ про «автомобили» и документ про «машины» не найдут друг друга, хотя они об одном. «Быстрый», «скорый», «стремительный» – три разных слова, один смысл. «Врач», «доктор», «медик» – то же самое. Язык избыточен, у каждого понятия десятки способов выражения. Мешок слов этого не видит.
Вернёмся к интернет-магазину. Покупатель ищет «красное платье». В каталоге есть «алый сарафан» – именно то, что нужно, идеальное попадание. Но слова не совпадают. «Красное» – не «алый». «Платье» – не «сарафан». Для поиска по ключевым словам это промах. Товар не найден. Покупатель уходит, продажа не состоялась. А ведь достаточно было понять, что «алый» – это оттенок красного, а «сарафан» – это разновидность платья.
Проблема вторая: омонимы – одинаковые слова с разными значениями. «Банк» – это финансовое учреждение или берег реки? «Ключ» – это инструмент, источник воды или разгадка шифра? «Мир» – это планета, отсутствие войны или сообщество людей? «Лук» – овощ или оружие? Одно слово, разные значения. Мешок слов считает слово «банк» и не знает, какой банк имеется в виду. Для него это просто последовательность символов, б-а-н-к, без контекста, без значения. Документ о рыбалке на берегу реки окажется «похож» на документ о финансовых операциях, потому что в обоих есть слово «банк». Документ про стрельбу из лука – на кулинарный рецепт с луком.
Проблема третья: порядок слов. «Собака укусила человека» и «человек укусил собаку» – совершенно разные события, но одинаковые мешки слов. Те же слова, та же частота. Для алгоритма – идентичные документы. Мешок слов теряет структуру, теряет связи между словами, теряет грамматику. Остаётся только набор ингредиентов без рецепта.
Есть улучшенные версии. TF-IDF – метод, который учитывает не просто частоту слов, а их важность: редкое слово весит больше, чем частое. Идея разумная: если слово встречается в каждом документе, оно мало что говорит о конкретном документе. Это помогает: слово «договор» в юридическом архиве встречается в каждом документе и потому почти бесполезно для различения, а слово «субаренда» – редкое и значимое, оно действительно указывает на тему. Но TF-IDF не решает проблемы синонимов и омонимов. Он всё ещё сравнивает слова, а не смыслы. «Субаренда» и «поднаём» для него – разные слова, хотя это одно и то же понятие.
Можно пойти дальше – использовать n-граммы, последовательности из нескольких слов подряд. «Банк реки» и «банк денег» станут разными n-граммами, и омонимы частично разрешатся. Но n-грамм комбинаторно много – каждая пара слов, каждая тройка, каждая четвёрка. Данные становятся разреженными, большинство n-грамм встречаются по одному разу, сравнивать становится сложно. И проблема синонимов всё равно остаётся – «берег реки» и «речной берег» будут разными n-граммами.
Текст – не просто набор слов. Слова – не просто символы. За словами стоит значение, и это значение нельзя вычислить простым подсчётом.
Остаются хэши. Хэш-функция берёт любые данные и превращает их в короткую строку фиксированной длины – «отпечаток пальца» данных. Одинаковые данные дают одинаковый хэш. Разные данные – с очень высокой вероятностью – разные хэши. Сравнить два хэша мгновенно: совпали или нет.
Хэши идеальны для поиска дубликатов. Точных дубликатов. Если нужно найти, есть ли в базе точно такой же файл – хэш справится. Быстро, надёжно, эффективно.
Но «похожее» – это не «точно такое же». Это принципиально другая задача. Измените в документе одну запятую – хэш изменится полностью, станет совершенно другой строкой, будто это другой документ. Измените в фотографии один пиксель – хэш станет другим. Пересохраните JPEG с чуть другим сжатием – хэш изменится, хотя картинка визуально неотличима. Для хэша нет понятия «почти совпадает» или «немного отличается». Есть только «да» и «нет», совпало или не совпало. Бинарно. Абсолютно.

