LangChain mit Claude Code: KI-Anwendungen mit Python 2026

LangChain ist das führende Python-Framework für LLM-Anwendungen — Chains, Agents, RAG, Vector Stores, Memory und LangGraph. Claude Code versteht das gesamte Ökosystem und generiert produktionsreifen LangChain-Code für komplexe KI-Workflows.

Chains & LCEL

Komponenten verketten mit der LangChain Expression Language — lesbar, modular, effizient.

RAG-Pipelines

Dokumente laden, aufteilen, vektorisieren und per Retrieval in LLM-Kontexte einbetten.

Autonome Agents

Agents mit eigenen Tools ausstatten — Websuche, Python-Ausführung, Datenbank-Queries.

LangGraph

Zyklische Workflows mit StateGraph — Multi-Agent-Koordination und Supervisor-Pattern.

$ pip install langchain langchain-anthropic langchain-openai langchain-community
$ pip install chromadb faiss-cpu tiktoken duckduckgo-search
$ pip install langgraph langchain-core

LangChain hat sich seit 2023 zum De-facto-Standard für produktionsreife LLM-Anwendungen entwickelt. Die Bibliothek abstrahiert die Komplexität von Sprachmodellen und bietet ein einheitliches Interface für GPT-4, Claude, Gemini und viele weitere Modelle. Claude Code kennt das gesamte LangChain-Ökosystem und kann komplexe Pipelines auf Zuruf generieren.

1. LangChain Grundlagen: Erste Schritte mit Claude und OpenAI

BasicsChatModels und Messages

# Claude Code Prompt: "LangChain Setup mit ChatAnthropic und Nachrichten" from langchain_anthropic import ChatAnthropic from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage, HumanMessage, AIMessage # Modell initialisieren — Claude via LangChain llm = ChatAnthropic( model="claude-sonnet-4-5", temperature=0.7, max_tokens=2048 ) # Alternativ: OpenAI # llm = ChatOpenAI(model="gpt-4o", temperature=0) # Einfacher Aufruf mit SystemMessage + HumanMessage messages = [ SystemMessage(content="Du bist ein Python-Experte. Antworte präzise auf Deutsch."), HumanMessage(content="Erkläre mir List Comprehensions in Python in 3 Sätzen.") ] response = llm.invoke(messages) print(response.content) # Streaming — Token für Token ausgeben for chunk in llm.stream(messages): print(chunk.content, end="", flush=True)

LCELLangChain Expression Language — Pipe-Syntax

# LCEL: Komponenten mit | verbinden (wie Unix Pipes) from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser prompt = ChatPromptTemplate.from_messages([ ("system", "Du bist ein hilfreicher Assistent der auf Deutsch antwortet."), ("human", "{input}") ]) # Die LCEL-Pipe-Syntax: prompt | llm | parser chain = prompt | llm | StrOutputParser() # invoke() für synchrone Aufrufe result = chain.invoke({"input": "Was ist der Unterschied zwischen list und tuple in Python?"}) print(result) # Batch-Verarbeitung — mehrere Inputs parallel results = chain.batch([ {"input": "Python Decorators erklären"}, {"input": "Was ist ein Generator in Python?"}, {"input": "Asyncio vs Threading — Unterschiede?"} ]) for r in results: print(r[:100], "...")
Claude Code Tipp: Die LCEL-Pipe-Syntax (|) ist der moderne LangChain-Ansatz. Claude Code generiert standardmäßig LCEL-Chains statt der veralteten LLMChain-Klasse. Das Ergebnis ist lesbarer, effizient parallelisierbar und einfacher zu debuggen.

2. Chains & Prompts: Komplexe Pipelines aufbauen

Mit LCEL lassen sich beliebig komplexe Pipelines aus einfachen Bausteinen zusammensetzen. RunnablePassthrough, RunnableParallel und RunnableLambda ermöglichen Branching, Merging und Transformation innerhalb einer Chain.

ChainsChatPromptTemplate und strukturierte Ausgaben

