LangChain Best Practices
Vertiefung für Teilnehmende, die nach dem Einsteiger-Guide belastbare LangChain-Muster nachschlagen möchten.
Diese Seite ist keine erste Einführung in LangChain. Sie dient als Referenz für saubere, moderne Patterns, wenn die Grundlagen bereits klar sind. Für den ersten Zugang empfiehlt sich zuerst LangChain Einsteiger.
Im Projektkontext werden einige dieser Patterns als Standard behandelt. Für Teilnehmende im Kurs ist wichtiger, die Unterschiede zwischen älteren und robusteren Mustern zu verstehen, nicht alle Punkte sofort auswendig zu beherrschen.
Typischer Fehler: Diese Seite wie eine lineare Einführung zu lesen. Als Lernpfad ist sie zu dicht. Als Nachschlagewerk bei konkreten Umsetzungsfragen ist sie deutlich nützlicher.
Inhaltsverzeichnis
- Überblick der wichtigsten LangChain-Standards
- 🆕 What’s New in LangChain v1.2.0 (December 15, 2025)
- 1️⃣
init_chat_model()- Unified Model Initialization - 2️⃣
with_structured_output()- Native Structured Outputs - 3️⃣
@toolDecorator - Tool Definitions - 4️⃣
create_agent()- Modern Agent API - 5️⃣ LCEL
|Chains - Expression Language - 6️⃣ Middleware für Agents - Production-Ready Features
- 7️⃣ Standard Message Content Blocks - Multimodal Support
- 8️⃣
.with_retry()und.with_fallbacks()- Robuste Chains - 🚀 Quick Start: Komplettes Beispiel
- 📚 Import-Cheatsheet
- ⚠️ Breaking Changes von 0.x zu 1.0+
- 🎯 Migration-Checkliste
- 📖 Weitere Ressourcen
- Abgrenzung zu verwandten Dokumenten
- 📝 Changelog
Überblick der wichtigsten LangChain-Standards
| # | Feature | Priorität | Ersetzt | Hauptvorteil |
|---|---|---|---|---|
| 1 | init_chat_model() | Kernstandard | ChatOpenAI() direkt | Provider-Unabhängigkeit |
| 2 | with_structured_output() | Kernstandard | PydanticOutputParser | Garantierte Schema-Konformität |
| 3 | @tool Decorator | Kernstandard | Tool() wrapper | Automatische Schema-Generierung |
| 4 | create_agent() | Kernstandard | initialize_agent() + AgentExecutor | Moderne Agenten-Erstellung |
| 5 | LCEL \| Chains | Kernstandard | Legacy Chain-Syntax | Moderne Pipe-Operator-Syntax |
| 6 | Middleware für Agents | Vertiefung | Hook-Pattern | Robusteres Laufzeitverhalten |
| 7 | Standard Content Blocks | Vertiefung | Provider-spezifische Formate | Multimodal-Support |
| 8 | .with_retry() / .with_fallbacks() | Empfehlung | Manuelle try/except-Blöcke | Robustere Chains |
🆕 What’s New in LangChain v1.2.0 (December 15, 2025)
Hinweis für Einsteiger: Diese Versionssektion ist nur dann wichtig, wenn bestehender Code modernisiert oder Unterschiede zwischen älteren und neueren Beispielen verstanden werden sollen. Für die ersten Kursmodule kann sie zunächst übersprungen werden.
LangChain v1.2.0 erweitert 3 von 7 Must-Haves mit production-ready Features:
| Feature | Update | Impact |
|---|---|---|
| #2 with_structured_output() | 🆕 Strict Schema für Agents | response_format in create_agent |
| #3 @tool Decorator | 🆕 Tool Extras | Provider-spezifische Tool-Parameter |
| #4 create_agent() | 🆕 response_format | Strikte Agent-Response-Validierung |
Wichtigste Neuerungen v1.2.0:
- ✨ Tool Extras: Provider-native Features (Anthropic programmatic tool calling, OpenAI strict mode)
- ✨ Strict Schema Adherence:
response_formatfür garantierte Agent-Output-Konformität - ✨ Built-in Client-Side Tools: Anthropic, OpenAI, und weitere Provider
Wichtigste Neuerungen v1.1.0 (bereits integriert):
- ✨ Model Profiles (
.profileAttribut): Chat-Modelle exposieren ihre Capabilities - ✨ Smart Structured Output:
ProviderStrategywird automatisch aus Profiles abgeleitet - ✨ SystemMessage in create_agent: Cache-Control für Anthropic Claude
- ✨ ModelRetryMiddleware: Automatische Retries mit exponential backoff
- ✨ ContentModerationMiddleware: OpenAI Moderation für User/Model/Tool-Outputs
- ✨ Verbesserter SummarizationMiddleware: Nutzt Model Profiles für intelligente Zusammenfassungen
Wichtigste Neuerungen v1.2.1-v1.2.10 (Januar/Februar 2026):
- ✨ ContextOverflowError: Neuer Fehlertyp in
langchain-core- wird vonlangchain-openaiundlangchain-anthropicausgelöst, wenn das Context-Window überschritten wird.SummarizationMiddlewaretriggert automatisch bei diesem Fehler. - ✨ Token-Zählung für Tool-Schemas:
count_tokens_approximately()zählt jetzt auch Tokens aus Tool-Schemas für genauere Budgetierung.
Wichtigste Neuerungen v1.1.10 (langchain-openai) (Februar 2026):
- ✨ Automatic Server-Side Compaction:
context_management=[{"type": "compaction", "compact_threshold": N}]— OpenAI komprimiert Konversationshistorie serverseitig, keine SummarizationMiddleware nötig.
Wichtigste Neuerungen v1.2.17 (Mai 2026):
- ✨ **: Middleware kann jetzt direkt antworten und den Agent-Loop beenden.
- ✨ Content-Block-Centric Streaming v2 ( 1.3.2): Streaming liefert strukturierte Content-Block-Events. enthält Block-Dicts mit , und .
Breaking Changes: Keine! v1.2.x ist vollständig rückwärtskompatibel mit v1.0+
1️⃣ init_chat_model() - Unified Model Initialization
❌ ALT (nicht mehr verwenden)
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# Auch veraltet: Langnotation mit separaten Variablen
model_provider = "openai"
model_name = "gpt-4o-mini"
llm = init_chat_model(model_name, model_provider=model_provider, temperature=0)
✅ NEU (PFLICHT) - Kurznotation “provider:model”
from langchain.chat_models import init_chat_model
# ✨ Kurznotation: "provider:model" (STANDARD seit Dezember 2025)
llm = init_chat_model("openai:gpt-4o-mini", temperature=0.0)
# Weitere Beispiele:
llm = init_chat_model("anthropic:claude-3-sonnet", temperature=0.3)
llm = init_chat_model("groq:llama-3.1-70b", temperature=0.7)
llm = init_chat_model("google:gemini-pro", temperature=0.5)
# Mit zusätzlichen Parametern:
llm = init_chat_model("openai:gpt-4o-mini", temperature=0.0, max_tokens=1000)
🎯 Vorteile
- ✅ Kompakte, lesbare Syntax
- ✅ Provider-übergreifende Kompatibilität
- ✅ Einfacher Modell-Wechsel
- ✅ Zukunftssichere API
🆕 NEU in v1.1.0: Model Profile System
Chat-Modelle exposieren jetzt ihre Capabilities über das .profile Attribut:
from langchain.chat_models import init_chat_model
# Kurznotation verwenden
llm = init_chat_model("openai:gpt-4o-mini", temperature=0.0)
# ✨ NEU: Model Profiles (sourced from models.dev)
print(llm.profile.supports_structured_output) # True (deprecated: use 'structured_output')
print(llm.profile.supports_function_calling) # True (deprecated: use 'tool_calling')
print(llm.profile.supports_vision) # True (deprecated: use 'image_inputs')
print(llm.profile.supports_json_mode) # True (deprecated: use JSON Mode check)
# ✨ Moderne Attribute (v1.1.0+)
print(llm.profile['structured_output']) # True
print(llm.profile['tool_calling']) # True
print(llm.profile['image_inputs']) # True
print(llm.profile['max_input_tokens']) # 128000
# Dynamische Feature-Detection statt hartcodierter Provider-Logik!
if llm.profile['image_inputs']:
# Bild-Verarbeitung möglich
response = llm.invoke([HumanMessage(content=[
{"type": "text", "text": "Was siehst du?"},
{"type": "image", "url": "..."}
])])
🆕 Utility-Funktion: get_model_profile()
Für einfachere Nutzung gibt es in genai_lib.utilities eine Hilfsfunktion:
from genai_lib.utilities import get_model_profile
# Formatierte Ausgabe aller wichtigen Capabilities
profile = get_model_profile("openai:gpt-4o-mini")
# Output:
# 🔍 Model Profile: openai:gpt-4o-mini
# ============================================================
#
# 📋 Core Capabilities:
# ✓ Structured Output: True
# ✓ Function Calling: True
# ✓ JSON Mode: True
# ✓ Reasoning: False
#
# 🎨 Multimodal Capabilities:
# ✓ Input: 📝 Text, 🖼️ Image
# ✓ Output: 📝 Text
#
# 📊 Token Limits:
# ✓ Max Input Tokens: 128000
# ✓ Max Output Tokens: 16384
#
# ⚙️ Model Configuration:
# ✓ Temperature: Yes
# ✓ Knowledge Cutoff: 2023-10
#
# 🔧 Additional Features:
# ✓ Streaming: True
# ✓ Async: True
# ============================================================
# Ohne Ausgabe (nur Profile-Dict zurückgeben)
profile = get_model_profile("anthropic:claude-3-sonnet", print_profile=False)
# Verschiedene Models vergleichen (mit Fehlerbehandlung)
for model in ["openai:gpt-4o-mini", "anthropic:claude-3-sonnet", "google:gemini-pro"]:
print(f"\n{model}:")
profile = get_model_profile(model, print_profile=False)
if profile: # Nur verarbeiten, wenn Model erfolgreich initialisiert
print(f" Context: {profile['max_input_tokens']} tokens")
print(f" Vision: {profile['image_inputs']}")
print(f" Reasoning: {profile.get('reasoning', False)}")
print(f" Knowledge: {profile.get('knowledge_cutoff', 'N/A')}")
else:
print(f" ⚠️ Model konnte nicht initialisiert werden (Provider-Bibliothek fehlt?)")
Vorteile:
- ✅ Automatische Capability-Detection
- ✅ Keine hardcoded Provider-Checks mehr
- ✅ Quelle: models.dev (Open-Source Model-Index)
- ✅ Basis für intelligente Middleware (z.B. SummarizationMiddleware)
- ✅
get_model_profile()für formatierte Ausgabe und Modellvergleiche
2️⃣ with_structured_output() - Native Structured Outputs
❌ ALT (nicht mehr verwenden)
from langchain.output_parsers import PydanticOutputParser
parser = PydanticOutputParser(pydantic_object=Person)
prompt = PromptTemplate(
template="...\n{format_instructions}",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
✅ NEU (PFLICHT)
from pydantic import BaseModel, Field
class Person(BaseModel):
name: str = Field(description="Name der Person")
age: int = Field(description="Alter in Jahren")
# Direkt strukturierte Ausgabe
structured_llm = llm.with_structured_output(Person)
result = structured_llm.invoke("Max ist 25 Jahre alt")
# result ist direkt ein Person-Objekt!
🎯 Vorteile
- ✅ Garantierte Schema-Konformität (nutzt OpenAI’s Native API)
- ✅ Keine manuelle
format_instructionsmehr - ✅ Robuster und weniger fehleranfällig
- ✅ Kein JSON-Parsing mehr nötig
🆕 NEU in v1.1.0: Auto-Inference von ProviderStrategy
ProviderStrategy wird jetzt automatisch aus Model Profiles abgeleitet:
from pydantic import BaseModel, Field
class MovieRecommendation(BaseModel):
title: str = Field(description="Filmtitel")
genre: str = Field(description="Genre")
rating: float = Field(description="Bewertung 1-10")
# ✨ NEU in v1.1.0: Automatische Provider-Detection
structured_llm = llm.with_structured_output(MovieRecommendation)
# Nutzt automatisch native API wenn verfügbar (z.B. OpenAI's Structured Output)
# Basiert auf llm.profile.supports_structured_output
# Optional: Explizite Strategie (wie vorher)
structured_llm = llm.with_structured_output(
MovieRecommendation,
provider_strategy="native" # Wird automatisch aus Profile erkannt!
)
Vorteile:
- ✅ Intelligente Defaults basierend auf Model Capabilities
- ✅ Weniger manuelle Konfiguration
- ✅ Optimale Strategie pro Provider (OpenAI native vs. fallback)
3️⃣ @tool Decorator - Tool Definitions
❌ ALT (nicht mehr verwenden)
from langchain.agents import Tool
multiply_tool = Tool(
name="multiply",
func=lambda a, b: a * b,
description="Multipliziert zwei Zahlen"
)
✅ NEU (PFLICHT)
from langchain_core.tools import tool
@tool
def multiply(a: int, b: int) -> int:
"""Multipliziert zwei Zahlen."""
return a * b
🎯 Vorteile
- ✅ Automatische Schema-Generierung aus Docstring
- ✅ Type-Safety durch Python Type Hints
- ✅ Weniger Boilerplate-Code
- ✅ Bessere IDE-Unterstützung
🆕 NEU in v1.2.0: Tool Extras für Provider-spezifische Features
Tools unterstützen jetzt extras für provider-native Konfigurationen:
from langchain_core.tools import tool
# ✨ NEU: Provider-spezifische Tool-Parameter
@tool(extras={
"anthropic": {
"cache_control": {"type": "ephemeral"}, # Anthropic Prompt Caching
"disable_parallel_tool_use": False
},
"openai": {
"strict": True # OpenAI Strict Mode (garantierte Schema-Konformität)
}
})
def search_database(query: str, limit: int = 10) -> str:
"""Durchsucht die Datenbank nach relevanten Informationen.
Args:
query: Suchanfrage
limit: Maximale Anzahl Ergebnisse
"""
return f"Gefunden: {limit} Ergebnisse für '{query}'"
# Tool mit Anthropic programmatic tool calling
@tool(extras={
"anthropic": {
"type": "computer_20241022", # Anthropic Computer Use
"display_width_px": 1024,
"display_height_px": 768
}
})
def take_screenshot() -> str:
"""Erstellt einen Screenshot des Bildschirms."""
return "screenshot.png"
Vorteile:
- ✅ Provider-native Features nutzen (Caching, Strict Mode, Computer Use)
- ✅ Built-in Client-Side Tools für Anthropic, OpenAI
- ✅ Optimierte Performance durch provider-spezifische Optimierungen
- ✅ Backwards-compatible: Tools ohne
extrasfunktionieren weiterhin
Use Cases:
- Anthropic Prompt Caching für häufig verwendete Tools
- OpenAI Strict Mode für garantierte Schema-Konformität
- Anthropic Computer Use für Browser-Automation
- Provider-spezifische Tool-Konfigurationen
4️⃣ create_agent() - Modern Agent API
❌ ALT (nicht mehr verwenden)
from langchain.agents import initialize_agent, AgentType
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
✅ NEU (PFLICHT)
from langchain.agents import create_agent
agent = create_agent(
model=llm, # oder "openai:gpt-4"
tools=[tool1, tool2],
system_prompt="You are a helpful assistant",
debug=True # Zeigt Denkprozess (= verbose=True)
)
# Agent aufrufen (gibt CompiledStateGraph zurück)
response = agent.invoke({
"messages": [{"role": "user", "content": "your question"}]
})
🎯 Vorteile
- ✅ Basiert auf LangGraph (State Machine)
- ✅ Kein
AgentExecutormehr nötig - ✅ Besseres Debugging mit
debug=True - ✅ Middleware-Support (siehe Feature #6)
🆕 NEU in v1.1.0: SystemMessage Support
system_prompt akzeptiert jetzt SystemMessage mit erweiterten Features:
from langchain.agents import create_agent
from langchain_core.messages import SystemMessage
# ❌ ALT: Nur String
agent = create_agent(
model=llm,
tools=tools,
system_prompt="You are a helpful assistant"
)
# ✅ NEU in v1.1.0: SystemMessage mit Cache-Control
agent = create_agent(
model=llm,
tools=tools,
system_prompt=SystemMessage(
content="You are a helpful research assistant with access to web search and databases.",
cache_control={"type": "ephemeral"} # Anthropic Cache-Control
)
)
# ✅ NEU: SystemMessage mit strukturierten Content Blocks
agent = create_agent(
model=llm,
tools=tools,
system_prompt=SystemMessage(
content=[
{"type": "text", "text": "You are a helpful assistant."},
{"type": "text", "text": "Important guidelines:", "cache_control": {"type": "ephemeral"}}
]
)
)
Vorteile:
- ✅ Cache-Control für Anthropic Claude (schneller + günstiger)
- ✅ Strukturierte Content Blocks im System-Prompt
- ✅ Richer System-Level Instructions mit Metadata
- ✅ Backwards-compatible: String-Prompts funktionieren weiterhin
🆕 NEU in v1.2.0: Strict Schema für Agent-Responses
Agents unterstützen jetzt response_format für strikte Validierung von Agent-Outputs:
from langchain.agents import create_agent
from pydantic import BaseModel, Field
# Definiere strukturiertes Response-Schema
class AgentResponse(BaseModel):
"""Strukturierte Agent-Antwort mit Reasoning."""
reasoning: str = Field(description="Denkprozess des Agents")
action: str = Field(description="Geplante Aktion")
tool_to_use: str | None = Field(description="Zu verwendendes Tool (optional)")
confidence: float = Field(description="Konfidenz 0-1", ge=0, le=1)
# ✨ NEU in v1.2.0: response_format für garantierte Schema-Konformität
agent = create_agent(
model=llm,
tools=[search_tool, calculator_tool],
system_prompt="You are a helpful research assistant",
response_format=AgentResponse, # Strikte Validierung!
provider_strategy="strict" # Nutzt OpenAI Structured Output (wenn verfügbar)
)
# Agent-Response ist garantiert schema-konform
response = agent.invoke({
"messages": [{"role": "user", "content": "Recherchiere die Bevölkerung von Berlin"}]
})
# Typsicherer Zugriff auf strukturierte Felder
print(response.reasoning) # str
print(response.confidence) # float (0-1)
Vorteile:
- ✅ Garantierte Schema-Konformität für Agent-Outputs (keine JSON-Parsing-Fehler)
- ✅ Type-Safety mit Pydantic-Validierung
- ✅ Bessere Fehlerbehandlung durch strukturierte Responses
- ✅ Strikte Provider-Integration (OpenAI Structured Output, Anthropic Tool Use)
- ✅ Predictable Agent-Behavior für Production-Systeme
Use Cases:
- Production-Agents mit garantierten Output-Formaten
- Multi-Step-Reasoning mit strukturierten Zwischenschritten
- Agent-Monitoring mit standardisierten Response-Metriken
- Integration in typsichere Workflows
Kombination mit Structured Output:
# response_format arbeitet nahtlos mit with_structured_output()
structured_llm = llm.with_structured_output(AgentResponse)
agent = create_agent(
model=structured_llm,
tools=tools,
response_format=AgentResponse, # Doppelte Validierung (LLM + Agent-Level)
provider_strategy="strict"
)
5️⃣ LCEL | Chains - Expression Language
❌ ALT (vermeiden)
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run(input="text")
✅ NEU (PFLICHT)
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# Pipe-Operator für Chain-Komposition
chain = prompt | llm | StrOutputParser()
# Aufruf
result = chain.invoke({"input": "text"})
# Asynchrone Unterstützung
result = await chain.ainvoke({"input": "text"})
🎯 Vorteile
- ✅ Moderne, lesbare Syntax
- ✅ Automatisches Streaming-Support
- ✅ Parallele Ausführung wo möglich
- ✅ Native async/await-Unterstützung
6️⃣ Middleware für Agents - Production-Ready Features
❌ ALT (deprecated)
# Hooks sind in 1.0+ deprecated
agent_executor.register_hook("before_agent", my_hook)
✅ NEU (PFLICHT)
from langchain.agents import create_agent
from langchain.agents.middleware import (
HumanInTheLoopMiddleware,
SummarizationMiddleware,
PIIMiddleware
)
middleware = [
HumanInTheLoopMiddleware(
tool_names=["delete_file", "execute_command"] # Genehmigung erforderlich
),
SummarizationMiddleware(
max_tokens=1000 # Automatische Kontext-Zusammenfassung
),
PIIMiddleware(
patterns=["email", "phone"] # PII-Redaktion
)
]
agent = create_agent(
model=llm,
tools=tools,
system_prompt="You are a helpful assistant",
middleware=middleware # Middleware hinzufügen
)
🎯 Vorteile
- ✅ Human-in-the-Loop für sensible Operationen (Essential für Production!)
- ✅ Automatische Kontextverwaltung bei langen Sessions (verhindert Token-Overflow)
- ✅ PII-Redaktion für Datenschutz (DSGVO-konform)
- ✅ Custom Middleware für spezifische Anforderungen
📦 Built-in Middleware
| Middleware | Zweck | Wann verwenden? |
|---|---|---|
HumanInTheLoopMiddleware | Manuelle Genehmigung vor Tool-Ausführung | Dateioperationen, API-Calls, kritische Aktionen |
SummarizationMiddleware | Automatische Zusammenfassung langer Konversationen | Chat-Apps, lange Sessions |
PIIMiddleware | Datenschutz durch Mustererkennung | DSGVO-Compliance, sensible Daten |
ModelRetryMiddleware 🆕 | Automatische Retries mit exponential backoff | Flaky APIs, Rate Limits |
ContentModerationMiddleware 🆕 | OpenAI Moderation für User/Model/Tool-Outputs | Safety-Layer, Content-Filter |
🆕 NEU in v1.1.0: Erweiterte Middleware
ModelRetryMiddleware (NEU!)
Automatische Retries bei API-Fehlern mit konfigurierbarem exponential backoff:
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware
agent = create_agent(
model=llm,
tools=tools,
middleware=[
ModelRetryMiddleware(
max_retries=3,
backoff_factor=2.0, # Exponential Backoff (2s, 4s, 8s)
retry_on=["rate_limit_error", "timeout", "server_error"],
jitter=True # Randomized delay
)
]
)
Use Cases:
- ✅ Rate-Limiting von API-Providern
- ✅ Transiente Netzwerkfehler
- ✅ Server-Timeouts
- ✅ Production-Resilience
HumanInTheLoopMiddleware respond()-Decision (NEU in v1.2.17)
Was neu ist: beendet den Agent-Loop sofort mit einer direkten Antwort.
In der Praxis relevant wenn: Guardrails sollen dem Nutzer eine klare Fehlermeldung liefern, die das LLM nicht nochmals umformulieren muss.
ContentModerationMiddleware (NEU!)
OpenAI Moderation API für konsistente Safety-Layer:
from langchain.agents.middleware import ContentModerationMiddleware
agent = create_agent(
model=llm,
tools=tools,
middleware=[
ContentModerationMiddleware(
provider="openai", # Nutzt OpenAI Moderation API
check_user_input=True, # Filter User-Inputs
check_model_output=True, # Filter Model-Responses
check_tool_output=True, # Filter Tool-Results
block_on_violation=True, # Workflow stoppen bei Violation
categories=["hate", "violence", "sexual"] # Spezifische Kategorien
)
]
)
Use Cases:
- ✅ User-Generated Content-Filter
- ✅ DSGVO-Compliance & Safety
- ✅ Brand-Safety für Production-Apps
- ✅ Multi-Layer-Content-Moderation
Verbesserter SummarizationMiddleware
Nutzt jetzt Model Profiles für intelligente Zusammenfassungen:
from langchain.agents.middleware import SummarizationMiddleware
# ✅ v1.1.0: Context-aware Summarization
middleware = SummarizationMiddleware(
max_tokens=1000,
# NEU: Automatische Detection von Summarization-Capabilities via llm.profile
# Provider-spezifische Optimierungen (GPT-4 vs Claude vs Gemini)
trigger_strategy="flexible" # Intelligente Trigger-Points basierend auf Model
)
Verbesserungen:
- ✅ Nutzt
llm.profilefür optimale Summarization-Strategie - ✅ Provider-spezifische Optimierungen
- ✅ Flexible Trigger-Points (nicht nur hard limit)
- ✅ Bessere Performance auf langen Sessions
🆕 ContextOverflowError (v1.2.1+, Januar 2026)
Neuer Fehlertyp für automatisches Context-Window-Management:
from langchain_core.exceptions import ContextOverflowError
from langchain.agents.middleware import SummarizationMiddleware
# SummarizationMiddleware fängt ContextOverflowError automatisch ab
# und fasst die bisherige Konversation zusammen, bevor der Aufruf wiederholt wird
middleware = SummarizationMiddleware(
max_tokens=1000,
# NEU: Automatischer Trigger bei ContextOverflowError
# Kein manuelles Token-Zählen mehr nötig!
)
Vorteile:
- ✅ Wird von
langchain-openaiundlangchain-anthropicnativ ausgelöst - ✅
SummarizationMiddlewarereagiert automatisch darauf - ✅ Kein manuelles Context-Window-Management mehr nötig
- ✅
count_tokens_approximately()zählt jetzt auch Tool-Schema-Tokens
🆕 Automatic Server-Side Compaction (langchain-openai 1.1.10, Feb 2026)
Alternative zu SummarizationMiddleware: OpenAI komprimiert die Konversationshistorie serverseitig – kein extra Middleware-Layer nötig.
from langchain.chat_models import init_chat_model
# OpenAI komprimiert automatisch bei langen Konversationen
llm = init_chat_model(
"openai:gpt-4o",
context_management=[{"type": "compaction", "compact_threshold": 10_000}]
# compact_threshold: Token-Schwellenwert, ab dem komprimiert wird
)
Vergleich: Server-Side vs. Client-Side Context-Management:
| Ansatz | Wie | Provider | Kosten |
|---|---|---|---|
SummarizationMiddleware | Client: LLM fasst zusammen | Alle | Zusätzliche LLM-Kosten |
context_management (neu) | Server: OpenAI komprimiert | Nur OpenAI | In API-Kosten enthalten |
Wann welchen Ansatz wählen:
- ✅
context_management→ OpenAI-Apps, einfachste Lösung - ✅
SummarizationMiddleware→ Provider-unabhängig, mehr Kontrolle
7️⃣ Standard Message Content Blocks - Multimodal Support
❌ ALT (provider-spezifisch)
# OpenAI-spezifisch
message.additional_kwargs["image_url"]
# Anthropic-spezifisch
message.additional_kwargs["content"]
✅ NEU (PFLICHT)
from langchain_core.messages import AIMessage, HumanMessage
# Standardisierte content_blocks
message = AIMessage(
content=[
{"type": "text", "text": "Here's the image analysis:"},
{"type": "image", "url": "data:image/png;base64,...", "mime_type": "image/png"}
]
)
# Provider-agnostischer Zugriff
for block in message.content_blocks:
if block["type"] == "text":
print(block["text"])
elif block["type"] == "image":
display_image(block["url"])
elif block["type"] == "audio":
play_audio(block["url"])
🎯 Vorteile
- ✅ Einheitliches Interface über alle Provider (OpenAI, Anthropic, Google, Cohere)
- ✅ Multimodal-Support: Text, Bilder, Audio, Video
- ✅ Reasoning Traces & Citations für transparente KI-Entscheidungen
- ✅ Einfacher Provider-Wechsel ohne Code-Änderungen
📦 Unterstützte Content-Typen
# Text
{"type": "text", "text": "..."}
# Bild
{"type": "image", "url": "...", "mime_type": "image/png"}
# Audio
{"type": "audio", "url": "...", "mime_type": "audio/mp3"}
# Video
{"type": "video", "url": "...", "mime_type": "video/mp4"}
# Reasoning Trace (für erklärbare KI)
{"type": "reasoning", "text": "...", "confidence": 0.95}
# Citation (Quellenangaben)
{"type": "citation", "text": "...", "source": "..."}
🎨 Anwendungsfälle
- ✅ Multimodale RAG-Systeme (perfekt für
04_modul/genai_lib/multimodal_rag.py) - ✅ Bild-zu-Text und Text-zu-Bild Pipelines
- ✅ Audio/Video-Analyse mit LLMs
- ✅ Provider-unabhängige Chatbots
🧠 Thinking-Formate parsen mit extract_thinking()
Verschiedene LLMs liefern “Thinking” (Denkprozess) in unterschiedlichen Formaten. Die Utility-Funktion extract_thinking() aus genai_lib.utilities bietet einen universellen Parser:
from genai_lib.utilities import extract_thinking
# Response von beliebigem LLM
response = llm.invoke("Erkläre Schritt für Schritt...")
# Universeller Parser für alle Formate
thinking, answer = extract_thinking(response)
print(f"Denkprozess: {thinking[:200]}...")
print(f"Antwort: {answer}")
Unterstützte Formate:
| Provider/Modell | Format | Beispiel |
|---|---|---|
| Claude (Extended Thinking) | Liste mit {"type": "thinking"} Blöcken | content = [{"type": "thinking", "thinking": "..."}] |
| Gemini | Liste mit {"type": "thinking"} Blöcken | content = [{"type": "thinking", "thinking": "..."}] |
| Qwen3, DeepSeek R1 | String mit <think> Tags | "<think>Denkprozess</think>Antwort" |
| DeepSeek | additional_kwargs["reasoning_content"] | Separates Feld im Response |
Vorteile:
- ✅ Provider-agnostisch: Ein Parser für alle LLMs
- ✅ Fallback-Logik: Prüft alle bekannten Formate
- ✅ Robust: Gibt leeren Thinking-String zurück, wenn kein Denkprozess vorhanden
8️⃣ .with_retry() und .with_fallbacks() - Robuste Chains
Beide Methoden gehören zum Runnable-Interface (LCEL) und lassen sich auf jede Chain, jedes LLM oder jeden OutputParser anwenden.
.with_retry() – Fehlertolerante Ausführung
Wiederholt einen Runnable automatisch bei definierten Fehlern (z. B. Rate Limits, Timeouts).
❌ ALT (manuell)
import time
for attempt in range(3):
try:
result = llm.invoke("...")
break
except RateLimitError:
time.sleep(2 ** attempt)
✅ NEU (EMPFOHLEN)
# Einfachste Form: 3 Versuche bei allen Fehlern
robust_llm = llm.with_retry(stop_after_attempt=3)
# Gezielt: nur bei Rate-Limit- und Timeout-Fehlern
from langchain_openai.exceptions import RateLimitError
import httpx
robust_llm = llm.with_retry(
retry_if_exception_type=(RateLimitError, httpx.TimeoutException),
stop_after_attempt=3,
wait_exponential_jitter=True # Exponential Backoff + Jitter
)
result = robust_llm.invoke("Wie ist das Wetter?")
Auf LCEL-Chains anwenden
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
chain = (
ChatPromptTemplate.from_template("Beantworte: {frage}")
| llm
| StrOutputParser()
).with_retry(stop_after_attempt=3)
result = chain.invoke({"frage": "Was ist LangChain?"})
🎯 Vorteile
- ✅ Kein Boilerplate-Code für Retry-Logik
- ✅ Konfigurierbare Fehlertypen (nur relevante Exceptions)
- ✅ Exponential Backoff mit Jitter verhindert API-Überlastung
- ✅ Gilt für LLMs, Chains, Tools – jeden Runnable
Wann verwenden?
- ✅ Rate-Limit-Fehler (OpenAI, Anthropic)
- ✅ Transiente Netzwerkfehler / Timeouts
- ✅ Flaky externe APIs in Tools
- ❌ Nicht bei Validierungs- oder Logikfehlern (die sind nicht transient)
.with_fallbacks() – Ausfallsichere Chains
Schaltet automatisch auf ein Fallback-LLM oder eine alternative Chain um, wenn der primäre Runnable fehlschlägt.
✅ Verwendung
from langchain.chat_models import init_chat_model
primary_llm = init_chat_model("openai:gpt-4o", temperature=0.0)
fallback_llm = init_chat_model("openai:gpt-4o-mini", temperature=0.0)
# Bei Fehler des primären LLMs → automatisch gpt-4o-mini
safe_llm = primary_llm.with_fallbacks([fallback_llm])
result = safe_llm.invoke("Erkläre Transformer-Modelle.")
Mehrere Fallbacks (Kaskade)
llm_gpt4 = init_chat_model("openai:gpt-4o", temperature=0.0)
llm_gpt4_mini = init_chat_model("openai:gpt-4o-mini", temperature=0.0)
llm_anthropic = init_chat_model("anthropic:claude-3-haiku", temperature=0.0)
# Kaskade: gpt-4o → gpt-4o-mini → claude-3-haiku
resilient_llm = llm_gpt4.with_fallbacks([llm_gpt4_mini, llm_anthropic])
Kombination mit .with_retry()
# Empfohlenes Pattern für Production:
# 1. Erst 3× Retry auf dem primären LLM
# 2. Dann Fallback auf alternatives Modell
safe_chain = (
llm_gpt4.with_retry(stop_after_attempt=3)
).with_fallbacks([llm_gpt4_mini])
Auf structured output anwenden
structured_primary = llm_gpt4.with_structured_output(Person)
structured_fallback = llm_gpt4_mini.with_structured_output(Person)
safe_structured = structured_primary.with_fallbacks([structured_fallback])
result = safe_structured.invoke("Anna Müller ist 32 Jahre alt.")
🎯 Vorteile
- ✅ Zero-Downtime bei Provider-Ausfällen
- ✅ Kostenkontrolle (teures Modell → günstiges Fallback)
- ✅ Provider-Diversität als Resilienz-Strategie
- ✅ Kombinierbar mit
.with_retry()undwith_structured_output()
Wann verwenden?
- ✅ Production-Systeme mit hoher Verfügbarkeitsanforderung
- ✅ Kostenoptimierung (Primär: leistungsstark, Fallback: günstig)
- ✅ Multi-Provider-Setups
- ❌ Nicht als Ersatz für Retry (Fallback = anderes Modell, nicht Wiederholung)
🚀 Quick Start: Komplettes Beispiel
# 1. Model Initialization
from langchain.chat_models import init_chat_model
llm = init_chat_model(
"gpt-4o-mini",
model_provider="openai",
temperature=0.0
)
# 2. Structured Output
from pydantic import BaseModel, Field
class MovieRecommendation(BaseModel):
title: str = Field(description="Filmtitel")
genre: str = Field(description="Genre")
rating: float = Field(description="Bewertung 1-10")
structured_llm = llm.with_structured_output(MovieRecommendation)
# 3. Tools mit @tool Decorator
from langchain_core.tools import tool
@tool
def search_movies(query: str) -> str:
"""Sucht nach Filmen in der Datenbank."""
return f"Ergebnisse für: {query}"
# 4. Agent mit Middleware
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
agent = create_agent(
model=llm,
tools=[search_movies],
system_prompt="Du bist ein hilfreicher Film-Assistent",
middleware=[
HumanInTheLoopMiddleware(tool_names=["search_movies"])
],
debug=True
)
# 5. LCEL Chain
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("Empfehle einen {genre}-Film")
chain = prompt | llm | StrOutputParser()
result = chain.invoke({"genre": "Sci-Fi"})
# 6. Multimodal Content Blocks
from langchain_core.messages import HumanMessage
message = HumanMessage(
content=[
{"type": "text", "text": "Was siehst du auf diesem Bild?"},
{"type": "image", "url": "data:image/png;base64,...", "mime_type": "image/png"}
]
)
response = llm.invoke([message])
📚 Import-Cheatsheet
# Models
from langchain.chat_models import init_chat_model
# Structured Output
from pydantic import BaseModel, Field
# Tools
from langchain_core.tools import tool
# Agents & Middleware
from langchain.agents import create_agent
from langchain.agents.middleware import (
HumanInTheLoopMiddleware,
SummarizationMiddleware,
PIIMiddleware,
ModelRetryMiddleware, # 🆕 v1.1.0
ContentModerationMiddleware # 🆕 v1.1.0
)
# Chains (LCEL)
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# Messages & Content Blocks
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
# Prompts
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
# Robustheit (with_retry / with_fallbacks sind Methoden auf Runnables,
# kein separater Import nötig – direkt auf llm/chain anwenden)
# Vectorstores & RAG
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
⚠️ Breaking Changes von 0.x zu 1.0+
| Alt (0.x) | Neu (1.0+) | Status |
|---|---|---|
ChatOpenAI() direkt | init_chat_model() | ⛔ Deprecated |
PydanticOutputParser | with_structured_output() | ⛔ Deprecated |
Tool() wrapper | @tool decorator | ⛔ Deprecated |
initialize_agent() + AgentExecutor | create_agent() | ⛔ Deprecated |
| Hook-Pattern | Middleware | ⛔ Deprecated |
| Provider-spezifische Content-Formate | Standard Content Blocks | ⛔ Deprecated |
🎯 Migration-Checkliste
Beim Refactoring von altem Code:
ChatOpenAI()→init_chat_model()ersetzenPydanticOutputParser→with_structured_output()ersetzenTool()wrapper →@tooldecorator ersetzeninitialize_agent()→create_agent()ersetzen- Legacy Chain-Syntax → LCEL
|ersetzen - Hooks → Middleware ersetzen
- Provider-spezifische Content →
content_blocksersetzen - Python 3.10+ erforderlich (3.9 wird nicht mehr unterstützt)
- Custom State muss
TypedDictverwenden (keine Pydantic Models)
📖 Weitere Ressourcen
- LangChain Docs: https://python.langchain.com/
- Migration Guide: https://docs.langchain.com/oss/python/migrate/langchain-v1
- LangChain Blog: https://blog.langchain.com/langchain-langgraph-1dot0/
- Projekt CLAUDE.md: Vollständige Projektinstruktionen im Repository
Abgrenzung zu verwandten Dokumenten
| Dokument | Frage |
|---|---|
| Erste Agenten | Wo starte ich als Einsteiger mit LangChain Best Practices? |
| Qualität und Sicherheit | Welche Produktionsstandards gelten für LangChain Best Practices? |
📝 Changelog
Version 1.7 (Mai 2026)
- 🆕
astream_events()v3 Protokoll —version="v3"in LangChain v1.3.0 verfügbar (bisher max. v2) - 🆕 langchain-core v1.4.0 — Content-Block-Streaming v2 jetzt stabil (war Beta in 1.3.2)
- 🆕
HumanInTheLoopMiddleware.respond()— direkte Antwort aus Middleware ohne weiteren LLM-Call (v1.2.17)
Version: 1.7
Stand: Mai 2026
Kurs: KI-Agenten. Verstehen. Anwenden. Gestalten.