До основного вмісту

RAG на VDS: AI-відповіді за вашими документами

AI-агенти на VDS · 19.04.2026 · 4 хв читання
Ілюстрація до статті «RAG на VDS: AI-відповіді за вашими документами»

Що таке RAG?

RAG (Retrieval-Augmented Generation) — техніка, за якої LLM перед генерацією відповіді спочатку шукає релевантні фрагменти в базі знань. Це дозволяє моделі точно відповідати на запитання про ваші документи, не вимагаючи додаткового навчання.

Як працює RAG: 1) Документ розбивається на чанки → 2) Кожен чанк перетворюється на вектор → 3) Вектори зберігаються у векторній БД → 4) При запиті знаходяться схожі чанки → 5) LLM генерує відповідь із контекстом.

Компоненти RAG-системи

  • Завантажувачі документів — PDF, DOCX, TXT, веб-сторінки
  • Text Splitter — розбивка на чанки (500-1000 токенів)
  • Embedding модель — перетворення тексту у вектори
  • Векторна БД — Chroma, Qdrant, FAISS
  • LLM — генерація відповіді на основі знайденого контексту

Встановлення залежностей

pip install langchain langchain-ollama langchain-community
pip install chromadb pypdf sentence-transformers

Повний приклад RAG на Python

from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OllamaEmbeddings
from langchain_ollama import OllamaLLM
from langchain.chains import RetrievalQA

# Завантаження і розбиття документа
loader = PyPDFLoader("document.pdf")
docs = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(docs)

# Створення векторної бази
embeddings = OllamaEmbeddings(model="nomic-embed-text")
db = Chroma.from_documents(chunks, embeddings, persist_directory="./chroma_db")

# RAG-ланцюжок
llm = OllamaLLM(model="llama3.2")
qa = RetrievalQA.from_chain_type(llm=llm, retriever=db.as_retriever())
result = qa.invoke("Яка головна тема документа?")
print(result["result"])

Embedding моделі для Ollama

# Завантажити спеціалізовану модель для ембеддингів
ollama pull nomic-embed-text

# Або англійський варіант
ollama pull mxbai-embed-large
Розмір чанків: Занадто великі чанки (2000+ токенів) знижують точність пошуку. Занадто маленькі (100 токенів) втрачають контекст. Оптимально: 300-800 токенів з 10-15% перекриттям.

Часті помилки RAG-систем

Більшість проблем з RAG не в коді, а в якості добування — модель відповідає не з контексту, тому що контекст спочатку знайдено неправильно.

Модель відповідає повз контекст, хоча потрібний фрагмент є в базі

Часта причина — промпт не змушує модель спиратися саме на знайдені чанки: вона відповідає із загальних знань, якщо явно не вказати "відповідай лише на основі наведеного контексту, і якщо відповіді там немає — скажи, що не знаєш". Друга причина — retriever повертає замало чанків (k=1-2), і потрібний фрагмент просто не потрапив у вибірку.

Dimension mismatch під час додавання документів у Chroma

chromadb.errors.InvalidDimensionException: Embedding dimension 768 does not match collection dimensionality 1024

Ця помилка виникає, якщо в ту саму колекцію Chroma додавали ембеддинги, згенеровані різними моделями — у них різна розмірність вектора. Рішення — використовувати одну embedding-модель протягом усього життя колекції або створювати окрему колекцію при зміні моделі.

Chroma, Qdrant і FAISS: порівняння

Критерій Chroma Qdrant FAISS
Запуск Вбудований, без сервера Окремий сервер або Docker Бібліотека, без сервера
Персистентність із коробки Так Так Потрібно зберігати індекс вручну
Фільтрація за метаданими Базова Просунута Відсутня
Підходить для Прототипів і невеликих баз Продакшену з великим обсягом Максимальної швидкості пошуку в пам'яті

Коли RAG не підходить

  • Документів мало, і вони цілком вміщуються в контекстне вікно моделі — простіше передати весь текст у промпт, без векторної БД.
  • Дані оновлюються майже в реальному часі — доведеться постійно переіндексувати чанки, і свіжість відповіді все одно відставатиме.
  • Потрібні точні обчислення або агрегація по всіх документах одразу — RAG знаходить схожі фрагменти, а не рахує суми і не порівнює всі записи.
  • Питання користувачів вимагають міркувань по всій базі, а не по окремих фрагментах — тут ближче повнотекстовий аналіз або SQL-запит, а не пошук за векторами.

Перевірка якості пошуку

results = db.similarity_search_with_score("тестове питання з вашої бази", k=3)
for doc, score in results:
    print(score, doc.page_content[:100])

Запустіть пошук із заздалегідь відомим питанням, відповідь на яке точно є в документах, і перевірте, що потрібний чанк опинився серед перших за релевантністю. Якщо він є в базі, але не потрапляє в top-k, варто зменшити розмір чанка або збільшити k, перш ніж змінювати модель ембеддингів.

Ще один нюанс — оновлення документів у базі. Якщо вихідний файл змінився, просте повторне додавання чанків у ту саму колекцію Chroma створить дублікати, а не замінить старі версії. Перед повторною індексацією варто або видаляти чанки з попереднім ідентифікатором джерела, або створювати окрему колекцію на кожну версію документа і явно перемикати retriever на актуальну.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці