Embeddings and Vector Databases
Погрузитесь в волшебный мир эмбеддингов, где слова облекаются в числа и обретают осмысленные «координаты». В этом модуле вы узнаете, как генерируются эти векторы, как надежно хранить их в векторных базах данных и эффективно использовать для поиска и рекомендаций. Готовьтесь дать мощный импульс своим AI‑приложениям и преобразить работу с неструктурированными данными!
Questions
Вопросы, которые мы будем обсуждать:
- Что значит "расстояние" между векторами?
- Почему между похожими словами расстояние близкое, а между непохожими - большое?
- Что такое векторные базы данных, какие использовать?
- Как защитить данные в векторных базах?
- Как возвращать пользователю "источники"?
Steps
1. Okay. What are word embeddings? I have only 7 minutes!
Внимание! Нельзя использовать разные text-to-embedding модели при индексации и при ретриве — их векторы несовместимы.
Если вы перейдёте на новую «модную» модель и забудете переиндексировать все данные, ретривер начнёт возвращать нерелевантные или «мусорные» результаты, и ваш RAG‑пайплайн полностью сломается!
2. VDBs
3. Which VDB to choose?
In 2025, VDBs are everywhere! Inside python, in SQLite, in PostGres, in Redis, in MongoDB - everywhere!
For educational purposes
- In-script: faiss
- Local: SQLite or Weaviate
Специально под AI:
- Self-hosted: Weaviate or Chroma
- Cloud: Managed OpenSearch or Managed Elasticsearch
- Serverless: Pinecone Cloud, Weaviate Cloud
Based on your business case
- Redis с модулем RediSearch Vector: подходит для real‑time поиска по embedding, чат‑ботов с низкой задержкой и рекомендательных систем на «горячих» данных
- PostgreSQL с расширением pgvector: идеально, когда нужны ACID‑транзакции, сложные SQL‑запросы и гибридный поиск по реляционным и векторным данным
- MongoDB с Atlas Vector Search (или аналогичные плагины): оптимально для полу‑структурированных JSON‑документов, динамических схем и масштабируемого распределённого векторного поиска
- SQLite с FTS5+vector или собственными векторными расширениями: выбор для мобильных приложений и офлайн‑режимов, когда необходима лёгковесная встроенная БД без дополнительных сервисов
For best performance and giant scale
- Managed OpenSearch or Managed Elasticsearch
For rapid development
- Supabase with pgvector: Row-level security, good dev experience (documentation and tutorials)
- Pinecone or Weaviate Cloud: easy to use, good dev experience (documentation and tutorials)
- Firebase with Firestore: good dev experience (documentation and tutorials)
4. Security
Представим ситуацию: у вас есть база знаний компании
- в которой хранится информация о продуктах, нужная всем клиентам (например, информация с веб-сайта компании)
- личная информация каждого клиена
- внутренние документы компании, которые мы не показываем клиентам
- секретные юридические документы, доступ к которым должен быть только у CEO и юристов
И вы сделали чат-бота на вашем сайте (ассистента в правом нижнем углу).
Как можно защитить информацию на разных уровнях?
-
Всё вперемешку:
Мы собрали все данные в один векторный индекс. Ужас! 💀 Теперь любой сможет получить доступ к личным данным любого клиента. Ыы нарушили закон. (GDPR, HIPAA, ...)
-
Вы указали чат-боту на вашем сайте, что он не должен отвечать на вопросы про личные данные клиентов и т.д.
💀 Но кто-то сделал промпт-инжект и чат-бот ответил на вопрос про личные данные клиента. Вы нарушили закон. (GDPR, HIPAA, ...)
-
Вы сделали классификатор промпт-инъекций в запросах и запретили промпт-инъекции.
💀 Но кто-то сделал промпт-инжект 100 разными вариантами, и чат-бот ответил на вопрос про личные данные клиента. Вы нарушили закон. (GDPR, HIPAA, ...)
-
Вы сделали 4 разных векторных индекса:
- для общедоступных данных
- для личных данных клиентов
- для внутренних документов компании
- для секретных юридических документов
И вы сделали 4 разных роли пользователей:
- anonymous user
- authenticated user
- employee
- admin
И настроили уровни доступа: более высокая роль включает в себя доступ к индексам более низких уровней.
🎯 Победа! Теперь никто не может получить доступ к данным, которые не предназначены для него.
-
Вы сделали 1 векторный индекс, но с Row-Level Security (RLS)
То есть теперь у каждого вектора есть метка, которая указывает, какие роли могут его видеть.
Например:
id text vector role 1 "Public data" [0.1, 0.2, 0.3] anonymous 2 "Private data" [0.1, 0.2, 0.3] authenticated 3 "Internal data" [0.1, 0.2, 0.3] employee 4 "Super secret data" [0.1, 0.2, 0.3] admin, legal-team 🎯 Победа! Теперь никто не может получить доступ к данным, которые не предназначены для него.
5. Как возвращать пользователю в ответе системы "ответ" и "источники"?
-
(Offline) Шаг векторизации документов
Сделайте так, чтобы каждому вектору соответствовала ссылка на документ.
id source text vector 1 "Full text of the document" "of the document" [0.1, 0.2, 0.3] 2 id_in_other_table "some text" [0.1, 0.2, 0.3] 3 "https://example.com/1" "some text" [0.1, 0.2, 0.3] 4 "user_docs:12345" "пример фрагмента пользовательского документа" [0.2, 0.1, 0.4] 5 "file://reports/report_2023.pdf?page=10" "отчет за 2023 год (страница 10)" [0.15, 0.22, 0.35] 6 "db://employees/emp_id=789" "профиль сотрудника №789" [0.05, 0.25, 0.45] 7 "s3://company-bucket/legal/contracts/contract_456.docx" "договор с клиентом №456" [0.3, 0.4, 0.2] -
(Online) Шаг ретрива
Когда пользователь отправляет запрос, система выполняет следующие шаги:
- Получаем роль(и) пользователя (например,
anonymous
,authenticated
,employee
,admin
). - Преобразуем текст запроса в эмбеддинг с помощью выбранной модели.
- Делаем поиск по векторной базе данных, передавая:
- вектор запроса,
- параметр
top_k
(количество возвращаемых фрагментов), - фильтр по метаданным RLS:
{
"role": { "$in": user_roles }
} - Получаем список документов/фрагментов, каждый из которых содержит:
- текст (
page_content
), - метаданные с полем
source
. - Собираем из найденных фрагментов контекст для LLM.
- Формируем промпт: сначала раздел «Контекст», затем «Вопрос».
- Отправляем промпт в LLM и получаем ответ.
- Возвращаем пользователю объект с двумя полями:
answer
— текст, сгенерированный LLM,sources
— список строк из метаданных, указывающих на реальные источники.
Пример псевдокода на Python:
# 1. Получаем роли пользователя
user_roles = get_user_roles(user_id)
# 2. Эмбеддинг запроса
query_embedding = embed_model.embed_query(query)
# 3. Поиск в векторной БД с фильтром RLS
results = vdb.similarity_search(
vector=query_embedding,
top_k=5,
filter={"role": {"$in": user_roles}}
)
# 4. Извлечение текста и источников
contexts = [doc.page_content for doc in results]
sources = [doc.metadata["source"] for doc in results]
# 5. Формирование промпта для LLM
prompt = (
"Контекст:\n" +
"\n\n".join(contexts) +
f"\n\nВопрос: {query}"
)
# 6. Генерация ответа
answer = llm.generate(prompt)
# 7. Возврат пользователю
return {
"answer": answer,
"sources": sources
}Теперь пользователь получает развёрнутый ответ и чёткий список источников, подтверждающих информацию.
- Получаем роль(и) пользователя (например,
6. Про другие модальности
Что такое струкурированные и неструктурированные данные?
Структурированные данные
Данные, представленные в заранее определённой и жёстко заданной форме — таблицы, записи с полями и типами, схема которых известна заранее. Примеры: реляционные базы данных, CSV-файлы, JSON с фиксированной структурой. Лёгко фильтруются, сортируются и обрабатываются через SQL-запросы.
Неструктурированные данные
Данные без явной схемы или формальной структуры: свободный текст, изображения, аудио, видео, 3D‑модели и т.д. Их хранение, поиск и анализ требуют использования методов NLP, компьютерного зрения или embeddings, поскольку традиционные реляционные запросы здесь неприменимы.
Помните, что видов неструктурированных данных много!
- текст
- изображения
- аудио
- видео
- 3D-модели
- ...
Каждый из них может быть представлен в виде вектора и храниться в векторной базе данных - а благодаря мультимодальным text-to-embedding моделям, мы можем хранить и использовать их в одном векторном индексе.
Extra Steps
E1. Choosing an Embedding Model
Алгоритм выбора такой же как и с LLM:
- Идем на популярный Massive Text Embedding Benchmark, смотрим на лучшие модельки
- Смотрим на их доступность нам по критериям:
- контур, в рамках которого мы работаем
- модель опенсурсная (а какая лицензия?) или проприетарная
- цена
- размер вектора (важно, если мы собираемся хранить миллионы векторов)
- Поддержка нужных языков и адаптация под специфичную доменную область
- Возможность тонкой настройки и дообучения эмбеддингов на собственном датасете
- скорость работы модели и необходимые вычислительные мощности (хотя сейчас все text-to-embedding модели очень быстрые и легкие)
- (в идеале) Offline evals: прогоняем на собственном датасете, далаем замеры через GPT-eval или асессорами
- возможно, делаем замеры с end-to-end RAG пайплайном (об этом позже)
- (в идеале-идеале) Online evals: делаем онлайн-замеры, AB-тесты, и т.д.
The Best Embedding Models for Information Retrieval in 2025
E2. Every Distance in Data Science explained
E3. Deep VDB understanding -> Playlist on Faiss (Facebook AI Similarity Search Engine)
E4. The Biggest Misconception about Embeddings
E5. Text Embeddings visualization
- https://github.com/uber-research/parallax
- https://www.reddit.com/r/LanguageTechnology/comments/16qyhwr/text_embedding_visualization/
E6. For deep understanding of embeddings
- https://youtu.be/f7o8aDNxf7k?si=Su3I0s55lKB9DU_b
- https://youtu.be/d2E-pU4H2gc?si=2Wn4gYH5PPA-LkoA (coding practice)
Now we know...
Мы увидели, как эмбеддинги превращают слова и любые неструктурированные данные в числовые векторы для эффективного поиска и анализа. Вы освоили принципы выбора модели эмбеддингов с учётом качества, скорости и бюджета, а также познакомились с основами работы векторных баз данных. Теперь вы готовы интегрировать эти инструменты в RAG‑пайплайны и создавать высокопроизводительные решения.
Exercises
- У вас есть готовый RAG по сайту из 5000 страниц сайта. Менеджер изменил одну страницу.
- И что теперь, запускать индексацию заново? Как это можно оптимизировать?
- Что будет, если мы возмем pdf файл (текст, картинки, графики) -> распознаем весь текст -> сделаем по этому тексту RAG:
- сможет ли наш чат-бот ответить на вопрос про картинки?
- сможет ли наш чат-бот ответить на вопрос про графики?
- сможет ли наш чат-бот ответить на вопрос про текст?
- При выборе text-to-embedding модели, какие критерии будут важнее для вас в каждом кейсе:
- простой чат-бот по информации на сайте
- чат-бот по инструкции к самолету (примерно 1 000 000 000 слов)
- чат-бот по секретным правительтвенным документам
- чат-бот по данным с несколькими модальностями (текст, картинки)
- Какую VDB вы выберете для следущих задач:
- RAG по информации на сайте, у вас 1 час на разработку
- RAG по книге, on-device
- RAG для голосового робота (важна скорость)
- RAG по всем кадрам всех видео на youtube
- Даже если мы сделали безопасный RAG: какие минусы могут быть у хранении в одном индексе данных пользователей (100млн) и данных внутренних сотрудников (30тыс)?
- Можно ли возвращать в источниках ссылки на разные источники источников: ссылку на публичный сайт, ссылку на документ внутри приватного диска?
- Что произойдет, если мы построим векторный индекс одной text-to-embedding моделью, а запросы будем проводить другой?