RAG csővezetékek építése 2026-ban: Gyakorlati útmutató a visszakeresés-alapú generáláshoz

Gyakorlati útmutató modern RAG csővezetékek építéséhez: darabolási stratégiák, hibrid keresés, újrarangsorolás, GraphRAG, ágensalapú RAG és RAGAS kiértékelés — valódi Python kódpéldákkal.

Miért a RAG a vállalati AI gerince 2026-ban?

Ha egyetlen technológiát kellene megneveznem, ami 2026-ban a vállalati mesterséges intelligencia legfontosabb építőkövévé vált, az kétségkívül a RAG (Retrieval-Augmented Generation) lenne — vagyis a visszakeresés-alapú generálás. A koncepció meglepően egyszerű: ahelyett, hogy a nagy nyelvi modellekre (LLM) bíznánk, hogy kizárólag a betanított tudásukból válaszoljanak, egy külső tudásbázisból visszakeresett, releváns dokumentumokat adunk hozzá a prompthoz. Így a modell aktuális, hiteles és ellenőrizhető válaszokat generál.

A RAG nem tegnap született ötlet — a Meta AI kutatói már 2020-ban publikálták az alapkoncepcióját —, de igazán 2026-ra ért be. A vállalatok végre rájöttek, hogy a teljes modell-finomhangolás (fine-tuning) drága, lassú, és a legtöbb esetben egyszerűen felesleges. Eközben egy jól felépített RAG csővezeték a költségek töredékéért biztosítja, hogy az LLM a cég saját adataiból, belső dokumentumaiból és valós idejű információkból dolgozzon. A Gartner elemzései szerint 2026-ban a vállalati AI-alkalmazások több mint 60%-a használ valamilyen RAG-komponenst, és ez az arány folyamatosan nő.

De mi tette a RAG-ot ennyire megkerülhetetlenné? Három fő tényező:

  • Hallucináció csökkentése: A RAG drámaian csökkenti az LLM-ek által generált hamis vagy kitalált információk arányát, mivel a válaszokat tényleges dokumentumokra alapozza.
  • Adatfrissesség: Míg egy betanított modell tudása a tanítási adatok lezárásakor „megfagy", a RAG rendszer mindig a legfrissebb információkat képes felhasználni.
  • Költséghatékonyság: Egy RAG csővezeték felépítése és karbantartása nagyságrendekkel olcsóbb, mint egy teljes modell újratanítása saját adatokon.

Ebben a cikkben végigmegyünk a modern RAG csővezetékek teljes építési folyamatán — az adatfeldolgozástól a vektoros adatbázisokon át a haladó visszakeresési technikákig, a kiértékelésig és a termelési környezetbe való átvitelig. Gyakorlati kódpéldákkal és 2026-os best practice-ekkel dolgozunk, szóval nem csak az elméletet fogod érteni, hanem azonnal alkalmazni is tudod majd.

A RAG csővezeték anatómiája: az öt alapvető réteg

Egy termelési szintű RAG rendszer nem egyszerűen „beágyazás + vektoros keresés + LLM hívás". Sokan gondolják így — és aztán csodálkoznak, hogy a prototípus miért nem működik élesben. A modern architektúra valójában öt jól elkülöníthető rétegből áll, amelyek mindegyike optimalizálható és cserélhető:

1. Adatfeldolgozás és betöltés (Ingestion)

Az első lépés a nyers adatok összegyűjtése és előkészítése. Ide tartozik a PDF-ek, Word-dokumentumok, weblapok, Confluence-oldalak, Slack-üzenetek, adatbázis-rekordok és egyéb forrásokból való adatkinyerés. A modern keretrendszerek — mint a LlamaIndex és a LangChain — több száz adatforrás-csatlakozóval (connector) rendelkeznek, szóval a legtöbb formátumot natívan kezelik.

A feldolgozás során eltávolítjuk a felesleges formázást, egységesítjük a kódolást, kinyerjük a metaadatokat (szerző, dátum, dokumentumtípus, hozzáférési szint), és felkészítjük a szöveget a darabolásra.

2. Darabolás és indexelés (Chunking & Indexing)

A dokumentumokat kisebb, kezelhető darabokra (chunk) kell bontani, majd ezeket vektoros beágyazásokká (embedding) alakítani és vektoros adatbázisba tölteni. A darabolási stratégia kritikusan fontos — őszintén szólva, ez az a pont, ahol a legtöbb RAG rendszer sikerül vagy megbukik.

3. Lekérdezés-transzformáció (Query Transformation)

A felhasználói kérdés ritkán optimális a visszakereséshez. (Gondolj csak bele, hányszor írsz te magad pontatlan keresőkifejezést a Google-be.) A lekérdezés-transzformáció átfogalmazza, kiegészíti vagy részekre bontja a kérdést, hogy a lehető legjobb találatokat kapjuk vissza.

