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
DSGVO und Data Residency, wenn ein LLM im Spiel ist
Wo läuft das Modell, wo liegen die Embeddings, wo die Logs? Die technische Liste, die eine Datenschutzprüfung für KI-Systeme erst möglich macht.
Artikel lesenRAG in Produktion
Der Weg von einer RAG-Demo zu einem System, das ein Audit besteht: Chunking, Hybrid-Retrieval, Reranking, Quellenbindung, Evaluation, Mandanten.
Artikel lesenTermin
30 Minuten. Wenn der Use-Case nicht in den Betrieb kann, sage ich das.