# Claude Code Prompt: "Erstelle eine Chain mit strukturierter Ausgabe" from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough, RunnableParallel from langchain_core.output_parsers import StrOutputParser, JsonOutputParser from pydantic import BaseModel, Field # Strukturiertes Output-Schema mit Pydantic class CodeReview(BaseModel): qualitaet: int = Field(description="Codequalität 1-10") probleme: list[str] = Field(description="Gefundene Probleme") verbesserungen: list[str] = Field(description="Verbesserungsvorschläge") zusammenfassung: str = Field(description="Kurze Zusammenfassung") # Structured Output — LLM gibt direkt Pydantic-Objekt zurück structured_llm = llm.with_structured_output(CodeReview) review_prompt = ChatPromptTemplate.from_messages([ ("system", "Du bist ein erfahrener Code-Reviewer. Analysiere den Code objektiv."), ("human", "Reviewe diesen Python-Code:\n\n{code}") ]) review_chain = review_prompt | structured_llm # Parallel-Chain — mehrere Analysen gleichzeitig parallel_chain = RunnableParallel({ "original_code": RunnablePassthrough(), "review": review_chain }) code_sample = """ def calculate(x, y): result = x/y return result """ output = parallel_chain.invoke({"code": code_sample}) review: CodeReview = output["review"] print(f"Qualität: {review.qualitaet}/10") print(f"Probleme: {', '.join(review.probleme)}")

Multi-ChainSequentielle und bedingte Chains

# Claude Code Prompt: "Chain die zuerst analysiert, dann verbessert" from langchain_core.runnables import RunnableLambda analyse_prompt = ChatPromptTemplate.from_template( "Analysiere diesen Text auf Hauptthemen: {text}" ) verbesser_prompt = ChatPromptTemplate.from_messages([ ("system", "Du verbesserst Texte basierend auf einer Analyse."), ("human", "Text: {text}\n\nAnalyse: {analyse}\n\nVerbessere den Text:") ]) # Schritt 1: Analyse analyse_chain = analyse_prompt | llm | StrOutputParser() # Schritt 2: Verbesserung mit Analyse als Kontext verbesser_chain = ( RunnableParallel({ "text": RunnablePassthrough(), "analyse": analyse_chain }) | verbesser_prompt | llm | StrOutputParser() ) # Gesamte Pipeline in einem Aufruf verbesserter_text = verbesser_chain.invoke({ "text": "KI ist gut. Sie macht viele Dinge. Unternehmen nutzen sie." }) print(verbesserter_text)

3. RAG: Retrieval-Augmented Generation mit Vector Stores

RAG ist eine der wichtigsten Architekturen für produktive LLM-Anwendungen: Dokumente werden in Vektoren umgewandelt, semantisch durchsucht und als Kontext in LLM-Prompts eingebettet. Claude Code beherrscht den gesamten RAG-Stack von der Dokumentenverarbeitung bis zur Antwortgenerierung.

RAGDokumente laden, aufteilen und vektorisieren

# Claude Code Prompt: "Vollständige RAG-Pipeline für PDF-Dokumente" from langchain_community.document_loaders import PyPDFLoader, TextLoader, WebBaseLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma import os # Dokument laden — PDF, Text oder Webseite loader = PyPDFLoader("dokumentation.pdf") # loader = WebBaseLoader("https://docs.langchain.com/docs/") # Webseite documents = loader.load() # Texte in Chunks aufteilen text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, # Zeichen pro Chunk chunk_overlap=200, # Überlappung für Kontext-Kontinuität separators=["\n\n", "\n", " ", ""] ) chunks = text_splitter.split_documents(documents) print(f"{len(documents)} Seiten → {len(chunks)} Chunks") # Embeddings erstellen und in Chroma Vector Store speichern embeddings = OpenAIEmbeddings(model="text-embedding-3-small") vectorstore = Chroma.from_documents( documents=chunks, embedding=embeddings, persist_directory="./chroma_db" # Persistenz auf Disk ) # Retriever — top-k semantisch ähnlichste Chunks retriever = vectorstore.as_retriever( search_type="mmr", # Max Marginal Relevance — Diversität search_kwargs={"k": 5, "fetch_k": 20} )

