Zum Inhalt

Pydantic AI Framework Cheat Sheet

Überblick

Pydantic AI ist ein leistungsfähiges Python-Agenten-Framework, das darauf abzielt, produktionsfähige Anwendungen mit Generative AI einfacher und zuverlässiger zu machen. Pydantic KI baut auf der beliebten Pydantic Datenvalidierungsbibliothek auf, überbrückt die Lücke zwischen traditionellen Python-Anwendungen und AI-getriebenen Workflows, indem sie robuste Typsicherheit, Schemavalidierung und strukturierte Ausgänge für KI-Interaktionen bereitstellen.

Was Pydantic AI unterscheidet, ist der Fokus auf Produktionsbereitschaft und Typsicherheit. Während viele KI-Frameworks die Flexibilität auf Kosten der Zuverlässigkeit priorisieren, stellt Pydantic KI sicher, dass KI-erzeugte Outputs den erwarteten Schemas entsprechen, wodurch es einfacher wird, robuste Anwendungen zu erstellen, die die Unvorhersehbarkeit großer Sprachmodelle bewältigen können. Durch die Verwendung von Pythons Typ-Annotationen und Pydantic's Validierungsfunktionen bietet das Framework einen strukturierten Ansatz zur KI-Entwicklung, der Kesselplattencode und mögliche Laufzeitfehler reduziert.

Pydantic KI ist besonders wertvoll für Entwickler, die KI-Fähigkeiten in bestehende Python-Anwendungen integrieren oder neue KI-fähige Features mit Vertrauen aufbauen müssen. Seine Betonung auf Typsicherheit, Validierung und saubere Integration mit modernen Python-Practices macht es zu einer ausgezeichneten Wahl für Produktionsumgebungen, in denen Zuverlässigkeit und Aufrechterhaltungsfähigkeit von größter Bedeutung sind.

Installation und Inbetriebnahme

Einfache Installation

# Install Pydantic AI
pip install pydantic-ai

# Install with optional dependencies
pip install "pydantic-ai[all]"

# Install development version
pip install git+https://github.com/pydantic/pydantic-ai.git
```_

### Umweltkonfiguration
```python
import os
from pydantic_ai import Agent, Output, Prompt

# Set up API keys
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

# Basic agent configuration
agent = Agent(
    model="gpt-4",
    temperature=0.7,
    max_tokens=1000
)
```_

### Projektstruktur

pydantic_ai_project/ ├── agents/ │ ├── init.py │ ├── text_agent.py │ └── structured_agent.py ├── models/ │ ├── init.py │ ├── input_models.py │ └── output_models.py ├── prompts/ │ ├── init.py │ └── templates.py ├── services/ │ ├── init.py │ └── ai_service.py ├── utils/ │ ├── init.py │ └── validators.py ├── config/ │ ├── init.py │ └── settings.py └── main.py ```_

Kernkonzepte

Agent

Die Agent-Klasse ist die primäre Schnittstelle zur Interaktion mit Sprachmodellen. Es behandelt die Kommunikation mit dem zugrunde liegenden LLM und bietet Methoden zur Generierung von Reaktionen.

Prompt

Prompts definieren die Anweisungen, die an das Sprachmodell gesendet werden. Pydantic AI bietet strukturierte Möglichkeiten, um Eingabeaufforderungen zu erstellen und zu verwalten.

Ausgabe

Ausgangsklassen definieren die erwartete Struktur der Antworten aus dem Sprachmodell. Sie nutzen die Validierungsfähigkeit von Pydantic, um sicherzustellen, dass Antworten dem erwarteten Schema entsprechen.

Gültig

Validatoren sind Funktionen, die überprüfen, ob die generierte Ausgabe bestimmte Kriterien über die grundlegende Schemavalidierung erfüllt.

Basisnutzung

Erstellen eines einfachen Agenten