4. Visszakeresés és újrarangsorolás (Retrieval & Reranking)

A vektoros adatbázisból visszakeresett dokumentumrészleteket relevancia szerint újrarangsoroljuk, szűrjük, és a legjobbakat továbbítjuk az LLM-nek.

5. Generálás és kiértékelés (Generation & Evaluation)

Az LLM a visszakeresett kontextus alapján generálja a választ, majd a rendszer kiértékeli a válasz minőségét, hűségét és relevanciáját. Ez az utolsó lépés sokszor elsikkad, pedig a rendszeres kiértékelés nélkül nem tudjuk, hogy a csővezetékünk valóban jól működik-e.

Darabolási stratégiák: a RAG rendszer alapköve

A darabolás (chunking) a RAG csővezeték egyik legkritikusabb lépése. Rossz darabolási stratégiával a legjobb beágyazási modell és a legerősebb LLM is gyenge válaszokat fog produkálni — hidd el, személyesen megtapasztaltam, milyen frusztráló, amikor a rendszer mindig „mellébeszél", mert a darabolás nem megfelelő. Nézzük a 2026-ban bevált megközelítéseket.

Rögzített méretű darabolás

A legegyszerűbb módszer: fix számú token vagy karakter mentén vágjuk a szöveget, átfedéssel (overlap). Gyors és egyszerű, de van egy nagy hátránya — nem tartja tiszteletben a szöveg szemantikai határait. Simán elvághat egy bekezdés közepén.

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=50,
    separators=["\n\n", "\n", ". ", " ", ""]
)

chunks = splitter.split_text(document_text)
print(f"Dokumentum {len(chunks)} darabra bontva")

Szemantikai darabolás

Ez már a 2026-os best practice. A lényeg: a szöveget szemantikai egységek mentén daraboljuk, beágyazási hasonlóság alapján. Ahol a szomszédos mondatok beágyazása között nagy az „ugrás" (alacsony koszinusz-hasonlóság), ott húzzuk meg a határt. Az eredmény? Minden darab koherens, önálló jelentéssel bíró egységet alkot.

from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(model="text-embedding-3-large")

semantic_splitter = SemanticChunker(
    embeddings=embeddings,
    breakpoint_threshold_type="percentile",
    breakpoint_threshold_amount=90
)

semantic_chunks = semantic_splitter.split_text(document_text)
print(f"Szemantikai darabolás: {len(semantic_chunks)} darab")

Szülő-dokumentum stratégia (Parent Retrieval)

Ez a megközelítés két szinten dolgozik, és őszintén szólva az egyik személyes kedvencem. Kis méretű darabokat használ a visszakereséshez (mert a kis darabok pontosabb beágyazásokat adnak), de a szülő-dokumentumot — a nagyobb kontextust — küldi az LLM-nek. Így a visszakeresés precíz, miközben az LLM-nek elegendő kontextusa van a válaszhoz.

from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

# Vektortár a kis darabok számára
vectorstore = Chroma(
    collection_name="child_chunks",
    embedding_function=OpenAIEmbeddings(model="text-embedding-3-large")
)

# Memória-tár a szülő-dokumentumok számára
docstore = InMemoryStore()

# Két szintű daraboló
from langchain.text_splitter import RecursiveCharacterTextSplitter

child_splitter = RecursiveCharacterTextSplitter(chunk_size=200)
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=1000)

retriever = ParentDocumentRetriever(
    vectorstore=vectorstore,
    docstore=docstore,
    child_splitter=child_splitter,
    parent_splitter=parent_splitter,
)

# Dokumentumok betöltése
retriever.add_documents(documents)

# Keresés: kis darab alapján keres, szülő-dokumentumot ad vissza
results = retriever.invoke("Mi a RAG rendszer előnye?")

Vektoros adatbázisok: melyiket válaszd 2026-ban?

A vektoros adatbázis a RAG csővezeték központi komponense — itt tároljuk a dokumentum-beágyazásokat, és innen keressük vissza a releváns darabokat. 2026-ban a piac meglehetősen érett, és szerencsére több kiváló megoldás közül válogathatunk.

