Подписывайтесь:

Блог AST-SoftPro

RAG-системы: как дать LLM доступ к вашим данным

12.06.2026 5 мин чтения

Современные большие языковые модели (LLM) демонстрируют впечатляющие способности к генерации текста, логическому рассуждению и пониманию контекста. Однако их знания ограничены датой последнего обучения, а в узкоспециализированных или корпоративных доменах они часто склонны к галлюцинациям. Именно поэтому Retrieval-Augmented Generation (RAG) стал индустриальным стандартом для интеграции внешних данных в AI-приложения. RAG позволяет динамически подгружать релевантные фрагменты из ваших документов, баз знаний или баз данных непосредственно во время инференса, что существенно повышает точность, актуальность и проверяемость ответов. В этой статье мы разберём архитектуру RAG-конвейера шаг за шагом, от подготовки данных до финальной генерации, с акцентом на практические аспекты реализации, выбор стека технологий и оптимизацию производительности. В компании AST-SOFT мы регулярно проектируем и внедряем подобные решения для enterprise-клиентов, поэтому в материале отражены не только теоретические основы, но и проверенные на практике подходы к построению отказоустойчивых и масштабируемых AI-систем.

Архитектура RAG: от пользовательского запроса к точному ответу

Классический RAG-пайплайн состоит из двух основных фаз: извлечения (Retrieval) и генерации (Generation). В фазе извлечения система анализирует входящий запрос пользователя, преобразует его в векторное представление и ищет наиболее похожие фрагменты в корпоративном хранилище данных. Найденные контекстные блоки затем объединяются с исходным промптом и передаются в LLM, которая формирует финальный ответ, опираясь исключительно на предоставленные факты. Такая архитектура решает сразу несколько критических задач: снижает вероятность галлюцинаций, позволяет быстро обновлять знания без переобучения модели и обеспечивает прозрачность источников информации.

В современных реализациях базовый векторный поиск часто дополняется гибридными стратегиями. Например, комбинация плотного векторного поиска (dense retrieval) и разреженного поиска по ключевым словам (sparse retrieval, BM25) позволяет улавливать как семантическое сходство, так и точные совпадения терминов. Дополнительно на этапе подготовки запроса применяются техники реформулирования (query expansion) или разбиения сложных запросов на подзапросы (subquery routing), что особенно важно для многошаговых аналитических задач.

Эмбеддинги: как превратить текст в математические векторы

Основа любого RAG-системы — качественный эмбеддинговый модельный слой. Эмбеддинги преобразуют текст (запрос или документ) в многомерный вектор, где геометрическая близость отражает семантическую схожесть. Выбор модели напрямую влияет на релевантность поиска, скорость инференса и стоимость хранения.

На текущий момент индустрия предлагает несколько категорий эмбеддингов:- Мультиязычные модели (например, bge-m3, multilingual-e5-large) — оптимальны для русскоязычных и смешанных корпоративных документов.- Специализированные модели (например, text-embedding-3-large от OpenAI, jina-embeddings-v3) — демонстрируют высокую точность на английских и технических текстах, но могут требовать адаптации для узких доменов.- Локальные open-source решения — позволяют запускать пайплайн полностью on-premise, что критично для работы с конфиденциальными данными в госструктурах и финансовом секторе.

Важные параметры при выборе:- Размерность вектора (от 384 до 1024+). Большие векторы точнее, но увеличивают нагрузку на память и задержки поиска.- Нормализация. L2-нормализация или косинусное расстояние должны быть согласованы между моделью и векторной БД.- Контекстное окно эмбеддера. Некоторые модели эффективно работают только с короткими фразами, другие — с абзацами.

Пример генерации эмбеддингов с использованием sentence-transformers:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer('BAAI/bge-m3')
# Поддержка мультиязычности и гибкой размерности
embeddings = model.encode(
    ["Как оформить отпуск в 2024 году?", "Политика компании в отношении удалёнки"],
    normalize_embeddings=True
)
print(embeddings.shape)  # (2, 1024)

Чанкинг документов: искусство нарезки без потери смысла

LLM и эмбеддинговые модели не работают с документами объёмом в сотни страниц напрямую. Необходим чанкинг — разбиение текста на фрагменты, которые сохраняют смысловую целостность и оптимальны для поиска. Неправильная нарезка приводит к потере контекста, дублированию информации или включению нерелевантного шума.

