Naive RAG: Was chunk_size=1000 und reine Vektorsuche anrichten
Dieser Text war einmal ein Praxisguide. Derselbe Stack steht weiter unten, als Befund, nicht als Bauanleitung.
In einem Gesundheitsprojekt lagen 500+ Videos und PDFs in Milvus, grob 50.000 Chunks, Antworten unter 100 ms. Revision fragt nicht nach der Latenz. Sie fragt nach der Stelle.
Was wir gebaut haben, war naives Retrieval: Chunking nach Zeichenzahl, nur Vektoren, kein Reranking. Halluzinationen sind dann kein Zufall.
Was danach kommen muss, steht in Hybrid-RAG und Reranking.
Was die Pipeline tat
Drei Stufen, wie in jedem Tutorial:
Stack: LangChain, GPT-4o, selbst-gehostetes Milvus (Docker), FastAPI, Python 3.12. Selbst-hosten war richtig: in dem Umfeld dürfen die Daten das Haus nicht verlassen. Der Fehler saß nicht bei Milvus. Er saß in der Annahme, Ähnlichkeit sei ein Beleg.
Befund 1: feste Chunk-Größe
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
)
chunks = splitter.split_documents(docs)
1000 / 200 war ein Kompromiss nach Gefühl. Überschriften, Tabellen, Normstellen: egal. Ein Chunk riss mitten in einer Tabelle. Der Nachbar-Chunk klang ähnlich und gewann die Suche. Die Aussage im Prompt stammte aus der falschen Zeile.
Chunk-Qualität schlägt Quantität. Das bleibt wahr. Feste Zeichenzahl erzeugt trotzdem erwartbare Fehler.
Befund 2: nur Vektoren
from langchain_openai import OpenAIEmbeddings
from langchain_milvus import Milvus
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Milvus.from_documents(
documents=chunks,
embedding=embeddings,
connection_args={"host": "localhost", "port": "19530"},
collection_name="knowledge_base",
)
Cosine-Similarity findet Paraphrasen. Sie findet keine Aktenzeichen, keine Paragraphen, keine Produktcodes. Metadata-Filter hätten geholfen. Wir hatten sie. Sie ersetzen keine Keyword-Suche.
Befund 3: ungeprüftes Top-k
from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vectorstore.as_retriever(search_kwargs={"k": 5}),
)
Die fünf nächsten Chunks gingen ins Prompt. Kein Reranker. Keine Regel „keine Quelle, keine Aussage“. „Ähnlich“ wurde wie „belegt“ behandelt. Quellenbindung verlangt das Gegenteil.
Evaluation war von Tag 1 geplant. Das Set existierte. Es hat die schnelle Pipeline nicht gestoppt, weil das Set Stil prüfte, nicht Herkunft.
Was ich heute anders mache
chunk_size=1000Der passende Einstieg ist der LLM-Readiness-Check. Tag 2 ist Retrieval und Quellenbindung. Praxis: Gesundheits-Chatbot.
Verwandte Artikel
Hybrid-RAG und Reranking statt naiver Vektorsuche
Chunking nach Zeichenzahl und reine Vektorsuche erzeugen erwartbare Halluzinationen. Was Hybrid-Suche und Reranking ändern, und was der ältere RAG-Artikel falsch lehrt.
Artikel lesenMandantentrennung für RAG und Agenten
Ein Pilot für einen Kunden ist kein Produkt für zwanzig. Was Mandantentrennung in RAG- und Agentensystemen konkret heißt.
Artikel lesenTermin
30 Minuten. Wenn der Use-Case nicht in den Betrieb kann, sage ich das.