Эмбеддинги и векторные хранилища
Урок о том, как текст становится вектором и как по векторам ищут похожее.
Embedding (эмбеддинг) — числовой вектор, в который модель превращает фрагмент текста так, что близкие по смыслу тексты дают близкие векторы.
Текст как точка в пространстве
Чтобы искать по смыслу, а не по точным словам, текст переводят в вектор чисел. Модель эмбеддингов устроена так, что семантически похожие фразы оказываются рядом в этом пространстве. Тогда «найти похожее» сводится к «найти ближайшие векторы». В LangChain за это отвечает интерфейс Embeddings.
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector = embeddings.embed_query("Что такое индекс в БД?")
print(len(vector)) # размерность вектора, напр. 1536Близость векторов
Похожесть обычно меряют косинусной близостью. Её идею можно посчитать на чистом Python:
import math
def cosine(a, b):
dot = sum(x * y for x, y in zip(a, b))
na = math.sqrt(sum(x * x for x in a))
nb = math.sqrt(sum(y * y for y in b))
return dot / (na * nb)
q = [1, 0, 1]
docs = {"про БД": [1, 0, 1], "про погоду": [0, 1, 0]}
for name, v in docs.items():
print(name, round(cosine(q, v), 2))Вывод:
про БД 1.0 про погоду 0.0
Векторное хранилище
VectorStore — база, которая хранит чанки вместе с их векторами и умеет быстро находить ближайшие к запросу. В LangChain единый интерфейс поверх разных движков (FAISS, Chroma, pgvector и др.), поэтому код добавления и поиска почти не зависит от выбранного хранилища.
from langchain_community.vectorstores import FAISS
store = FAISS.from_documents(chunks, embeddings)
results = store.similarity_search("Что такое индекс?", k=3)
for doc in results:
print(doc.page_content[:60])Как работает под капотом
При индексации каждый чанк прогоняется через модель эмбеддингов и кладётся в хранилище вместе со своим вектором. На запросе вектор вопроса считается тем же способом, и хранилище ищет k ближайших векторов по выбранной метрике. Чтобы поиск был корректным, вопрос и документы обязаны быть закодированы одной и той же моделью эмбеддингов — иначе их векторы лежат в «разных пространствах» и близость бессмысленна.
Частые ошибки
- Разные модели для индекса и запроса. Вектора несравнимы; всегда одна модель эмбеддингов.
- Переиндексировать всё при каждом запуске. Эмбеддинги стоят денег; сохраняйте индекс на диск.
- Брать слишком большое
k. В контекст попадёт шум и вырастет стоимость.
Итог
- Эмбеддинг превращает текст в вектор, близкий для похожих по смыслу фрагментов.
- Похожесть меряют косинусной близостью векторов.
VectorStoreхранит чанки с векторами и ищет ближайшие к запросу.- Индекс и запрос кодируют одной и той же моделью эмбеддингов.