RAG ChainVollständige RAG-Chain mit LCEL

# RAG-Chain zusammenbauen from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser rag_prompt = ChatPromptTemplate.from_messages([ ("system", """Du bist ein Assistent der Fragen basierend auf Dokumenten beantwortet. Nutze NUR den bereitgestellten Kontext. Falls die Antwort nicht im Kontext steht, sage das ehrlich. Antworte auf Deutsch. Kontext: {context}"""), ("human", "{question}") ]) def format_docs(docs): return "\n\n---\n\n".join( f"Quelle: {doc.metadata.get('source', 'Unbekannt')}\n{doc.page_content}" for doc in docs ) # Vollständige RAG-Chain mit LCEL rag_chain = ( { "context": retriever | format_docs, "question": RunnablePassthrough() } | rag_prompt | llm | StrOutputParser() ) # Frage stellen — Dokumente werden automatisch abgerufen antwort = rag_chain.invoke( "Welche Hauptfunktionen bietet das System laut der Dokumentation?" ) print(antwort) # FAISS als Alternative zu Chroma (keine Persistenz, in-memory) from langchain_community.vectorstores import FAISS vectorstore_faiss = FAISS.from_documents(chunks, embeddings) vectorstore_faiss.save_local("faiss_index")
Wichtig: OpenAIEmbeddings verursacht API-Kosten pro Embedding-Aufruf. Für lokale Entwicklung empfiehlt sich HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2") — kostenlos, offline, und für deutschsprachige Texte gut geeignet.

4. Agents & Tools: Autonome KI-Agenten mit LangChain

LangChain-Agents können eigenständig entscheiden, welche Tools sie in welcher Reihenfolge nutzen. Mit dem @tool-Decorator lassen sich eigene Werkzeuge in wenigen Zeilen definieren. Claude Code generiert vollständige Agent-Setups inklusive Custom Tools auf Anfrage.

Agents@tool Decorator und AgentExecutor

# Claude Code Prompt: "Agent mit Websuche und eigenen Python-Tools" from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.tools import tool from langchain_community.tools import DuckDuckGoSearchRun from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder import math, json # Eigenes Tool mit @tool Decorator definieren @tool def berechne_zinsen(kapital: float, zinssatz: float, jahre: int) -> str: """Berechnet Zinseszinsen. Args: kapital (€), zinssatz (%), jahre (Anzahl)""" endkapital = kapital * ((1 + zinssatz / 100) ** jahre) gewinn = endkapital - kapital return json.dumps({ "endkapital": round(endkapital, 2), "gewinn": round(gewinn, 2), "rendite_prozent": round(gewinn / kapital * 100, 2) }) @tool def lese_datei(dateipfad: str) -> str: """Liest den Inhalt einer Textdatei. Args: dateipfad (absoluter Pfad)""" try: with open(dateipfad, "r", encoding="utf-8") as f: return f.read()[:2000] # Ersten 2000 Zeichen except FileNotFoundError: return f"Datei nicht gefunden: {dateipfad}" # Tools zusammenstellen search = DuckDuckGoSearchRun() tools = [search, berechne_zinsen, lese_datei] # Agent-Prompt mit Platzhalter für Chat-History agent_prompt = ChatPromptTemplate.from_messages([ ("system", "Du bist ein hilfreicher Assistent mit Zugang zu Tools. Nutze sie wenn nötig. Antworte auf Deutsch."), MessagesPlaceholder(variable_name="chat_history", optional=True), ("human", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad") ]) # Agent erstellen — nutzt Tool-Calling (Function Calling) agent = create_tool_calling_agent(llm, tools, agent_prompt) executor = AgentExecutor( agent=agent, tools=tools, verbose=True, # Zeigt Reasoning-Schritte max_iterations=10, # Maximale Tool-Aufrufe return_intermediate_steps=True ) result = executor.invoke({ "input": "Was sind aktuelle KI-Trends 2026? Und: Wie viel habe ich nach 10 Jahren bei 5% Zins aus 10.000€?" })

Custom ToolsFortgeschrittene Tool-Definitionen

# Komplexeres Tool mit Pydantic-Schema für präzise Parameter from langchain_core.tools import BaseTool from pydantic import BaseModel, Field from typing import Type import requests class WetterInput(BaseModel): stadt: str = Field(description="Name der Stadt (z.B. Berlin, München)") einheit: str = Field(default="celsius", description="Temperatureinheit: celsius oder fahrenheit") class WetterTool(BaseTool): name: str = "wetter_abfragen" description: str = "Ruft aktuelle Wetterdaten für eine Stadt ab" args_schema: Type[BaseModel] = WetterInput def _run(self, stadt: str, einheit: str = "celsius") -> str: # Open-Meteo API — kostenlos, kein API-Key nötig geo_url = f"https://geocoding-api.open-meteo.com/v1/search?name={stadt}&count=1&language=de" geo = requests.get(geo_url).json() if "results" not in geo: return f"Stadt '{stadt}' nicht gefunden" lat = geo["results"][0]["latitude"] lon = geo["results"][0]["longitude"] temp_unit = "celsius" if einheit == "celsius" else "fahrenheit" weather_url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}¤t=temperature_2m,wind_speed_10m&temperature_unit={temp_unit}" weather = requests.get(weather_url).json() temp = weather["current"]["temperature_2m"] wind = weather["current"]["wind_speed_10m"] return f"{stadt}: {temp}°{'C' if einheit == 'celsius' else 'F'}, Wind: {wind} km/h" tools_erweitert = [search, berechne_zinsen, WetterTool()]

5. Memory & Conversation: Gesprächskontext beibehalten

Produktive Chatbots müssen sich an frühere Nachrichten erinnern. LangChain bietet verschiedene Memory-Implementierungen — von einfachem Buffer-Memory bis zu zusammenfassendem Memory für sehr lange Gespräche.

MemoryConversationBufferMemory und ChatMessageHistory

# Claude Code Prompt: "Chatbot mit persistentem Gesprächsverlauf" from langchain.memory import ConversationBufferMemory, ConversationSummaryMemory from langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder # In-Memory Store für mehrere Sessions store = {} def get_session_history(session_id: str) -> ChatMessageHistory: """Erstellt oder gibt bestehende Session-History zurück""" if session_id not in store: store[session_id] = ChatMessageHistory() return store[session_id] # Prompt mit Platzhalter für Message History memory_prompt = ChatPromptTemplate.from_messages([ ("system", "Du bist ein persönlicher Assistent. Merke dir Details über den Nutzer."), MessagesPlaceholder(variable_name="history"), ("human", "{input}") ]) base_chain = memory_prompt | llm | StrOutputParser() # Chain mit automatischer History-Verwaltung chain_with_history = RunnableWithMessageHistory( base_chain, get_session_history, input_messages_key="input", history_messages_key="history" ) # Gespräch führen — session_id trennt verschiedene User-Sessions config = {"configurable": {"session_id": "user-42"}} antwort1 = chain_with_history.invoke( {"input": "Mein Name ist Klaus und ich interessiere mich für Python."}, config=config ) print("Bot:", antwort1) antwort2 = chain_with_history.invoke( {"input": "Was habe ich dir über mich erzählt?"}, config=config ) print("Bot:", antwort2) # Erinnert sich an Klaus + Python

Summary MemoryZusammenfassendes Memory für lange Gespräche

# ConversationSummaryMemory — fasst ältere Nachrichten zusammen statt zu löschen from langchain.memory import ConversationSummaryBufferMemory # Letzte 2000 Tokens direkt, älteres als Zusammenfassung summary_memory = ConversationSummaryBufferMemory( llm=llm, max_token_limit=2000, return_messages=True, memory_key="history" ) # Redis für persistente Sessions über Neustarts hinweg # from langchain_community.chat_message_histories import RedisChatMessageHistory # redis_history = RedisChatMessageHistory( # session_id="user-42", # url="redis://localhost:6379", # ttl=3600 # 1 Stunde Ablaufzeit # ) # PostgreSQL für produktive Deployments # from langchain_community.chat_message_histories import PostgresChatMessageHistory # pg_history = PostgresChatMessageHistory( # connection_string="postgresql://user:pass@localhost/chatdb", # session_id="user-42" # ) # Aktuellen Gesprächsverlauf inspizieren def zeige_konversation(session_id: str): history = get_session_history(session_id) for msg in history.messages: prefix = "User" if msg.type == "human" else "Bot" print(f"{prefix}: {msg.content[:80]}...")

