RAG (Retrieval-Augmented Generation) to jedna z najważniejszych technik stosowanych w praktycznym wdrażaniu dużych modeli językowych (LLM). Rozwiązuje fundamentalny problem: LLM nie wiedzą wszystkiego, a to, co wiedzą, może być nieaktualne. RAG łączy potęgę generowania tekstu z precyzją wyszukiwania w dedykowanej bazie wiedzy.
Problem, który RAG rozwiązuje
LLM — takie jak ChatGPT, Claude czy Gemini — mają trzy fundamentalne ograniczenia:
- Data odcięcia — wiedza modelu kończy się w momencie zakończenia treningu. Model wytrenowany do stycznia 2025 nie wie o wydarzeniach z marca 2025
- Halucynacje — model „nie wie, czego nie wie" i generuje fałszywe informacje brzmiące wiarygodnie
- Brak wiedzy prywatnej — model nie ma dostępu do wewnętrznych dokumentów firmy, baz danych, regulaminów
RAG rozwiązuje wszystkie trzy problemy: model nie musi „pamiętać" informacji — może je wyszukać w zewnętrznej bazie wiedzy i wygenerować odpowiedź na ich podstawie.
Architektura RAG — jak to działa?
System RAG składa się z dwóch faz:
Faza 1: Retrieval (wyszukiwanie)
- Pytanie użytkownika jest zamieniane na embedding (wektor liczbowy) przez model embeddingowy
- Baza wiedzy — wcześniej przetworzone dokumenty, również zamienione na embeddingi i zapisane w bazie wektorowej
- Wyszukiwanie — system szuka dokumentów (lub fragmentów dokumentów) z embeddingami najbardziej podobnymi do embeddingu pytania (cosine similarity)
- Wynik — top-K najbardziej relevantnych fragmentów (typowo 3–10)
Faza 2: Augmented Generation (wzbogacone generowanie)
- Odnalezione fragmenty dokumentów są dołączane do promptu jako kontekst
- LLM generuje odpowiedź na podstawie dostarczonych fragmentów, nie wyłącznie z własnej pamięci
- Idealnie model cytuje źródła i odmawia odpowiedzi, gdy kontekst nie zawiera relevantnych informacji
Prompt RAG — typowa struktura
Kontekst:
[Fragment dokumentu 1]
[Fragment dokumentu 2]
[Fragment dokumentu 3]
Pytanie użytkownika: [pytanie]
Odpowiedz na pytanie WYŁĄCZNIE na podstawie podanego kontekstu.
Jeśli kontekst nie zawiera odpowiedzi, powiedz „Nie znalazłem tej informacji".
Kluczowe komponenty systemu RAG
1. Chunking — dzielenie dokumentów
Dokumenty źródłowe są zbyt długie, żeby podawać je w całości. Dzielimy je na fragmenty (chunki):
- Fixed-size chunks — fragmenty o stałej długości (np. 500 tokenów). Proste, ale mogą przeciąć zdania
- Recursive character splitting — dzielenie na akapity, potem zdania, zachowując granice semantyczne
- Semantic chunking — podział na fragmenty na podstawie zmian tematycznych (wymaga modelu embeddingowego)
- Overlap — nakładanie się fragmentów (np. 50 tokenów) zapobiegające utracie kontekstu na granicach
Rozmiar chunka to kluczowy hiperparametr: za duży = mało precyzyjne wyszukiwanie; za mały = utrata kontekstu.
2. Embeddingi — wektorowa reprezentacja tekstu
Model embeddingowy zamienia tekst na wektory liczbowe w przestrzeni wielowymiarowej (typowo 768–3072 wymiarów). Podobne semantycznie fragmenty mają bliskie wektory.
Popularne modele embeddingowe:
- OpenAI text-embedding-3-large — 3072 wymiary, wielojęzyczny
- Cohere Embed v3 — zoptymalizowany pod RAG
- BGE-M3 — open-source, wielojęzyczny
- E5-mistral-7b — duży, precyzyjny model embeddingowy
3. Baza wektorowa (Vector Database)
Specjalizowana baza danych przechowująca embeddingi i umożliwiająca szybkie wyszukiwanie najbliższych sąsiadów (ANN — Approximate Nearest Neighbors):
- Pinecone — w pełni zarządzana, SaaS
- Weaviate — open-source, hybrydowe wyszukiwanie
- ChromaDB — lekka, idealna do prototypów
- Qdrant — wydajna, open-source, napisana w Rust
- pgvector — rozszerzenie PostgreSQL — RAG bez dodatkowej bazy danych
4. Reranking — poprawianie jakości wyników
Wyszukiwanie embeddingowe (semantic search) to przybliżenie. Reranker — osobny model — ocenia dopasowanie każdego fragmentu do pytania i przesortowuje wyniki. ## GraphRAG i Agentic RAG (trendy 2024-2026)
GraphRAG (Microsoft Research, 2024) — kluczowa ewolucja RAG: ekstrakcja encji i relacji do grafu wiedzy (Neo4j), LLM nawiguje po grafie zamiast tylko przeglądać chunki. Lepszy dla pytań wymagających wieloetapowego rozumowania o relacjach. Open-source: LightRAG (2025) — lżejsza alternatywa.
Agentic RAG — agent decyduje kiedy i czego szukać, zamiast zawsze uruchamiać retrieval. Używa tool calling, może wielokrotnie iterować zapytania. Frameworki: LangGraph, AutoGen.
Rerankery
Modele rerankerów: Cohere Rerank 3 (2024), BGE-Reranker v2-m3, Voyage Rerank-2, Jina Reranker v2. Hybrid search (BM25 + vector) to standard produkcyjny 2025.
Pipeline: embedding search (top-20) → reranker (top-5) → LLM.
Zaawansowane wzorce RAG
RAG Fusion
Zamiast jednego zapytania generuje wiele wariantów pytania (query expansion) i wyszukuje dokumenty dla każdego. Wyniki są łączone (reciprocal rank fusion). Poprawia recall — zmniejsza ryzyko pominięcia relevantnego dokumentu.
Hypothetical Document Embedding (HyDE)
LLM generuje hipotetyczną odpowiedź na pytanie. Embedding tej odpowiedzi jest używany do wyszukiwania — zamiast embeddingu pytania. Intuicja: odpowiedź jest semantycznie bliższa dokumentowi źródłowemu niż pytanie.
Self-RAG
Model sam decyduje, czy potrzebuje zewnętrznej wiedzy. Jeśli pytanie dotyczy wiedzy ogólnej (np. „co to jest DNA?"), model odpowiada z pamięci. Jeśli specjalistycznej — uruchamia retrieval. Zmniejsza latencję i koszty.
Agentic RAG
Agent AI dynamicznie decyduje o strategii wyszukiwania: które źródła odpytać, ile dokumentów pobrać, czy potrzebne jest doprecyzowanie pytania. Korzysta z wielu baz wiedzy, API i narzędzi.
RAG vs. Fine-tuning — kiedy co?
| Kryterium | RAG | Fine-tuning |
|---|---|---|
| Aktualizacja wiedzy | Natychmiastowa (dodaj dokument) | Wymaga ponownego treningu |
| Koszt | Niski (embedding + baza wektorowa) | Wysoki (GPU, dane treningowe) |
| Halucynacje | Zmniejsza (grounding w źródłach) | Nie eliminuje |
| Styl odpowiedzi | Zależy od promptu | Zmienia wewnętrzne zachowanie modelu |
| Wiedza specjalistyczna | Dobra (jeśli jest w dokumentach) | Lepsza dla specjalistycznej terminologii |
| Skalowalność wiedzy | Miliony dokumentów | Ograniczona pojemnością modelu |
Reguła kciuka: RAG do wiedzy (co model powinien wiedzieć), fine-tuning do zachowania (jak model powinien odpowiadać).
Wyzwania i ograniczenia RAG
1. Jakość dokumentów = jakość odpowiedzi
„Garbage in, garbage out". Jeśli baza wiedzy zawiera nieaktualne, sprzeczne lub niekompletne informacje, RAG je powieli.
2. Okno kontekstu
Nawet z RAG kontekst jest ograniczony. Jeśli odpowiedź wymaga informacji rozproszonych po 50 dokumentach, a okno kontekstu mieści 10 fragmentów — model nie zobaczy pełnego obrazu.
3. Lost in the middle
Badania pokazują, że LLM lepiej wykorzystują informacje z początku i końca kontekstu, „gubiąc" informacje ze środka. Kolejność fragmentów w prompcie RAG ma znaczenie.
4. Wielojęzyczność
Wyszukiwanie cross-lingwalne (pytanie po polsku, dokumenty po angielsku) wymaga wielojęzycznych modeli embeddingowych. Jakość spada dla języków niedoreprezentowanych w danych treningowych.
End-to-end pipeline RAG w Pythonie
Kompletny przykład działającego systemu RAG z LangChain (najpopularniejsza biblioteka):
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
# 1. Załaduj dokumenty
docs = TextLoader("knowledge_base.txt").load()
# 2. Podziel na chunki (~500 znaków, 50 znaków overlap)
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", ". ", " "]
)
chunks = splitter.split_documents(docs)
# 3. Embed i zapisz w bazie wektorowej
vectorstore = Chroma.from_documents(
chunks,
OpenAIEmbeddings(model="text-embedding-3-small"),
persist_directory="./chroma_db"
)
# 4. Retrieve + Generate
qa = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4o-mini", temperature=0),
retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
return_source_documents=True
)
# 5. Pytanie → odpowiedź na podstawie dokumentów
result = qa({"query": "Jakie są kluczowe pojęcia uczenia ze wzmocnieniem?"})
print(result["result"])
for doc in result["source_documents"]:
print("\nŹródło:", doc.metadata)
Czysty Python — bez frameworka
Dla pełnej kontroli, RAG bez LangChain (bardziej production-ready, mniej magii):
from openai import OpenAI
import numpy as np
client = OpenAI()
# Embedduj dokumenty (raz)
def embed(texts: list[str]) -> np.ndarray:
res = client.embeddings.create(model="text-embedding-3-small", input=texts)
return np.array([d.embedding for d in res.data])
docs = ["Q-learning to algorytm RL...", "Transformery wykorzystują attention..."]
doc_embs = embed(docs)
# Retrieve
def retrieve(query: str, k: int = 3) -> list[str]:
q_emb = embed([query])[0]
sims = doc_embs @ q_emb / (np.linalg.norm(doc_embs, axis=1) * np.linalg.norm(q_emb))
top_idx = np.argsort(sims)[::-1][:k]
return [docs[i] for i in top_idx]
# Generate
def rag_answer(query: str) -> str:
context = "\n\n".join(retrieve(query))
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": f"Odpowiadaj na podstawie kontekstu:\n{context}"},
{"role": "user", "content": query}
]
)
return response.choices[0].message.content
print(rag_answer("Czym jest Q-learning?"))
Hybrydowe wyszukiwanie — semantyczne + keyword (BM25)
from rank_bm25 import BM25Okapi
import numpy as np
# Tokenizuj dla BM25
tokenized_docs = [d.lower().split() for d in docs]
bm25 = BM25Okapi(tokenized_docs)
def hybrid_retrieve(query: str, alpha: float = 0.5, k: int = 4) -> list[str]:
# Semantic scores
q_emb = embed([query])[0]
sem_scores = doc_embs @ q_emb / (np.linalg.norm(doc_embs, axis=1) * np.linalg.norm(q_emb))
# BM25 scores
bm_scores = np.array(bm25.get_scores(query.lower().split()))
# Normalize i połącz (alpha * semantyczne + (1-alpha) * BM25)
sem_norm = (sem_scores - sem_scores.min()) / (sem_scores.max() - sem_scores.min() + 1e-9)
bm_norm = (bm_scores - bm_scores.min()) / (bm_scores.max() - bm_scores.min() + 1e-9)
final = alpha * sem_norm + (1 - alpha) * bm_norm
top_idx = np.argsort(final)[::-1][:k]
return [docs[i] for i in top_idx]
Hybrydowe podejście (Reciprocal Rank Fusion, BM25 + embeddingi) jest standardem produkcyjnym — czysto semantyczne wyszukiwanie zawodzi przy zapytaniach z konkretnymi nazwami własnymi (numery wersji, kody błędów, nazwiska).
Podsumowanie
RAG to most między potęgą generatywną LLM a precyzją informacji specyficznych dla Twojej organizacji. Zamiast próbować „wpychać" wiedzę do modelu przez fine-tuning, RAG pozwala LLM korzystać z zewnętrznych źródeł w czasie rzeczywistym — jak człowiek korzysta z encyklopedii czy Google.
W praktyce wdrożeniowej RAG to nie „podłącz bazę i gotowe" — to system wymagający starannego doboru chunkingu, modeli embeddingowych, bazy wektorowej i promptów. Ale dobrze zaprojektowany RAG dramatycznie zmniejsza halucynacje, umożliwia aktualizację wiedzy bez ponownego treningu i otwiera drzwi do budowania specjalistycznych asystentów AI na własnych danych.