Claude Code & Pydantic AI: KI-Agenten typsicher bauen
Wer Python-Agenten baut, kennt das Problem: Ein LLM antwortet mit Text, aber der Code dahinter erwartet Struktur. Irgendwer muss parsen, validieren, Fehler abfangen — und das ist meistens ungetypter Boilerplate, der bei der nächsten Modelländerung bricht. Pydantic AI löst genau das: ein Framework vom Team hinter Pydantic, das typsichere Agenten-Workflows direkt in Python ermöglicht, mit nativer Unterstützung für Claude.
Dieser Artikel zeigt, wie du Pydantic AI mit Claude als Backbone einsetzt — von der ersten Agent-Klasse über Tool-Registrierung und strukturierte Antworten bis hin zu Dependency Injection und Multi-Agenten-Systemen. Mit Claude Code als Entwicklungsumgebung schreibst du diese Patterns schneller als je zuvor.
KI-Agenten auf Deutsch — vom ersten Agent bis zum produktiven System
Pydantic AI, Claude Code, MCP-Server, Multi-Agenten-Workflows: der Kurs zeigt den vollständigen Stack auf Deutsch. Einmalig bezahlt, kein Abo.
Zum Kurs — Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht1. Was ist Pydantic AI?
Pydantic AI ist ein Agent-Framework, entwickelt vom selben Team, das Pydantic gebaut hat — die Validierungsbibliothek, die FastAPI, SQLModel und inzwischen fast den gesamten Python-Stack antreibt. Das Framework überträgt dieselbe Philosophie auf KI-Agenten: Typen zuerst, Validierung automatisch, Fehler früh und explizit.
Was Pydantic AI von anderen Agent-Frameworks unterscheidet:
- Typsicherheit durch Pydantic-Modelle: Antworten des Modells werden direkt in typisierte Python-Objekte geparst und validiert — kein manuelles JSON-Parsing, keine
dict.get()-Ketten. - Dependency Injection: Datenbankverbindungen, HTTP-Clients, Konfigurationsobjekte werden dem Agenten typsicher übergeben — testbar und austauschbar.
- Multi-Modell-Support: Claude (Anthropic), OpenAI, Gemini, Groq — dieselbe API, austauschbares Backend.
- Kein Async-Zwang: Synchrone und asynchrone Ausführung werden gleichermaßen unterstützt.
Installation: pip install pydantic-ai genügt für den Start. Für Claude-Support werden keine weiteren Pakete benötigt — der Anthropic-Client ist integriert. API-Key via Umgebungsvariable: ANTHROPIC_API_KEY aus os.environ.
2. Die Agent-Klasse: Einstiegspunkt
Alles in Pydantic AI dreht sich um die Agent-Klasse. Sie kapselt Modell, System-Prompt, Tools und den erwarteten Antworttyp in einem einzigen, konfigurierbaren Objekt.
import os
from pydantic_ai import Agent
agent = Agent(
"anthropic:claude-opus-4-5",
system_prompt="Du bist ein hilfreicher Assistent. Antworte präzise und auf Deutsch.",
)
result = agent.run_sync("Was ist der Unterschied zwischen async und await in Python?")
print(result.data)
Der erste Parameter ist die Modell-ID im Format provider:modell. Pydantic AI liest den API-Key automatisch aus der Umgebungsvariable — kein expliziter Client-Setup nötig. Das Ergebnis ist ein typisiertes RunResult-Objekt, dessen .data-Attribut die validierte Antwort enthält.
System-Prompts: statisch und dynamisch
System-Prompts können direkt im Konstruktor übergeben werden oder als dekorierte Funktion — dann werden sie bei jedem Lauf neu berechnet und können auf den aktuellen Context zugreifen:
from pydantic_ai import Agent, RunContext
from dataclasses import dataclass
@dataclass
class UserContext:
username: str
locale: str
agent = Agent("anthropic:claude-sonnet-4-5")
@agent.system_prompt
def build_system_prompt(ctx: RunContext[UserContext]) -> str:
return (
f"Du assistierst {ctx.deps.username}. "
f"Antworte immer in der Sprache: {ctx.deps.locale}."
)
Diese Variante erlaubt es, den System-Prompt zur Laufzeit anzupassen — abhängig vom eingeloggten Nutzer, der aktuellen Session oder externen Daten, ohne den Agenten neu zu instanziieren.
3. Tools registrieren
Tools sind Python-Funktionen, die der Agent aufrufen kann, um Informationen zu beschaffen oder Aktionen auszuführen. Pydantic AI leitet die Tool-Schema direkt aus den Python-Typ-Annotierungen ab — kein manuelles JSON-Schema nötig.
import os
import httpx
from pydantic_ai import Agent, RunContext
agent = Agent("anthropic:claude-opus-4-5")
@agent.tool_plain
def get_current_weather(city: str) -> str:
"""Gibt das aktuelle Wetter für eine Stadt zurück."""
api_key = os.environ["WEATHER_API_KEY"]
resp = httpx.get(
"https://api.openweathermap.org/data/2.5/weather",
params={"q": city, "appid": api_key, "lang": "de", "units": "metric"},
)
data = resp.json()
return f"{city}: {data['main']['temp']}°C, {data['weather'][0]['description']}"
result = agent.run_sync("Wie ist das Wetter gerade in Berlin und München?")
print(result.data)
Der Decorator @agent.tool_plain registriert eine Funktion ohne Zugriff auf den Context. Für Tools, die Dependency-Injection benötigen — z.B. eine Datenbankverbindung — gibt es @agent.tool, das RunContext als ersten Parameter erhält.
Secrets niemals im Code: API-Keys für Tools immer aus os.environ lesen — nie als Standardwert oder hartcodiert im Quellcode. Für lokale Entwicklung eine .env-Datei mit python-dotenv laden, für Produktion Umgebungsvariablen des Deployment-Systems nutzen.
4. Strukturierte Antworten mit result_type
Das stärkste Feature von Pydantic AI: der Agent gibt nicht einfach einen String zurück, sondern ein validiertes Python-Objekt. Du definierst ein Pydantic-Modell, und das Framework sorgt dafür, dass die Modellantwort exakt diesem Schema entspricht — inklusive Typprüfung, Pflichtfeldern und Validatoren.
from pydantic import BaseModel
from pydantic_ai import Agent
class CodeReview(BaseModel):
summary: str
issues: list[str]
severity: str # "low", "medium", "high", "critical"
refactoring_needed: bool
agent = Agent(
"anthropic:claude-opus-4-5",
result_type=CodeReview,
system_prompt=(
"Du bist ein erfahrener Code-Reviewer. "
"Analysiere den übergebenen Code und antworte strukturiert."
),
)
result = agent.run_sync("""
def process_user(data):
name = data['name']
email = data['email']
db.execute(f"INSERT INTO users VALUES ('{name}', '{email}')")
return True
""")
review: CodeReview = result.data
print(f"Schweregrad: {review.severity}")
print(f"SQL-Injection-Risiko erkannt: {review.refactoring_needed}")
for issue in review.issues:
print(f" - {issue}")
Das Modell muss keine JSON-Formatierungs-Instruktionen im System-Prompt erhalten — Pydantic AI übernimmt das intern über Tool-Use oder strukturierte Outputs, je nach Modell-Support. Das Ergebnis ist ein vollständig validiertes CodeReview-Objekt, typsicher und mypy-kompatibel.
5. Dependency Injection
Komplexere Agenten brauchen Zugriff auf externe Ressourcen: Datenbankverbindungen, HTTP-Clients, Konfigurationsobjekte. Pydantic AI löst das mit einem generischen deps_type-Parameter, der den Typ des Context-Objekts definiert:
import os
from dataclasses import dataclass
import httpx
from pydantic_ai import Agent, RunContext
@dataclass
class AgentDeps:
http_client: httpx.AsyncClient
api_base_url: str
agent = Agent(
"anthropic:claude-sonnet-4-5",
deps_type=AgentDeps,
system_prompt="Du hilfst beim Abrufen und Analysieren von API-Daten.",
)
@agent.tool
async def fetch_product(ctx: RunContext[AgentDeps], product_id: int) -> dict:
"""Ruft ein Produkt aus der API ab."""
resp = await ctx.deps.http_client.get(
f"{ctx.deps.api_base_url}/products/{product_id}"
)
return resp.json()
async def main():
async with httpx.AsyncClient() as client:
deps = AgentDeps(
http_client=client,
api_base_url=os.environ["API_BASE_URL"],
)
result = await agent.run(
"Was kann mir Produkt 42 bieten?",
deps=deps,
)
print(result.data)
Der entscheidende Vorteil: In Tests ersetzt du AgentDeps durch ein Mock-Objekt mit einem httpx.MockTransport — der Agent-Code bleibt unverändert, die Tool-Logik ist vollständig testbar ohne echte API-Calls.
6. Multi-Agenten-Systeme
Pydantic AI unterstützt Agenten, die andere Agenten aufrufen — entweder direkt über agent.run() innerhalb eines Tools, oder über eine orchestrierende Struktur. Das ermöglicht Spezialisierung: ein Routing-Agent entscheidet, welcher Spezialist die Anfrage übernimmt.
from pydantic import BaseModel
from pydantic_ai import Agent
class RoutingDecision(BaseModel):
agent: str # "code", "data", "general"
reason: str
router = Agent(
"anthropic:claude-haiku-4-5",
result_type=RoutingDecision,
system_prompt=(
"Entscheide, welcher Spezialist diese Anfrage bearbeiten soll: "
"'code' für Code-Fragen, 'data' für Datenanalyse, 'general' für alles andere."
),
)
code_agent = Agent(
"anthropic:claude-opus-4-5",
system_prompt="Du bist ein erfahrener Python-Entwickler.",
)
data_agent = Agent(
"anthropic:claude-opus-4-5",
system_prompt="Du bist ein Datenanalyst mit Expertise in Pandas und SQL.",
)
async def handle_request(user_input: str) -> str:
decision = await router.run(user_input)
if decision.data.agent == "code":
result = await code_agent.run(user_input)
elif decision.data.agent == "data":
result = await data_agent.run(user_input)
else:
result = await code_agent.run(user_input)
return result.data
Das Haiku-Modell übernimmt das günstige Routing, teure Modelle nur die eigentliche Verarbeitung. Dieses Pattern skaliert: Agenten können über Tool-Calls kommunizieren, Ergebnisse weitergeben und auf dem Ergebnis eines anderen Agenten aufbauen.
7. Claude Code als Entwicklungsumgebung
Pydantic AI und Claude Code ergänzen sich natürlich: Das Framework, das du mit Claude Code schreibst, läuft selbst mit Claude als Backend. Ein paar Tipps aus der Praxis:
- Agent-Struktur generieren lassen: Beschreibe das gewünschte Verhalten, und Claude Code entwirft die Pydantic-Modelle, Tool-Signaturen und die
Agent-Konfiguration in einem Schritt. - Tests mit Mocks: Bitte Claude Code explizit, Tests mit
pytestund gemocktenAgentDepszu schreiben — das Framework ist darauf ausgelegt, und die Tests entstehen parallel zum Code. - Prompt-Iteration: System-Prompts direkt im Chat verfeinern, dann in den Code übertragen — Claude Code kann den aktuellen Prompt lesen und Verbesserungen vorschlagen.
- Fehleranalyse: Validation-Errors von Pydantic sind präzise. Sie direkt an Claude Code übergeben liefert sofort den Fix am richtigen Feld.
"Schreib einen Pydantic AI Agent, der Rechnungen analysiert und die Felder Betrag, Währung, Fälligkeitsdatum und Lieferant als typisiertes Objekt zurückgibt. Mit Tests."
Dieser eine Satz an Claude Code liefert in Sekunden ein vollständiges, typsicheres Setup — Agent, Pydantic-Modell, pytest-Tests mit Mock-Responses inklusive. Was früher ein halber Nachmittag war, ist heute ein Ausgangspunkt.
Zwei verwandte Artikel, die auf diesem Thema aufbauen:
- Claude Code für Python-Projekte — Setup, Workflow und Python-spezifische Tipps
- Claude Code Debugging — Stack Traces, Logs und Root-Cause-Analyse systematisch lösen
KI-Agenten mit Claude — vom ersten Prototyp bis zum produktiven System
Pydantic AI ist ein Teil des Stacks. Im Kurs lernst du außerdem MCP-Server, Hooks, Multi-Agent-Workflows und Claude Code als Entwicklungsumgebung. Vollständig auf Deutsch, einmalig bezahlt.
Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage RückgaberechtKurs · Claude Code Mastery
Typsichere KI-Agenten — von Pydantic AI bis Multi-Agent-Systeme
Pydantic AI. Claude Code. MCP. Dependency Injection. Multi-Agent-Workflows. Alles auf Deutsch, einmalig bezahlt — kein Abo, keine Plattformabhängigkeit.
Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht