Pydantic AI: как собрать типобезопасного AI-агента на Python с MCP и Ollama
Большинство AI-примеров начинается с пары строк: отправить prompt и вывести текст. В реальном приложении быстро появляются другие требования: строгая структура ответа, tools, зависимости, MCP, retries, тесты, измерение стоимости и восстановление долгого workflow после сбоя. Pydantic AI превращает эти задачи в обычные Python-типы и управляемые компоненты, а не в набор строк и ручного JSON-парсинга.
Pydantic AI — не модель и не готовый агент, а framework для сборки своего
Центральный объект — Agent.
Он объединяет instructions, модель, tools/toolsets, structured output,
зависимости и runtime settings.
При этом обычный Python type system остаётся частью архитектуры:
IDE и статический type checker знают, какой тип должен вернуть agent.
Agent строится обычным Python-кодом, а не только визуальной схемой.
Результат можно валидировать как Pydantic model до попадания в business logic.
Model backend можно заменить без переписывания всей agent architecture.
Есть observability, evals, retries, usage limits и durable execution.
Pydantic AI v2 — отдельная стабильная линия с новой архитектурой capabilities/toolsets
Stable v2 вышел 23 июня 2026 года. Текущий v2.46.0 уже относится к production/stable линии. Старые примеры v0.x/v1.x могут использовать другие имена аргументов, старый MCP API и прежнюю структуру integrations.
V2 делает capability основной composable единицей поведения агента.
Локальные tools, MCP и dynamic toolsets подключаются единообразно.
Старые instrumentation versions постепенно уходят.
Некоторые providers и integrations больше не ставятся по умолчанию.
Для нового проекта ориентируйтесь на v2 docs, а не на статьи 2024–2025 годов
с result_type, старым MCP API или v0.x imports.
Установка Pydantic AI 2.46.0
python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
pip install pydantic-ai==2.46.0
С uv:
uv init
uv add pydantic-ai==2.46.0
Обычный пакет уже включает frontier providers и основные integrations: OpenAI, Anthropic, Google, CLI, MCP, evals, web, retries и Logfire. Дополнительные providers вроде Bedrock/Groq/OpenRouter/Hugging Face подключаются через extras.
uv add "pydantic-ai[openrouter]"
uv add "pydantic-ai[bedrock]"
uv add "pydantic-ai[ag-ui]"
LLM может возвращать не строку, а валидированный Python-объект
from pydantic import BaseModel
from pydantic_ai import Agent
class DeviceFault(BaseModel):
device: str
severity: str
probable_cause: str
needs_human: bool
agent = Agent(
"openai:gpt-5.2",
output_type=DeviceFault,
)
result = agent.run_sync(
"Блок питания греется, напряжение проседает под нагрузкой."
)
fault = result.output
print(fault.device)
print(fault.needs_human)
Внутри framework строит JSON Schema и валидирует model output. Если модель не возвращает структуру нужного вида, результат не должен бесконтрольно пройти дальше как «почти JSON».
Structured result оформляется через tool-call schema.
Используется native structured-output feature модели, если она поддерживается.
Fallback-подход для моделей без полноценного native schema mode.
Pydantic проверит, что severity и needs_human имеют допустимый тип,
но не докажет, что диагноз модели верен.
Agent получает реальные функции вместо попытки «угадать ответ»
from pydantic_ai import Agent
agent = Agent(
"openai:gpt-5.2",
instructions="Используй инструменты, когда нужны фактические данные.",
)
@agent.tool_plain
def cable_price(section_mm2: float) -> float:
"""Return demo cable price per meter."""
demo_prices = {
1.5: 55.0,
2.5: 82.0,
4.0: 128.0,
}
return demo_prices[section_mm2]
result = agent.run_sync(
"Сколько стоят 20 метров кабеля 2.5 мм²?"
)
print(result.output)
Tool schema строится из Python signature и type hints. Модель решает, когда вызвать function, framework валидирует arguments и возвращает результат обратно в agent loop.
Простой локальный action.
Удобно разделять capabilities по доменам.
GitHub, БД, browser, CRM и другие services.
Например, разные permissions для разных пользователей.
API client, database connection и user context не нужно хранить в global variables
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
@dataclass
class Deps:
user_id: int
database: object
agent = Agent(
"openai:gpt-5.2",
deps_type=Deps,
)
@agent.tool
def get_user_name(ctx: RunContext[Deps]) -> str:
"""Read user data from application dependencies."""
return f"user-{ctx.deps.user_id}"
deps = Deps(
user_id=42,
database=object(),
)
result = agent.run_sync(
"Кто текущий пользователь?",
deps=deps,
)
Такой подход полезен для production: agent code получает только те зависимости, которые приложение передало конкретному run, а type checker видит их тип.
Tool может проверять роль пользователя до обращения к БД или внешнему API, вместо того чтобы надеяться, что LLM сама «помнит правила доступа».
Pydantic AI может быть MCP-клиентом и подключать внешние tools прямо к Agent
В современной v2-линии MCP реализован через toolsets.
Текущий MCPToolset работает с FastMCP 3 и 4,
а для remote server рекомендуемый transport — Streamable HTTP.
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPToolset
tools = MCPToolset(
"http://localhost:8000/mcp"
)
agent = Agent(
"openai:gpt-5.2",
toolsets=[tools],
)
result = agent.run_sync(
"Используй доступные инструменты и ответь на вопрос."
)
Поддерживаются также stdio, SSE для legacy deployments, готовый FastMCP Client и даже in-process FastMCP server без network round-trip.
Новый deployment лучше строить вокруг него.
Удобно для CLI MCP servers.
MCP SSE transport deprecated; используйте его только для совместимости.
Подходит для тестов или single-process приложения.
Официальная документация предупреждает: config может указывать executable/arguments для subprocess и разворачивать environment variables. Не загружайте MCP config из недоверенного источника.
Pydantic AI напрямую поддерживает self-hosted Ollama
Для локального Ollama используется OpenAI-compatible endpoint
http://localhost:11434/v1.
# Linux/macOS
export OLLAMA_BASE_URL="http://localhost:11434/v1"
# Windows PowerShell
$env:OLLAMA_BASE_URL = "http://localhost:11434/v1"
from pydantic_ai import Agent
agent = Agent("ollama:qwen3")
result = agent.run_sync(
"Объясни разницу между RAG и fine-tuning."
)
print(result.output)
Structured output с локальным Ollama
from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai.models.ollama import OllamaModel
from pydantic_ai.output import NativeOutput
from pydantic_ai.providers.ollama import OllamaProvider
class CheckResult(BaseModel):
ok: bool
reason: str
model = OllamaModel(
"qwen3",
provider=OllamaProvider(
base_url="http://localhost:11434/v1"
),
)
agent = Agent(
model,
output_type=NativeOutput(CheckResult),
)
Self-hosted Ollama умеет schema-constrained structured output,
поэтому Pydantic AI может использовать NativeOutput
для локальной модели.
В v2.41 появился отдельный OpenAI Codex provider для subscription authentication
Release v2.41.0 добавил provider openai-codex,
предназначенный для аутентификации через ChatGPT/Codex subscription.
Это отдельный integration path от классического OpenAI API key.
Для developer framework это интересное изменение: один и тот же Agent API может работать с обычными cloud providers, локальным Ollama и отдельными subscription-backed providers.
Pydantic AI — framework вашего Python-приложения. Codex provider — один из способов дать framework доступ к модели; он не превращает приложение автоматически в coding-agent.
Pydantic Evals позволяет гонять одинаковый набор кейсов после каждого изменения prompt/model
from pydantic_evals import Case, Dataset
dataset = Dataset(
name="support-agent",
cases=[
Case(
name="simple",
inputs="Сеть пропала после перезагрузки роутера",
expected_output="check_wan",
),
],
)
def my_task(inputs: str) -> str:
# Здесь вызывается agent/application code.
return "check_wan"
report = dataset.evaluate_sync(my_task)
report.print()
Реальные примеры из вашего продукта.
Позволяет замечать regression.
Можно измерять не только точное совпадение строк.
Есть evaluators для корректности tools, аргументов и количества model requests.
Он может дать правильный результат после десяти лишних tool calls, вызвать опасный tool или передать неправильные arguments. Agentic evals проверяют и траекторию.
Agent run можно разложить на model requests, tools, tokens, latency и ошибки
import logfire
logfire.configure()
logfire.instrument_pydantic_ai()
Tracing показывает сообщения, tool calls и arguments, token usage, latency и errors. При этом instrumentation построена на OpenTelemetry, поэтому telemetry можно отправлять не только в Logfire, но и в совместимые backends.
Полезно при сложных dynamic instructions.
Видны arguments и return values.
Можно сравнивать разные model paths.
Не только final exception, но и контекст span.
Durable execution сохраняет progress workflow после сбоя приложения или API
Pydantic AI поддерживает несколько durability engines: Temporal, DBOS, Prefect, Restate, AWS Lambda, а также внешние integrations с Kitaru и Apache Airflow. Есть builder для подключения других engines.
DBOS: простой пример
from dbos import DBOS, DBOSConfig
from pydantic_ai import Agent
from pydantic_ai.durable_exec.dbos import DBOSDurability
DBOS(
config={
"name": "agent-app",
"system_database_url": "sqlite:///dbos.sqlite",
}
)
agent = Agent(
"openai:gpt-5.2",
name="support-agent",
capabilities=[DBOSDurability()],
)
@DBOS.workflow()
async def answer(question: str) -> str:
result = await agent.run(question)
return result.output
Model requests и MCP communication становятся durable steps. После restart workflow может продолжить работу с checkpoint, а не повторять всё с начала.
Официальные docs отдельно подчёркивают: durable engine сохраняет progress одного workflow после crash, но не заменяет обычное хранение conversation history в вашей БД.
Основной риск начинается не с hallucination, а с реального side effect
Не давать agent административный API, если нужен read-only search.
Pydantic schema помогает, но business permissions проверяет сам tool.
Оплата, удаление данных и deployment требуют отдельного подтверждения.
Он может запускать subprocess и читать environment variables.
Prompt injection остаётся возможным даже при корректных Python types.
Web/MCP integrations регулярно получают security fixes.
Свежие security fixes сентября 2026
В v2.44.0 были исправлены несколько security issues,
которые также отдельно опубликованы в GitHub Security Advisories.
Среди них — обход ограничения blocked_domains
в web_fetch_tool через hostname normalization
и SSRF bypass cloud-metadata blocklist через IPv6 zone identifiers.
Также исправлялась ситуация, когда OpenTelemetry spans могли содержать
exceptions, instructions и output template даже при include_content=False.
Текущий v2.46.0 уже новее исправленной 2.44.0.
Type validation защищает форму данных. Authorization, network boundaries, sandbox и подтверждение dangerous actions остаются ответственностью вашего приложения.
Pydantic AI хорошо подходит Python-разработчику, но не снимает сложность agent systems
Это framework, а не no-code builder.
Разные модели по-разному реализуют tools, reasoning и structured output.
Schema-valid ответ всё равно может быть фактически неверным.
Каждый внешний tool становится новой границей доверия.
Temporal/DBOS/Prefect требуют отдельной operational дисциплины.
Minor releases выходят часто; фиксируйте versions для production.
Возьмите одну понятную функцию: typed input → 1–3 tools → typed output → eval dataset. После этого уже добавляйте MCP, memory и durable execution.
Где Pydantic AI особенно уместен
Строго вернуть категорию, severity и следующий action.
Tool получает документы, output возвращается валидированной структурой.
Agent вызывает CRM/БД/MCP tools с обычной application authorization.
Вся inference-часть может оставаться внутри локальной сети.
Durable engine восстанавливает agent после restart или API failure.
Pydantic Evals проверяет outputs, tools и trajectory после изменений.
Pydantic AI: release, types, tools, MCP, Ollama, durable execution и security
На дату проверки latest stable — v2.46.0 от 18 сентября 2026 года,
Python >=3.10, лицензия MIT.
Pydantic AI полезен там, где LLM должна стать частью обычного надёжного Python-приложения
Сильная сторона framework не в том, что он «лучше думает» за модель, а в том, что он ставит вокруг LLM привычные инженерные границы: типы, dependency injection, tool schemas, evals, traces и durable execution.
Это особенно хорошо сочетается с локальными backend: Ollama отвечает за inference, Pydantic AI — за agent logic, MCP — за внешние инструменты, а evals и OpenTelemetry позволяют проверять результат вместо слепого доверия prompt.
Частые вопросы про Pydantic AI
Что такое Pydantic AI простыми словами?
Python framework для создания AI-агентов с типизированными outputs, tools, dependencies, MCP, evals и observability.
Это готовый аналог Claude Code или Codex?
Нет. Pydantic AI — библиотека для разработки собственного AI-приложения или агента.
Можно ли использовать локальную модель?
Да. Есть официальный provider для self-hosted Ollama; также можно использовать OpenAI-compatible backends через подходящие providers.
Поддерживается ли MCP?
Да. Pydantic AI умеет подключать MCP servers как toolsets через Streamable HTTP, stdio, SSE и in-process FastMCP.
Чем structured output лучше обычного JSON в prompt?
Framework строит schema, валидирует результат и сохраняет Python type information до application code. Но фактическую истинность данных всё равно нужно проверять отдельно.
Можно ли тестировать agent без ручной проверки каждого ответа?
Да. Pydantic Evals позволяет собирать datasets и evaluators, включая agentic metrics по tool calls и trajectory.
Что такое durable agent?
Agent run, progress которого checkpoint'ится и может продолжиться после restart или transient failure через Temporal, DBOS, Prefect и другие engines.
Поддерживается ли ChatGPT/Codex subscription?
Да. Начиная с v2.41.0 в Pydantic AI есть отдельный openai-codex provider для subscription authentication.
Какая версия актуальна?
На 21 сентября 2026 года актуальный stable release — Pydantic AI 2.46.0.
Нужно собрать собственного локального агента, а не просто ещё один чат?
Можно разделить задачу на model backend, tools, permissions, structured output, MCP и eval dataset — и выбрать минимальный stack без лишней инфраструктуры.