```python from pydantic_ai import Agent

Create a basic agent

agent = Agent( model="gpt-4", temperature=0.7, max_tokens=1000 )

Generate a simple text response

response = agent.run("Explain quantum computing in simple terms.") print(response) ```_

Strukturierte Ausgabe mit Pydantischen Modellen

```python from pydantic_ai import Agent, Output from pydantic import BaseModel, Field from typing import List

Define output schema

class MovieRecommendation(BaseModel): title: str = Field(description="The title of the movie") year: int = Field(description="The year the movie was released") director: str = Field(description="The director of the movie") genre: List[str] = Field(description="List of genres for the movie") rating: float = Field(description="Rating from 0.0 to 10.0")

class MovieRecommendations(BaseModel): recommendations: List[MovieRecommendation] = Field(description="List of movie recommendations") reasoning: str = Field(description="Explanation for these recommendations")

Create output definition

movie_output = Output(MovieRecommendations)

Create agent and get structured recommendations

agent = Agent(model="gpt-4") result = agent.run( "Recommend 3 science fiction movies from the 1980s", output=movie_output )

Access structured data

for movie in result.recommendations: print(f"\\{movie.title\\} (\\{movie.year\\}) - Directed by \\{movie.director\\}") print(f"Genres: \\{', '.join(movie.genre)\\}") print(f"Rating: \\{movie.rating\\}/10") print() ```_

Prompt Vorlagen

```python from pydantic_ai import Agent, Prompt from typing import List

Create a prompt template

movie_prompt = Prompt( """ You are a movie expert with extensive knowledge of cinema history.

Please recommend \\\\{num_movies\\\\} movies that match these criteria:
- Genre: \\\\{genre\\\\}
- Time period: \\\\{era\\\\}
- Mood: \\\\{mood\\\\}

For each movie, provide:
1. Title
2. Year of release
3. Director
4. Brief plot summary
5. Why it matches the criteria
"""

)

Use the template with parameters

agent = Agent(model="gpt-4") response = agent.run( movie_prompt.format( num_movies=3, genre="Film Noir", era="1940s", mood="Suspenseful" ) )

print(response) ```_

Erweiterte Funktionen

Strukturierte Vorteile mit Pydantic

```python from pydantic_ai import Agent, StructuredPrompt from pydantic import BaseModel, Field from typing import List, Optional

Define input schema

class MovieCriteria(BaseModel): genres: List[str] = Field(description="List of movie genres") release_years: Optional[List[int]] = Field(description="List of years or range of years") directors: Optional[List[str]] = Field(description="List of directors to include") exclude_directors: Optional[List[str]] = Field(description="List of directors to exclude") min_rating: Optional[float] = Field(description="Minimum rating threshold (0-10)") keywords: Optional[List[str]] = Field(description="Thematic keywords to match")

Create structured prompt

movie_prompt = StructuredPrompt( """ As a film expert, recommend 5 movies that match the following criteria:

\\\\{\\\\{criteria\\\\}\\\\}

For each movie, provide the title, year, director, and a brief explanation of why it matches the criteria.
""",
criteria=MovieCriteria

)

Use structured prompt

agent = Agent(model="gpt-4") response = agent.run( movie_prompt, criteria=MovieCriteria( genres=["Science Fiction", "Horror"], release_years=[1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979], directors=["John Carpenter", "David Cronenberg", "Ridley Scott"], min_rating=7.5, keywords=["Body horror", "Dystopia", "Alien"] ) )

print(response) ```_

Zollamt

