Skip to main content
Pydantic AI 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

pip install pydantic-ai openai pydantic

Configure

Create an OpenAIProvider pointed at dottxt, then wrap it in an OpenAIChatModel:
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:
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')
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 and Pydantic Authoring.

Agent with dependencies and tools

Use deps_type to inject runtime context, and @agent.tool to give the agent callable functions:
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 for how to write effective schemas.