Разработка RAG-системы (Retrieval-Augmented Generation)
RAG (Retrieval-Augmented Generation) — архитектура, в которой языковая модель при генерации ответа обращается к внешнему хранилищу знаний. Вместо того чтобы полагаться только на знания, «зашитые» в веса при предобучении, модель получает релевантный контекст в момент инференса. Это позволяет работать с актуальными данными, корпоративными документами и специализированными базами знаний без дорогостоящего fine-tuning.
Базовая архитектура RAG
Пользователь → Запрос
↓
Embedding-модель
↓
Векторный поиск (Top-K)
↓
Извлечённые чанки + запрос
↓
LLM
↓
Ответ
Компоненты:
- Indexing pipeline: загрузка документов, разбивка на чанки, embedding, сохранение в векторную БД
- Retrieval: перевод запроса в вектор, поиск ближайших соседей
- Generation: передача контекста + запрос в LLM
Стек для RAG-системы
| Компонент | Варианты |
|---|---|
| Embedding модель | OpenAI text-embedding-3-large, Cohere Embed v3, BGE-M3, E5-large, Nomic Embed |
| Векторная БД | Pinecone, Weaviate, Qdrant, ChromaDB, pgvector, Milvus |
| LLM | GPT-4o, Claude 3.5 Sonnet, Llama 3.1, Mistral |
| Оркестратор | LangChain, LlamaIndex, самописный |
| Reranker | Cohere Rerank, BGE-Reranker, FlashRank |
Пайплайн индексации
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Qdrant
from langchain_community.document_loaders import PyPDFDirectoryLoader
# Загрузка документов
loader = PyPDFDirectoryLoader("./docs/")
documents = loader.load()
# Разбивка на чанки
splitter = RecursiveCharacterTextSplitter(
chunk_size=512,
chunk_overlap=64,
separators=["\n\n", "\n", ".", " "],
)
chunks = splitter.split_documents(documents)
# Embedding и сохранение
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
vectorstore = Qdrant.from_documents(
chunks,
embeddings,
url="http://localhost:6333",
collection_name="corporate-docs",
force_recreate=True,
)
Пайплайн ответа на запрос
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import ChatPromptTemplate
template = """Ты — ассистент, отвечающий строго на основе предоставленного контекста.
Если ответ не содержится в контексте, скажи "Информация не найдена в базе знаний".
Всегда указывай источник (название документа и раздел).
Контекст:
{context}
Вопрос: {question}
Ответ:"""
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# Retrieval + Generation
retriever = vectorstore.as_retriever(
search_type="mmr", # Maximum Marginal Relevance — снижает дублирование
search_kwargs={"k": 5, "fetch_k": 20}
)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=retriever,
chain_type_kwargs={"prompt": prompt},
return_source_documents=True,
)
result = qa_chain.invoke({"query": "Какой срок гарантийного обслуживания?"})
Практический кейс: RAG для страховой компании
Задача: ассистент для обработки обращений клиентов — поиск по договорам страхования, правилам выплат, прецедентным решениям (12 000 документов, ~2M страниц).
Ключевые решения:
Embedding: BGE-M3 (многоязычный, хорошо работает на русском, бесплатный self-hosted). Размерность 1024.
Chunking: гибридная стратегия — структурные границы (разделы договора) вместо фиксированного размера. Размер чанка 200–600 токенов.
Reranking: CrossEncoder после векторного поиска. Top-50 кандидатов → Top-5 после rerank. +18% к faithfulness.
Метрики (RAGAS):
| Метрика | До rerank | После rerank |
|---|---|---|
| Context Precision | 0.68 | 0.84 |
| Context Recall | 0.71 | 0.79 |
| Faithfulness | 0.74 | 0.91 |
| Answer Relevancy | 0.81 | 0.89 |
Размер чанка: как выбирать
- Маленькие чанки (128–256 токенов): высокая точность retrieval, но могут не содержать полный контекст для ответа. Хорошо для FAQ и коротких фактов.
- Средние чанки (512–1024 токенов): баланс. Оптимум для большинства задач.
- Большие чанки (1024–2048 токенов): захватывают больше контекста, но ухудшают precision retrieval. Для документов с длинными взаимосвязанными секциями.
Parent Document Retriever — решение дилеммы: индексируем мелкие чанки для поиска, отдаём крупные в LLM.
Сроки разработки RAG-системы
- Прототип (базовый RAG): 1–2 недели
- Production-ready система с оценкой качества: 4–8 недель
- Расширенный RAG (hybrid search, reranking, evaluation): 8–14 недель







