KI-Agenten & Python

LangChain Agents mit Claude Code: KI-Workflows automatisieren 2026

📅 5. Mai 2026 ⏱ 11 min Lesezeit ✍️ SpockyMagicAI Team
🔗 LangChain LCEL 🤖 Agents vs. Chains 🛠 Custom Tools 💾 Memory 🕸 LangGraph 🔭 LangSmith

LangChain ist 2026 das meistgenutzte Python-Framework für produktionsreife KI-Agenten. In Kombination mit Claude Code — Anthropics autonomem Coding-Assistenten — entstehen Systeme, die Recherche, Codegeneration, Datenbankabfragen und externe APIs in einem einzigen kontrollierten Workflow verbinden. Dieser Guide zeigt dir, wie du das gesamte LangChain-Ökosystem produktiv einsetzt.

LangChain Expression Language (LCEL): Chains bauen

LCEL ist die deklarative Kompositions-API von LangChain. Statt imperativem Callback-Spaghetti verbindest du Komponenten mit dem |-Operator — ähnlich wie Unix-Pipes. Jede Komponente ist ein Runnable: gleiche Schnittstelle, beliebig austauschbar.

LCEL Grundprinzip

input | prompt | llm | output_parser — jede Stufe transformiert den Output der vorherigen. Alle Runnables unterstützen .invoke(), .stream(), .batch() und async-Varianten out of the box.

from langchain_anthropic import ChatAnthropic from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # Modell initialisieren llm = ChatAnthropic(model="claude-opus-4-5", max_tokens=2048) # Prompt-Template prompt = ChatPromptTemplate.from_messages([ ("system", "Du bist ein erfahrener Python-Entwickler. Antworte präzise auf Deutsch."), ("human", "{question}") ]) # LCEL Chain zusammenstellen chain = prompt | llm | StrOutputParser() # Synchron aufrufen result = chain.invoke({"question": "Erkläre async/await in Python"}) # Streaming (Token-für-Token) for chunk in chain.stream({"question": "Erkläre async/await in Python"}): print(chunk, end="", flush=True)

Parallele Chains mit RunnableParallel

Mit RunnableParallel führst du mehrere Branches gleichzeitig aus — ideal für Analysen, die unabhängige Sub-Tasks kombinieren:

from langchain_core.runnables import RunnableParallel, RunnablePassthrough summary_chain = prompt_summary | llm | StrOutputParser() sentiment_chain = prompt_sentiment | llm | StrOutputParser() parallel = RunnableParallel( zusammenfassung=summary_chain, stimmung=sentiment_chain, original=RunnablePassthrough() ) output = parallel.invoke({"text": "Langer Kundenbericht..."}) # output = {"zusammenfassung": "...", "stimmung": "positiv", "original": {...}}

Agents vs. Chains: Wann welches Pattern?

Die häufigste Architektur-Frage: Reicht eine Chain, oder brauche ich einen vollwertigen Agent? Die Antwort hängt davon ab, ob der Ablauf zur Laufzeit entschieden werden muss.

Kriterium Chain Agent
AblaufFest vordefiniertDynamisch, LLM entscheidet
Tool-NutzungOptional, statisch eingebautBeliebige Tools, zur Laufzeit gewählt
LatenzNiedrig (1–3 LLM-Calls)Höher (ReAct-Loop, N Calls)
KostenBesser kontrollierbarVariabel, Token-Budget nötig
DebuggingEinfachKomplex (LangSmith empfohlen)
AnwendungsfallRAG, Summarization, ETLRecherche, Code-Ausführung, Multi-Step
Faustregel: Beginne immer mit einer Chain. Wenn du merkst, dass das LLM entscheiden muss welche Tools es in welcher Reihenfolge aufruft — wechsle zum Agent-Pattern.

LangChain Tools: Eigene Tools definieren

Tools sind das Herzstück von LangChain-Agenten. Mit dem @tool-Decorator oder der StructuredTool-Klasse bindest du beliebige Python-Funktionen als abrufbare Fähigkeiten ein.

Custom Tool mit Pydantic-Schema

Der Docstring wird automatisch als Tool-Beschreibung genutzt — schreibe ihn so, als würdest du einem Menschen erklären, wann das Tool verwendet werden soll.