```python from pydantic_ai import Agent, Output, Validator from pydantic import BaseModel, Field from typing import List

Define output schema

class NewsArticleSummary(BaseModel): title: str = Field(description="The title of the article") source: str = Field(description="The source of the article") summary: str = Field(description="A concise summary of the article") key_points: List[str] = Field(description="Key points from the article") bias_assessment: str = Field(description="Assessment of potential bias in the article")

Create custom validators

def check_summary_length(output: NewsArticleSummary) -> bool: """Ensure summary is between 100 and 300 characters.""" return 100 <= len(output.summary) <= 300

def check_key_points(output: NewsArticleSummary) -> bool: """Ensure there are 3-5 key points and none are too long.""" if not (3 <= len(output.key_points) <= 5): return False return all(len(point) <= 100 for point in output.key_points)

Create validator with custom checks

news_validator = Validator( checks=[check_summary_length, check_key_points], max_retries=3 )

Create output with validator

news_output = Output( NewsArticleSummary, validator=news_validator )

Use with agent

agent = Agent(model="gpt-4") result = agent.run( "Summarize this news article about climate change: [article text here]", output=news_output )

print(f"Title: \\{result.title\\}") print(f"Source: \\{result.source\\}") print(f"Summary: \\{result.summary\\}") print("Key Points:") for point in result.key_points: print(f"- \\{point\\}") print(f"Bias Assessment: \\{result.bias_assessment\\}") ```_

Antworten zu optimieren

```python from pydantic_ai import Agent import asyncio

Create agent

agent = Agent(model="gpt-4")

Synchronous streaming

for chunk in agent.stream("Write a short story about a robot learning to paint."): print(chunk, end="", flush=True)

Asynchronous streaming

async def stream_response(): async for chunk in agent.astream("Write a poem about artificial intelligence."): print(chunk, end="", flush=True)

asyncio.run(stream_response()) ```_

Funktion Anruf

```python from pydantic_ai import Agent, Function from pydantic import BaseModel, Field from typing import List, Optional

Define function input schema

class WeatherRequest(BaseModel): location: str = Field(description="City and country or postal code") forecast_days: Optional[int] = Field(default=1, description="Number of days to forecast") units: Optional[str] = Field(default="metric", description="Units system (metric or imperial)")

Define function

def get_weather(request: WeatherRequest) -> str: """Get the current weather and forecast for a location.""" # In a real application, this would call a weather API return f"Weather for \\{request.location\\}: Sunny, 25°C, with light winds."

Register function with agent

agent = Agent(model="gpt-4") weather_function = Function(get_weather) agent.register_function(weather_function)

Use function calling

response = agent.run( "What's the weather like in Paris, France today?", functions=[weather_function] )

print(response) ```_

Werkzeugintegration

```python from pydantic_ai import Agent, Tool from pydantic import BaseModel, Field from typing import List, Optional import requests

Define tool input schema

class SearchQuery(BaseModel): query: str = Field(description="Search query string") num_results: Optional[int] = Field(default=5, description="Number of results to return")

Define tool output schema

class SearchResult(BaseModel): title: str = Field(description="Title of the search result") url: str = Field(description="URL of the search result") snippet: str = Field(description="Text snippet from the search result")

class SearchResults(BaseModel): results: List[SearchResult] = Field(description="List of search results")

Create search tool

def web_search(query: SearchQuery) -> SearchResults: """Search the web for information.""" # In a real application, this would call a search API mock_results = [ SearchResult( title=f"Result \\{i\\} for \\{query.query\\}", url=f"https://example.com/result\\{i\\}", snippet=f"This is a snippet for result \\{i\\} about \\{query.query\\}..." ) for i in range(1, query.num_results + 1) ] return SearchResults(results=mock_results)

Register tool with agent

agent = Agent(model="gpt-4") search_tool = Tool( name="web_search", function=web_search, description="Search the web for current information" ) agent.register_tool(search_tool)

Use tool in conversation

response = agent.run( "Find me information about the latest advancements in quantum computing", tools=[search_tool] )

print(response) ```_

Erweiterte Muster

Kette des Denkens Begründung

