Czym jest RAG i dlaczego to ważne dla Twojej firmy
Wyobraź sobie nowego pracownika, który ma dostęp do całej dokumentacji firmowej i odpowiada na pytania klientów lub kolegów — ale zamiast szukać przez godziny, robi to w 3 sekundy. I nigdy nie zapomina żadnej procedury. To jest RAG.
RAG — Retrieval-Augmented Generation — to architektura, która łączy dwa komponenty:
- Retrieval (Wyszukiwanie) — semantyczne przeszukiwanie bazy dokumentów w celu znalezienia relevantnych fragmentów dla danego pytania
- Generation (Generowanie) — LLM generuje odpowiedź bazując TYLKO na znalezionych fragmentach, nie na swojej „pamięci" treningowej
Dlaczego to ważne? Klasyczne LLM (GPT-4, Claude) mają odcięcie wiedzy (knowledge cutoff) i halucynują fakty spoza danych treningowych. RAG rozwiązuje oba problemy: model zawsze odpowiada na podstawie aktualnych, Twoich własnych dokumentów.
RAG to różnica między „ChatGPT który zmyśla odpowiedź o Twojej firmie" a „asystentem który naprawdę przeczytał Twoje procedury".
LlamaIndex vs LangChain — który wybrać?
Oba są popularnymi frameworkami do budowania aplikacji LLM w Pythonie. Wybór zależy od przypadku użycia:
LlamaIndex — kiedy wybrać
- Budujesz system RAG na dokumentach (PDF, Word, Notion, Confluence)
- Potrzebujesz zaawansowanych strategii chunking i indeksowania
- Ważna jest jakość wyszukiwania (hybrid search, reranking)
- Chcesz prostej integracji z vector databases (Qdrant, Pinecone, Weaviate)
LangChain — kiedy wybrać
- Budujesz złożone, wieloetapowe pipelines agentowe
- Potrzebujesz integracji z wieloma narzędziami i API
- Chcesz gotowych „chains" do specyficznych zadań (summarization, extraction)
Dla typowego RAG na dokumentach firmowych: LlamaIndex jest prostszy i daje lepsze wyniki out-of-the-box. LangChain to dobry wybór gdy RAG jest tylko jednym elementem bardziej złożonego agenta.
Architektura systemu RAG z LlamaIndex
Kompletny system RAG składa się z dwóch faz:
Faza 1: Indeksowanie (jednorazowa)
Dokumenty (PDF/Word/HTML)
↓
Document Loader (LlamaIndex)
↓
Text Splitter — chunking na fragmenty (np. 512 tokenów)
↓
Embedding Model — zamiana tekstu na wektory numeryczne
↓
Vector Database — przechowywanie wektorów (Qdrant/Chroma)
↓
[Index gotowy]
Faza 2: Zapytanie (przy każdym pytaniu)
Pytanie użytkownika: "Jaki jest czas realizacji zamówień?"
↓
Embedding pytania (ten sam model co indeksowanie)
↓
Vector Search — znajdź top-K najsimilarniejszych fragmentów
↓
Reranker (opcjonalnie) — doprecyzuj ranking
↓
Prompt do LLM: "Odpowiedz na pytanie bazując na tych fragmentach: [kontekst]"
↓
Odpowiedź LLM z cytatami źródeł
Implementacja krok po kroku
Krok 1: Instalacja
pip install llama-index llama-index-vector-stores-qdrant
pip install llama-index-embeddings-openai
pip install qdrant-client python-dotenv
Krok 2: Załadowanie dokumentów
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core import Settings
from llama_index.embeddings.openai import OpenAIEmbedding
# Konfiguracja
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
# Wczytaj dokumenty z folderu
documents = SimpleDirectoryReader(
input_dir="./docs_firmowe",
recursive=True,
required_exts=[".pdf", ".docx", ".txt", ".md"]
).load_data()
print(f"Załadowano {len(documents)} dokumentów")
Krok 3: Indeksowanie w Qdrant
from llama_index.vector_stores.qdrant import QdrantVectorStore
from qdrant_client import QdrantClient
# Połącz z lokalnym Qdrant (lub Qdrant Cloud)
client = QdrantClient(host="localhost", port=6333)
vector_store = QdrantVectorStore(
client=client,
collection_name="dokumenty_firmowe"
)
# Zbuduj index
index = VectorStoreIndex.from_documents(
documents,
vector_store=vector_store,
show_progress=True
)
print("Indeksowanie zakończone!")
Krok 4: Zapytanie
from llama_index.llms.openai import OpenAI
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0)
query_engine = index.as_query_engine(
similarity_top_k=5, # pobierz top 5 fragmentów
response_mode="compact"
)
response = query_engine.query(
"Jaka jest polityka zwrotów dla klientów B2B?"
)
print(response.response)
print("\n--- Źródła ---")
for node in response.source_nodes:
print(f"- {node.metadata.get('file_name', 'nieznany')} (score: {node.score:.3f})")
Krok 5: Optymalizacja — Hybrid Search
Sam embedding (dense search) może nie wystarczyć dla specjalistycznej terminologii (nazwy produktów, numery katalogowe). Hybrid search łączy dense + sparse (BM25):
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.retrievers.bm25 import BM25Retriever
from llama_index.core.retrievers import QueryFusionRetriever
# Dense retriever
dense_retriever = VectorIndexRetriever(index=index, similarity_top_k=5)
# Sparse retriever (BM25)
bm25_retriever = BM25Retriever.from_defaults(
docstore=index.docstore,
similarity_top_k=5
)
# Fusion — łączy wyniki z obu
hybrid_retriever = QueryFusionRetriever(
retrievers=[dense_retriever, bm25_retriever],
similarity_top_k=5,
num_queries=1, # nie generuj parafraz
mode="reciprocal_rerank"
)
query_engine = RetrieverQueryEngine(retriever=hybrid_retriever)
Wariant lokalny — pełna kontrola nad danymi
Dla firm, które nie mogą wysyłać danych do OpenAI (RODO, poufne informacje handlowe), LlamaIndex w pełni obsługuje lokalne LLM przez Ollama:
Instalacja Ollama
# Na serwerze Linux
curl -fsSL https://ollama.ai/install.sh | sh
# Pobierz modele
ollama pull llama3.1:8b # LLM do generowania
ollama pull nomic-embed-text # model embeddings
Konfiguracja LlamaIndex z Ollama
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.ollama import OllamaEmbedding
Settings.llm = Ollama(
model="llama3.1:8b",
base_url="http://localhost:11434",
temperature=0,
request_timeout=120.0
)
Settings.embed_model = OllamaEmbedding(
model_name="nomic-embed-text",
base_url="http://localhost:11434"
)
# Reszta kodu identyczna jak w wariancie OpenAI
Wymagania sprzętowe dla Llama 3.1 8B: minimum 8GB RAM (CPU-only, wolno) lub GPU z 8GB VRAM (zalecane). Dla Mistral 7B wymagania identyczne.
Przejście do produkcji
Obsługa inkrementalnych aktualizacji
Gdy dodajesz nowe dokumenty, nie musisz przeindeksowywać wszystkiego:
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.node_parser import SentenceSplitter
pipeline = IngestionPipeline(
transformations=[
SentenceSplitter(chunk_size=512, chunk_overlap=50),
Settings.embed_model,
],
vector_store=vector_store,
)
# Dodaj nowe dokumenty
new_docs = SimpleDirectoryReader("./nowe_dokumenty").load_data()
pipeline.run(documents=new_docs)
Monitorowanie jakości odpowiedzi
Kluczowa metryka RAG to „faithfulness" — czy odpowiedź jest rzeczywiście zakorzeniona w dokumentach, czy model zaczyna wymyślać. Użyj ragas do ewaluacji:
pip install ragas
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision
# Zbuduj dataset testowy (pytania + oczekiwane odpowiedzi)
# Uruchom ewaluację
results = evaluate(
dataset=test_dataset,
metrics=[faithfulness, answer_relevancy, context_precision]
)
print(results)
Przypadki użycia dla polskich MŚP
1. Inteligentna baza wiedzy dla supportu
Indeksuj: procedury, FAQ, instrukcje produktów, historię ticketów. Efekt: agent supportu w 3 sekundy odpowiada na pytanie klienta cytując konkretną procedurę. Oszczędność: 2–4h dziennie na dziale obsługi klienta.
2. Asystent prawno-kontraktowy
Indeksuj: umowy, regulaminy, RODO, polityki wewnętrzne. Zapytanie: „Czy możemy udostępnić dane klienta X podwykonawcy Y zgodnie z naszą umową?" Odpowiedź z cytowaniem konkretnych paragrafów umowy.
Case Study: Firma logistyczna, 45 pracowników
Problem: kierowcy dzwonili do dyspozytorni z pytaniami o procedury (40+ telefonów dziennie). Rozwiązanie: RAG na 200 dokumentach operacyjnych + chatbot przez WhatsApp Business API. Efekt: 70% redukcja telefonów, czas wdrożenia 5 dni, koszt miesięczny 180 zł (OpenAI API).
3. Onboarding nowych pracowników
Indeksuj: handbook pracowniczy, procedury działu, historyczne e-maile z decyzjami, dokumentację systemów wewnętrznych. Nowy pracownik pyta: „Jak wygląda proces zatwierdzania faktur powyżej 10 000 zł?" — dostaje odpowiedź z linkiem do konkretnego dokumentu polityki.
4. Research i analiza ofert przetargowych
Indeksuj: specyfikacje SIWZ, warunki przetargu, profil firmy, referencje. Zapytanie: „Jakie wymagania z tego SIWZ możemy spełnić? Które są problematyczne?" — RAG porównuje wymagania z możliwościami firmy.
FAQ
Co to jest RAG (Retrieval-Augmented Generation)?
RAG to technika, która łączy wyszukiwanie semantyczne z generowaniem tekstu przez LLM. Zamiast odpowiadać z pamięci (gdzie LLM może halucynować), model najpierw wyszukuje relevantne fragmenty z Twoich dokumentów, a potem generuje odpowiedź opartą na tych faktach.
Czym LlamaIndex różni się od LangChain?
LlamaIndex jest wyspecjalizowany w indeksowaniu i wyszukiwaniu danych (RAG). LangChain jest bardziej ogólnym frameworkiem do budowania aplikacji LLM, ale ma mniej zaawansowane opcje indeksowania. Dla czystego RAG na dokumentach LlamaIndex jest zwykle lepszym wyborem.
Czy RAG można wdrożyć lokalnie bez wysyłania danych do OpenAI?
Tak. LlamaIndex obsługuje lokalne LLM przez Ollama (Llama 3, Mistral, Qwen) i lokalne embeddingi (nomic-embed-text, mxbai-embed). Możesz uruchomić kompletny stack RAG na własnym serwerze bez żadnych danych opuszczających firmową infrastrukturę.
Ile kosztuje wdrożenie RAG dla małej firmy?
Wariant chmurowy (OpenAI embeddings + GPT-4o-mini): 50–200 zł/miesiąc dla typowego użycia MŚP. Wariant lokalny (Ollama na dedykowanym serwerze): jednorazowy koszt sprzętu (GPU server: 8–20k zł) lub VPS z GPU (~500 zł/miesiąc). Hosting open-source vector DB (Qdrant, Chroma): bezpłatny self-hosted.