from langchain_core.tools import tool from pydantic import BaseModel, Field import httpx # Einfaches Tool mit @tool Decorator @tool def get_current_weather(city: str) -> str: """Gibt das aktuelle Wetter für eine Stadt zurück. Nutze dieses Tool wenn der Nutzer nach dem aktuellen Wetter fragt.""" resp = httpx.get(f"https://api.weather.example.com/?q={city}") return resp.text # Tool mit strukturiertem Input-Schema class SearchInput(BaseModel): query: str = Field(description="Die Suchanfrage") max_results: int = Field(default=5, description="Anzahl der Ergebnisse") @tool(args_schema=SearchInput) def web_search(query: str, max_results: int = 5) -> str: """Durchsucht das Internet nach aktuellen Informationen.""" # Integration mit Tavily, SerpAPI, etc. return perform_search(query, max_results) # Agent mit Tools erstellen from langchain.agents import create_tool_calling_agent, AgentExecutor tools = [get_current_weather, web_search] agent = create_tool_calling_agent(llm, tools, agent_prompt) executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
Best Practice: Definiere jeden Tool-Docstring mit Beispiel-Triggern. Das LLM wählt das richtige Tool nur dann zuverlässig, wenn es versteht, wann es aufgerufen werden soll — nicht nur was es tut.

Memory: ConversationBufferMemory & VectorStore Memory

Ohne Memory ist jeder LLM-Call zustandslos. LangChain bietet mehrere Memory-Strategien — von einfachem Buffer bis zu semantisch durchsuchbarem Langzeit-Speicher.

Memory-Typen im Überblick
from langchain.memory import ConversationBufferMemory from langchain_community.vectorstores import Chroma from langchain_anthropic import AnthropicEmbeddings from langchain.memory import VectorStoreRetrieverMemory # Einfacher Buffer (Short-Term Memory) buffer_memory = ConversationBufferMemory( memory_key="chat_history", return_messages=True, output_key="output" ) # VectorStore Memory (Long-Term Memory) embeddings = AnthropicEmbeddings() vectorstore = Chroma( collection_name="agent_memory", embedding_function=embeddings, persist_directory="./chroma_db" ) retriever = vectorstore.as_retriever(search_kwargs={"k": 5}) vs_memory = VectorStoreRetrieverMemory(retriever=retriever) # Memory in Chain einbinden from langchain.chains import ConversationChain conv_chain = ConversationChain( llm=llm, memory=buffer_memory, verbose=True ) response1 = conv_chain.predict(input="Mein Name ist Klaus.") response2 = conv_chain.predict(input="Wie heißt du nochmal mein Name?") # → "Du hast mir gesagt, dass du Klaus heißt."
Praxis-Tipp: Kombiniere beide Strategien: ConversationBufferWindowMemory (k=10) für den aktiven Kontext + VectorStoreRetrieverMemory für Langzeit-Fakten. So bleiben Tokens kontrollierbar und trotzdem kein Wissen verloren.

LangGraph: State-Machines für komplexe Agent-Flows

LangGraph ist die Antwort auf die Grenzen einfacher ReAct-Agenten. Statt linearer Loops modellierst du Agent-Verhalten als gerichteten azyklischen Graphen (DAG) — mit Zyklen, bedingten Kanten und persistierendem State.

Wann LangGraph statt AgentExecutor?
from langgraph.graph import StateGraph, END from typing import TypedDict, Annotated, List import operator # State-Schema definieren class ResearchState(TypedDict): question: str search_results: List[str] draft: str final_answer: str iteration: int # Knoten-Funktionen (je ein LLM-Call oder Tool-Aufruf) def search_node(state: ResearchState) -> ResearchState: results = web_search.invoke(state["question"]) return {"search_results": [results], "iteration": state["iteration"] + 1} def draft_node(state: ResearchState) -> ResearchState: context = "\n".join(state["search_results"]) draft = draft_chain.invoke({"context": context, "question": state["question"]}) return {"draft": draft} def quality_check(state: ResearchState) -> str: # Bedingte Kante: ausreichend oder nochmal suchen? if state["iteration"] >= 3 or is_sufficient(state["draft"]): return "finalize" return "search" # Graph zusammenstellen workflow = StateGraph(ResearchState) workflow.add_node("search", search_node) workflow.add_node("draft", draft_node) workflow.add_node("finalize", finalize_node) workflow.set_entry_point("search") workflow.add_edge("search", "draft") workflow.add_conditional_edges("draft", quality_check, {"search": "search", "finalize": "finalize"}) workflow.add_edge("finalize", END) app = workflow.compile() result = app.invoke({"question": "Beste LLM-Frameworks 2026?", "iteration": 0, "search_results": []})