A főbb szereplők összehasonlítása

  • Chroma: Nyílt forráskódú, könnyűsúlyú, fejlesztőbarát. Ideális prototípusokhoz és kisebb alkalmazásokhoz. Natív Python integráció, egyszerű API.
  • Pinecone: Teljes körűen menedzselt felhőszolgáltatás. Kiváló skálázhatóság, beépített metaadat-szűrés. Termelési környezetben az egyik legmegbízhatóbb választás.
  • Weaviate: Nyílt forráskódú, hibrid keresést (vektor + kulcsszó) natívan támogat. Beépített GraphQL API, moduláris architektúra.
  • Qdrant: Rust nyelven írt, rendkívül gyors vektoros keresés. Kiváló szűrési képességek, memóriába térképezett (mmap) indexek a nagy teljesítményért.
  • Milvus: Nagyvállalati szintű, elosztott rendszer milliárdos vektormennyiségekhez. GPU-gyorsítás, többféle indexelési algoritmus.
  • pgvector (PostgreSQL): Ha már PostgreSQL-t használsz, ez a legkézenfekvőbb út — közvetlenül a meglévő adatbázisodba integrálható. A skálázhatósága korlátozott, de sok projekt számára bőven elegendő.

Szóval melyiket válaszd? Prototípushoz a Chroma vagy pgvector tökéletes. Termelési környezetben a Pinecone vagy Qdrant a legnépszerűbb, nagyvállalati szinten pedig a Milvus vagy Weaviate vezet. A lényeg: ne a hype alapján válassz, hanem az adott felhasználási eset alapján.

Példa: Chroma vektortár felépítése

import chromadb
from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction

# Kliens inicializálás (perzisztens tárolás)
client = chromadb.PersistentClient(path="./chroma_db")

# Beágyazási függvény
embedding_fn = OpenAIEmbeddingFunction(
    api_key="sk-...",
    model_name="text-embedding-3-large"
)

# Kollekció létrehozása
collection = client.get_or_create_collection(
    name="tudazbazis",
    embedding_function=embedding_fn,
    metadata={"hnsw:space": "cosine"}
)

# Dokumentumok hozzáadása metaadatokkal
collection.add(
    documents=["A RAG rendszer visszakeresés alapján generál...",
               "A vektoros adatbázisok beágyazásokat tárolnak..."],
    metadatas=[{"forras": "belso_wiki", "datum": "2026-02-15"},
               {"forras": "technikai_dok", "datum": "2026-02-10"}],
    ids=["doc_001", "doc_002"]
)

# Lekérdezés metaadat-szűréssel
results = collection.query(
    query_texts=["Hogyan működik a visszakeresés?"],
    n_results=5,
    where={"forras": "belso_wiki"}
)

for doc, score in zip(results["documents"][0], results["distances"][0]):
    print(f"[Relevancia: {1 - score:.3f}] {doc[:80]}...")

Hibrid keresés: amikor a vektor és a kulcsszó együtt erősebb

A 2026-os termelési RAG rendszerek egyik legfontosabb tanulsága: a kizárólag vektoros keresés nem elég. A sűrű (dense) vektoros beágyazások kiválóak a szemantikai hasonlóság megragadásában — „pénzügyi eredmények" kérdésre simán megtalálják a „negyedéves bevétel"-ről szóló szövegrészt. De specifikus kulcsszavaknál, kódoknál, termékazonosítóknál vagy tulajdonneveknél? Ott a hagyományos kulcsszavas keresés (BM25) sokkal pontosabb.

A hibrid keresés a két módszert kombinálja: futtatja a sűrű vektoros keresést és a ritka (sparse) BM25 keresést is, majd az eredményeket egyesíti. A gyakorlati mérések szerint ez 18-22%-kal javítja a visszakeresés pontosságát a különálló módszerekhez képest. Ez nem elhanyagolható szám.

from langchain_community.retrievers import BM25Retriever
from langchain.retrievers import EnsembleRetriever
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

# Sűrű (vektoros) visszakereső
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=OpenAIEmbeddings(model="text-embedding-3-large")
)
dense_retriever = vectorstore.as_retriever(search_kwargs={"k": 10})

# Ritka (BM25 kulcsszavas) visszakereső
sparse_retriever = BM25Retriever.from_documents(chunks, k=10)

# Hibrid kombináció: 60% vektor, 40% kulcsszó
hybrid_retriever = EnsembleRetriever(
    retrievers=[dense_retriever, sparse_retriever],
    weights=[0.6, 0.4]
)

# Lekérdezés a hibrid visszakeresővel
results = hybrid_retriever.invoke("Milyen előnyei vannak a RAG-nak?")
print(f"Visszakeresett darabok száma: {len(results)}")

Újrarangsorolás: a relevancia finomhangolása

A visszakeresés után jön a következő kritikus lépés: az újrarangsorolás (reranking). Az ötlet egyszerű — az első visszakeresési fázisban szándékosan több darabot kérünk le (mondjuk a top-20-at), majd egy cross-encoder modellel újrarangsoroljuk őket, és csak a legjobbakat (a top-5-öt) küldjük az LLM-nek.