```python from pydantic_ai import Agent, Output from pydantic import BaseModel, Field from typing import List

Define output schema with reasoning steps

class MathSolution(BaseModel): problem: str = Field(description="The original math problem") reasoning_steps: List[str] = Field(description="Step-by-step reasoning process") final_answer: str = Field(description="The final numerical answer") confidence: float = Field(description="Confidence in the answer (0-1)")

Create output

math_output = Output(MathSolution)

Use with agent

agent = Agent(model="gpt-4") result = agent.run( "Solve this math problem: If a train travels at 120 km/h and covers a distance of 360 km, how long does the journey take?", output=math_output )

print(f"Problem: \\{result.problem\\}") print("Reasoning Steps:") for i, step in enumerate(result.reasoning_steps, 1): print(f"\\{i\\}. \\{step\\}") print(f"Final Answer: \\{result.final_answer\\}") print(f"Confidence: \\{result.confidence:.2f\\}") ```_

Mehrstufige Verarbeitung

```python from pydantic_ai import Agent, Output from pydantic import BaseModel, Field from typing import List

Define intermediate and final output schemas

class TextAnalysis(BaseModel): main_topics: List[str] = Field(description="Main topics identified in the text") sentiment: str = Field(description="Overall sentiment of the text") key_entities: List[str] = Field(description="Key entities mentioned in the text")

class ArticleSummary(BaseModel): title: str = Field(description="Suggested title for the article") summary: str = Field(description="Concise summary of the article") keywords: List[str] = Field(description="Keywords for SEO")

Create agent

agent = Agent(model="gpt-4")

Multi-step process

def process_article(text: str) -> ArticleSummary: # Step 1: Analyze the text analysis_output = Output(TextAnalysis) analysis = agent.run( f"Analyze this text and identify main topics, sentiment, and key entities:\n\n\\{text\\}", output=analysis_output )

# Step 2: Generate summary based on analysis
summary_output = Output(ArticleSummary)
summary = agent.run(
    f"""
    Based on the following analysis, create a title, summary, and keywords:

    Main Topics: \\\\{', '.join(analysis.main_topics)\\\\}
    Sentiment: \\\\{analysis.sentiment\\\\}
    Key Entities: \\\\{', '.join(analysis.key_entities)\\\\}

    Original Text:
    \\\\{text\\\\}
    """,
    output=summary_output
)

return summary

Use the multi-step process

article_text = """ [Long article text here...] """

result = process_article(article_text) print(f"Title: \\{result.title\\}") print(f"Summary: \\{result.summary\\}") print(f"Keywords: \\{', '.join(result.keywords)\\}") ```_

Fehlerbehandlung und Retries

```python from pydantic_ai import Agent, Output, Validator from pydantic import BaseModel, Field, ValidationError from typing import List, Optional import time

Define output schema

class CodeSolution(BaseModel): problem_statement: str = Field(description="The original coding problem") language: str = Field(description="Programming language used") code: str = Field(description="The solution code") explanation: str = Field(description="Explanation of how the code works") test_cases: List[str] = Field(description="Example test cases")

Custom validator with specific code checks

def validate_python_code(solution: CodeSolution) -> bool: if solution.language.lower() != "python": return True # Skip validation for non-Python code

# Check for common Python syntax issues
code = solution.code
if "import" not in code and "def " not in code:
    return False

# Check for test cases
if len(solution.test_cases) < 2:
    return False

return True

Create validator with retry logic

code_validator = Validator( checks=[validate_python_code], max_retries=3, retry_delay=1.0 )

Create output with validator

code_output = Output( CodeSolution, validator=code_validator )

Use with agent and handle errors

agent = Agent(model="gpt-4")

try: result = agent.run( "Write a Python function to find the longest palindromic substring in a given string.", output=code_output )

print(f"Language: \\\\{result.language\\\\}")
print(f"Solution:\n\\\\{result.code\\\\}")
print(f"Explanation: \\\\{result.explanation\\\\}")
print("Test Cases:")
for test in result.test_cases:
    print(f"- \\\\{test\\\\}")

except ValidationError as e: print(f"Validation error: \\{e\\}") # Handle validation failure

except Exception as e: print(f"Error: \\{e\\}") # Handle other errors ```_

