Впровадження RAG для корпоративного AI-бота на сайті
Типовий AI-бот, навчений лише на загальних даних, не знає ваш продукт. Він вигадує відповіді — галюцинує. RAG (Retrieval-Augmented Generation) — архітектурний патерн — вирішує цю проблему: бот знаходить релевантні фрагменти з вашої бази знань (документація, FAQ, статті) і формує відповідь строго по них. Результат — точні, перевірені відповіді без вигадок. Наш досвід: понад 5 років розробки NLP-систем, 10+ впроваджених RAG-ботів.
Наприклад, компанія з 5000 сторінками технічної документації витрачала 20 людино-годин на тиждень на відповіді однотипних питань. Після впровадження RAG-бота час скоротився до 2 годин, а точність відповідей перевищила 95%. При цьому бот використовує лише перевірені дані, виключаючи ризик витоку.
Як працює 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('ukrainian', content), query) AS rank
FROM documents, to_tsquery('ukrainian', %s) query
WHERE to_tsvector('ukrainian', 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 під ключ — зв'яжіться з нами для оцінки вашого проекту. Отримайте консультацію безкоштовно.







