9201ef759e
Harness Compat / harness compat (push) Failing after 0s
CI / test on 3.12 (standard) (push) Has been cancelled
CI / test on 3.13 (standard) (push) Has been cancelled
CI / test on 3.14 (standard) (push) Has been cancelled
CI / test on 3.10 (all-extras) (push) Has been cancelled
CI / test on 3.11 (all-extras) (push) Has been cancelled
CI / test on 3.12 (all-extras) (push) Has been cancelled
CI / test on 3.14 (pydantic-ai-slim) (push) Has been cancelled
CI / test on 3.10 (pydantic-evals) (push) Has been cancelled
CI / test on 3.11 (pydantic-evals) (push) Has been cancelled
CI / test on 3.12 (pydantic-evals) (push) Has been cancelled
CI / deploy-docs-preview (push) Has been cancelled
CI / build release artifacts (push) Has been cancelled
CI / publish to PyPI (push) Has been cancelled
CI / Send tweet (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / mypy (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / test on 3.10 (standard) (push) Has been cancelled
CI / test on 3.11 (standard) (push) Has been cancelled
CI / test on 3.13 (all-extras) (push) Has been cancelled
CI / test on 3.14 (all-extras) (push) Has been cancelled
CI / test on 3.10 (pydantic-ai-slim) (push) Has been cancelled
CI / test on 3.11 (pydantic-ai-slim) (push) Has been cancelled
CI / test on 3.12 (pydantic-ai-slim) (push) Has been cancelled
CI / test on 3.13 (pydantic-ai-slim) (push) Has been cancelled
CI / test on 3.13 (pydantic-evals) (push) Has been cancelled
CI / test on 3.14 (pydantic-evals) (push) Has been cancelled
CI / test on 3.10 (lowest-versions) (push) Has been cancelled
CI / test on 3.11 (lowest-versions) (push) Has been cancelled
CI / test on 3.12 (lowest-versions) (push) Has been cancelled
CI / test on 3.13 (lowest-versions) (push) Has been cancelled
CI / test on 3.14 (lowest-versions) (push) Has been cancelled
CI / test examples on 3.11 (push) Has been cancelled
CI / test examples on 3.12 (push) Has been cancelled
CI / test examples on 3.13 (push) Has been cancelled
CI / test examples on 3.14 (push) Has been cancelled
CI / coverage (push) Has been cancelled
CI / check (push) Has been cancelled
CI / deploy-docs (push) Has been cancelled
189 lines
8.1 KiB
Markdown
189 lines
8.1 KiB
Markdown
# Agent Specs
|
|
|
|
Agent specs let you define agents declaratively in YAML or JSON — [model](models/overview.md), [instructions](agent.md#instructions), [capabilities](capabilities.md), and all. One line to load, no Python agent construction code required.
|
|
|
|
This is useful for:
|
|
|
|
- Separating agent configuration from application code
|
|
- Letting non-developers (prompt engineers, domain experts) configure agents
|
|
- Storing agent definitions alongside other config files
|
|
- Sharing agent configurations across teams or projects
|
|
|
|
## Defining a spec
|
|
|
|
A spec file defines the agent's configuration in YAML or JSON:
|
|
|
|
```yaml {title="agent.yaml" test="skip"}
|
|
model: anthropic:claude-opus-4-6
|
|
instructions: You are a helpful research assistant.
|
|
model_settings:
|
|
max_tokens: 8192
|
|
capabilities:
|
|
- WebSearch:
|
|
local: duckduckgo
|
|
- Thinking:
|
|
effort: high
|
|
```
|
|
|
|
## Loading specs
|
|
|
|
[`Agent.from_file`][pydantic_ai.Agent.from_file] loads a spec from a YAML or JSON file and constructs an agent:
|
|
|
|
```python {title="from_file_example.py" test="skip"}
|
|
from pydantic_ai import Agent
|
|
|
|
agent = Agent.from_file('agent.yaml')
|
|
```
|
|
|
|
[`Agent.from_spec`][pydantic_ai.Agent.from_spec] accepts a dict or [`AgentSpec`][pydantic_ai.agent.spec.AgentSpec] instance and supports additional keyword arguments that supplement or override the spec:
|
|
|
|
```python {title="from_spec_example.py"}
|
|
from dataclasses import dataclass
|
|
|
|
from pydantic_ai import Agent
|
|
|
|
|
|
@dataclass
|
|
class UserContext:
|
|
user_name: str
|
|
|
|
|
|
agent = Agent.from_spec(
|
|
{
|
|
'model': 'anthropic:claude-opus-4-6',
|
|
'instructions': 'You are helping {{user_name}}.',
|
|
'capabilities': [{'WebSearch': {'local': 'duckduckgo'}}],
|
|
},
|
|
deps_type=UserContext,
|
|
)
|
|
```
|
|
|
|
Keyword arguments interact with spec fields as follows:
|
|
|
|
* **Scalar fields** (`model`, `name`, `end_strategy`, etc.) — the keyword argument overrides the spec value when provided. For retry budgets, the `retries` keyword argument overrides the spec's `retries` value.
|
|
* **`instructions`** — merged: spec instructions come first, then keyword argument instructions.
|
|
* **`capabilities`** — merged: spec capabilities come first, then keyword argument capabilities.
|
|
* **`model_settings`** — merged additively: keyword argument settings override matching spec settings.
|
|
* **`output_type`** — takes precedence over `output_schema` from the spec.
|
|
|
|
When `deps_type` is passed, [template strings](#template-strings) in the spec's `instructions`, `description`, and capability arguments are compiled and validated against the deps type at construction time.
|
|
|
|
For more control over spec loading, use [`AgentSpec.from_file`][pydantic_ai.agent.spec.AgentSpec.from_file] to load the spec separately before passing it to `Agent.from_spec`.
|
|
|
|
## Template strings
|
|
|
|
[`TemplateStr`][pydantic_ai.TemplateStr] provides Handlebars-style templates (`{{variable}}`) that are rendered against the agent's [dependencies](dependencies.md) at runtime. In spec files, strings containing `{{` are automatically converted to template strings:
|
|
|
|
```yaml {test="skip"}
|
|
instructions: "You are assisting {{name}}, who is a {{role}}."
|
|
```
|
|
|
|
Template variables are resolved from the fields of the `deps` object. When a `deps_type` (or [`deps_schema`](#deps_schema)) is provided, template variable names are validated at construction time.
|
|
|
|
In Python code, [`TemplateStr`][pydantic_ai.TemplateStr] can be used explicitly, but a callable with [`RunContext`][pydantic_ai.tools.RunContext] is generally preferred for IDE autocomplete and type checking:
|
|
|
|
```python {title="template_instructions.py"}
|
|
from dataclasses import dataclass
|
|
|
|
from pydantic_ai import Agent, TemplateStr
|
|
|
|
|
|
@dataclass
|
|
class UserProfile:
|
|
name: str
|
|
role: str
|
|
|
|
|
|
agent = Agent(
|
|
'openai:gpt-5.2',
|
|
deps_type=UserProfile,
|
|
instructions=TemplateStr('You are assisting {{name}}, who is a {{role}}.'),
|
|
)
|
|
result = agent.run_sync('hello', deps=UserProfile(name='Alice', role='engineer'))
|
|
print(result.output)
|
|
#> Hello! How can I help you today?
|
|
```
|
|
|
|
## Capability spec syntax
|
|
|
|
Capabilities in specs support three forms:
|
|
|
|
* `'MyCapability'` — no arguments, calls `MyCapability.from_spec()`
|
|
* `{'MyCapability': value}` — single positional argument, calls `MyCapability.from_spec(value)`
|
|
* `{'MyCapability': {key: value, ...}}` — keyword arguments, calls `MyCapability.from_spec(**kwargs)`
|
|
|
|
## Custom capabilities in specs
|
|
|
|
See [Publishing capabilities](capabilities.md#publishing-capabilities) for how to make custom capabilities work with agent specs.
|
|
|
|
## `AgentSpec` reference
|
|
|
|
The [`AgentSpec`][pydantic_ai.agent.spec.AgentSpec] model represents the full spec structure:
|
|
|
|
| Field | Type | Description |
|
|
|---|---|---|
|
|
| `model` | `str` | [Model](models/overview.md) name (required) |
|
|
| `name` | `str \| None` | Agent name |
|
|
| `description` | `str \| None` | Agent description (supports [templates](#template-strings)) |
|
|
| `instructions` | `str \| list[str] \| None` | [Instructions](agent.md#instructions) (supports [templates](#template-strings)) |
|
|
| `model_settings` | `dict \| None` | [Model settings](agent.md#model-run-settings) |
|
|
| `capabilities` | `list` | [Capabilities](capabilities.md) (see [spec syntax](#capability-spec-syntax)) |
|
|
| `deps_schema` | `dict \| None` | JSON Schema for [template string](#template-strings) validation (see below) |
|
|
| `output_schema` | `dict \| None` | JSON Schema for [structured output](output.md) (see below) |
|
|
| `retries` | `int \| AgentRetries \| None` | Retry budgets for [tools](tools-advanced.md#tool-retries) and [output validation](output.md#output-validator-functions). Pass an integer to use the same budget for both, or [`AgentRetries`][pydantic_ai.agent.AgentRetries] to configure them separately. |
|
|
| `end_strategy` | `EndStrategy` | When to stop (`'early'`, `'graceful'`, or `'exhaustive'`) |
|
|
| `tool_timeout` | `float \| None` | Default [tool](tools.md) timeout in seconds |
|
|
| `instrument` | `bool \| None` | Enable [Logfire](logfire.md) instrumentation |
|
|
| `metadata` | `dict \| None` | Agent [metadata](agent.md#run-metadata) |
|
|
|
|
### `deps_schema`
|
|
|
|
When loading a spec file without a Python `deps_type`, `deps_schema` provides a JSON Schema that validates [template string](#template-strings) variable names at construction time. It does **not** validate the actual deps object at runtime — it only ensures that template variables like `{{user_name}}` correspond to properties defined in the schema.
|
|
|
|
### `output_schema`
|
|
|
|
When provided (and no `output_type` keyword argument is passed to `from_spec`), `output_schema` defines the structure the model should produce as its final output. Under the hood, it creates a [`StructuredDict`][pydantic_ai.output.StructuredDict] output type: the JSON Schema is sent to the model API so the model knows what structure to produce, and the response is returned as a `dict[str, Any]`.
|
|
|
|
!!! note
|
|
The model's response is not validated against the schema's `properties` or `required` fields — it is accepted as a plain dict. The schema serves as an instruction to the model, not a runtime validation constraint.
|
|
|
|
```yaml {title="agent_with_schema.yaml" test="skip"}
|
|
model: anthropic:claude-opus-4-6
|
|
deps_schema:
|
|
type: object
|
|
properties:
|
|
user_name:
|
|
type: string
|
|
required: [user_name]
|
|
output_schema:
|
|
type: object
|
|
properties:
|
|
answer:
|
|
type: string
|
|
confidence:
|
|
type: number
|
|
required: [answer, confidence]
|
|
instructions: "You are helping {{user_name}}. Always include a confidence score."
|
|
capabilities:
|
|
- WebSearch:
|
|
local: duckduckgo
|
|
```
|
|
|
|
## Saving specs
|
|
|
|
[`AgentSpec.to_file`][pydantic_ai.agent.spec.AgentSpec.to_file] saves a spec to YAML or JSON and optionally generates a companion JSON Schema file for editor autocompletion:
|
|
|
|
```python {title="save_spec_example.py"}
|
|
from pydantic_ai import AgentSpec
|
|
|
|
spec = AgentSpec(
|
|
model='anthropic:claude-opus-4-6',
|
|
instructions='You are a helpful assistant.',
|
|
capabilities=[{'WebSearch': {'local': 'duckduckgo'}}],
|
|
)
|
|
spec.to_file('agent.yaml')
|
|
# Also generates ./agent_schema.json for editor autocompletion
|
|
```
|
|
|
|
The generated JSON Schema file enables autocompletion and validation in editors that support the [YAML Language Server](https://github.com/redhat-developer/yaml-language-server) protocol. Pass `schema_path=None` to skip schema generation.
|