Asyndische Operationen

```python from pydantic_ai import Agent, Output from pydantic import BaseModel, Field import asyncio from typing import List

Define output schemas

class TranslationResult(BaseModel): original_text: str = Field(description="The original text") translated_text: str = Field(description="The translated text") language: str = Field(description="The target language")

Create agent

agent = Agent(model="gpt-4")

Async translation function

async def translate_text(text: str, languages: List[str]) -> List[TranslationResult]: # Create output translation_output = Output(TranslationResult)

# Create translation tasks
tasks = []
for language in languages:
    task = agent.arun(
        f"Translate the following text to \\\\{language\\\\}:\n\n\\\\{text\\\\}",
        output=translation_output
    )
    tasks.append(task)

# Run tasks concurrently
results = await asyncio.gather(*tasks)
return results

Use async function

async def main(): text = "Artificial intelligence is transforming the world in unprecedented ways." languages = ["Spanish", "French", "German", "Japanese", "Russian"]

translations = await translate_text(text, languages)

for translation in translations:
    print(f"\\\\{translation.language\\\\}: \\\\{translation.translated_text\\\\}")

Run async function

asyncio.run(main()) ```_

Integration mit Web Frameworks

Schnelle Integration

```python from fastapi import FastAPI, HTTPException from pydantic_ai import Agent, Output from pydantic import BaseModel, Field from typing import List

app = FastAPI()

Initialize agent

agent = Agent(model="gpt-4")

Define request and response models

class SummaryRequest(BaseModel): text: str = Field(description="Text to summarize") max_length: int = Field(default=200, description="Maximum summary length")

class SummaryResponse(BaseModel): original_length: int = Field(description="Length of original text") summary: str = Field(description="Generated summary") keywords: List[str] = Field(description="Key topics in the text")

Define output schema

class TextSummary(BaseModel): summary: str = Field(description="Concise summary of the text") keywords: List[str] = Field(description="Key topics extracted from the text")

Create endpoint

@app.post("/summarize", response_model=SummaryResponse) async def summarize_text(request: SummaryRequest): try: # Create output summary_output = Output(TextSummary)

    # Generate summary
    result = await agent.arun(
        f"""
        Summarize the following text in no more than \\\\{request.max_length\\\\} characters:

        \\\\{request.text\\\\}
        """,
        output=summary_output
    )

    # Create response
    return SummaryResponse(
        original_length=len(request.text),
        summary=result.summary,
        keywords=result.keywords
    )
except Exception as e:
    raise HTTPException(status_code=500, detail=str(e))

Run with: uvicorn app:app --reload

```_

Integration von Flask

```python from flask import Flask, request, jsonify from pydantic_ai import Agent, Output from pydantic import BaseModel, Field from typing import List

app = Flask(name)

Initialize agent

agent = Agent(model="gpt-4")

Define output schema

class ContentGenerator(BaseModel): title: str = Field(description="Attention-grabbing title") introduction: str = Field(description="Engaging introduction paragraph") sections: List[str] = Field(description="Main content sections") conclusion: str = Field(description="Concluding paragraph")

Create output

content_output = Output(ContentGenerator)

@app.route("/generate-content", methods=["POST"]) def generate_content(): data = request.json topic = data.get("topic", "") tone = data.get("tone", "informative") length = data.get("length", "medium")

if not topic:
    return jsonify(\\\\{"error": "Topic is required"\\\\}), 400

try:
    # Generate content
    result = agent.run(
        f"""
        Generate content about "\\\\{topic\\\\}" with a \\\\{tone\\\\} tone.
        The content should be \\\\{length\\\\} length.
        """,
        output=content_output
    )

    # Create response
    return jsonify(\\\\{
        "title": result.title,
        "introduction": result.introduction,
        "sections": result.sections,
        "conclusion": result.conclusion
    \\\\})
except Exception as e:
    return jsonify(\\\\{"error": str(e)\\\\}), 500

Run with: flask run

```_

