Qdrant + LangChain + Heli: RAG с эмбеддингами и генерацией через один ключ

Qdrant хранит векторы и ищет похожие фрагменты, а модели нужны на двух этапах: эмбеддинги для индексации и поиска, chat-модель для ответа. Обе части можно взять из Heli с одним ключом sk-heli-, а Qdrant запустить у себя в Docker или использовать облачный. Векторы и документы остаются в вашей базе — в Heli уходят только тексты для эмбеддингов и запросы к модели.

Установка

code
pip install langchain-openai langchain-qdrant qdrant-client
docker run -p 6333:6333 qdrant/qdrant

Индексация и ответ

python
import os
from langchain_core.documents import Document
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_qdrant import QdrantVectorStore

HELI = dict(base_url="https://getheli.ru/v1", api_key=os.environ["HELI_API_KEY"])

embeddings = OpenAIEmbeddings(
    model="openai/text-embedding-3-small",
    check_embedding_ctx_length=False,
    **HELI,
)
docs = [Document(page_content="Ключ Heli создаётся во вкладке «Ключи» кабинета.")]
store = QdrantVectorStore.from_documents(
    docs, embedding=embeddings, url="http://localhost:6333", collection_name="kb"
)
retriever = store.as_retriever(search_kwargs={"k": 4})
llm = ChatOpenAI(model="openai/gpt-5.4-mini", **HELI)

question = "Где взять ключ Heli?"
context = "\n\n".join(d.page_content for d in retriever.invoke(question))
answer = llm.invoke([
    ("system", "Отвечай только по контексту. Если ответа в нём нет, так и скажи."),
    ("human", f"Контекст: {context}  Вопрос: {question}"),
])
print(answer.content)

Важные детали

  • check_embedding_ctx_length=False заставляет OpenAIEmbeddings отправлять обычный текст. Иначе LangChain режет текст на токены через tiktoken и шлёт массивы токенов — для OpenAI-совместимых API надёжнее отправлять строки.
  • Размер вектора задаётся моделью: 1536 у text-embedding-3-small и 3072 у text-embedding-3-large. Коллекция создаётся под эту размерность, поэтому при смене модели эмбеддингов нужна новая коллекция и переиндексация.
  • Индексируйте и ищите одной и той же моделью эмбеддингов — векторы разных моделей несравнимы.
  • Документы режьте на фрагменты, например через RecursiveCharacterTextSplitter из langchain-text-splitters. Целые документы дают плохой поиск и раздувают контекст.
  • Для Qdrant Cloud передайте url кластера и api_key Qdrant — это отдельный ключ, не ключ Heli.

Embedding-модели в Heli API

Модели

Для большинства баз знаний на русском хватает text-embedding-3-small. Для генерации ответа берите быструю модель и передавайте ей 3–5 релевантных фрагментов, а не весь найденный текст.

text-embedding-3-small

GPT-5.4 mini

Gemini 3.5 Flash

LangChain + Heli

Какую модель выбрать для RAG

Обновление базы знаний

Чтобы при повторной загрузке документа не плодить дубли, задавайте фрагментам стабильные идентификаторы и передавайте их в add_documents через параметр ids. Qdrant принимает в качестве id только целые числа или UUID, поэтому удобно строить UUID из пути документа и номера фрагмента через uuid5.

В metadata документа сохраняйте источник, раздел и дату: по этим полям Qdrant умеет фильтровать поиск, и retriever можно ограничить, например, только актуальными документами. Если пользователи часто ищут точные термины и артикулы, посмотрите гибридный режим поиска в langchain-qdrant, где плотные эмбеддинги дополняются разреженными.

Попробуйте Heli

Ключ sk-heli- появляется после подтверждения почты. Через Google и Яндекс — сразу в кабинете.

Документация API · Модели и цены

Читайте также