6. LangGraph: Komplexe Workflows mit Zustandsautomaten

LangGraph erweitert LangChain um zyklische Graphen — ideal für Multi-Agent-Systeme, iterative Verbesserungsschleifen und Supervisor-Patterns. Im Gegensatz zu linearen Chains können LangGraph-Workflows Zustände verwalten, Entscheidungen treffen und zu früheren Schritten zurückspringen.

LangGraphStateGraph Grundlagen

# Claude Code Prompt: "LangGraph Workflow mit StateGraph und Conditional Edges" from langgraph.graph import StateGraph, END from typing import TypedDict, Annotated, Sequence import operator # Zustandsdefinition — wird zwischen Nodes weitergegeben class AgentState(TypedDict): nachrichten: Annotated[list, operator.add] # Akkumuliert Nachrichten naechster_schritt: str iterationen: int finale_antwort: str # Node-Funktionen — jede Node transformiert den Zustand def analysiere_frage(state: AgentState) -> AgentState: frage = state["nachrichten"][-1] analyse = llm.invoke([ SystemMessage(content="Analysiere die Frage und bestimme ob sie Recherche erfordert."), HumanMessage(content=f"Frage: {frage}\n\nBrauche ich Websuche? Antworte nur: JA oder NEIN") ]) benoetigt_suche = "JA" in analyse.content.upper() return { "naechster_schritt": "suche" if benoetigt_suche else "antworte", "iterationen": state.get("iterationen", 0) + 1 } def web_recherche(state: AgentState) -> AgentState: frage = state["nachrichten"][-1] search_tool = DuckDuckGoSearchRun() ergebnis = search_tool.run(frage) return { "nachrichten": [f"Recherche-Ergebnis: {ergebnis[:1000]}"], "naechster_schritt": "antworte" } def generiere_antwort(state: AgentState) -> AgentState: antwort = llm.invoke([ SystemMessage(content="Beantworte die Frage basierend auf dem Kontext. Antworte auf Deutsch."), HumanMessage(content=f"Kontext: {state['nachrichten']}") ]) return {"finale_antwort": antwort.content} # Conditional Edge — Router-Funktion def route_nach_analyse(state: AgentState) -> str: return state["naechster_schritt"] # Graph aufbauen workflow = StateGraph(AgentState) workflow.add_node("analysiere", analysiere_frage) workflow.add_node("suche", web_recherche) workflow.add_node("antworte", generiere_antwort) workflow.set_entry_point("analysiere") workflow.add_conditional_edges( "analysiere", route_nach_analyse, {"suche": "suche", "antworte": "antworte"} ) workflow.add_edge("suche", "antworte") workflow.add_edge("antworte", END) app = workflow.compile() ergebnis = app.invoke({"nachrichten": ["Was sind die neuesten LangChain Features 2026?"]})

SupervisorMulti-Agent Supervisor Pattern

# Claude Code Prompt: "Supervisor-Agent der Subagenten koordiniert" from langgraph.graph import StateGraph, END from langchain_core.messages import HumanMessage, SystemMessage from typing import TypedDict, Literal # Supervisor entscheidet wer als nächstes arbeitet AGENTEN = ["researcher", "writer", "reviewer"] class TeamState(TypedDict): nachrichten: list naechster_agent: str recherche: str entwurf: str finaler_text: str def supervisor_node(state: TeamState) -> TeamState: """Supervisor entscheidet den nächsten Schritt""" system_msg = f"""Du koordinierst ein Team: {AGENTEN}. Basierend auf dem Fortschritt entscheide wer als nächstes arbeitet. Wenn die Aufgabe abgeschlossen ist, antworte mit 'FINISH'. Antworte NUR mit einem Agentennamen oder 'FINISH'.""" response = llm.invoke([ SystemMessage(content=system_msg), HumanMessage(content=f"Aktueller Stand: {state['nachrichten'][-3:]}") ]) naechster = response.content.strip().lower() if naechster not in AGENTEN + ["finish"]: naechster = "researcher" # Fallback return {"naechster_agent": naechster} def researcher_node(state: TeamState) -> TeamState: aufgabe = state["nachrichten"][0] recherche = llm.invoke([ SystemMessage(content="Du recherchierst Fakten. Sei präzise und zitiere Quellen wenn möglich."), HumanMessage(content=f"Recherchiere: {aufgabe}") ]) return { "recherche": recherche.content, "nachrichten": state["nachrichten"] + [f"[Researcher] Recherche abgeschlossen: {recherche.content[:100]}..."] } def writer_node(state: TeamState) -> TeamState: entwurf = llm.invoke([ SystemMessage(content="Du schreibst klare, informative Texte auf Basis von Recherchen."), HumanMessage(content=f"Schreibe einen Text basierend auf: {state['recherche']}") ]) return { "entwurf": entwurf.content, "nachrichten": state["nachrichten"] + ["[Writer] Entwurf fertig"] } def reviewer_node(state: TeamState) -> TeamState: review = llm.invoke([ SystemMessage(content="Du reviewst und verbesserst Texte. Gib den finalen, verbesserten Text zurück."), HumanMessage(content=f"Review und verbessere: {state['entwurf']}") ]) return { "finaler_text": review.content, "nachrichten": state["nachrichten"] + ["[Reviewer] Review abgeschlossen"] } def route_supervisor(state: TeamState) -> str: return state["naechster_agent"] # Supervisor-Graph zusammenbauen graph = StateGraph(TeamState) graph.add_node("supervisor", supervisor_node) graph.add_node("researcher", researcher_node) graph.add_node("writer", writer_node) graph.add_node("reviewer", reviewer_node) graph.set_entry_point("supervisor") graph.add_conditional_edges("supervisor", route_supervisor, { "researcher": "researcher", "writer": "writer", "reviewer": "reviewer", "finish": END }) for agent in ["researcher", "writer", "reviewer"]: graph.add_edge(agent, "supervisor") team_app = graph.compile() final_state = team_app.invoke({ "nachrichten": ["Schreibe einen Artikel über KI-Trends 2026"], "naechster_agent": "researcher" })
LangGraph vs. AgentExecutor: Für einfache, lineare Agent-Tasks ist AgentExecutor ausreichend. LangGraph eignet sich für komplexe Workflows mit Verzweigungen, Rückkopplungsschleifen und mehreren kooperierenden Agenten. Claude Code wählt automatisch das richtige Werkzeug basierend auf der Aufgaben-Komplexität.

LangChain 2026: Produktive KI mit weniger Code

LangChain hat sich 2026 als Standard-Framework für LLM-Anwendungen etabliert. Die LCEL-Pipe-Syntax macht komplexe Pipelines lesbar, LangGraph ermöglicht echte Multi-Agent-Koordination und die nahtlose Integration von Vector Stores, Memory und Tools macht es möglich, in wenigen Stunden produktive KI-Anwendungen zu bauen.

Claude Code kennt das gesamte LangChain-Ökosystem in- und auswendig — von Retrieval-Chains über Tool-Calling-Agents bis zu komplexen LangGraph-Supervisor-Patterns. Beschreibe deine Anforderungen auf natürlichem Deutsch, und Claude Code generiert produktionsreifen, getesteten Python-Code — inklusive Fehlerbehandlung, Logging und Deployment-Vorbereitung.

Sofort starten mit Claude Code + LangChain

Lade dir den kostenlosen 14-Tage-Trial und starte deinen ersten LangChain-Agenten noch heute — kein Vorwissen nötig, Claude Code erklärt jeden Schritt.

14 Tage kostenlos testen →