De miért van erre szükség? A bi-encoder (beágyazási) modellek külön-külön dolgozzák fel a kérdést és a dokumentumot, majd koszinusz-hasonlósággal hasonlítják össze. Ez gyors, de nem mindig pontos. A cross-encoder ezzel szemben a kérdést és a dokumentumot együtt dolgozza fel egy transzformer modellben, ami jóval finomabb relevancia-értékelést tesz lehetővé. Persze lassabb is — ezért nem használjuk az első szűrésre, csak a szűkített listán.

from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank

# Cohere reranker inicializálása
reranker = CohereRerank(
    model="rerank-v3.5",
    top_n=5
)

# Kontextuális tömörítéssel kombinált visszakereső
compression_retriever = ContextualCompressionRetriever(
    base_compressor=reranker,
    base_retriever=hybrid_retriever  # Az előző hibrid visszakereső
)

# Lekérdezés újrarangsorolással
reranked_results = compression_retriever.invoke(
    "Milyen kihívásai vannak a RAG termelési környezetben?"
)

for i, doc in enumerate(reranked_results):
    print(f"#{i+1}: {doc.page_content[:100]}...")
    print(f"    Relevancia: {doc.metadata.get('relevance_score', 'N/A')}")
    print()

Lekérdezés-transzformáció: az okos kérdésfeltevés művészete

A valós felhasználók ritkán fogalmazzák meg a kérdéseiket úgy, ahogy az a visszakeresés szempontjából optimális lenne. (Kézen fogva tudom végigvezetni ezen, mert eleget láttam már ilyet.) Egy rövid, homályos vagy túl összetett kérdés gyenge visszakeresési eredményekhez vezet — teljesen mindegy, milyen remek a beágyazási modellünk. A lekérdezés-transzformáció három fő technikával operál:

Lekérdezés-átfogalmazás (Query Rewriting)

Az LLM-mel átfogalmaztatjuk a kérdést, domain-specifikus kifejezéseket használva. Például a „Miért nem megy?" kérdésből „Milyen hibák léphetnek fel az autentikációs folyamat során?" lesz. Óriási különbség a visszakeresési találatok minőségében.

Lekérdezés-bővítés (Query Augmentation)

Rövid kérdésekhez kontextust adunk: az LLM kiegészíti a kérdést háttérinformációkkal, szinonimákkal és kapcsolódó fogalmakkal.

Lekérdezés-felbontás (Query Decomposition)

Komplex, többrészes kérdéseket al-kérdésekre bontunk. Minden al-kérdés külön megy át a RAG csővezetéken, és az eredményeket a végén egyesítjük. Ez különösen a többlépéses érvelést (multi-hop reasoning) igénylő kérdéseknél hatékony.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

llm = ChatOpenAI(model="gpt-4o", temperature=0)

# Lekérdezés-felbontás: komplex kérdés al-kérdésekre bontása
decomposition_prompt = ChatPromptTemplate.from_messages([
    ("system", """Tapasztalt kutatási asszisztens vagy. A felhasználó
    komplex kérdését bontsd 2-4 egyszerű, önálló al-kérdésre,
    amelyek együtt lefedik az eredeti kérdést.

    Formátum: Minden al-kérdést új sorba írj, sorszámozva."""),
    ("human", "{question}")
])

chain = decomposition_prompt | llm

response = chain.invoke({
    "question": "Hogyan építhetek termelési szintű RAG rendszert, "
                "ami hibrid keresést használ és képes valós idejű "
                "adatfrissítésre nagy dokumentummennyiség mellett?"
})

print("Al-kérdések:")
print(response.content)

HyDE: hipotetikus dokumentum-beágyazás

A HyDE (Hypothetical Document Embeddings) az egyik legelegánsabb trükk a RAG eszköztárban. Ahelyett, hogy közvetlenül a kérdést ágyaznánk be és keresnénk vele, az LLM-mel generáltatunk egy hipotetikus választ, majd azt ágyazzuk be és azzal keresünk. Miért? Mert a beágyazási tér gyakran jobban reprezentálja a válaszokat, mint a kérdéseket, így a hipotetikus válasz beágyazása közelebb áll a tényleges releváns dokumentumokéhoz.

Amikor először hallottam erről a technikáról, kicsit „varázslat"-nak tűnt — de a gyakorlatban meglepően jól működik.

from langchain.chains import HypotheticalDocumentEmbedder
from langchain_openai import OpenAIEmbeddings, ChatOpenAI

# HyDE beágyazó létrehozása
hyde_embeddings = HypotheticalDocumentEmbedder.from_llm(
    llm=ChatOpenAI(model="gpt-4o-mini", temperature=0.3),
    base_embeddings=OpenAIEmbeddings(model="text-embedding-3-large"),
    prompt_key="web_search"  # Beépített prompt sablon
)

# Használat a vektortárral
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=hyde_embeddings
)

# Keresés HyDE-dal: a kérdésből előbb hipotetikus dokumentumot generál
results = vectorstore.similarity_search(
    "Milyen vektoros adatbázist válasszak termelési környezetbe?",
    k=5
)

GraphRAG: tudásgráf alapú visszakeresés

2026 egyik legizgalmasabb fejleménye a GraphRAG térnyerése. A hagyományos, kizárólag vektoros RAG-nak van egy alapvető korlátja: az információkat izolált darabokként kezeli, és egyszerűen nem „látja" az entitások közötti kapcsolatokat és összefüggéseket. A GraphRAG erre ad választ: a dokumentumokból tudásgráfot (knowledge graph) épít, amely az entitásokat és a köztük lévő relációkat strukturáltan tárolja.

A Microsoft GraphRAG kutatócsapata 2024-ben nyílt forráskódúvá tette a rendszert, és azóta a közösség folyamatosan fejleszti. Mikor érdemes bevetni a GraphRAG-ot?

  • Többlépéses érvelés szükséges: „Hogyan hat az X policy a Y osztály Z projektjére?"
  • Kapcsolat-alapú kérdések merülnek fel: „Milyen kapcsolat van A és B termék között?"
  • Összefoglaló jellegű kérdések: „Mi a fő téma az összes dokumentumban?"

A legelterjedtebb megközelítés a hibrid Graph + Vector RAG: a vektoros keresés adja az első jelölteket, a gráf-bejárás pedig kiterjeszti a kontextust a kapcsolódó entitásokkal és relációkkal. A Neo4j gráf-adatbázis vált a de facto szabvánnyá ezen a téren, mivel egyszerre támogatja a gráf-lekérdezéseket és a vektoros keresést.

from langchain_community.graphs import Neo4jGraph
from langchain_openai import ChatOpenAI
from langchain.chains import GraphCypherQAChain

# Neo4j kapcsolat
graph = Neo4jGraph(
    url="bolt://localhost:7687",
    username="neo4j",
    password="password"
)

# Gráf séma lekérdezése
print(graph.schema)

# GraphRAG lánc: természetes nyelvű kérdésből Cypher lekérdezést generál
chain = GraphCypherQAChain.from_llm(
    llm=ChatOpenAI(model="gpt-4o", temperature=0),
    graph=graph,
    verbose=True,
    allow_dangerous_requests=True
)

# Kapcsolat-alapú kérdés
response = chain.invoke({
    "query": "Mely projektekhez kapcsolódik az AI-stratégia "
             "dokumentum, és kik a felelős személyek?"
})

print(response["result"])

Ágensalapú RAG: az intelligens visszakeresés

2026 egyik legfontosabb paradigmaváltása az ágensalapú RAG (Agentic RAG) előretörése. A hagyományos RAG egyetlen lövésből (one-shot) dolgozik: visszakeres, generál, kész. Az ágensalapú RAG ezzel szemben tervezést, reflexiót és iterációt épít a folyamatba. Az ágens képes felülbírálni a visszakeresési eredményeket, újrapróbálni más stratégiával, sőt akár több tudásbázist is bevonni egyszerre.

A CRAG (Corrective RAG) egy konkrét implementáció, ami különösen jól működik a gyakorlatban. Mielőtt az LLM generálna, a rendszer megvizsgálja, hogy a visszakeresett darabok valóban relevánsak-e. Ha nem eléggé, automatikusan újabb visszakeresést indít szigorúbb szűrőkkel, vagy teljesen más forráshoz fordul. Ez a „beépített minőségellenőrzés" drámaian csökkenti a hallucinációk arányát.

Lássunk egy ágensalapú RAG megvalósítást LangGraph-fal, amely adaptívan dönt a visszakeresési stratégiáról:

from typing import TypedDict, List, Literal
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.documents import Document

class AgenticRAGState(TypedDict):
    question: str
    sub_questions: List[str]
    retrieved_docs: List[Document]
    relevance_score: float
    strategy: str
    answer: str
    attempts: int

llm = ChatOpenAI(model="gpt-4o", temperature=0)

def route_question(state: AgenticRAGState) -> dict:
    """Az ágens eldönti, melyik visszakeresési stratégiát használja."""
    question = state["question"]

    response = llm.invoke(
        f"""Elemezd a következő kérdést és döntsd el, melyik
        visszakeresési stratégia lenne a leghatékonyabb:

        Kérdés: {question}

        Lehetőségek:
        - "vector": Egyszerű szemantikai keresés
        - "hybrid": Hibrid keresés (vektor + kulcsszó)
        - "graph": Tudásgráf-alapú keresés kapcsolatokhoz
        - "decompose": Kérdés felbontása al-kérdésekre

        Válaszolj egyetlen szóval."""
    )

    strategy = response.content.strip().lower().strip('"')
    return {"strategy": strategy}

