Векторные представления текста для RAG и поиска — Python, Ollama, совместимые с API OpenAI
Встраивания для RAG — Python, Ollama, API OpenAI.
Если вы работаете с генерацией с расширением поиска (RAG), этот раздел объясняет векторные представления текста (эмбеддинги) простым языком: что это такое, как они работают в поиске и извлечении данных, и как вызывать два распространенных локальных режима из Python с помощью Ollama или OpenAI-совместимого HTTP API (так как многие серверы на базе llama.cpp поддерживают такой интерфейс).

Для клиентов на Go и сравнения SDK для Ollama см. SDK для Ollama на Go — сравнение с примерами.
Что такое векторное представление текста (эмбеддинг)?
Векторное представление текста (эмбеддинг) — это вектор (список чисел с плавающей точкой), создаваемый моделью эмбеддингов. Модель преобразует текст переменной длины в пространство с фиксированной размерностью так, что тексты со схожим смыслом оказываются близко друг к другу согласно метрике расстояния или сходства (часто используется косинусное сходство на L2-нормализованных векторах).
Эмбеддинги не являются идентификаторами токенов и не являются результатом чат-запроса. Это слой представления, который используется для поиска, кластеризации, удаления дубликатов и, в архитектуре RAG, для извлечения данных.
Распространенные сценарии использования
| Сценарий | Роль эмбеддингов |
|---|---|
| Семантический поиск / Извлечение в RAG | Преобразование запросов и фрагментов документов в векторы; ранжирование по сходству для получения релевантных отрывков. |
| Переранжирование с помощью моделей эмбеддингов | Преобразование запроса и каждого кандидата в векторы; оценка пар по сходству (см. Переранжирование с помощью моделей эмбеддингов). |
| Кластеризация и удаление дубликатов | Группировка или удаление дубликатов в пространстве эмбеддингов без ручной разметки каждого примера. |
| Оценка в стиле классификации | Сравнение текста с описаниями прототипов или названиями классов в том же пространстве (паттерны зависят от модели). |
Для мультимодальных настроек (текст-изображение и связанные концепции) см. Кросс-модальные эмбеддинги.
Эмбеддинги внутри конвейера RAG
Типичный оффлайн процесс выглядит так:
- Фрагментация документов (размер, перекрытие и структура имеют значение — см. Стратегии фрагментации в RAG).
- Векторизация каждого фрагмента; опциональное сохранение метаданных (идентификатор источника, раздел, ACL).
- Индексация векторов в памяти, в библиотеке индексов или в векторной базе данных (сравнение компромиссов см. в Векторные хранилища для RAG — сравнение).
В момент запроса:
- Векторизация пользовательского запроса (одна короткая строка или небольшая пакетная обработка).
- Извлечение топ-k наиболее похожих фрагментов с помощью векторного поиска (опционально с добавлением ключевого слова или гибридного поиска).
- Создание промпта на основе извлеченных фрагментов обычного текста и вызов вашей чат-модели.
Важный нюанс — большие языковые модели в чат-API потребляют текст (и инструменты), а не произвольные тензоры эмбеддингов. Вы используете эмбеддинги для выбора текста, который нужно вставить. Если вы видите фразу «запросить LLM с заранее рассчитанными эмбеддингами», на практике это означает извлечь данные с помощью эмбеддингов, а затем отправить выбранный текст в LLM.
Получение эмбеддингов с помощью Ollama (Python)
Ollama предоставляет HTTP API. Для получения эмбеддингов вызовите POST /api/embed на вашем хосте Ollama (по умолчанию http://127.0.0.1:11434). JSON-тело запроса включает имя model и input (строка или список строк). В ответе содержится поле embeddings — список векторов, соответствующих вашим входным данным.
Установите httpx (или используйте requests аналогичным образом).
import httpx
OLLAMA = "http://127.0.0.1:11434"
MODEL = "nomic-embed-text" # замените на модель эмбеддингов, которую вы загрузили
def embed_ollama(texts: list[str]) -> list[list[float]]:
r = httpx.post(
f"{OLLAMA}/api/embed",
json={"model": MODEL, "input": texts},
timeout=120.0,
)
r.raise_for_status()
data = r.json()
return data["embeddings"]
if __name__ == "__main__":
q = "Что такое генерация с расширением поиска?"
chunks = [
"RAG объединяет извлечение данных с генерацией.",
"Эмбеддинги отображают текст в векторное пространство для поиска по сходству.",
]
qv = embed_ollama([q])[0]
doc_vs = embed_ollama(chunks)
print(len(qv), len(doc_vs), len(doc_vs[0]))
Операционные заметки
- Сначала загрузите модель (
ollama pull …для выбранного тега). Для моделей класса Qwen3 в Ollama см. Модели Qwen3 для эмбеддингов и переранжирования в Ollama. - При высокой нагрузке пропускная способность эмбеддингов зависит от того, как Ollama планирует задачи — см. Как Ollama обрабатывает параллельные запросы.
Получение эмбеддингов через OpenAI-совместимый сервер (Python)
Многие локальные серверы (включая распространенные HTTP-конфигурации на базе llama.cpp) предоставляют OpenAI-совместимые маршруты, такие как POST /v1/embeddings. Вы можете использовать официальную библиотеку openai для Python и указать base_url на корень …/v1 вашего сервера.
from openai import OpenAI
# Пример — замените хост, порт и идентификатор модели на значения вашего сервера
client = OpenAI(
base_url="http://127.0.0.1:8080/v1",
api_key="not-needed", # многие локальные серверы игнорируют это
)
def embed_openai_compatible(text: str, model: str) -> list[float]:
r = client.embeddings.create(model=model, input=text)
return r.data[0].embedding
if __name__ == "__main__":
v = embed_openai_compatible("привет от llama.cpp", "your-embedding-model-id")
print(len(v))
Почему оба паттерна объединены на одной странице? Концепции (фрагментация, векторизация, индексация, запрос, извлечение текста) идентичны; меняется только HTTP-интерфейс. Одна статья в стиле воркшопа позволяет избежать дублирования одного и того же повествования под двумя URL.
Сохранение векторов и их запрос
В минимальном варианте необходимо сохранить три вещи для каждого фрагмента — вектор, текст и метаданные (идентификатор источника, смещения, ACL). Для быстрого прототипирования можно хранить все в списке Python и использовать косинусное сходство с NumPy или scikit-learn. Для растущих объемов данных используйте векторную базу данных или библиотечный индекс (FAISS и др.); см. Векторные хранилища для RAG — сравнение для сравнения компромиссов на уровне продуктов.
Концептуальный цикл запроса:
query_vec = embed(query)neighbors = index.search(query_vec, k)context = "\n\n".join(chunk.text for chunk in neighbors)- Отправить
contextи вопрос пользователя в ваш чат-API.
Переранжирование после извлечения
Переранжировщик (часто кросс-энкодер или вторая модель оценки) может переупорядочить лучших кандидатов после векторного извлечения. На этом сайте есть примеры на Python и Go, включая Переранжирование с помощью моделей эмбеддингов и Переранжирование с Ollama и Qwen3 Embedding на Go.
На этом сайте — связанные статьи
| Тема | Статья |
|---|---|
| Полная архитектура RAG | Учебник по RAG — архитектура, реализация, продакшн |
| Фрагментация перед векторизацией | Стратегии фрагментации в RAG |
| Выбор векторной БД | Векторные хранилища для RAG — сравнение |
| Qwen3 в Ollama | Модели Qwen3 для эмбеддингов и переранжирования в Ollama |
| Кросс-модальные | Кросс-модальные эмбеддинги |
| Ollama CLI и советы | Шпаргалка по Ollama |
| Go + Ollama | Использование Ollama в Go — сравнение SDK |
Полезные ссылки
- Ollama — модели и runtime
- Ollama API — embed — референс API от разработчиков для
/api/embed - Библиотека OpenAI для Python — работает с любым OpenAI-совместимым
base_url