Installs just this skill. Get the whole plugin for auto-invocation.
⚡ How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/pydantic-ai
👁️ Context preview
The summary Claude sees to decide when to auto-load this skill.
Build production-ready AI agents with PydanticAI — type-safe tool use, structured outputs, dependency injection, and multi-model support.
📊 Stats
Stars29,853
Forks3,189
LanguagePython
LicenseMIT
📦 Ships with claude-code-templates
</> SKILL.md
pydantic-ai.SKILL.md
---name: pydantic-ai
description: "Build production-ready AI agents with PydanticAI — type-safe tool use, structured outputs, dependency injection, and multi-model support."
category: ai-agents
risk: safe
source: community
date_added: "2026-03-18"
author: suhaibjanjua
tags: [pydantic-ai, ai-agents, llm, openai, anthropic, gemini, tool-use, structured-output, python]
tools: [claude, cursor, gemini]
---# PydanticAI — Typed AI Agents in Python
## Overview
PydanticAI is a Python agent framework from the Pydantic team that brings the same type-safety and validation guarantees as Pydantic to LLM-based applications. It supports structured outputs (validated with Pydantic models), dependency injection for testability, streamed responses, multi-turn conversations, and tool use — across OpenAI, Anthropic, Google Gemini, Groq, Mistral, and Ollama. Use this skill when building production AI agents, chatbots, or LLM pipelines where correctness and testability matter.
## When to Use This Skill
- Use when building Python AI agents that call tools and return structured data
- Use when you need validated, typed LLM outputs (not raw strings)
- Use when you want to write unit tests for agent logic without hitting a real LLM
research = await researcher.run(f'Research the topic: {topic}')
# Stage 2: write based on research
post = await writer.run(
f'Write a blog post about: {topic}\n\nResearch:\n' +
'\n'.join(f'- {p}' for p in research.data.key_points) +
f'\n\nConclusion: {research.data.conclusion}'
)
return post.data
```
## Best Practices
- ✅ Always define `result_type` with a Pydantic model — avoid returning raw strings in production
- ✅ Use `deps_type` with a dataclass for dependency injection — makes agents testable
- ✅ Use `TestModel` in unit tests — never hit a real LLM in CI
- ✅ Add `@agent.result_validator` for business-logic checks beyond Pydantic validation
- ✅ Use `run_stream` for long outputs in user-facing applications to show progressive results
- ❌ Don't put secrets (API keys) in `Agent()` arguments — use environment variables
- ❌ Don't share a single `Agent` instance across async tasks if deps differ — create per-request instances or use `agent.run()` with per-call `deps`
- ❌ Don't catch `ValidationError` broadly — let PydanticAI retry with `ModelRetry` for recoverable LLM output errors
## Security & Safety Notes
- Set API keys via environment variables (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, etc.) — never hardcode them.
- Validate all tool inputs before passing to external systems — use Pydantic models or manual checks.
- Tools that mutate data (write to DB, send emails, call payment APIs) should require explicit user confirmation before the agent invokes them in production.
- Log `result.all_messages()` for audit trails when agents perform consequential actions.
- Set `retries=` limits on `Agent()` to prevent runaway loops on persistent validation failures.
## Common Pitfalls
- **Problem:** `ValidationError` on every LLM response — structured output never validates
**Solution:** Simplify `result_type` fields. Use `Optional` and `default` where appropriate. The model may struggle with overly strict schemas.
- **Problem:** Tool is never called by the LLM
**Solution:** Write a clear, specific docstring for the tool function — PydanticAI sends the docstring as the tool description to the LLM.
- **Problem:** `RunContext` dependency is `None` inside a tool
**Solution:** Pass `deps=` when calling `agent.run()` or `agent.run_sync()`. Dependencies are not set globally.
- **Problem:** `asyncio.run()` error when calling `agent.run()` inside FastAPI
**Solution:** Use `await agent.run()` directly in async FastAPI route handlers — don't wrap in `asyncio.run()`.
## Related Skills
- `@langchain-architecture` — Alternative Python AI framework (more flexible, less type-safe)
- `@llm-application-dev-ai-assistant` — General LLM application development patterns
- `@fastapi-templates` — Serving PydanticAI agents via FastAPI endpoints