LangChain + Ollama Integration: Vollständiger Leitfaden für lokale LLM-Apps
Letzten Monat habe ich mir die OpenAI-Rechnung angesehen: 52,3 $. Ehrlich gesagt war ich etwas schockiert – als Einzelentwickler, der gelegentlich mit KI spielt, so viel auszugeben. Dann fiel mir ein, dass Ollama lokal läuft – kostenloses Llama 3.1, bereit zum Einsatz.
Aber es gibt ein Problem: Direkt die Ollama-API in einer App zu nutzen, bedeutet viel Boilerplate. Request-Format, Response-Parsing, Fehlerbehandlung – bei jedem Projekt wieder von vorn. Hier kommt LangChain ins Spiel: fertige Abstraktionen für Chat, RAG und Agent – und Modelle per Zeile Code wechselbar.
Dieser Artikel ist der Framework-Integrations-Teil der Ollama Local LLM-Serie. Von langchain-ollama geht es zu Chat, RAG und Agent in der Praxis. Wer die vorherigen Teile (API-Aufruf, Multi-Modell-Deployment) kennt, findet hier das zusammenhängende Entwicklungsgerüst.
langchain-ollama: Einstieg
Zuerst ein Stolperstein, den ich selbst erlebt habe. Früher nutzte ich langchain_community.llms.Ollama – lief, fühlte sich aber falsch an. In der Doku stand überall „langchain-ollama“. LangChain hat die Ollama-Integration in ein eigenes Paket ausgelagert: langchain-ollama.
Warum das offizielle Paket?
Bessere Type Hints, IDE-Autovervollständigung. Wartung synchron zur LangChain-Hauptversion – weniger Kompatibilitätsprobleme. Community-Pakete können deprecated werden; das offizielle Paket ist die Langfrist-Option – das habe ich schmerzhaft gelernt.
Installation in einer Zeile:
pip install langchain-ollama
Das Paket liefert drei Kernklassen für unterschiedliche Szenarien:
| Klasse | Zweck | Typische Anwendung |
|---|---|---|
ChatOllama | Dialogmodell | Mehrturn-Chat, Q&A |
OllamaLLM | Text-Vervollständigung | Einmal-Generierung, Fortsetzung |
OllamaEmbeddings | Vektor-Embeddings | RAG, semantische Suche |
In der Praxis reicht ChatOllama in 90 % der Fälle. Mehrturn-Dialog und Streaming – Zeichen für Zeichen statt eines Blocktexts – verbessern die UX deutlich.
Minimales Beispiel:
from langchain_ollama import ChatOllama
# Modell initialisieren
llm = ChatOllama(
model="llama3.1:8b", # Modellname – vorher mit Ollama pullen
temperature=0.7 # Zufälligkeit, 0–1
)
# Nachricht senden
response = llm.invoke("Hallo, stell dich kurz vor")
print(response.content)
Vor dem Start: ollama pull llama3.1:8b. Ollama noch nicht installiert? Siehe den Einstiegsartikel der Serie.
OllamaEmbeddings wandelt Text in Vektoren um – ausführlich im RAG-Abschnitt. Kurzbeispiel:
from langchain_ollama import OllamaEmbeddings
embeddings = OllamaEmbeddings(model="nomic-embed-text")
# Einzeltext einbetten
vector = embeddings.embed_query("Dies ist ein Testtext")
print(f"Vektordimension: {len(vector)}") # meist 768 oder mehr
# Batch-Einbettung
vectors = embeddings.embed_documents([
"Erster Text",
"Zweiter Text"
])
nomic-embed-text ist ein gängiges Embedding-Modell für semantische Suche. Hohe Dimension (meist 768+), bessere Retrieval-Qualität als generische Modelle.
Chat in der Praxis: Mehrturn-Dialog und Streaming
Ein einzelner API-Aufruf ist trivial – echte Chats brauchen Kontext über mehrere Runden. LangChain modelliert das mit Nachrichtenlisten.
Mehrturn-Dialog
Drei Nachrichtentypen:
SystemMessage: Rolle und Verhalten (z. B. „Du bist ein Entwickler-Assistent“)HumanMessage: NutzereingabeAIMessage: Modellantwort
Code:
from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
# Dialogverlauf
messages = [
SystemMessage(content="Du bist ein Entwickler-Assistent, der technische Konzepte klar erklärt."),
HumanMessage(content="Was ist eine REST-API?"),
AIMessage(content="Eine REST-API ist ein Architekturstil für Webservices mit HTTP-Methoden (GET/POST/PUT/DELETE) auf Ressourcen. Kurz: Daten über URLs ansprechen."),
HumanMessage(content="Worin unterscheidet sich GraphQL davon?")
]
# Antwort basiert auf dem gesamten Verlauf
response = llm.invoke(messages)
print(response.content)
Das Modell sieht die vorherige Antwort und erkennt die Nachfrage zu GraphQL vs. REST. Ohne AIMessage würde es GraphQL von Grund auf erklären – der Faden reißt.
Streaming: Antworten wirken lebendig
Streaming vermeidet leere Wartezeit – Text erscheint Wort für Wort. Besonders bei langen Antworten wichtig.
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1:8b")
# Streaming
print("Modellantwort: ", end="", flush=True)
for chunk in llm.stream("Schreibe Quicksort in Python und erkläre das Prinzip"):
print(chunk.content, end="", flush=True)
print() # Zeilenumbruch
stream() liefert einen Iterator; jeder Chunk ist ein Textstück. flush=True zeigt sofort an, ohne Puffer.
In Tests fühlt sich Streaming deutlich reaktiver an – ab ca. 100 Zeichen wirkt das System aktiv statt hängend.
RAG in der Praxis: Lokale Wissensbasis
RAG (Retrieval-Augmented Generation) ist einer der praktischsten LLM-Anwendungsfälle: Zuerst relevante Dokumente abrufen, dann darauf basierend antworten – Wissen jenseits der Trainingsdaten.
RAG-Ablauf
Fünf Schritte:
- Dokumente laden – PDF, TXT, Markdown usw.
- Text splitten – lange Dokumente in suchbare Chunks
- Vektoren erzeugen – Embedding-Modell
- Index speichern – Vektordatenbank (hier ChromaDB)
- Retrieval + Generierung – bei Fragen relevante Chunks finden und antworten
Vollständiger, getesteter Code:
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_chroma import Chroma
from langchain_community.document_loaders import PyPDFLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# === 1. Dokumente laden ===
loader = TextLoader("./my_document.txt") # eigenen Pfad setzen
docs = loader.load()
# === 2. Text splitten ===
# chunk_size=1000: ca. 1000 Zeichen pro Chunk
# chunk_overlap=200: Überlappung gegen Informationsbrüche
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
splits = text_splitter.split_documents(docs)
# === 3 & 4. Vektoren erzeugen und speichern ===
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db" # Persistenzpfad
)
# === 5. Retriever ===
# k=4: die 4 relevantesten Chunks
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# === 6. RAG Chain ===
template = """Beantworte die Frage anhand des Kontexts. Wenn keine relevanten Infos vorliegen, sage klar „Keine relevanten Informationen im Dokument".
Kontext:
{context}
Frage: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOllama(model="llama3.1:8b")
# LCEL-Syntax: Komponenten mit | verketten
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# === 7. Abfrage ===
response = rag_chain.invoke("Was sind die Hauptinhalte des Dokuments?")
print(response)
Der Kern ist rag_chain – LCEL (LangChain Expression Language) verbindet Retriever, Prompt, Modell und Parser.
Praktische Parameter:
chunk_size: Bei dichten Tech-Docs 800; Prosa 1000–1500.
k: Meist 3–5 – zu viele Chunks verwässern, zu wenige lassen Details aus.
persist_directory ist Pflicht – sonst bei jedem Neustart neu embedden, langsam und teuer.
Beim ersten RAG-Versuch ohne Persistenz musste ich nach jedem Code-Change neu embedden. Mit persist_directory lädt der Index in Sekunden.
Agent in der Praxis: JSON-basiertes Tool-Calling
Der Unterschied zum normalen Chat: Der Agent ruft externe Tools auf.
Fragt jemand „Wie ist das Wetter in Peking?“, antwortet ein reines Chat-Modell oft erfunden. Ein Agent ruft zuerst eine Wetter-API auf und antwortet mit echten Daten.
Die Ollama-Grenze bei Tool-Calling
Offen gesagt: Ollama ist hier schwächer als OpenAI. OpenAI-Modelle unterstützen Function Calling nativ – wann und mit welchen Parametern ein Tool aufgerufen wird. Llama 3.1 und Co. sind noch nicht auf dem Niveau.
LangChains Lösung: JSON-based Agent.
Das Modell gibt strukturiertes JSON aus; das Framework parst es und wählt Tools. In Tests funktioniert das brauchbar – nicht so flüssig wie OpenAI, aber für Basisaufgaben ausreichend.
Eigene Tools
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""Wetterinformationen für eine Stadt abrufen"""
weather_data = {
"Peking": "Sonnig, 25°C, gute Luftqualität",
"Shanghai": "Bewölkt, 22°C, leichter Regen möglich",
"Shenzhen": "Heiß, 30°C, starke UV-Strahlung"
}
return weather_data.get(city, f"Keine Wetterdaten für {city}")
@tool
def calculate(expression: str) -> str:
"""Mathematische Berechnung ausführen"""
try:
result = eval(expression) # Hinweis: in Produktion sicherer implementieren
return f"Ergebnis: {result}"
except:
return "Berechnungsfehler – Ausdruck prüfen"
@tool
def search_local_docs(query: str) -> str:
"""Lokale Dokumentenbibliothek durchsuchen"""
return f"Suche nach '{query}': 3 relevante Treffer gefunden"
@tool macht aus Funktionen LangChain-Tools. Der Docstring wird zur Tool-Beschreibung – das Modell wählt danach.
JSON Agent erstellen:
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOllama(model="llama3.1:8b")
tools = [get_weather, calculate, search_local_docs]
prompt = ChatPromptTemplate.from_messages([
("system", "Du bist ein hilfreicher Assistent mit Tool-Zugriff."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({
"input": "Wie ist das Wetter in Peking heute? Und berechne 23 + 45"
})
print(response["output"])
verbose=True zeigt den Entscheidungsprozess – hilfreich beim Debuggen.
Praxiserfahrung:
JSON Agent liegt bei ca. 70–80 % Erfolg. Wetter und Rechnen klappen meist; mehrere Tools kombiniert scheitern gelegentlich – falsches Format oder falsches Tool. Typisch für lokale LLM-Agents, weniger stabil als OpenAI.
Bei hohen Anforderungen:
- Stärkeres Modell (z. B. Qwen 2.5 oder DeepSeek)
- Weniger Tools, einfachere Abläufe
- OpenAI Function Calling – teurer, deutlich stabiler
OpenAI vs. Ollama: Wechsel per Zeile Code
Oft gefragt: LangChain-Code für beide Backends? Ja – erstaunlich einfach.
Variante 1: Import ändern
OpenAI-Code:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4", temperature=0.7)
response = llm.invoke("Erkläre Quantencomputing")
Zu Ollama – nur der Import:
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
response = llm.invoke("Erkläre Quantencomputing")
Prompt-Vorlagen, Chains, Parser – unverändert. LangChains Abstraktion macht den Wechsel nahezu transparent.
Variante 2: OpenAI-kompatible API
Ollama kann sich als OpenAI ausgeben – Import bleibt:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="llama3.1:8b",
base_url="http://localhost:11434/v1",
api_key="ollama" # beliebig – Ollama prüft nicht
)
response = llm.invoke("Erkläre Quantencomputing")
Sinnvoll, wenn das Projekt schon ChatOpenAI nutzt und lokale Modelle testen soll.
Vergleich
| Kriterium | OpenAI (GPT-4) | Ollama (Llama 3.1) |
|---|---|---|
| Kosten | $0,03/1K Input-Tokens | Kostenlos (lokale GPU-Strom) |
| Datenschutz | Cloud – Compliance beachten | Lokal – Daten verlassen den Rechner nicht |
| Tool-Calling | Nativ, stabil | JSON Agent, ca. 70–80 % |
| Latenz | Schnell (Cloud, 1–3 s TTFB) | Abhängig von GPU (3–10 s) |
| Modellstärke | GPT-4 top-tier | Llama 3.1 8B solide, unter GPT-4 |
Empfehlung:
- Lernen, Prototypen: Ollama – günstig, experimentierfreundlich
- Produktion, hohe Last: OpenAI – Stabilität und Geschwindigkeit
- Sensible Daten: Ollama – alles lokal
- Komplexe Agent-Aufgaben: OpenAI – zuverlässigeres Tool-Calling
Ideal: Beides – Ollama in der Entwicklung, OpenAI live. Wechselkosten: eine Zeile.
Fazit
LangChain + Ollama – der Integrationspfad steht.
Von langchain-ollama über ChatOllama, OllamaLLM und OllamaEmbeddings zu drei Szenarien: Chat mit Streaming, RAG für lokale Dokumente, Agent mit JSON Agent als Kompromiss. OpenAI und Ollama wechseln sich per Zeile – von ~50 $/Monat auf kostenlos lokal.
Wann Ollama?
Sparen, Datenschutz oder LLM-Entwicklung lernen – lokal ausprobieren ohne Rechnungsschock.
Wann OpenAI?
Komplexe Agents, Produktion mit hoher Last, wenn Geschwindigkeit und Stabilität zählen. Lokale LLMs ersetzen die Cloud-Erfahrung noch nicht vollständig.
Einstieg: Chat – wenig Code, schneller Effekt. Danach RAG mit eigenen Dokumenten. Agent später – mehr Feintuning nötig.
In der Serie folgen Multi-Modell-Deployment, Performance-Tuning und Produktions-Deployment. Gerne weiterlesen.
Fragen in den Kommentaren oder auf GitHub. Die Beispiele sind getestet – Fehler meist fehlendes Modell oder Dependencies; Fehlermeldung folgen reicht meist.
LangChain + Ollama Integration
Von Installation und Konfiguration bis zu Chat, RAG und Agent – alles für die lokale LLM-App-Entwicklung
⏱️ Estimated time: 60 min
- 1
Step 1: langchain-ollama installieren
Installationsbefehl ausführen:
```bash
pip install langchain-ollama
```
Ollama muss installiert sein und ein Modell heruntergeladen (z. B. `ollama pull llama3.1:8b`). - 2
Step 2: Chat-App erstellen
ChatOllama initialisieren und Nachricht senden:
```python
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
response = llm.invoke("Hallo")
print(response.content)
```
Unterstützt Mehrturn-Dialog und Streaming. - 3
Step 3: RAG-Wissensbasis aufbauen
Fünf Schritte:
• Dokumente laden (TextLoader / PyPDFLoader)
• Text splitten (RecursiveCharacterTextSplitter)
• Vektoren erzeugen (OllamaEmbeddings)
• Index speichern (ChromaDB)
• Retrieval-Generierung (RAG Chain)
Wichtige Parameter: chunk_size=1000, k=4, persist_directory unbedingt setzen. - 4
Step 4: Agent-Tool-Calling implementieren
Tool-Funktionen definieren und JSON Agent erstellen:
```python
@tool
def get_weather(city: str) -> str:
"""Wetterinformationen abrufen"""
...
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools)
```
Erfolgsrate ca. 70–80 %, komplexe Aufgaben besser mit OpenAI. - 5
Step 5: OpenAI / Ollama wechseln
Variante 1: Import ändern
```python
from langchain_ollama import ChatOllama # Ollama
from langchain_openai import ChatOpenAI # OpenAI
```
Variante 2: OpenAI-kompatible API (Import unverändert)
```python
llm = ChatOpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama"
)
```
FAQ
Was ist der Unterschied zwischen langchain-ollama und langchain_community.llms.Ollama?
ChatOllama oder OllamaLLM – was nehmen?
Wie setzt man chunk_size und k in RAG-Systemen?
Warum ist Tool-Calling bei Ollama weniger stabil als bei OpenAI?
Wie wechselt man zwischen OpenAI und Ollama?
Eignet sich Ollama für Produktion?
8 Min. Lesezeit · Veröffentlicht am: 7. Apr. 2026 · Aktualisiert am: 9. Juli 2026
Ollama Local LLM Guide
Wenn du über die Suche hier gelandet bist, kommst du am schnellsten weiter, indem du zum vorherigen oder nächsten Beitrag dieser Serie springst.
Vorheriger
Ollama API in der Praxis: Entwicklungsleitfaden für Python- und Node.js-Clients
Ausführliche Anleitung zur Ollama-API: Python- und Node.js-SDK, Streaming, Tool-Calling mit Agent Loop, Thinking-Modus und Vergleich mit der OpenAI-kompatiblen Schnittstelle
Teil 14 von 19
Nächster
Ollama Embedding in der Praxis: Lokale Vektorsuche und RAG aufbauen
Lokales RAG-System mit Ollama: mxbai-embed-large vs nomic-embed-text im Modellvergleich, Vektordatenbank-Auswahl ChromaDB/FAISS/Milvus, vollständiger Python-Code
Teil 16 von 19
Ähnliche Beiträge
Ollama-Einstieg: Erster Schritt zu lokalen Großsprachmodellen

Ollama-Einstieg: Erster Schritt zu lokalen Großsprachmodellen
Ollama-Modellverwaltung: Download, Wechsel, Löschen und Versionskontrolle


Kommentare
Melde dich mit GitHub an, um einen Kommentar zu hinterlassen