RAG-Frameworks: LangChain, LlamaIndex, Haystack
Auf dieser Seite
RAG ohne eigene Implementierung
Sie haben eine vollständige RAG-Pipeline in reinem Python aufgebaut, und das war der richtige Weg: Sie wissen nun, was jede Zeile tut, wo Missalignments versteckt lauern und warum ein schlecht geschnittenes Chunk eine Antwort ruinieren kann. In der Produktion können Sie zudem auf spezialisierte Frameworks zurückgreifen, die die technische Infrastruktur übernehmen und erweiterte Funktionen hinzufügen. Die drei wichtigsten davon – LangChain, LlamaIndex und Haystack – sind alle mit Mistral AI kompatibel, und die Wahl zwischen ihnen hängt weniger von der Qualität ab als vom Typ der Anwendung, die Sie anvisieren.
LangChain mit Mistral
LangChain ist das populärste Framework für LLM-Anwendungen. Seine Hauptstärke liegt in der Breite seines Integrations-Ökosystems, ergänzt durch das LangGraph-Modul für komplexe Steuerungsabläufe. Die Installation umfasst den Kern, den Mistral-Anschluss, Community-Integrationen und FAISS.
pip install langchain langchain-mistralai langchain-community faiss-cpu
Die minimale RAG-Implementierung passt dann in etwa dreißig Zeilen, und der Punkt besteht darin, zu erkennen, was im Vergleich zur manuellen Implementierung verschwunden ist. Batch-Verarbeitung, Retry-Logik, Konvertierung in float32, die Ausrichtung zwischen Vektoren und Metadaten: All dies wird von FAISS.from_texts absorbiert. Der RecursiveCharacterTextSplitter ersetzt Ihre Chunking-Funktionen mit denselben Parametern wie zuvor, 1500 Zeichen und 200 Überlappung. Die finale Kette wird mit dem Pipe-Operator geschrieben, der Schritte von links nach rechts zusammensetzt: Der Retriever speist den Kontext, RunnablePassthrough leitet die Frage unverändert weiter, der Prompt montiert sie, das Modell generiert, und der Parser extrahiert den String.
from langchain_mistralai import ChatMistralAI, MistralAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# Mistral-Modelle
embeddings = MistralAIEmbeddings(model="mistral-embed")
llm = ChatMistralAI(model="mistral-large-latest", temperature=0.1)
# Aufteilung und Indizierung
splitter = RecursiveCharacterTextSplitter(
chunk_size=1500,
chunk_overlap=200,
)
chunks = splitter.split_text(document_text)
# Vektorspeicher erstellen
vectorstore = FAISS.from_texts(chunks, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# RAG-Kette
prompt = ChatPromptTemplate.from_template(
"""Context: {context}
Question: {question}
Answer based on the context."""
)
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# Nutzung
answer = rag_chain.invoke("Wie funktioniert FAISS?")
print(answer)
LangGraph für korrigierendes, selbstüberwachendes und adaptives RAG
Die lineare Kette oben funktioniert für Standard-RAG, kann aber nicht Schleifen oder Verzweigungen bilden – doch genau das tun die Architekturen in den vorherigen drei Lektionen. LangGraph adressiert diesen Bedarf, indem es Steuerungsabläufe als Graphen definiert. Der typisierte GraphState fungiert als gemeinsamer Speicher: Jeder Knoten empfängt ihn, liest das Benötigte und gibt die Felder zurück, die er aktualisiert. Sie werden Ihre eigenen Funktionen hinter retrieve_node, grade_node und generate_node wiedererkennen, wobei grade_document unverändert wiederverwendet wird.
Der wirklich neue Mechanismus ist add_conditional_edges. Wo Ihre Python-Klasse if-Anweisungen verkettete, deklariert der Graph eine Entscheidungsfunktion – hier route_after_grade – und die Tabelle der möglichen Ziele. Diese Trennung zwischen der Geschäftslogik der Knoten und der Fluss-Topologie macht die Pipeline auf einen Blick lesbar und modifizierbar, ohne den Schritt-Code anzufassen. Sobald kompiliert, wird der Graph wie eine einfache Funktion aufgerufen.
from langgraph.graph import StateGraph, END
from typing import TypedDict
class GraphState(TypedDict):
question: str
documents: list
generation: str
web_search_needed: bool
def retrieve_node(state):
"""Retrieval-Knoten."""
question = state["question"]
docs = retriever.get_relevant_documents(question)
return {"documents": docs, "question": question}
def grade_node(state):
"""Dokument-Bewertungsknoten."""
question = state["question"]
docs = state["documents"]
relevant = []
web_needed = False
for doc in docs:
# Verwenden Sie das LLM zur Bewertung der Relevanz
grade = grade_document(question, doc.page_content)
if grade:
relevant.append(doc)
else:
web_needed = True
return {"documents": relevant, "web_search_needed": web_needed}
def generate_node(state):
"""Generierungsknoten."""
question = state["question"]
docs = state["documents"]
context = "\n\n".join([d.page_content for d in docs])
generation = llm.invoke(f"Context: {context}\n\nQuestion: {question}")
return {"generation": generation.content}
def route_after_grade(state):
"""Bedingte Entscheidung nach der Bewertung."""
if state["web_search_needed"]:
return "web_search"
return "generate"
# Graph aufbauen
workflow = StateGraph(GraphState)
# Knoten hinzufügen
workflow.add_node("retrieve", retrieve_node)
workflow.add_node("grade", grade_node)
workflow.add_node("generate", generate_node)
# Fluss definieren
workflow.set_entry_point("retrieve")
workflow.add_edge("retrieve", "grade")
workflow.add_conditional_edges("grade", route_after_grade, {
"generate": "generate",
"web_search": "web_search",
})
workflow.add_edge("generate", END)
# Kompilieren
app = workflow.compile()
# Ausführen
result = app.invoke({"question": "Wie funktioniert RAG?"})
print(result["generation"])
LlamaIndex mit Mistral
LlamaIndex geht die Abstraktion noch weiter, da es speziell für RAG und die Verwaltung strukturierter Dokumente optimiert ist.
pip install llama-index llama-index-llms-mistralai llama-index-embeddings-mistralai
Die Konfiguration erfolgt über ein globales Settings-Objekt, das das Generierungsmodell und das Embedding-Modell einmal und für immer festlegt. SimpleDirectoryReader lädt ein ganzes Verzeichnis, indem es Formate errät, und VectorStoreIndex.from_documents verknüpft Chunking und Kodierung, ohne dass Sie diese parametrisieren müssen. Der Gewinn an Kürze ist real, aber messen Sie, was dies impliziert: Die Aufteilungsstrategie, die Sie nun kennen und die die Retrieval-Qualität bestimmt, wird hier für Sie gewählt. Sie ist komfortabel für den Einstieg, und sie ist die erste Einstellung, die Sie am Tag zurücknehmen müssen, an dem die Antworten enttäuschen. Beachten Sie, dass response.source_nodes Metadaten bewahrt, wodurch die von Ihnen manuell implementierte Rückverfolgbarkeit erhalten bleibt.
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.mistralai import MistralAI
from llama_index.embeddings.mistralai import MistralAIEmbedding
from llama_index.core import Settings
# Globale Konfiguration
Settings.llm = MistralAI(model="mistral-large-latest", temperature=0.1)
Settings.embed_model = MistralAIEmbedding(model_name="mistral-embed")
# Dokumente laden
documents = SimpleDirectoryReader("./data/").load_data()
# Index erstellen (automatisches Chunking + Embedding)
index = VectorStoreIndex.from_documents(documents)
# Abfrage-Engine erstellen
query_engine = index.as_query_engine(similarity_top_k=3)
# Frage stellen
response = query_engine.query("Was sind die Schritte von RAG?")
print(response)
print(f"\nQuellen: {[n.metadata for n in response.source_nodes]}")
Haystack mit Mistral
Haystack, entwickelt von deepset, verfolgt eine dritte Philosophie: die der modularen Pipelines, bei denen jeder Komponente ein Name gegeben wird, hinzugefügt und dann explizit mit seinen Nachbarn verbunden wird.
pip install haystack-ai mistral-haystack
Die untenstehende Indizierungspipeline illustriert diesen Ansatz gut. Drei Komponenten werden deklariert – der Splitter, der Encoder über MistralDocumentEmbedder und der Writer für den Dokumentenspeicher – und dann durch connect-Aufrufe verknüpft, die den Datenfluss im Code sichtbar machen. Diese Verbissenheit, die bei einem einfachen Fall unnötig wirken mag, wird zum Vorteil, sobald die Pipeline verzweigt oder Sie einen Link ersetzen müssen, ohne die anderen zu berühren. Beachten Sie auch den Unterschied zwischen MistralDocumentEmbedder und MistralTextEmbedder: Der Erstere kodiert Dokumente zum Indizierungszeitpunkt, der Letztere wird Abfragen zum Abfragezeitpunkt kodieren, eine Trennung, die den klassischen Fehler verhindert, beide auf dieselbe Weise zu behandeln.
from haystack import Pipeline
from haystack.components.writers import DocumentWriter
from haystack.components.preprocessors import DocumentSplitter
from haystack_integrations.components.embedders.mistral import (
MistralDocumentEmbedder,
MistralTextEmbedder,
)
from haystack_integrations.components.generators.mistral import MistralChatGenerator
from haystack.document_stores.in_memory import InMemoryDocumentStore
# Dokumentenspeicher
doc_store = InMemoryDocumentStore()
# Indizierungspipeline
indexing_pipeline = Pipeline()
indexing_pipeline.add_component("splitter", DocumentSplitter(
split_by="passage", split_length=5
))
indexing_pipeline.add_component("embedder", MistralDocumentEmbedder(
model="mistral-embed"
))
indexing_pipeline.add_component("writer", DocumentWriter(
document_store=doc_store
))
indexing_pipeline.connect("splitter", "embedder")
indexing_pipeline.connect("embedder", "writer")
Welche Wahl treffen?
Jedes Framework hat seine Stärken, und die folgende Tabelle fasst die Abwägung zusammen.
| Framework | Hauptstärke | Ideal für |
|---|---|---|
| LangChain | Reichstes Ökosystem, LangGraph für komplexe Steuerungsabläufe | Agenten und fortgeschrittenes RAG |
| LlamaIndex | Einfachstes für RAG, native Handhabung strukturierter Dokumente | Schneller Start, Einsteiger |
| Haystack | Modularer Pipeline-Ansatz, stark in der Evaluation | Produktionsbereitstellung |
Nächste Schritte
Sie haben nun alle Grundlagen, um RAG-Systeme mit Mistral AI zu bauen. Sie wissen, wie man Text mit mistral-embed und seinen 1024 Dimensionen kodiert, Code mit codestral-embed und seinen konfigurierbaren Dimensionen bis zu 3072, eine RAG-Pipeline von Grund auf mit FAISS und der Mistral-API aufbaut und diese dann mit korrigierenden, selbstüberwachenden und adaptiven Architekturen verstärkt. Diese letzte Lektion fügt den Framework-Pfad hinzu: LangChain, LlamaIndex und Haystack.
Um weiterzukommen, erkunden Sie die offiziellen Mistral AI Cookbooks sowie die Notebooks für jedes Framework, die die API-Entwicklung enger verfolgen als jeder Kurs. RAG ist ein schnelllebiges Feld: Chunking-, Retrieval- und Verifikationstechniken verbessern sich ständig, und genau weil Sie jeden Schritt von Hand geschrieben haben, werden Sie in der Lage sein, das nächste, das erscheint, zu bewerten.
Kernaussagen
- LangChain + LangGraph ist die primäre Wahl für fortgeschrittene RAG-Steuerungsabläufe
- LlamaIndex ist das Einfachste für Standard-RAG mit Mistral
- Haystack glänzt in Modularität und Pipeline-Evaluation
- Alle drei Frameworks unterstützen
mistral-embedundmistral-largenativ - Beginnen Sie mit RAG von Grund auf, um zu verstehen, und migrieren Sie dann zu einem Framework für die Produktion
Wissen prüfen
Embeddings, RAG und fortgeschrittene Varianten: die große Abschlussprüfung.
1. Welche zwei Embedding-Modelle hat Mistral und wozu dienen sie?
Antwort: mistral-embed für allgemeinen Text und codestral-embed für Code – jedes projiziert seinen Bereich in einen Raum, in dem semantische Ähnlichkeit gemessen wird.
2. Welche Schritte machen die RAG-Pipeline des Kurses aus?
Antwort: Datenvorbereitung (Chunking), Erstellen von Embeddings, Speichern in einem Vektorspeicher (FAISS), dann Retrieval + Generierung: Die Frage findet ihre Passagen, das Modell antwortet darauf basierend.
3. Was korrigiert Corrective RAG?
Antwort: Schlechte Retrievals: Es bewertet die Relevanz der abgerufenen Passagen und löst eine Korrektur (neue Suche, Reformulierung) aus, bevor es generiert – anstatt auf Rauschen zu antworten.
4. Self-RAG und Adaptive RAG: Was ist die gemeinsame Idee?
Antwort: Die Pipeline reflexiv machen: Entscheiden, wann zu retrieven, die eigenen Ausgaben kritisieren, die Strategie an die Frage anpassen – RAG hört auf, ein festes Rohr zu sein.
5. Was bringen LangChain, LlamaIndex oder Haystack?
Antwort: Werkzeugkasten: Vorgefertigte Komponenten für Ingestion, Indizes, Ketten und Evaluation – nützlich für Geschwindigkeit, sofern Sie verstehen, was sie zusammenstellen (was dieser Kurs gelehrt hat).
Sie wissen nun, wie man eine RAG von Hand baut und sie einem Framework mit vollem Bewusstsein anvertraut – das ist die richtige Reihenfolge.