Внедрение RAG для корпоративного AI-бота на сайте
Типичный AI-бот, обученный только на общих данных, не знает ваш продукт. Он выдумывает ответы — галлюцинирует. RAG (Retrieval-Augmented Generation) — архитектурный паттерн — решает эту проблему: бот находит релевантные фрагменты из вашей базы знаний (документация, FAQ, статьи) и формирует ответ строго по ним. Результат — точные, проверяемые ответы без вымысла. Наш опыт: более 5 лет разработки NLP-систем, 10+ внедрённых RAG-ботов.
Например, компания с 5000 страницами технической документации тратила 20 человеко-часов в неделю на ответы однотипных вопросов. После внедрения RAG-бота время сократилось до 2 часов, а точность ответов превысила 95%. Затраты на поддержку снизились вдвое — экономия составила более 1 млн рублей в год. Экономия бюджета на поддержку достигает 60%, а окупаемость проекта — в течение полугода. При этом бот использует только проверенные данные, исключая риск утечки.
Как работает RAG-система?
RAG состоит из нескольких компонентов:
- Knowledge base — источник данных: документация, FAQ, статьи базы знаний, страницы сайта, PDF-файлы, тикеты поддержки.
- Ingestion pipeline — процесс загрузки, разбивки на чанки и индексации документов.
- Vector store — база данных, хранящая эмбеддинги и обеспечивающая семантический поиск.
- Retrieval — по запросу пользователя находим топ-N релевантных чанков.
- Generation — отправляем найденные чанки + вопрос в LLM, получаем ответ.
Каждый этап настраивается индивидуально под ваш объём данных и требования к скорости.
Ingestion Pipeline
Разбивка документов на чанки — критичный этап. Слишком маленькие чанки теряют контекст, слишком большие — снижают точность поиска. Оптимально: 500–1000 токенов с перекрытием 100–200 токенов.
from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.document_loaders import ( WebBaseLoader, PyPDFLoader, UnstructuredMarkdownLoader ) def load_and_chunk_documents(sources: list[dict]) -> list: documents = [] for source in sources: if source["type"] == "url": loader = WebBaseLoader(source["path"]) elif source["type"] == "pdf": loader = PyPDFLoader(source["path"]) elif source["type"] == "markdown": loader = UnstructuredMarkdownLoader(source["path"]) docs = loader.load() documents.extend(docs) splitter = RecursiveCharacterTextSplitter( chunk_size=800, chunk_overlap=150, separators=["\n\n", "\n", ". ", " ", ""] ) return splitter.split_documents(documents) Эмбеддинги и векторное хранилище
Модели эмбеддингов:
-
text-embedding-3-small(OpenAI) — 1536 измерений, $0.02 за 1M токенов, отличное соотношение цены и качества -
text-embedding-3-large— 3072 измерений, лучше для сложных запросов -
multilingual-e5-large(локально, Hugging Face) — бесплатно, хорошо для русского языка
Векторные хранилища:
| Решение | Тип | Масштаб | Особенности |
|---|---|---|---|
| pgvector | PostgreSQL расширение | до 10M векторов | Знакомый SQL, транзакции |
| Qdrant | Self-hosted / Cloud | сотни миллионов | Фильтрация по payload |
| Weaviate | Self-hosted / Cloud | сотни миллионов | GraphQL API |
| Pinecone | SaaS | любой | Полностью управляемый |
| Chroma | In-process / Server | до 1M | Удобен для старта |
Для сайта со средней нагрузкой и базой до 100 000 документов — pgvector или Qdrant. Не нужно поднимать отдельный сервис.
import psycopg2 from pgvector.psycopg2 import register_vector import numpy as np def store_embeddings(chunks: list, embeddings: list[list[float]]): conn = psycopg2.connect(DATABASE_URL) register_vector(conn) cur = conn.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS documents ( id SERIAL PRIMARY KEY, content TEXT, embedding vector(1536), metadata JSONB, source_url TEXT, created_at TIMESTAMP DEFAULT NOW() ) """) cur.execute("CREATE INDEX IF NOT EXISTS documents_embedding_idx ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100)") for chunk, embedding in zip(chunks, embeddings): cur.execute( "INSERT INTO documents (content, embedding, metadata, source_url) VALUES (%s, %s, %s, %s)", (chunk.page_content, np.array(embedding), json.dumps(chunk.metadata), chunk.metadata.get("source", "")) ) conn.commit() Поиск: семантический и гибридный
Семантический поиск возвращает чанки по косинусному сходству эмбеддингов. Для точных запросов (артикулы, имена) он иногда промахивается — тогда подключаем гибридный поиск с полнотекстовым индексом (BM25).
def hybrid_search(query: str, top_k: int = 5) -> list[dict]: # Семантический поиск query_embedding = get_embedding(query) conn = psycopg2.connect(DATABASE_URL) register_vector(conn) cur = conn.cursor() cur.execute(""" SELECT content, source_url, metadata, 1 - (embedding <=> %s::vector) AS similarity FROM documents WHERE 1 - (embedding <=> %s::vector) > 0.75 ORDER BY embedding <=> %s::vector LIMIT %s """, (query_embedding, query_embedding, query_embedding, top_k * 2)) semantic_results = cur.fetchall() # Полнотекстовый поиск cur.execute(""" SELECT content, source_url, ts_rank(to_tsvector('russian', content), query) AS rank FROM documents, to_tsquery('russian', %s) query WHERE to_tsvector('russian', content) @@ query ORDER BY rank DESC LIMIT %s """, (prepare_ts_query(query), top_k * 2)) keyword_results = cur.fetchall() # Reciprocal Rank Fusion return reciprocal_rank_fusion(semantic_results, keyword_results, top_k) Generation: формирование ответа
from openai import OpenAI client = OpenAI() SYSTEM_PROMPT = """Ты помощник службы поддержки компании. Отвечай ТОЛЬКО на основе предоставленного контекста. Если ответа нет в контексте — честно скажи об этом. Не придумывай информацию. Указывай источник из контекста.""" def generate_answer(query: str, context_chunks: list[dict]) -> dict: context = "\n\n".join([ f"[Источник: {c['source']}]\n{c['content']}" for c in context_chunks ]) response = client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": f"Контекст:\n{context}\n\nВопрос: {query}"} ], temperature=0.1, max_tokens=800 ) sources = list({c["source"] for c in context_chunks if c.get("source")}) return { "answer": response.choices[0].message.content, "sources": sources, "chunks_used": len(context_chunks) } Re-ranking и оценка качества
Векторный поиск возвращает кандидатов по косинусному сходству, но не всегда самый семантически близкий чанк — самый полезный. Cross-encoder re-ranking переоценивает кандидатов с учётом вопроса, поднимая релевантные чанки в топ. Мы используем модель cross-encoder/ms-marco-MiniLM-L-6-v2 из библиотеки Sentence Transformers.
Метрики RAG-системы включают Faithfulness (не противоречит ли ответ контексту), Answer Relevance (отвечает ли на вопрос), Context Recall (все ли нужные факты найдены) и Context Precision (нет ли лишнего в контексте). Для оценки применяем RAGAS (open-source) и LangSmith (платный SaaS). Настроенный мониторинг гарантирует стабильное качество.
Обновление индекса
При изменении контента на сайте нужно пересчитать эмбеддинги. Стратегии:
- Полная переиндексация — раз в сутки, при объёме до 50 000 документов занимает 15–30 минут.
- Инкрементальная — при изменении страницы удаляем старые чанки по source_url, добавляем новые. Подходит для CMS с webhook на публикацию.
- Мягкое удаление — помечаем устаревшие чанки флагом, не удаляем немедленно. Позволяет откатиться при ошибке.
Сколько времени занимает внедрение RAG?
Сроки зависят от объёма данных и требований. Ориентировочные этапы:
| Этап | Срок |
|---|---|
| Ingestion pipeline + эмбеддинги + pgvector | 5–7 дней |
| Retrieval + базовая генерация | 3–4 дня |
| Гибридный поиск + re-ranking | 3–4 дня |
| Чат-интерфейс на сайте (виджет) | 4–5 дней |
| Инкрементальная переиндексация | 2–3 дня |
| Метрики качества + мониторинг | 3–4 дня |
Минимально рабочий RAG-бот с одним источником данных — 2 недели. Продуктовая система с несколькими источниками, гибридным поиском и мониторингом — 4–5 недель.
Что входит в работу
При заказе внедрения RAG вы получаете:
- Полноценный ingestion pipeline под ваши источники данных
- Векторное хранилище (pgvector или Qdrant)
- Семантический и гибридный поиск
- Генерацию ответов с указанием источников
- Re-ranking для повышения точности
- Интеграцию с сайтом (виджет чата)
- Документацию по архитектуре и настройке
- Обучение сотрудников работе с системой
- Гарантию 3 месяца на работу системы
Мы имеем опыт внедрения RAG для интернет-магазинов, корпоративных порталов и служб поддержки. Реализовали 10+ проектов.
Закажите внедрение RAG под ключ — свяжитесь с нами для оценки вашего проекта. Получите консультацию бесплатно.