LangGraph Checkpointing — Workflows pausieren

Mit dem integrierten Checkpointer kannst du Workflows unterbrechen, menschliche Genehmigung einholen und dann weitermachen — ohne den gesamten State neu aufzubauen:

from langgraph.checkpoint.sqlite import SqliteSaver memory = SqliteSaver.from_conn_string(":memory:") app = workflow.compile( checkpointer=memory, interrupt_before=["finalize"] # Pause vor dem finalen Schritt ) config = {"configurable": {"thread_id": "research-42"}} app.invoke({"question": "..."}, config) # Läuft bis "finalize"-Pause # → Menschliche Prüfung hier einfügen app.invoke(None, config) # Weiter vom Checkpoint

LangSmith: Debugging und Monitoring von Agents

LangSmith ist das Observability-Layer für LangChain. Jeder LLM-Call, jeder Tool-Aufruf, jede Chain-Ausführung wird als Trace erfasst — mit voller Sichtbarkeit auf Input, Output, Latenz und Token-Verbrauch.

LangSmith Setup (2 Minuten)
# .env Datei LANGCHAIN_TRACING_V2=true LANGCHAIN_ENDPOINT="https://api.smith.langchain.com" LANGCHAIN_API_KEY="ls__dein_api_key" LANGCHAIN_PROJECT="claude-code-agents"
import os from dotenv import load_dotenv load_dotenv() # Ab hier werden ALLE LangChain-Calls automatisch getraced result = chain.invoke({"question": "..."}) # → Sichtbar in smith.langchain.com unter Projekt "claude-code-agents" # Manuelle Traces mit @traceable from langsmith import traceable @traceable(name="preprocessing_step") def preprocess_data(raw_text: str) -> str: # Diese Funktion erscheint als eigener Span im Trace return raw_text.strip().lower() # Evaluierungen erstellen from langsmith.evaluation import evaluate results = evaluate( lambda inputs: chain.invoke(inputs), data="mein-test-dataset", evaluators=["correctness", "relevance"] )
LangSmith-Workflow mit Claude Code: Lass Claude Code deine Chains implementieren, dann öffne LangSmith und schau dir die Traces an. Häufigste Bugs: falsches Prompt-Format, fehlende Tool-Descriptions, Memory-Key-Konflikte — alles sofort im Trace sichtbar.

Datasets & Regression Testing

LangSmith ermöglicht es, aus echten Produktions-Runs automatisch Test-Datasets zu erstellen. So merkst du sofort, wenn ein Prompt-Update eine Regression verursacht — bevor es in Produktion geht.

from langsmith import Client client = Client() # Dataset aus Produktion erstellen dataset = client.create_dataset( dataset_name="production-edge-cases", description="Schwierige Anfragen aus Produktion" ) # Testfälle hinzufügen client.create_examples( inputs=[{"question": "Komplexe Anfrage 1"}], outputs=[{"answer": "Erwartete Antwort"}], dataset_id=dataset.id )

Bereit für produktionsreife LangChain-Agenten?

Starte kostenlos und lass Claude Code deine komplexen KI-Workflows bauen — von LCEL Chains bis zu LangGraph State-Machines.

Kostenlos testen →

Fazit: LangChain + Claude Code = Production-Ready AI

Das LangChain-Ökosystem 2026 ist ausgereifte Infrastruktur. LCEL macht Chains komponierbar und testbar. LangGraph löst die Grenzen einfacher ReAct-Loops. LangSmith gibt dir die Sichtbarkeit, die du in Produktion brauchst.

Der entscheidende Vorteil von Claude Code als Entwicklungspartner: Du beschreibst dein Ziel, Claude Code generiert die vollständige Implementierung — inklusive Fehlerbehandlung, Retry-Logik und Tests. Was früher Tage dauerte, entsteht in Stunden.