def retrieve_documents(state: AgenticRAGState) -> dict:
    """A választott stratégia szerint visszakeres."""
    strategy = state["strategy"]
    question = state["question"]

    if strategy == "hybrid":
        docs = hybrid_retriever.invoke(question)
    elif strategy == "graph":
        docs = graph_retriever.invoke(question)
    elif strategy == "decompose":
        # Al-kérdésekre bontás és külön visszakeresés
        sub_q = decompose_question(question)
        docs = []
        for q in sub_q:
            docs.extend(hybrid_retriever.invoke(q))
    else:
        docs = dense_retriever.invoke(question)

    return {"retrieved_docs": docs}

def evaluate_relevance(state: AgenticRAGState) -> dict:
    """Értékeli a visszakeresett dokumentumok relevanciáját."""
    docs = state["retrieved_docs"]
    question = state["question"]

    response = llm.invoke(
        f"""Értékeld 0-1 skálán, mennyire relevánsak az alábbi
        dokumentumok a kérdéshez.

        Kérdés: {question}
        Dokumentumok: {[d.page_content[:200] for d in docs[:5]]}

        Válaszolj egyetlen számmal (pl. 0.85)."""
    )

    score = float(response.content.strip())
    attempts = state.get("attempts", 0) + 1
    return {"relevance_score": score, "attempts": attempts}

def should_retry(state: AgenticRAGState) -> Literal["generate", "retry"]:
    """CRAG logika: elég jók a találatok, vagy újra kell próbálni?"""
    if state["relevance_score"] >= 0.7:
        return "generate"
    if state["attempts"] >= 3:
        return "generate"  # Maximum 3 próbálkozás
    return "retry"

def generate_answer(state: AgenticRAGState) -> dict:
    """Az LLM generálja a végső választ a kontextus alapján."""
    docs_context = "\n\n".join(
        [d.page_content for d in state["retrieved_docs"][:5]]
    )

    response = llm.invoke(
        f"""A következő kontextus alapján válaszolj a kérdésre.
        Ha a kontextus nem tartalmaz elegendő információt, jelezd.

        Kontextus:
{docs_context}

        Kérdés: {state['question']}"""
    )

    return {"answer": response.content}

# Gráf összeállítása
workflow = StateGraph(AgenticRAGState)
workflow.add_node("route", route_question)
workflow.add_node("retrieve", retrieve_documents)
workflow.add_node("evaluate", evaluate_relevance)
workflow.add_node("generate", generate_answer)

workflow.set_entry_point("route")
workflow.add_edge("route", "retrieve")
workflow.add_edge("retrieve", "evaluate")
workflow.add_conditional_edges("evaluate", should_retry, {
    "generate": "generate",
    "retry": "route"  # Visszaugrás: új stratégiával próbál
})
workflow.add_edge("generate", END)

app = workflow.compile()

Az ágensalapú RAG egyik legfontosabb előnye, hogy több tudásbázist is képes párhuzamosan kezelni. Gondolj egy ügyfélszolgálati rendszerre: az ágens egyszerre kereshet a termékdokumentációban, a korábbi jegyekben és a belső tudásbázisban, majd eldönti, melyik forrás eredményei a legrelevánsabbak az adott kérdéshez.

A RAG csővezeték kiértékelése: RAGAS és társai

Egy termelési RAG rendszert nem elég felépíteni — folyamatosan mérni és kiértékelni is kell. Kiértékelés nélkül vakon repülsz: nem tudod, hogy a rendszered javul vagy romlik, és nem tudod azonosítani a szűk keresztmetszeteket.

A RAGAS (Retrieval Augmented Generation Assessment) a legnépszerűbb nyílt forráskódú kiértékelési keretrendszer, és van egy hatalmas előnye: referencia nélküli (reference-free) kiértékelést tesz lehetővé. Ez azt jelenti, hogy nem szükséges emberi annotátorok által készített „tökéletes válasz" adathalmaz (na jó, egy metrikához mégis kell, de erről mindjárt).

