# PydanticAI

Source: https://staging-docs.aiand.com/integrations/pydantic-ai/

[PydanticAI](https://ai.pydantic.dev/) treats LLMs as typed functions. It works against ai& through its OpenAI-compatible provider.

## Setup

```bash
pip install pydantic-ai
```

```python
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIModel
from pydantic_ai.providers.openai import OpenAIProvider

model = OpenAIModel(
    "openai/gpt-oss-120b",
    provider=OpenAIProvider(
        base_url="https://api.aiand.com/v1",
        api_key="sk-your-api-key",
    ),
)
```

## A typed agent

```python
agent = Agent(model, system_prompt="Be concise.")
result = await agent.run("What is the capital of France?")
print(result.output)
```

## Structured outputs

```python
from pydantic import BaseModel

class Contact(BaseModel):
    name: str
    email: str

agent = Agent(model, output_type=Contact)
result = await agent.run("From: Jane Doe <jane@example.com>")
print(result.output.name, result.output.email)
```

The schema is shipped to ai& as a strict JSON Schema and the output is parsed back into the Pydantic model.

## Tools

```python
@agent.tool_plain
def get_weather(city: str) -> str:
    """Get current weather for a city."""
    return f"Sunny in {city}, 22°C"

result = await agent.run("What's the weather in Tokyo?")
print(result.output)
```

<Aside type="tip">
  PydanticAI maps `output_type` directly to ai&'s `response_format: json_schema`. Models with `tool_calling` on the [Catalog](/models/catalog/) generally accept this; otherwise fall back to a Pydantic-free prompt.
</Aside>
