---
title: "Pydantic AI with EU-hosted models · Setup guide"
description: "Connect Pydantic AI agents to inference.eu with OpenAICompatibleProvider and get typed, validated output from open-weight models processed in the EU."
canonical: "https://inference.eu/integrations/pydantic-ai/"
language: "en"
---

Frameworks · Pydantic AI

# Use Pydantic AI with open-source models hosted in the EU

Pydantic AI is a Python agent framework from the team behind Pydantic, built around type-safe tools and validated output. Its \`OpenAICompatibleProvider\` connects to any OpenAI-compatible endpoint, so your agents can run on open-weight models at inference.eu, processed in European data centres.

[Contact sales](https://inference.eu/contact/)[Setup](#setup)

1.  01API format: OpenAI
2.  02EU data centres
3.  03Covered by one DPA

## Set it up in a few minutes

1.  1

    Create an API key in your inference.eu account and store it as `INFERENCE_EU_API_KEY`.

2.  2

    Install the library with `pip install pydantic-ai-slim[openai]` or the full `pydantic-ai` package.

3.  3

    Create an `OpenAICompatibleProvider` named `inference-eu` with `base_url` set to the inference.eu base URL and your key.

4.  4

    Wrap it in `OpenAIChatModel` with an inference.eu model id and pass the model to `Agent`.

5.  5

    Run the agent with `run_sync` or `run` and check the typed output.

python

```
import os
from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai_compatible import OpenAICompatibleProvider

model = OpenAIChatModel(
    "glm-5.3",
    provider=OpenAICompatibleProvider(
        "inference-eu",
        base_url="https://api.inference.eu/v1",
        api_key=os.environ["INFERENCE_EU_API_KEY"],
    ),
)

class Invoice(BaseModel):
    supplier: str
    total_eur: float

