Blog
RAG für Entwickler: Domänenwissen in LLMs einbinden
Der Prompt lautet: "Welche Klassen verwalten die Auftragsabwicklung in unserem ERP?" Die Antwort von ChatGPT: eine generische Erklärung über typische ERP-Architekturen, vermutlich mit Java oder SAP als Referenz. Nicht falsch — nur vollständig nutzlos für ein System das 2009 in einem anderen Land von einem Team entwickelt wurde das seit zehn Jahren niemanden mehr kennt.
Das ist kein Prompt-Engineering-Problem. Es ist ein Grundprinzip: LLMs kennen nur was in ihren Trainingsdaten steht. Euer ERP, eure interne API-Dokumentation auf Confluence, eure 200-seitigen Compliance-Richtlinien — nichts davon ist im Training-Corpus von GPT-4 oder Claude. Fine-Tuning wäre eine Option, aber für dynamische, sich ändernde interne Dokumentation ist es das falsche Werkzeug: zu teuer, zu langsam, und jede Änderung an der Doku erfordert einen neuen Training-Run. RAG löst das — nicht elegant, aber pragmatisch.
Was RAG tut
Retrieval-Augmented Generation ist keine neue Architektur. Die Idee ist einfach: Bevor ihr dem LLM eure Frage schickt, sucht ihr in eurer eigenen Datenbasis nach relevanten Dokumenten und schiebt sie als Kontext in den Prompt. Das LLM sieht also nicht nur die Frage, sondern die Frage plus die 3–5 relevantesten Code-Dateien oder Doku-Seiten aus eurer tatsächlichen Codebase. Generation passiert mit Kontext statt ohne.
Die Pipeline hat drei Phasen. Indexierung passiert einmal und dann inkremental: ihr nehmt eure Dokumente — Code, Markdown, PDFs, Confluence-Exports — splittet sie in Chunks von typisch 500–1500 Tokens und wandelt jeden Chunk mit einem Embedding-Modell in einen Vektor um. Diese Vektoren landen in einem Vector Store: FAISS lokal, Chroma für schnelles Prototyping, Pinecone oder Weaviate für Production. Retrieval: bei jeder Anfrage wandelt ihr die Frage genauso in einen Embedding-Vektor um und sucht nach den Chunks mit höchster Cosine-Similarity. Augmentation: diese Chunks kommen als Kontext-Block in den Prompt, bevor das LLM antwortet.
Was RAG nicht kann: Wenn eure Chunks zu groß sind, verliert das LLM den Faden. Wenn sie zu klein sind, fehlt Kontext. Chunk-Größe und Overlap sind reale Tuning-Parameter, keine akademischen Details. Und wenn eure Indexierung veraltet ist — weil niemand einen Sync-Job eingerichtet hat — antwortet das LLM auf Basis alter Doku. Das ist schwerer zu debuggen als ein 404.
Drei Szenarien wo das funktioniert
Legacy-Codebase-Analyse ist der naheliegendste Fall. Ihr indexiert euren kompletten Source-Code und ein Entwickler kann Fragen stellen die normalerweise ein grep -r plus manuelles Lesen von 15 Dateien erfordern würden. "Wo wird customer_id gesetzt bevor er in die DB geschrieben wird?" — das ist eine legitime RAG-Query. Ihr bekommt relevante Code-Snippets als Kontext, das LLM erklärt den Datenfluss. Das funktioniert gut für Codebases die nicht im öffentlichen Training-Corpus auftauchen. Es funktioniert weniger gut wenn euer Code selbsterklärender wäre wenn jemand einfach Kommentare schreiben würde.
Interne API-Dokumentation: Viele Teams haben ihre Docs auf Confluence, in GitLab-Wikis oder als OpenAPI-YAMLs die sich wöchentlich ändern. Hier ist RAG sinnvoller als Fine-Tuning, weil ihr keinen Training-Run braucht — ein inkrementaler Sync bei jedem Confluence-Update reicht. Das LLM antwortet mit den aktuellen Endpoint-Definitionen statt mit halluzinierten Parametern.
Compliance und interne Richtlinien ist ein echter Pain. Entwickler fragen "Darf ich AWS S3 für DSGVO-relevante Daten verwenden?" und bekommen entweder keine Antwort oder müssen selbst im Intranet suchen. RAG über Compliance-Dokumente gibt eine konkrete Antwort — mit dem relevanten Policy-Text als Beleg im Kontext. Das LLM kann immer noch falsch liegen, aber wenn der tatsächliche Policy-Chunk vorhanden ist, ist das Risiko deutlich geringer als bei einer Frage ohne Grounding.
Die minimale Pipeline in Python
from openai import OpenAI
import faiss
import numpy as np
client = OpenAI()
def get_embedding(text: str) -> list[float]:
response = client.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data[0].embedding
def build_index(chunks: list[str]) -> tuple[faiss.Index, list[str]]:
embeddings = [get_embedding(chunk) for chunk in chunks]
matrix = np.array(embeddings, dtype="float32")
index = faiss.IndexFlatIP(matrix.shape[1])
index.add(matrix)
return index, chunks
def rag_query(
question: str,
index: faiss.Index,
chunks: list[str],
k: int = 3
) -> str:
query_vec = np.array([get_embedding(question)], dtype="float32")
_, indices = index.search(query_vec, k)
context = "\n\n---\n\n".join(chunks[i] for i in indices[0])
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": f"Beantworte ausschließlich auf Basis "
f"dieses Kontexts:\n\n{context}"
},
{"role": "user", "content": question}
]
)
return response.choices[0].message.content
Das ist kein Production-Code. Es fehlt Error Handling, Chunking-Logik, Persistenz für den FAISS-Index und vernünftiges Embedding-Batching. Aber die Struktur ist klar: get_embedding für Indexierung und Retrieval, IndexFlatIP für Cosine-Similarity, dann Kontext in den System-Prompt. LangChain und LlamaIndex abstrahieren das weg — aber wer die Abstraktion nicht versteht, debuggt blind wenn die Retrieval-Qualität schlecht ist.
Für Production: ChromaDB statt FAISS wenn ihr Persistenz ohne Extra-Code wollt, und text-embedding-3-small für den Trade-off zwischen Kosten und Qualität. Das große Modell (text-embedding-3-large) bringt in den meisten Code-Retrieval-Szenarien keinen messbaren Vorteil der die höheren API-Kosten rechtfertigt.
Ein ehrlicher Hinweis zum Schluss: RAG ist kein Schutz vor Halluzinationen. Das LLM kann Kontext falsch interpretieren oder Lücken zwischen Chunks füllen. Was RAG verhindert ist das schlimmste Szenario — Antworten die vollständig erfunden sind weil kein Grounding existiert. Für kritische interne Entscheidungen reicht das nicht als alleinige Verifikation. Als Recherche-Assistent für Entwickler funktioniert es.
Quellen: Lewis et al. — "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks" (NeurIPS 2020). OpenAI Embeddings API Documentation (2024). FAISS — Facebook AI Similarity Search (Meta AI Research).
RAG in euer System integrieren?
Wir zeigen euch den Weg von der Indexierung bis zur Production-Pipeline.
Erstgespräch buchen →