A RAGAS négy alapvető metrikája

  • Context Precision (Kontextus-precizitás): A visszakeresett darabok mekkora része valóban releváns? Magas érték = kevés „zaj" a kontextusban.
  • Context Recall (Kontextus-fedés): A válaszhoz szükséges összes releváns információ benne van a visszakeresett kontextusban? (Ez az egyetlen metrika, amelyhez emberi annotáció szükséges.)
  • Faithfulness (Hűség): A generált válasz tényszerűen megfelel a visszakeresett kontextusnak? Alacsony hűség = hallucináció.
  • Answer Relevancy (Válasz-relevancia): A generált válasz mennyire releváns az eredeti kérdéshez? Nem tér-e el a lényegtől?
from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall
)
from datasets import Dataset

# Kiértékelési adathalmaz összeállítása
eval_data = {
    "question": [
        "Mi a RAG előnye a fine-tuninghoz képest?",
        "Hogyan működik a hibrid keresés?",
        "Mikor érdemes GraphRAG-ot használni?"
    ],
    "answer": [
        rag_chain.invoke("Mi a RAG előnye a fine-tuninghoz képest?"),
        rag_chain.invoke("Hogyan működik a hibrid keresés?"),
        rag_chain.invoke("Mikor érdemes GraphRAG-ot használni?")
    ],
    "contexts": [
        [retrieved_contexts_1],
        [retrieved_contexts_2],
        [retrieved_contexts_3]
    ],
    "ground_truth": [
        "A RAG olcsóbb, gyorsabb és frissebb adatokkal dolgozik...",
        "A hibrid keresés kombinálja a vektor és BM25 keresést...",
        "GraphRAG többlépéses érvelésnél és kapcsolat-kérdéseknél..."
    ]
}

dataset = Dataset.from_dict(eval_data)

# Kiértékelés futtatása
results = evaluate(
    dataset=dataset,
    metrics=[
        faithfulness,
        answer_relevancy,
        context_precision,
        context_recall
    ]
)

print(f"Hűség:              {results['faithfulness']:.3f}")
print(f"Válasz-relevancia:  {results['answer_relevancy']:.3f}")
print(f"Kontextus-precizitás: {results['context_precision']:.3f}")
print(f"Kontextus-fedés:    {results['context_recall']:.3f}")

A kiértékelés nem egyszeri feladat — a legjobb gyakorlat a folyamatos monitoring. A LangSmith és a Langfuse remekül integrálhatók a RAGAS-szal: valós idejű dashboardon jelenítik meg a metrikákat, figyelmeztetnek, ha a teljesítmény csökken, és nyomon követik a prompt-változtatások hatását.

Termelési szintű RAG: gyakorlati tanácsok és buktatók

A prototípusból termelési rendszert építeni egészen más kihívás. Néha frusztrálóan más. Íme a 2026-ban bevált gyakorlati tanácsok, amelyeket érdemes szem előtt tartani:

1. Metaadat-szűrés a visszakeresés előtt

Ne csak szemantikailag keress — szűrj metaadatok alapján mielőtt a vektoros keresés elindul. Dátum, dokumentumtípus, hozzáférési szint, nyelv, szerző — ezek mind csökkentik a keresési teret és javítják a precizitást. Egy belső tudásbázisban a hozzáférési jogosultságok szerinti szűrés biztonsági szempontból is kritikus — erről sokan megfeledkeznek, és az komoly problémákhoz vezethet.

2. Kontextuális tömörítés

Ha a visszakeresett dokumentumok túl nagyok az LLM kontextusablakához képest, alkalmazz kontextuális tömörítést: egy kisebb modellel vagy heurisztikával foglald össze a visszakeresett darabokat, mielőtt a fő LLM-nek adod. Csökkenti a token-költséget és a latenciát, miközben megőrzi a lényegi információt.

3. Gyorsítótárazás (Caching)

A gyakori kérdésekre adott válaszokat érdemes gyorsítótárazni. A szemantikai gyorsítótár nemcsak az azonos, hanem a hasonló kérdésekre is visszaadja a korábbi választ, így jelentősen csökkenti az API-hívások számát és költségét. A LangChain beépített SemanticCache komponense ezt viszonylag egyszerűen megvalósíthatóvá teszi.

4. Inkrementális indexelés

A teljes újraindexelés nagy dokumentummennyiségnél lassú és drága. Implementálj inkrementális indexelést: csak az új és módosított dokumentumokat dolgozd fel. Tartsd nyilván a dokumentumok hash-ét vagy utolsó módosítási dátumát, és csak a változásokat szinkronizáld a vektortárral.

5. Hibakezelés és visszaesési stratégiák

Mi történik, ha a vektoros adatbázis nem elérhető? Ha a visszakeresés nem talál releváns dokumentumot? Ha az LLM API-hívás időtúllépést szenved? Termelési környezetben minden ilyen esetet kezelni kell: visszaesési (fallback) stratégiákkal, circuit breakerekkel és megfelelő felhasználói kommunikációval. Az üzleti felhasználók nem akarják a „500 Internal Server Error" üzenetet látni.