agent = Agent(model, output_type=Invoice)
print(agent.run_sync("Supplier: Acme GmbH, total due 1.240,50 EUR").output)
```

## What Pydantic AI is

Pydantic AI is an open-source Python framework for building agents and model-backed features. You declare tools as typed Python functions and describe the output you expect as a Pydantic model; the framework handles the conversation with the model, tool calls, retries on validation errors and streaming.

It supports many providers. For services without a dedicated integration, the documented route is `OpenAICompatibleProvider` combined with `OpenAIChatModel`, which speaks the Chat Completions format. That is how you connect Pydantic AI to inference.eu while keeping the same agent code.

## How the configuration works

`OpenAICompatibleProvider` takes a name, `base_url` (the inference.eu base URL ending in `/v1`) and `api_key`. Keep the name stable, for example `inference-eu`, because Pydantic AI records it on every response and uses it to decide which data from earlier turns may be sent back.

`OpenAIChatModel` takes the inference.eu model id and the provider. Use it rather than `OpenAIResponsesModel`, since Chat Completions is the most widely supported format. Avoid `OpenAIProvider` with a custom URL: it assumes OpenAI's own models and features. If a feature misbehaves, adjust the `OpenAIModelProfile` passed as `profile`.

## Which models to choose

Pydantic AI relies on tool calls for structured output and for your own tools, so models with dependable tool calling work best. `glm-5.3` and `kimi-k3` are strong defaults for agents with several tools or complex output types, and they follow nested schemas well.

For extraction, classification and other quick typed calls, `gpt-oss-120b` keeps latency low. For agents that generate or review code, use `qwen3-coder-480b-a35b-instruct`. You can create several models on the same provider and assign them to different agents, for example a fast triage agent that hands off to a stronger specialist.

## Troubleshooting

A 401 error means the key is missing or wrong. A 404 usually means `base_url` has an extra path or the model id does not exist at inference.eu.

If the agent raises an error after retrying output validation, simplify the output model or raise `output_retries`, and choose a model with strong tool calling. If tool definitions are rejected, set `openai_supports_strict_tool_definition=False` in the profile. If a request fails because of multiple system messages, set `openai_chat_supports_multiple_system_messages=False`. Both are fields of `OpenAIModelProfile`.

## Keeping data in the EU

With the provider pointed at inference.eu, every prompt, tool result and output your agents exchange with the model is processed in EU data centres and never used for training. We sign a data processing agreement under Article 28 GDPR, publish our subprocessor list and bill in euros.

Pydantic AI itself only calls the provider you configure. It integrates with OpenTelemetry, and Logfire can record prompts and outputs when you enable instrumentation; check where your tracing backend stores that data. Tools your agents call, such as search APIs, also receive data under their own terms.

## Pydantic AI

Category

Frameworks

Maker

Pydantic

API format

OpenAI

Processing

EU data centres

Website

[pydantic.dev](https://pydantic.dev/docs/ai/overview/)

Documentation

[pydantic.dev](https://pydantic.dev/docs/ai/models/compatible-apis/)

## Pydantic AI: common questions

The questions buyers, developers and legal teams ask us most. Something missing? Ask us directly.

Create an \`OpenAICompatibleProvider\` with a name, \`base\_url\` and \`api\_key\`, wrap it in \`OpenAIChatModel\` with your model id, and pass the model to \`Agent\`. This is the documented route for services without a dedicated Pydantic AI provider.

Use \`OpenAICompatibleProvider\`. \`OpenAIProvider\` also takes a \`base\_url\`, but it is meant for OpenAI itself or a transparent proxy to it, and assumes OpenAI-specific features. The compatible provider applies a profile suited to other services.

GLM-5.3 and Kimi K3 are strong defaults for agents with several tools or nested output types. gpt-oss-120b suits quick extraction and classification, and Qwen3 Coder 480B is a good fit for agents that work with code.

Yes. Set \`output\_type\` to a Pydantic model and the agent returns a validated instance. By default Pydantic AI uses tool calls for this, retrying with the validation error if the model's first answer does not match the schema.

The model did not produce valid output within the allowed retries. Simplify the output model, add field descriptions, raise \`output\_retries\`, or choose a model with stronger tool calling such as GLM-5.3 or Kimi K3.

Yes. Use \`agent.run\_stream(...)\` to stream text, or stream partially validated structured output as it arrives. inference.eu streams tokens in the standard Chat Completions format that \`OpenAIChatModel\` expects, including token usage at the end.

Pydantic AI records the name on every response and uses it to decide which data from earlier responses can be sent back to the service. Keeping it fixed, for example \`inference-eu\`, keeps message history consistent across runs and stored conversations.

Use \`OpenAIChatModel\`. Chat Completions is the format every inference.eu model supports and the one Pydantic AI recommends for compatible services. Your agent code stays the same either way; only the model class differs.

No. Tools are plain Python functions and their schemas are generated by Pydantic AI. If a model rejects strict tool definitions, set \`openai\_supports\_strict\_tool\_definition=False\` in the profile; the tools themselves stay unchanged.

Not unless you enable it. Pydantic AI calls only the provider you configure. If you turn on Logfire or another OpenTelemetry exporter, prompts and outputs may be recorded there, so choose where that data is stored before enabling it.

[Ask a question](https://inference.eu/contact/)

## Related

[All integrations](https://inference.eu/integrations/)

-   [CrewAIRun CrewAI agents and crews on open-weight models processed in EU data centres by giving the LLM class the inference.eu base URL and key.Frameworks](https://inference.eu/integrations/crewai/)
-   [OpenAI SDK (Python and JavaScript)Point the official OpenAI Python or JavaScript SDK at inference.eu with base\_url and an API key, and call open-weight models processed in the EU.SDKs](https://inference.eu/integrations/openai-sdk/)
-   [LangChainConnect LangChain's ChatOpenAI to inference.eu with base\_url and run chains, agents and LangGraph workflows on open-weight models processed in the EU.Frameworks](https://inference.eu/integrations/langchain/)

## Move your AI workloads to EU infrastructure

Tell us which models you use and roughly how much traffic you have. We reply within one working day with pricing and next steps.

-   Reply within one working day
-   Pricing for your volume
-   DPA ready to sign
