Практикум: RAG на русском языке

Практикум по RAG на русском в 2026: Python, Qdrant, multilingual embeddings, metadata filters, hybrid-ready retrieval и grounded answers вместо старого Chroma-only baseline.

Этот практикум в 2026 уже не стоит строить вокруг старой схемы LangChain + ChromaDB + один retriever. Для русскоязычного RAG сегодня полезнее брать стек, который сразу допускает:

  • multilingual embeddings;
  • нормальные metadata filters;
  • дальнейший переход в hybrid retrieval;
  • более production-friendly storage.

Поэтому в качестве baseline здесь используется Python + Qdrant + multilingual embeddings + grounded answer policy.

Русскоязычный RAG отличается не отдельной магией, а тем, что retrieval должен нормально переживать морфологию, длинные слова, смешанные формулировки и иногда русско-английские термины в одном вопросе.
Не начинайте с англоязычных embeddings “потому что они популярные”. На русском retrieval quality от этого часто проседает сильнее, чем кажется, особенно на policy, support и docs-корпусах.

Что мы собираем

Базовый pipeline:

documents
-> chunking
-> multilingual embeddings
-> Qdrant index
-> retrieval with filters
-> grounded answer

Почему такой стек

КомпонентПочему
Qdrantудобный modern retrieval store, легко развивать дальше
Multilingual embeddingsлучше держат русский и mixed-language queries
Metadata filtersважны для локали, типа документа, даты и ACL
Grounded answer policyснижает фантазии при слабом retrieval
ПромптRussian RAG assistant
Вопрос: «Какой срок возврата электроники?»

Retrieved context:
- «Электронику можно вернуть в течение 7 дней»
- «Для возврата нужен чек или номер заказа»
Ответ модели

Электронику можно вернуть в течение 7 дней. Для возврата понадобится чек или номер заказа.

Что важно для русского

  • multilingual embeddings;
  • аккуратный chunking;
  • metadata filters;
  • возможность позже добавить hybrid retrieval;
  • evaluation именно на русских запросах, а не только на английских тестах.

1. Почему русскоязычный RAG требует отдельной дисциплины

На русском retrieval чаще ломается из-за сочетания факторов:

  • богатая морфология;
  • длинные слова и compound-like формулировки;
  • mix русского и английского терминов;
  • разные способы назвать одну и ту же сущность;
  • официально-канцелярский стиль документов.

Из-за этого baseline “взяли любую embedding model и всё взлетело” работает хуже, чем хотелось бы.

2. Минимальная архитектура практикума

Этот практикум сознательно строится не как full production system, а как strong baseline:

  1. собираем документы;
  2. режем на chunks;
  3. считаем multilingual embeddings;
  4. кладём в Qdrant;
  5. делаем retrieval;
  6. отвечаем только по найденному контексту.

Этого уже достаточно, чтобы дальше добавлять:

  • hybrid retrieval;
  • reranking;
  • citations;
  • corrective gates.

3. Какие embeddings выбирать

Практически полезны два класса:

Hosted embeddings

Подходят, если важны:

  • быстрый старт;
  • меньше local infra;
  • хорошая managed latency.

Open multilingual embeddings

Подходят, если нужны:

  • локальная обработка;
  • контроль над индексом;
  • минимизация vendor lock-in.

Для русского особенно полезно смотреть на:

  • multilingual-e5;
  • BGE-M3;
  • другие multilingual retrieval models, а не англо-центричный baseline.

4. Почему Qdrant здесь лучше старого “Chroma как default”

Chroma остаётся нормальным учебным инструментом, но для практикума 2026 Qdrant удобнее как baseline, потому что:

  • лучше смотрится как путь к production;
  • поддерживает более зрелую retrieval конфигурацию;
  • удобно развивать filters и hybrid paths;
  • не заставляет потом полностью переучивать mental model команды.

То есть этот практикум не про “самую простую локальную игрушку”, а про правильный стартовый стек, который не придётся сразу выбрасывать.

5. Chunking для русского

Практические правила:

  • не делать chunks слишком маленькими;
  • учитывать структуру документа;
  • сохранять section headers;
  • не резать policy/FAQ ответы так, чтобы терялся смысл;
  • держать metadata по источнику, разделу и типу документа.

Для русских документов особенно важно, чтобы chunking был structure-aware, а не только символо-ориентированным.

6. Retrieval должен быть grounded и filter-aware

Даже в простом прототипе полезно сразу иметь:

  • document type metadata;
  • language / locale;
  • source;
  • updated_at;
  • optional tenant or access metadata.

Это помогает не только поиску, но и future scaling:

  • фильтровать старые документы;
  • отделять policy от marketing;
  • изолировать клиентские данные;
  • объяснять, откуда взят ответ.
Без техники
{ "title": "Слабо", "content": "В индекс кладутся только тексты чанков без source metadata, поэтому retrieval может смешивать FAQ, маркетинг и старые политики." }
С техникой
{ "title": "Лучше", "content": "Каждый чанк идёт в индекс вместе с source, section, type и датой. Retrieval становится более управляемым и безопасным." }

7. Почему grounded answer policy важнее красивого текста

Для русскоязычного практикума лучше сразу задать модели простое правило:

  • отвечать только по найденному;
  • если evidence нет, так и говорить;
  • не допридумывать детали.

Это скучнее, чем “креативный помощник”, но намного полезнее для реального RAG.

8. Минимальный пример

from qdrant_client import QdrantClient, models
from openai import OpenAI

qdrant = QdrantClient(":memory:")
client = OpenAI()

qdrant.create_collection(
    collection_name="docs",
    vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE),
)

texts = [
    "Электронику можно вернуть в течение 7 дней с момента покупки.",
    "Для возврата нужен чек или номер заказа.",
]

embeddings = client.embeddings.create(
    model="text-embedding-3-small",
    input=texts,
)

qdrant.upsert(
    collection_name="docs",
    points=[
        models.PointStruct(
            id=i,
            vector=item.embedding,
            payload={"text": text, "source": "returns.md", "lang": "ru"},
        )
        for i, (text, item) in enumerate(zip(texts, embeddings.data))
    ],
)

Это hosted embedding path, но retrieval surface остаётся в вашем контроле. Если нужен fully local route, embeddings можно заменить на open multilingual model.

9. Что улучшать следующим шагом

После working baseline логичный порядок такой:

  1. eval на реальных русских запросах;
  2. metadata filtering;
  3. hybrid retrieval;
  4. reranking;
  5. citations and no-answer behavior.

И только потом стоит думать про agentic upgrades.

Плюсы

  • Даёт современный baseline для русскоязычного RAG без завязки на устаревший стек
  • Сразу учитывает multilingual retrieval и metadata
  • Проще масштабировать к production, чем старый Chroma-only tutorial
  • Хорошо совместим с дальнейшим hybrid и reranking paths

Минусы

  • Чуть сложнее, чем совсем учебный локальный пример
  • Качество всё равно зависит от реальных русских eval-наборов
  • Hosted embeddings добавляют vendor dependency
  • Без hybrid/reranking baseline может пропускать сложные query types

Что стоит добавить сразу после MVP

Минимальный upgrade list:

  • source, section, type, updated_at в metadata;
  • оффлайн-набор русских queries для eval;
  • no-answer prompt policy;
  • explicit logging retrieved chunks;
  • later: hybrid retrieval and reranking.
Проверьте себя

1. Что наиболее важно для русского baseline RAG?

2. Почему в практикуме 2026 разумнее взять Qdrant как baseline?

3. Какой следующий шаг после working MVP?