/
Вопросы и ответы
/
RAG
/

Как работают embeddings?

Как работают embeddings?

11 часов назад

Никита Вихров

Ответы

0

Как работают embeddings — объяснение через код

Embedding — это числовое представление текста. Предложение превращается в вектор из сотен чисел, где близкие по смыслу тексты дают близкие векторы. Это и есть основа поиска в RAG: ищем не по ключевым словам, а по смыслу.


Как выглядит embedding

from anthropic import Anthropic
import numpy as np

# Anthropic не предоставляет embeddings API — используем популярную альтернативу
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")

texts = [
    "Как подключиться к базе данных?",
    "Инструкция по настройке PostgreSQL",
    "Как приготовить борщ?",
]

embeddings = model.encode(texts)
print(embeddings.shape)  # (3, 384) — три вектора по 384 числа каждый
print(embeddings[0][:5])  # [-0.023, 0.187, -0.341, 0.092, 0.215]

Числа сами по себе не читаются. Важно расстояние между векторами.


Косинусное сходство — как измерить близость

def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

emb_question = model.encode(["Как подключиться к базе данных?"])[0]
emb_postgres  = model.encode(["Инструкция по настройке PostgreSQL"])[0]
emb_borscht   = model.encode(["Как приготовить борщ?"])[0]

print(cosine_similarity(emb_question, emb_postgres))  # 0.74 — высокое сходство
print(cosine_similarity(emb_question, emb_borscht))   # 0.08 — низкое сходство

Чем ближе к 1 — тем тексты смысловее похожи. Это и есть семантический поиск.


Простой RAG через embeddings без внешних библиотек

import json
from sentence_transformers import SentenceTransformer
import numpy as np
from anthropic import Anthropic

model_emb = SentenceTransformer("all-MiniLM-L6-v2")
client = Anthropic()

# База знаний
documents = [
    {"id": 1, "content": "Для подключения к PostgreSQL используй DATABASE_URL в .env файле. Формат: postgresql://user:password@host:5432/dbname"},
    {"id": 2, "content": "Аутентификация через JWT. Токен передаётся в заголовке Authorization: Bearer <token>. Срок жизни — 24 часа."},
    {"id": 3, "content": "API rate limit — 100 запросов в минуту на пользователя. При превышении — статус 429."},
]

# Создаём embeddings для всех документов заранее
doc_embeddings = model_emb.encode([d["content"] for d in documents])


def find_relevant(question: str, top_k: int = 2) -> list:
    question_emb = model_emb.encode([question])[0]

    similarities = [
        cosine_similarity(question_emb, doc_emb)
        for doc_emb in doc_embeddings
    ]

    # Берём top_k самых похожих
    top_indices = np.argsort(similarities)[::-1][:top_k]
    return [documents[i] for i in top_indices]


def ask(question: str) -> str:
    relevant = find_relevant(question)
    context = "\n".join([f"- {d['content']}" for d in relevant])

    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=512,
        system=f"Отвечай только на основе этой документации:\n{context}",
        messages=[{"role": "user", "content": question}]
    )
    return response.content[0].text


print(ask("Как передать токен в запросе?"))
# → "Токен передаётся в заголовке Authorization: Bearer <token>"

print(ask("Что будет если слать 200 запросов в минуту?"))
# → "Превысишь rate limit в 100 запросов — получишь статус 429"

Почему keyword-поиск хуже

# Keyword-поиск: ищем "подключение"
question = "Как законнектиться к базе?"

# В документах нет слова "законнектиться" или "коннект"
# Keyword-поиск: ничего не найдено

# Embedding-поиск: "законнектиться к базе" ≈ "подключиться к PostgreSQL"
# Находит правильный документ несмотря на другие слова

Embedding-поиск работает со синонимами, разными формулировками и даже с вопросами на другом языке — потому что ищет по смыслу, а не по буквам.

11 часов назад

Никита Вихров

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845