6. Többnyelvű RAG

Magyar és más nem angol nyelvű tartalmak esetén különösen fontos a megfelelő beágyazási modell kiválasztása. A multilingual-e5-large és a text-embedding-3-large (OpenAI) modellek jól teljesítenek többnyelvű környezetben. Érdemes tesztelni, hogy a kérdés és a dokumentum azonos vagy eltérő nyelvű-e, és ennek megfelelően választani stratégiát — a vegyes nyelvű szcenáriók meglepően gyakoriak a magyar vállalati környezetben.

Teljes RAG csővezeték: az összes elem együtt

Na, most jöjjön a nagy egész. Zárásként nézzünk egy komplett, termelési szintű RAG csővezetéket, amely az összes eddig tárgyalt technikát integrálja egyetlen koherens rendszerbe:

from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_community.retrievers import BM25Retriever
from langchain.retrievers import EnsembleRetriever
from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 1. Komponensek inicializálása
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
llm = ChatOpenAI(model="gpt-4o", temperature=0)

# 2. Vektortár (feltételezve, hogy az indexelés megtörtént)
vectorstore = Chroma(
    persist_directory="./production_db",
    embedding_function=embeddings
)

# 3. Hibrid visszakereső
dense_retriever = vectorstore.as_retriever(search_kwargs={"k": 15})
sparse_retriever = BM25Retriever.from_documents(all_chunks, k=15)

hybrid_retriever = EnsembleRetriever(
    retrievers=[dense_retriever, sparse_retriever],
    weights=[0.6, 0.4]
)

# 4. Újrarangsorolás
reranker = CohereRerank(model="rerank-v3.5", top_n=5)
final_retriever = ContextualCompressionRetriever(
    base_compressor=reranker,
    base_retriever=hybrid_retriever
)

# 5. RAG prompt sablon
rag_prompt = ChatPromptTemplate.from_messages([
    ("system", """Segítőkész asszisztens vagy, aki kizárólag a megadott
    kontextus alapján válaszol. Ha a kontextus nem tartalmaz elegendő
    információt, mondd el őszintén. Hivatkozz a forrásokra.

    Kontextus:
    {context}"""),
    ("human", "{question}")
])

# 6. A teljes lánc összeállítása
def format_docs(docs):
    return "\n\n---\n\n".join(
        f"[Forrás: {d.metadata.get('source', 'ismeretlen')}]\n"
        f"{d.page_content}"
        for d in docs
    )

rag_chain = (
    {
        "context": final_retriever | format_docs,
        "question": RunnablePassthrough()
    }
    | rag_prompt
    | llm
    | StrOutputParser()
)

# 7. Használat
answer = rag_chain.invoke(
    "Milyen előnyei vannak a hibrid keresésnek "
    "a tisztán vektoros kereséshez képest?"
)

print(answer)

Összefoglalás és következő lépések

A RAG csővezetékek 2026-ban messze túlléptek az egyszerű „beágyazás + vektoros keresés" paradigmán. Egy modern, termelési szintű RAG rendszer a következő elemekből épül fel:

  • Intelligens darabolás: Szemantikai darabolás és szülő-dokumentum stratégia a pontosabb visszakeresésért
  • Hibrid keresés: A sűrű vektoros és a ritka kulcsszavas keresés kombinálása 18-22%-os javulásért
  • Újrarangsorolás: Cross-encoder modellek a relevancia finomhangolásához
  • Lekérdezés-transzformáció: HyDE, kérdés-felbontás és átfogalmazás az optimális visszakeresésért
  • GraphRAG: Tudásgráf-alapú visszakeresés a kapcsolat-alapú kérdésekhez
  • Ágensalapú RAG: Adaptív, önjavító visszakeresési folyamatok CRAG logikával
  • Folyamatos kiértékelés: RAGAS metrikák és monitoring a teljesítmény nyomon követésére

Ha eddig csak alap RAG prototípussal dolgoztál, a következő lépésed a hibrid keresés és az újrarangsorolás bevezetése legyen — ez a két technika a legkisebb ráfordítással adja a legnagyobb javulást. Ha már van termelési rendszered, érdemes az ágensalapú RAG és a GraphRAG irányába elmozdulni.

A RAG technológia 2026-ban nem pusztán egy eszköz a fejlesztők kezében — a vállalati AI-alkalmazások alapvető architektúrális mintájává vált. Aki most fektet be a RAG csővezetékek mélyebb megértésébe és termelési szintű implementálásába, az komoly versenyelőnyre tesz szert. És őszintén? Most van az ideális pillanat, hogy elkezdd.

A Szerzőről Editorial Team

Our team of expert writers and editors.