Pydantic AI: using the VIDAI Control Plane as the backend¶
Pydantic AI's OpenAIModel takes an explicit OpenAIProvider.
Set the provider's base_url to the control plane and every
agent using that model routes through it.
TL;DR¶
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIModel
from pydantic_ai.providers.openai import OpenAIProvider
model = OpenAIModel(
"gpt-4o-mini",
provider=OpenAIProvider(
base_url="https://your-vidai-server.example.com/v1",
api_key="your-vidai-key",
),
)
agent = Agent(model)
result = agent.run_sync("reply with: ok")
print(result.output)
Prerequisites¶
pip install pydantic-ai(any recent version withOpenAIProvider— 0.0.14 onward).- Control plane base URL and an API key from API Keys.
- A model registered on the Models page.
Structured output¶
Pydantic AI's whole point is typed output. It works transparently — the control plane forwards the JSON-mode request unchanged:
from pydantic import BaseModel
from pydantic_ai import Agent
class Ticket(BaseModel):
priority: str
reason: str
agent = Agent(model, output_type=Ticket)
result = agent.run_sync("Priority for: printer is on fire")
print(result.output.priority, result.output.reason)
Tools¶
Tools attached with the @agent.tool decorator are called
through the same model. No extra setup:
@agent.tool
def get_stock(ctx, symbol: str) -> float:
return 137.42
result = agent.run_sync("What's the current price of AAPL?")
Every tool-call round trip is a control-plane request that appears in Request Logs.
Streaming¶
agent.run_stream() streams tokens back — the control plane
forwards the stream unchanged:
async with agent.run_stream("write a haiku about ships") as run:
async for chunk in run.stream_text():
print(chunk, end="", flush=True)
Cross-provider routing¶
Pydantic AI has separate AnthropicModel, GeminiModel, etc.,
but you don't need them to reach non-OpenAI upstreams — a model
registered on the control plane that routes to Anthropic is
still callable via OpenAIModel("claude-haiku-4-5", ...). The
control plane handles the wire-format translation.
If your code specifically needs AnthropicModel (say, for
Anthropic-specific tool-call schemas), point its provider
at the control plane the same way:
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.anthropic import AnthropicProvider
model = AnthropicModel(
"claude-haiku-4-5",
provider=AnthropicProvider(
base_url="https://your-vidai-server.example.com",
api_key="your-vidai-key",
),
)
Note the base URL for AnthropicProvider is the root (no
/v1); the SDK adds /v1/messages itself.
Verify it works¶
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIModel
from pydantic_ai.providers.openai import OpenAIProvider
model = OpenAIModel(
"gpt-4o-mini",
provider=OpenAIProvider(
base_url="https://your-vidai-server.example.com/v1",
api_key="your-vidai-key",
),
)
agent = Agent(model)
print(agent.run_sync("reply with exactly: ok").output)
If something's off¶
Raise an issue at github.com/vidaiUK/vidai-quickstart/issues with your provider config and the agent snippet that reproduces the issue. We'll get it sorted.