RAG по своим документам: поиск по базе знаний и ответы с цитатами через TokenMaster

· rag embeddings поиск ai

RAG (Retrieval-Augmented Generation) — это способ заставить языковую модель отвечать по вашим документам, а не по общей памяти. Система сначала ищет нужные фрагменты в вашей базе знаний, а затем передаёт их модели, которая строит ответ с опорой на эти куски. Так модель отвечает по актуальным данным и может ссылаться на конкретный документ, а не выдумывать факты.

Что понадобится

  • API-ключ TokenMaster — создаётся в разделе «Ключи» после регистрации на tokenmaster.ru.
  • Python 3.8+ и библиотеки openai, chromadb и sentence-transformers.
  • Тексты ваших документов: регламенты, договоры, инструкции, статьи базы знаний.

Библиотеки устанавливаются одной командой:

pip install openai chromadb sentence-transformers

Пошаговая сборка RAG

Схема работы простая: разбиваем документы на чанки, переводим их в векторы (embeddings), сохраняем в векторную базу, а на запрос находим похожие чанки и подставляем их в промпт модели.

1. Разбиваем документы на чанки

Модель не может держать в контексте целую библиотеку, поэтому текст режут на небольшие пересекающиеся фрагменты:

def split_text(text, chunk_size=500, overlap=50):
    words = text.split()
    chunks = []
    for i in range(0, len(words), chunk_size - overlap):
        chunks.append(" ".join(words[i:i + chunk_size]))
    return chunks

with open("docs.txt", encoding="utf-8") as f:
    chunks = split_text(f.read())

Перекрытие (overlap) нужно, чтобы фрагмент не обрывался на середине мысли.

2. Получаем embeddings и сохраняем в векторную БД

Embedding — это числовой вектор, отражающий смысл текста: похожие по смыслу фрагменты оказываются рядом в векторном пространстве. Для эмбеддингов берём локальную модель, а сохраняем всё в Chroma:

from sentence_transformers import SentenceTransformer
import chromadb

model = SentenceTransformer("intfloat/multilingual-e5-small")
embeddings = model.encode(chunks)

client = chromadb.Client()
collection = client.get_or_create_collection("my_docs")
collection.add(
    ids=[str(i) for i in range(len(chunks))],
    documents=chunks,
    embeddings=embeddings.tolist(),
)

3. На запрос ищем похожие чанки

Запрос переводим в тот же векторный вид и ищем ближайшие по смыслу фрагменты:

query = "Как расторгнуть договор аренды?"
query_embedding = model.encode([query])[0]
results = collection.query(
    query_embeddings=[query_embedding.tolist()],
    n_results=3,
)
context = "\n\n".join(results["documents"][0])

4. Отдаём контекст в LLM

Найденные чанки подставляем в промпт и просим модель отвечать только по ним:

from openai import OpenAI

client = OpenAI(
    base_url="https://tokenmaster.ru/v1",
    api_key="sk-...",  # ваш ключ TokenMaster
)

prompt = (
    "Ответь на вопрос, используя только приведённый контекст. "
    "Если ответа в контексте нет, так и скажи.\n\n"
    f"Контекст:\n{context}\n\n"
    f"Вопрос: {query}"
)

answer = client.chat.completions.create(
    model="deepseek-flash",  # или glm-4.5, qwen
    messages=[{"role": "user", "content": prompt}],
)
print(answer.choices[0].message.content)

Добавив в промпт номера фрагментов и требование указывать их в ответе, вы получите ответы с цитатами на конкретные куски документа.

Подключение TokenMaster

TokenMaster — это AI-шлюз с OpenAI-совместимым API, поэтому модель вызывается стандартной библиотекой openai без изменений. Подключение сводится к двум параметрам:

  1. Base URL: https://tokenmaster.ru/v1
  2. API Key: ваш ключ вида sk-…

Почему TokenMaster? Один ключ и один баланс для моделей DeepSeek, GLM (Zhipu) и Qwen, оплата из России. Base URL единый — https://tokenmaster.ru/v1.

Модель выбирается под задачу: deepseek-flash подойдёт для быстрых ответов по базе знаний, а более мощные модели — для сложных вопросов по длинным документам. Актуальный каталог и цены — на tokenmaster.ru/pricing, документация по API — на tokenmaster.ru/docs.

Проверка работы

Запустите скрипт и задайте вопрос, ответ на который есть в ваших документах. Если модель отвечает по тексту и не выдумывает лишнего — RAG работает. Типичные ошибки:

  • 401 / invalid api key — ключ неверный или скопирован не целиком; он должен начинаться с sk-.
  • connection error — проверьте Base URL: ровно https://tokenmaster.ru/v1, без лишнего /chat/completions в конце.
  • insufficient quota — на балансе недостаточно средств; пополните его в личном кабинете.
  • ответ не по документам — увеличьте n_results или перепроверьте разбивку на чанки: слишком большие или слишком мелкие фрагменты ухудшают поиск.

Частые вопросы

Чем RAG лучше простого «загрузить файл в чат»? Загруженный файл упирается в лимит контекста модели. RAG хранит всю базу в векторном виде и подставляет в промпт только релевантные фрагменты, поэтому работает с большими объёмами документов.

Где брать embeddings? Для эмбеддингов не нужен платный API: локальная модель sentence-transformers даёт качественные векторы бесплатно. Для продакшена с большими объёмами можно взять Chroma с постоянным хранилищем, FAISS или специализированные векторные базы.

Можно ли получать ответы с цитатами? Да. Пронумеруйте чанки при сохранении и попросите модель в промпте указывать номера фрагментов, на которые она ссылается, — тогда ответ будет легко проверить по исходному документу.

Итог

RAG по своим документам — это короткий конвейер на Python: разбили текст на чанки, получили embeddings, сохранили в векторную базу, а на запрос нашли похожие фрагменты и передали их в промпт модели. Подключите OpenAI-совместимый API TokenMaster по Base URL https://tokenmaster.ru/v1 с ключом sk-… — и получите чат, который отвечает по вашей базе знаний с опорой на конкретные документы.

Подключите модели через TokenMaster

Один ключ sk-… и base URL https://tokenmaster.ru/v1 — доступ к DeepSeek, GLM, Qwen и другим моделям. Зарегистрироваться →