Best Practices

Entwurf

  • Start Simple: Beginnen Sie mit einfachen Schemas und fügen Sie allmählich Komplexität hinzu
  • *Use Field Descriptions: Immer klare Beschreibungen für jedes Feld enthalten
  • *Appropriate Types: Wählen Sie geeignete Typen für jedes Feld (String, Int, Float, Liste, etc.)
  • *Optionale Felder: Verwenden Sie Optional für Felder, die nicht immer vorhanden sein könnten
  • *Validation Constraints: Fügen Sie Zwänge wie min/max Länge, Regex Muster, etc. hinzu.
  • *Nested Models: Verwenden Sie geschachtelte Modelle für komplexe Datenstrukturen
  • *Enums: Verwenden Sie Enum-Klassen für Felder mit einem festen Satz von möglichen Werten

Prompt Engineering

  • *Clear Instructions: Geben Sie klare, spezifische Anweisungen in Aufforderungen
  • Context: Einschlägiger Kontext für die Aufgabe
  • Beispiele: Inklusive der erwarteten Leistung, wenn möglich
  • *Structured Format: Verwenden Sie strukturierte Formate wie nummerierte Listen oder Abschnitte
  • *Avoid Ambiguity: Seien Sie explizit, was Sie wollen, das Modell zu tun
  • *Iterative Refinement: Refine-Prompts basierend auf Modellausgängen

Fehlerbehebung

  • *Validationsfehler: Handle Validierungsfehler anmutig
  • Retry Logic: Implementierung von Retry-Logik für transiente Fehler
  • *Fallbacks: Haben Rückschläge Strategien, wenn der primäre Ansatz scheitert
  • Logging: Logfehler und Modellantworten für Debugging
  • User Feedback: Bereitstellung hilfreicher Fehlermeldungen für Benutzer

Leistungsoptimierung

  • *Batch Processing: Verarbeiten Sie mehrere Einzelteile nach Möglichkeit
  • Caching: Cache-Antworten für gleiche oder ähnliche Anfragen
  • Async Operations: Verwenden Sie Async-Funktionen für gleichzeitige Operationen
  • Auswahl: Wählen Sie geeignete Modelle basierend auf Task-Komplexität
  • Token Management: Achten Sie auf Token-Nutzung, um Kosten zu kontrollieren

Fehlerbehebung

Gemeinsame Themen

Schema Validierungsfehler

  • Cause: Modellausgabe passt nicht zum erwarteten Schema
  • Solution: Reduzieren Sie die Eingabeaufforderungen, um mehr über das gewünschte Format zu erfahren oder das Schema anzupassen, um flexibler zu sein

Inkonsistente Ausgänge

  • ** Denn**: Vague-Eingänge oder hohe Temperatureinstellungen
  • Solution: Machen Sie die Eingabeaufforderungen genauer und reduzieren Sie die Temperatur für konsistentere Ausgänge

Langsame Leistung

  • ** Denn**: Große Anfragen, komplexe Schemata oder ineffiziente Verarbeitung
  • Solution: Optimierung von Eingabeaufforderungen, Verwendung von Async-Operationen oder Implementierung von Cache

Hohe Token-Nutzung

  • Cause: Verbose fordert oder unnötigen Kontext
  • Solution: Streamline-Prompts, effizientere Modelle verwenden oder Token-Nutzungsüberwachung implementieren

--

*Diese umfassende Pydantic AI-Cheatsheet bietet alles, was nötig ist, um produktionsfähige KI-Anwendungen mit Typsicherheit und Validierung aufzubauen. Von grundlegender Einrichtung bis hin zu fortgeschrittenen Mustern, verwenden Sie diese Beispiele und Best Practices, um robuste, pflegefähige KI-Funktionen mit dem strukturierten Ansatz von Pydantic AI zu schaffen. *