Основные стратегии чанкинга:- Фиксированный размер с перекрытием (fixed-size with overlap). Самый простой метод. Перекрытие (обычно 10-20% от размера чанка) предотвращает разрыв ключевых фраз на границах.- Рекурсивное разбиение (Recursive Character/Text Splitter). Делит текст по естественным разделителям: параграфы, предложения, символы переноса. Используется в LangChain как стандарт де-факто.- Семантический чанкинг. Использует LLM или модель классификации для определения границ абзацев по смыслу. Точнее, но требует дополнительных вычислительных ресурсов.

Рекомендуемые параметры для корпоративных документов:- chunk_size: 500–1500 токенов (зависит от контекстного окна LLM и длины эмбеддера)- chunk_overlap: 50–200 токенов- Сохранение метаданных (название файла, раздел, автор, дата) для последующей фильтрации и атрибуции.

Пример настройки сплиттера:

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separators=["\n\n", "\n", " ", ""]
)
chunks = splitter.split_documents(documents)

Векторные базы данных: выбор хранилища и индексации

Векторная база данных (Vector DB) отвечает за эффективное хранение, индексацию и поиск по эмбеддингам. При выборе хранилища учитываются объём данных, требования к задержкам, необходимость фильтрации по метаданным и инфраструктурные ограничения.

База данных Тип хранения Индексация Фильтрация Лицензия Особенности
FAISS In-memory / Disk IVF, HNSW, PQ Ограниченная MIT Высокая скорость, требует ручной настройки
Qdrant Disk / RAM HNSW Поддержка payload-фильтров Apache 2.0 Гибкая API, хорошая поддержка Rust/Python
Milvus Disk / RAM IVF, HNSW, DiskANN Полная поддержка SQL-подобных фильтров Apache 2.0 Масштабируемость, подходит для больших кластеров
Weaviate Disk / RAM HNSW, Flat GraphQL-фильтрация AGPLv3 / Enterprise Встроенные модули генерации и классификации
Pinecone Cloud-only Proprietary Метакатегории SaaS Минимум инфраструктуры, платный тариф

Для большинства корпоративных проектов рекомендуется использовать HNSW (Hierarchical Navigable Small World) индекс. Он обеспечивает баланс между скоростью поиска и точностью, позволяя настраивать параметры ef_construction и ef_search под конкретные требования к задержкам. При работе с большими объёмами данных (более 10 млн векторов) стоит рассматривать шардирование и репликацию, а также кэширование популярных запросов.

Ранкинг и реранкинг: фильтрация релевантности

Векторный поиск возвращает топ-N похожих чанков, но не гарантирует их семантической релевантности к конкретному запросу. Косинусное сходство может улавливать общие темы, но пропускать тонкие нюансы, особенно при сложных или многокомпонентных запросах. На этом этапе включается реранкинг — вторичная оценка найденных фрагментов с использованием cross-encoder моделей.

В отличие от bi-encoder (эмбеддинговой модели), cross-encoder оценивает пару (запрос, документ) одновременно, вычисляя точный балл релевантности. Это требует больше вычислений, но значительно повышает качество контекста, передаваемого в LLM. Популярные модели реранкинга: bge-reranker-v2-m3, jina-reranker-v2-base-multilingual, cross-encoder/ms-marco-MiniLM-L-6-v2.

Рабочий процесс реранкинга:1. Выполняется быстрый векторный поиск (top-50 или top-100).2. Модель реранкера оценивает каждую пару (query, chunk).3. Сортировка по убыванию балла и отсечение нерелевантных фрагментов (top-3 или top-5).4. Формирование финального контекста для генерации.

Пример интеграции реранкера:

from sentence_transformers import CrossEncoder

reranker = CrossEncoder('BAAI/bge-reranker-v2-m3')
query = "Какие требования к отчётности по 64-ФЗ?"
retrieved_chunks = ["...текст чанка 1...", "...текст чанка 2...", "...текст чанка 3..."]

pairs = [[query, chunk] for chunk in retrieved_chunks]
scores = reranker.predict(pairs)

# Сортировка и отбор топ-3
ranked = sorted(zip(retrieved_chunks, scores), key=lambda x: x[1], reverse=True)
final_context = [chunk for chunk, _ in ranked[:3]]

Практическая реализация конвейера на Python

Объединим рассмотренные компоненты в единый пайплайн. В продакшене важно разделять этапы подготовки данных (offline) и инференса (online), а также внедрить логирование, мониторинг задержек и fallback-механизмы на случай отсутствия релевантных результатов.

import qdrant_client
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

# 1. Инициализация компонентов
client = qdrant_client.QdrantClient(url="http://localhost:6333")
llm = ChatOpenAI(model="gpt-4o", temperature=0.1)

# 2. Шаблон промпта с инструкцией по использованию контекста
prompt_template = ChatPromptTemplate.from_messages([
    ("system", "Ты — корпоративный ассистент. Используй ТОЛЬКО предоставленные данные. Если информации недостаточно, скажи об этом явно."),
    ("human", "Контекст:\n{context}\n\nВопрос: {question}"),
])

# 3. Функция поиска и реранкинга (упрощённо)
def retrieve_and_rank(query, top_k=3):
    # Векторный поиск по Qdrant
    search_results = client.query_points(
        collection_name="docs",
        query_vector=embed_query(query),
        limit=10,
        query_filter={"key": "department", "match": {"value": "HR"}}
    )
    chunks = [hit.payload["text"] for hit in search_results.points]

    # Реранкинг
    pairs = [[query, chunk] for chunk in chunks]
    scores = reranker.predict(pairs)
    ranked_chunks = [chunk for _, chunk in sorted(zip(scores, chunks), reverse=True, key=lambda x: x[0])[:top_k]]
    return "\n---\n".join(ranked_chunks)

# 4. Цепочка генерации
chain = prompt_template | llm | StrOutputParser()

# 5. Инференс
question = "Как рассчитать компенсацию за неиспользованный отпуск?"
context = retrieve_and_rank(question)
response = chain.invoke({"context": context, "question": question})
print(response)

В реальных проектах AST-SOFT дополняет подобные конвейеры системами валидации ответов, кэшированием эмбеддингов, динамическим выбором LLM (маршрутизация между быстрыми и точными моделями) и интеграцией с внутренними ERP/CRM-системами через безопасные API-шлюзы.

Оптимизация производительности и типичные ошибки

Построение RAG-системы — это не только выбор моделей, но и тщательная настройка под бизнес-требования. Частые ошибки на старте:- Слишком большие чанки. Приводят к размытию фокуса эмбеддинга и увеличению токенов в промпте, что растёт стоимость и задержки.- Отсутствие реранкинга. Векторный поиск без вторичной оценки часто возвращает тематически близкие, но фактологически неверные фрагменты.- Игнорирование метаданных. Фильтрация по дате, отделу или статусу документа может сократить пространство поиска на 90%, ускоряя инференс и повышая точность.- Отсутствие мониторинга. Без метрик (latency, token usage, retrieval accuracy, user feedback) невозможно итеративно улучшать систему.

Для оптимизации рекомендуется:- Использовать квантование векторов (PQ, SQ) при работе с миллионами записей.- Внедрить асинхронный поиск и параллельную обработку запросов.- Настроить автоматическое обновление индекса при изменении источников данных (CDC, webhook-триггеры).- Применять фреймворки оценки качества, такие как RAGAS или DeepEval, для измерения точности извлечения и верности генерации.

Заключение

RAG-архитектура стала мостом между универсальными языковыми моделями и специфическими корпоративными знаниями. Успешная реализация зависит не от одной «волшебной» модели, а от грамотной настройки всего конвейера: от стратегии чанкинга и выбора эмбеддингов до оптимизации векторной БД и внедрения реранкинга. Каждая из этих составляющих влияет на точность, скорость и стоимость работы системы в продакшене.

В AST-SOFT мы проектируем RAG-решения, которые соответствуют enterprise-стандартам: обеспечивают безопасность данных, масштабируются под растущие объёмы документов и интегрируются с существующей IT-инфраструктурой компании. Если ваша задача — внедрить AI-ассистента, систему поиска по регламентам или аналитический чат-бот, опирающийся на внутренние документы, наша команда готова помочь с архитектурным проектированием, выбором стека и запуском пилотного проекта. RAG — это не просто технология, а инженерный процесс, требующий глубокого понимания как машинного обучения, так и бизнес-контекста заказчика.

Развитие направления идёт в сторону многомодальных RAG-систем, динамического контекстного окна и агентных архитектур, где извлечение данных сочетается с выполнением внешних действий (вызовы API, работа с базами, планирование задач). Следить за этими трендами и адаптировать их под реальные бизнес-процессы — ключ к созданию по-настоящему полезных AI-инструментов.

AI-Помощник