> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dottxt.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Pydantic AI

[Pydantic AI](https://ai.pydantic.dev/) is the official agent framework by the Pydantic team. It supports typed structured output via `output_type` and works with any OpenAI-compatible endpoint.

For dottxt, `output_type` is the important integration point: Pydantic AI derives JSON Schema from your output model, sends that schema through the OpenAI-compatible API, and parses the result back into a typed object.

## Install

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
pip install pydantic-ai openai pydantic
```

## Configure

Create an `OpenAIProvider` pointed at dottxt, then wrap it in an `OpenAIChatModel`:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import os
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

provider = OpenAIProvider(
    base_url="https://api.dottxt.ai/v1",
    api_key=os.environ["DOTTXT_API_KEY"],
)
model = OpenAIChatModel("openai/gpt-oss-20b", provider=provider)
```

## Basic usage

Pass a Pydantic model as `output_type` to get typed structured output:

<CodeGroup>
  ```python Pydantic AI theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  from pydantic import BaseModel, ConfigDict, Field
  from pydantic_ai import Agent

  class CityLocation(BaseModel):
      model_config = ConfigDict(extra="forbid")

      city: str = Field(description="City name")
      country: str = Field(description="Country name")

  agent = Agent(model, output_type=CityLocation)

  result = agent.run_sync("Where were the 2012 Olympics held?")
  print(result.output)
  # CityLocation(city='London', country='United Kingdom')
  ```

  ```json Response theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "city": "London",
    "country": "United Kingdom"
  }
  ```
</CodeGroup>

Pydantic AI generates the schema from `output_type` and parses the response back into `result.output`. Under the hood, this still uses the same dottxt structured generation flow described in [API Overview](/api/overview) and [Pydantic Authoring](/json-schema/authoring/pydantic).

## Agent with dependencies and tools

Use `deps_type` to inject runtime context, and `@agent.tool` to give the agent callable functions:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from dataclasses import dataclass
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field
from pydantic_ai import Agent, RunContext

@dataclass
class SupportDeps:
    customer_name: str
    account_id: int

class SupportResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    greeting: str
    answer: str
    follow_up_question: str = Field(min_length=8)
    priority: Literal["low", "medium", "high"]

agent = Agent(
    model,
    output_type=SupportResponse,
    deps_type=SupportDeps,
    instructions="You are a helpful customer support agent. Always greet the customer by name.",
)

@agent.tool
def get_account_status(ctx: RunContext[SupportDeps]) -> str:
    """Look up the account status for the current customer."""
    return f"Account #{ctx.deps.account_id} is active and in good standing."

result = agent.run_sync(
    "What is the status of my account?",
    deps=SupportDeps(customer_name="Alice", account_id=42),
)
print(result.output.greeting)
print(result.output.answer)
```

## Notes

* Use `output_type`, not `result_type`; the latter was removed in Pydantic AI v0.6.0.
* `agent.run()` is async, `agent.run_sync()` is synchronous, `agent.run_stream()` is async streaming.
* The result is accessed via `result.output`, typed according to `output_type`.
* `ConfigDict(extra="forbid")` is useful when you want `additionalProperties: false` in the generated schema.
* See the [Pydantic authoring guide](/json-schema/authoring/pydantic) for how to write effective schemas.
