# RAG i LLM w 2026: Retrieval-Augmented Generation na rozmowach z data science > Retrieval-Augmented Generation (RAG) wyjaśniony pod kątem rozmów z data science w 2026 roku. Bazy wektorowe, strategie chunkingu, modele osadzeń, agentic RAG, Graph RAG i architektura pipeline'u gotowego do produkcji. - Published: 2026-06-06 - Updated: 2026-06-06 - Author: SharpSkill - Tags: RAG, retrieval augmented generation, LLM, data science, vector database, interview preparation, AI engineering - Reading time: 10 min --- Retrieval-Augmented Generation (RAG) stało się standardową architekturą do osadzania wyników modeli LLM w faktach i aktualnych danych. Na rozmowach z zakresu data science i inżynierii AI w 2026 roku pytania o RAG pojawiają się obok klasycznych tematów ML — sprawdzając zarówno myślenie w kategoriach projektowania systemów, jak i praktyczne umiejętności implementacyjne. > **Czym jest RAG w jednym zdaniu?** > > Retrieval-Augmented Generation łączy system wyszukiwania (przeszukiwanie wektorowe bazy wiedzy) z generatorem LLM, dzięki czemu model odpowiada na podstawie rzeczywistych dokumentów, a nie zapamiętanych danych treningowych. ## Jak działa pipeline RAG od początku do końca System RAG działa w dwóch fazach: **offline'owej fazie ingestii**, która buduje bazę wiedzy, oraz **online'owej fazie zapytań**, która pobiera odpowiedni kontekst i generuje odpowiedź. Podczas ingestii surowe dokumenty przechodzą przez czyszczenie, dzielenie na fragmenty (chunking) i osadzanie (embedding), zanim trafią do bazy wektorowej. Podczas wnioskowania zapytanie użytkownika podąża tą samą ścieżką osadzania, a wyszukiwanie najbliższych sąsiadów pobiera najbardziej trafne fragmenty. Fragmenty te stają się częścią promptu LLM, osadzając wygenerowaną odpowiedź w materiale źródłowym. ```python # rag_pipeline.py from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_community.vectorstores import Chroma from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough # Offline: ingest documents into the vector store def build_index(documents: list[str]) -> Chroma: splitter = RecursiveCharacterTextSplitter( chunk_size=512, # tokens per chunk chunk_overlap=64, # overlap preserves context at boundaries separators=["\n\n", "\n", ". ", " "] ) chunks = splitter.create_documents(documents) embeddings = OpenAIEmbeddings(model="text-embedding-3-large") return Chroma.from_documents(chunks, embeddings) # Online: retrieve + generate def query(vectorstore: Chroma, question: str) -> str: retriever = vectorstore.as_retriever( search_type="mmr", # Maximal Marginal Relevance for diversity search_kwargs={"k": 5, "fetch_k": 20} ) prompt = ChatPromptTemplate.from_template( "Answer based on this context only:\n{context}\n\nQuestion: {question}" ) chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | ChatOpenAI(model="gpt-4o", temperature=0) ) return chain.invoke(question).content ``` Ten pipeline obejmuje główną pętlę RAG: podziel, osadź, zapisz, pobierz, wygeneruj. Parametr `search_type="mmr"` zapewnia, że pobrane fragmenty są zarówno trafne, jak i zróżnicowane, redukując redundancję w oknie kontekstu. ## Strategie chunkingu, które naprawdę mają znaczenie Chunking wpływa na jakość wyszukiwania bardziej niż jakikolwiek inny komponent. Słaby chunking oznacza, że wyszukiwarka zwraca fragmenty, które albo nie mają kontekstu, albo rozcieńczają sygnał nieistotną treścią. W systemach produkcyjnych w 2026 roku dominują trzy podejścia do chunkingu: **Chunking o stałym rozmiarze** dzieli tekst po ustalonej liczbie tokenów (zwykle 256-512 tokenów) z zakładką (overlap). Prosty w implementacji, ale dzieli zdania i myśli w połowie. **Chunking semantyczny** wykrywa granice tematów, mierząc podobieństwo osadzeń między kolejnymi zdaniami. Gdy podobieństwo spada poniżej progu, zaczyna się nowy fragment. Każdy fragment niesie spójną myśl, a nie przypadkowy wycinek tekstu. **Późny chunking (late chunking)** najpierw stosuje model transformera do całego dokumentu, tworząc kontekstowe osadzenia tokenów, a dopiero potem dzieli na fragmenty. Zachowuje to zależności dalekiego zasięgu, które tradycyjny chunking niszczy. ```python # semantic_chunking.py import numpy as np from sentence_transformers import SentenceTransformer def semantic_chunk(text: str, threshold: float = 0.3) -> list[str]: """Split text where semantic similarity drops below threshold.""" model = SentenceTransformer("all-MiniLM-L6-v2") sentences = text.split(". ") embeddings = model.encode(sentences) chunks, current_chunk = [], [sentences[0]] for i in range(1, len(sentences)): # Cosine similarity between consecutive sentences sim = np.dot(embeddings[i-1], embeddings[i]) / ( np.linalg.norm(embeddings[i-1]) * np.linalg.norm(embeddings[i]) ) if sim < threshold: # topic shift detected chunks.append(". ".join(current_chunk)) current_chunk = [sentences[i]] else: current_chunk.append(sentences[i]) chunks.append(". ".join(current_chunk)) # final chunk return chunks ``` Kluczowy wniosek na rozmowę: rozmiar fragmentu to kompromis między precyzją a czułością (precision-recall). Małe fragmenty (100 tokenów) poprawiają precyzję wyszukiwania, ale fragmentują kontekst. Duże fragmenty (1000 tokenów) zachowują kontekst, ale rozcieńczają specyficzność osadzeń. Większość systemów produkcyjnych ląduje na 256-512 tokenach z 10-20% zakładką. ## Bazy wektorowe i modele osadzeń w produkcji Baza wektorowa przechowuje osadzenia i obsługuje szybkie przybliżone wyszukiwanie najbliższych sąsiadów (ANN). Dobór odpowiedniej kombinacji modelu osadzeń i bazy wektorowej bezpośrednio wpływa na opóźnienie i dokładność wyszukiwania. [Modele osadzeń](https://huggingface.co/spaces/mteb/leaderboard) w 2026 roku skupiły się wokół kilku wysokowydajnych opcji. `text-embedding-3-large` od OpenAI (3072 wymiary) oraz rozwiązania open-source, takie jak `bge-m3` od BAAI czy `embed-v4` od Cohere, oferują mocne wyszukiwanie wielojęzyczne. [Ranking MTEB](https://huggingface.co/spaces/mteb/leaderboard) pozostaje standardowym benchmarkiem do porównywania jakości osadzeń. Bazy wektorowe, takie jak [Pinecone](https://www.pinecone.io/), Weaviate, Milvus, Qdrant i pgvector, przyjmują różne kompromisy: | Baza | Indeksowanie | Zarządzana | Mocna strona | |----------|----------|---------|----------| | Pinecone | Własnościowe | Tak | Prostota, skalowanie serverless | | Weaviate | HNSW | Tak/własna | Wyszukiwanie hybrydowe (wektory + BM25) | | Milvus | IVF, HNSW | Tak/własna | Zbiory miliardowej skali | | Qdrant | HNSW | Tak/własna | Filtrowanie + przechowywanie payloadu | | pgvector | IVF, HNSW | Własna | Integracja z PostgreSQL | W kontekście rozmowy kwalifikacyjnej kluczowe jest zrozumienie algorytmu HNSW (Hierarchical Navigable Small World): buduje on wielowarstwowy graf, w którym każdy węzeł łączy się z najbliższymi sąsiadami, umożliwiając wyszukiwanie O(log n) kosztem większego zużycia pamięci. ## Wyszukiwanie hybrydowe: łączenie wyszukiwania gęstego i rzadkiego Czyste wyszukiwanie wektorowe zawodzi przy dokładnych dopasowaniach słów kluczowych i rzadkich terminach. Czyste wyszukiwanie leksykalne (BM25) pomija podobieństwo semantyczne. Wyszukiwanie hybrydowe łączy oba podejścia i w 2026 roku jest to domyślne rozwiązanie dla produkcyjnych systemów RAG. Standardowy wzorzec wykorzystuje [Reciprocal Rank Fusion (RRF)](https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf) do scalania uszeregowanych wyników z obu wyszukiwarek: ```python # hybrid_retrieval.py from rank_bm25 import BM25Okapi import numpy as np def reciprocal_rank_fusion( dense_results: list[str], sparse_results: list[str], k: int = 60 ) -> list[str]: """Merge dense (vector) and sparse (BM25) results using RRF.""" scores: dict[str, float] = {} for rank, doc_id in enumerate(dense_results): scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1) for rank, doc_id in enumerate(sparse_results): scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1) # Sort by combined RRF score, highest first return sorted(scores.keys(), key=lambda d: scores[d], reverse=True) ``` Wyszukiwanie hybrydowe rozwiązuje problem „niedopasowania słownictwa", gdy użytkownik pyta o „anulowanie subskrypcji", a właściwy dokument używa sformułowania „polityka rozwiązania konta". BM25 wychwytuje dokładne pokrycie terminów, podczas gdy wyszukiwanie wektorowe ujmuje relację semantyczną. ## Reranking: filtr drugiego etapu Wyszukiwanie zwraca kandydatów. Reranking sortuje ich według rzeczywistej trafności. Rerankery typu cross-encoder, takie jak [Cohere Rerank](https://cohere.com/rerank) czy `bge-reranker-v2.5-gemma2-lightweight`, oceniają każdą parę zapytanie-dokument wspólnie, dając znacznie dokładniejsze oceny trafności niż podobieństwo bi-enkodera. Dwuetapowy pipeline wyszukiwania — szeroki pierwszy etap (top 50-100 kandydatów przez wektory + BM25), a następnie precyzyjny reranking (top 5-10 do promptu) — jest standardem w produkcji. Utrzymuje to opóźnienie pod kontrolą: pierwszy etap używa szybkiego wyszukiwania ANN, a kosztowny cross-encoder przetwarza tylko mały zbiór kandydatów. > **Reranking — wskazówka na rozmowę** > > Cross-enkodery są dokładniejsze niż bi-enkodery, ponieważ przetwarzają zapytanie i dokument razem przez wszystkie warstwy transformera. Bi-enkodery osadzają je niezależnie, tracąc subtelne sygnały interakcji. Kompromisem jest szybkość: cross-enkoderów nie da się wstępnie zindeksować. ## Agentic RAG: poza jednorazowym wyszukiwaniem Naiwny RAG wyszukuje raz i generuje. [Agentic RAG](https://arxiv.org/abs/2501.09136) traktuje LLM jako agenta rozumującego, który decyduje, kiedy wyszukiwać, czego wyszukiwać i czy pobrany kontekst jest wystarczający. W 2026 roku agentic RAG jest dominującym wzorcem dla złożonych zapytań wymagających wieloetapowego rozumowania. Agent może: - **Samoocena**: Ocenić, czy pobrane dokumenty odpowiadają na pytanie - **Ponowne zapytanie**: Przeformułować zapytanie, jeśli początkowe wyniki są niewystarczające - **Routing**: Wybrać między różnymi źródłami wiedzy (baza wektorowa, baza SQL, API) - **Weryfikacja**: Skontrolować fakty w wielu pobranych fragmentach ```python # agentic_rag.py from langgraph.graph import StateGraph, END from typing import TypedDict class RAGState(TypedDict): question: str documents: list[str] generation: str retries: int def retrieve(state: RAGState) -> RAGState: """Retrieve documents from vector store.""" docs = vectorstore.similarity_search(state["question"], k=5) return {"documents": [d.page_content for d in docs]} def grade_documents(state: RAGState) -> str: """Decide if documents are relevant enough to answer.""" prompt = f"Are these documents relevant to: {state['question']}?\n" prompt += "\n".join(state["documents"]) relevance = llm.invoke(prompt) # returns 'relevant' or 'not_relevant' return "generate" if "relevant" in relevance.content else "rewrite" def rewrite_query(state: RAGState) -> RAGState: """Reformulate the query for better retrieval.""" new_query = llm.invoke( f"Rewrite this query for better search results: {state['question']}" ) return {"question": new_query.content, "retries": state["retries"] + 1} # Build the agent graph workflow = StateGraph(RAGState) workflow.add_node("retrieve", retrieve) workflow.add_node("grade", grade_documents) # conditional routing workflow.add_node("rewrite", rewrite_query) workflow.add_node("generate", generate_answer) workflow.set_entry_point("retrieve") workflow.add_edge("retrieve", "grade") workflow.add_conditional_edges("grade", grade_documents, {"generate": "generate", "rewrite": "rewrite"}) workflow.add_edge("rewrite", "retrieve") # retry loop workflow.add_edge("generate", END) ``` Ten wzorzec — wyszukaj, oceń, opcjonalnie przeformułuj i ponów — znany jest jako Corrective RAG (CRAG). Framework LangGraph modeluje przepływ pracy jako skierowany graf cykliczny z warunkowym rozgałęzianiem, co ułatwia dodawanie kroków weryfikacji, punktów kontrolnych z udziałem człowieka (human-in-the-loop) czy routingu wieloźródłowego. ## Graph RAG: wyszukiwanie wiedzy strukturalnej [Graph RAG](https://microsoft.github.io/graphrag/) wyodrębnia encje i relacje z dokumentów do grafu wiedzy, a następnie odpytuje zarówno graf, jak i bazę wektorową. Ta architektura redukuje halucynacje przy zapytaniach faktograficznych, osadzając odpowiedzi w jawnych relacjach między encjami zamiast w niestrukturalnym podobieństwie tekstu. Pipeline ingestii wyodrębnia trójki (podmiot, predykat, obiekt) z każdego fragmentu dokumentu. W czasie zapytania system identyfikuje istotne encje w pytaniu, przemierza graf wiedzy w poszukiwaniu powiązanych faktów i łączy kontekst pobrany z grafu z fragmentami pobranymi wektorowo. Graph RAG sprawdza się przy pytaniach wymagających rozumowania wieloetapowego (multi-hop), takich jak „Który zespół prowadzi projekt korzystający z frameworku wspomnianego w dokumencie X?" — zapytaniach wymagających łączenia faktów z wielu dokumentów. Czyste wyszukiwanie wektorowe ma tu trudności, ponieważ żaden pojedynczy fragment nie zawiera kompletnej odpowiedzi. > **Kompromis Graph RAG** > > Graph RAG znacząco poprawia dokładność faktograficzną (nawet o 40% mniej halucynacji przy zapytaniach bogatych w encje), ale wymaga dojrzałego pipeline'u ekstrakcji encji. Zaszumiona ekstrakcja tworzy zaszumiony graf, co może pogorszyć wyniki poniżej naiwnego RAG. ## Ocena systemów RAG: metryki, które mają znaczenie Ocena RAG dzieli się na metryki wyszukiwania i metryki generowania. Oba zestawy trzeba mierzyć niezależnie, aby diagnozować awarie. **Metryki wyszukiwania:** - **Recall@k**: Czy istotne dokumenty pojawiły się w top k wyników? - **MRR (Mean Reciprocal Rank)**: Jak wysoko uszeregowany jest pierwszy istotny wynik? - **NDCG**: Czy uszeregowanie odpowiada idealnej kolejności trafności? **Metryki generowania:** - **Wierność (faithfulness)**: Czy odpowiedź korzysta wyłącznie z informacji z pobranego kontekstu? (Mierzy halucynacje) - **Trafność odpowiedzi**: Czy odpowiedź odnosi się do pierwotnego pytania? - **Precyzja kontekstu**: Czy pobrane fragmenty są rzeczywiście wykorzystane w odpowiedzi? Frameworki takie jak [Ragas](https://docs.ragas.io/) i [DeepEval](https://docs.confident-ai.com/) automatyzują te oceny, wykorzystując wzorce LLM-jako-sędzia (LLM-as-judge). [Najczęstsze pytania na rozmowach z data science](/blog/data-science/top-25-data-science-interview-questions-2026) coraz częściej obejmują projektowanie oceny RAG — należy spodziewać się pytania o to, jak zmierzyć, czy system RAG działa poprawnie. ## Tryby awarii w produkcji i debugowanie Systemy RAG zawodzą w przewidywalny sposób. Znajomość tych wzorców jest niezbędna zarówno na rozmowach, jak i w rzeczywistym wdrożeniu. **Zanieczyszczenie okna kontekstu** następuje, gdy zbyt wiele pobranych fragmentów rozcieńcza istotny sygnał. LLM otrzymuje 10 fragmentów, ale tylko 2 zawierają przydatne informacje. Rozwiązanie: użyj rerankera do filtrowania i zmniejsz top-k w wyszukiwarce. **Artefakty chunkingu** powstają, gdy dzielenie o stałym rozmiarze przerywa zdania, tabele lub bloki kodu w połowie elementu. Pobrany fragment jest składniowo niekompletny i semantycznie bezużyteczny. Rozwiązuje to chunking semantyczny lub dzielenie świadome dokumentu (z poszanowaniem nagłówków, akapitów, bloków kodu). **Dryf osadzeń (embedding drift)** pojawia się, gdy model osadzeń zostaje zaktualizowany, ale baza wektorowa nadal zawiera osadzenia ze starego modelu. Zapytania zakodowane nowym modelem przeszukują przestrzeń wektorową zbudowaną przez stary, pogarszając jakość wyszukiwania. Rozwiązanie: ponownie osadź cały korpus po każdej zmianie modelu. **Przestarzałe indeksy** dostarczają nieaktualnych informacji, ponieważ pipeline ingestii pozostał w tyle za aktualizacjami dokumentów. W [systemach uczenia maszynowego](/blog/data-science/machine-learning-algorithms-explained) jest to analogiczne do rozbieżności trening-serwowanie (training-serving skew) — system wyszukiwania widzi inny rozkład danych niż ten istniejący w produkcji. ## Podsumowanie - RAG łączy wyszukiwanie (przeszukiwanie wektorowe bazy wiedzy) z generowaniem LLM, aby tworzyć osadzone w faktach odpowiedzi bez ponownego trenowania modelu - Strategia chunkingu ma największy wpływ na jakość wyszukiwania — chunking semantyczny i późny chunking przewyższają dzielenie o stałym rozmiarze w większości zastosowań - Wyszukiwanie hybrydowe (gęste wektory + rzadkie BM25) z Reciprocal Rank Fusion to produkcyjny standard, rozwiązujący problem niedopasowania słownictwa, z którym czyste wyszukiwanie wektorowe nie radzi sobie - Rerankery cross-encoder dodają warstwę precyzji po szerokim wyszukiwaniu, przetwarzając tylko mały zbiór kandydatów, aby utrzymać akceptowalne opóźnienie - Agentic RAG (wyszukaj, oceń, przeformułuj, ponów) i Graph RAG (ekstrakcja relacji encji) to dwa główne postępy architektoniczne 2026 roku, obsługujące złożone zapytania wieloetapowe, na których naiwny RAG zawodzi - Ocena musi oddzielać metryki wyszukiwania (Recall@k, MRR) od metryk generowania (wierność, trafność odpowiedzi), aby diagnozować, gdzie pipeline się załamuje - Najczęstsze awarie produkcyjne — zanieczyszczenie kontekstu, artefakty chunkingu, dryf osadzeń, przestarzałe indeksy — mają proste rozwiązania, gdy zostaną zidentyfikowane --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/data-science/rag-retrieval-augmented-generation-llm-data-science-interview-2026