agents.yaml and workflow.yaml files.
Quick Start
How It Works
Both files are fully compatible! PraisonAI accepts both
agents.yaml and workflow.yaml with the same features. The difference is primarily in naming conventions.Quick Comparison
- agents.yaml Style
- workflow.yaml Style (Canonical)
Field Name Mapping
PraisonAI accepts both old and new field names. Use canonical names for new projects.| Canonical (Recommended) | Alias (Also Works) | Purpose |
|---|---|---|
agents | roles | Define agent personas |
instructions | backstory | Agent behavior/persona |
action | description | What the step does |
steps | tasks (nested in roles) | Define work items |
name | - | Workflow identifier |
input | topic | Data passed INTO the workflow |
The validator automatically normalises these aliases —
agents↔roles, topic↔input, and stream↔streaming are all accepted and converted to their canonical form. You can mix old and new names freely.instructions is normalised to backstory at two points: once at YAML load (_normalize_yaml_config) and once at schema validation — so downstream code that reads backstory works correctly regardless of which input shape you use.List vs. Dict Shape
PraisonAI auto-normalises list-formagents, roles, and tasks into dict form on load — you don’t need to convert legacy configs by hand.
- List form (e.g. imported from CrewAI-style YAML)
- Dict form (canonical — recommended for new projects)
When a top-level
tasks: list is normalised, each task is attached to its named agent’s tasks: map. A task whose agent: key doesn’t match any defined agent is logged as a warning and skipped — the run continues rather than crashing.Automatic Field Validation
PraisonAI validates every field name in youragents.yaml before execution begins — unknown fields produce warnings and invalid configs abort immediately.
Fail-Fast Errors
These conditions abort the run immediately with an aggregated error message. Missing required field:Required Agent Fields
role, goal, and backstory are schema-enforced required fields for every agent. Omitting any of them aborts the run with a ValueError.Recognized Fields
All recognized field names for agents in bothagents: and roles: sections:
| Field | Type | Purpose |
|---|---|---|
role | string | Agent’s job title |
goal | string | Agent’s objective |
instructions | string | Behavior instructions |
backstory | string | Personality/background context |
tools | array | List of tool names |
tasks | object | Nested task definitions (legacy) |
llm | string | dict | Model to use |
function_calling_llm | string | dict | Model for tool calls |
allow_delegation | bool | Allow task delegation |
max_iter | int | Maximum iterations |
max_rpm | int | Max requests per minute |
max_execution_time | int | Timeout in seconds |
verbose | bool | Verbose output |
cache | bool | Enable response caching |
system_template | string | Custom system prompt |
prompt_template | string | Custom prompt template |
response_template | string | Custom response template |
tool_timeout | int | Per-call tool execution timeout in seconds. Enforced at two layers when running framework: praisonai: (1) the wrapper wraps every tool callable in a timeout-enforcing shim that raises ToolTimeoutError (a TimeoutError subclass) on timeout — framework adapters translate it per framework — and (2) the SDK Agent’s executor pool also honours the same value. Sync tools run in an instance-owned ThreadPoolExecutor on the wrapper layer; async tools use asyncio.wait_for. When multiple values are declared across roles/agents, the wrapper uses the largest value (CLI --tool-timeout overrides all); YAML bool values (tool_timeout: yes) are ignored. See Concurrency → Effective Timeout Precedence and Tool Configuration for the full contract. In Python this maps to tool_config=ToolConfig(timeout=…) — the standalone tool_timeout= kwarg on Agent(...) was removed. |
tool_retry_policy | object | Tool retry configuration with exponential backoff. See example below. |
planning_tools | array | Tools for planning |
planning | bool | Enable planning |
autonomy | string/object | Autonomy configuration |
guardrails | array | Guardrail functions |
streaming | bool | Enable streaming |
stream | bool | Alias for streaming |
approval | bool | Require human approval |
skills | array | Skill definitions |
runtime | string / dict | Per-agent runtime override. Requires framework: praisonai. See Runtime Selection. |
cli_backend | string / dict | Deprecated — use runtime or models.<name>.runtime instead. Still works through 2.0.0 with DeprecationWarning. Run praisonai doctor fix --execute (or praisonai doctor runtime --fix --execute) to migrate. See Runtime Selection. |
reflection | bool/object | Reflection configuration |
Unknown-Field Warnings
Unknown keys at the top level or in agent/role definitions produce warnings:--strict (or PRAISONAI_VALIDATE_STRICT=true) to promote them to errors.
Both Sections Covered
The validator inspects bothagents: and roles: sections. The warning text changes from agent 'X' to role 'X' accordingly.
Strict Mode
Promote all warnings to errors globally:Run once after editing YAML
Run once after editing YAML
Start the workflow once and grep logs for
Unknown field to catch all typos at once.Don't disable the warning
Don't disable the warning
Instead of disabling warnings, fix the typo or add a comment explaining the custom field. The validator helps catch configuration mistakes.
Custom fields are ignored, not preserved
Custom fields are ignored, not preserved
If you intentionally use a non-standard key, the parser will not pass it through to the agent. Only recognized fields are used.
Root-Level Options
All options available at the root level of your YAML file.Workflow Metadata
Workflow Metadata
| Field | Type | Default | Description |
|---|---|---|---|
name | string | ”Workflow” | Workflow identifier |
description | string | "" | Workflow description |
input | string | "" | Data passed INTO workflow (use {{input}} in steps) |
topic | string | "" | Alias for input (legacy) |
framework | string | ”praisonai” | Framework: praisonai, crewai, autogen, langgraph, openai_agents, google_adk |
process | string | ”sequential” | Process type: sequential, hierarchical, workflow |
manager_llm | string | - | LLM for hierarchical process manager |
Workflow Settings
Workflow Settings
| Field | Type | Default | Description |
|---|---|---|---|
planning | bool | false | Enable planning mode |
planning_llm | string | - | LLM for planning |
reasoning | bool | false | Enable reasoning mode |
verbose | bool | false | Verbose output |
default_llm | string | ”gpt-4o-mini” | Default LLM for agents |
output | string | ”normal” | Output mode preset |
memory_config | object | - | Memory configuration |
Context Management
Context Management
Prevent token overflow errors with automatic context compaction.
| Field | Type | Default | Description |
|---|---|---|---|
auto_compact / enabled | bool | false | Enable auto-compaction |
compact_threshold / threshold | float | 0.8 | Trigger threshold (0-1) |
strategy | string | ”smart” | Compaction strategy |
tool_output_max / max_tool_output_tokens | int | 10000 | Max tokens per tool |
Tool Retry Policy
Tool Retry Policy
Configure automatic retry for failed tool calls with exponential backoff:
For detailed configuration options, see Tool Retry Policy.
| Field | Type | Default | Description |
|---|---|---|---|
max_attempts | int | 3 | Total attempts including the first try |
retry_on | array | [“timeout”, “rate_limit”, “connection_error”] | Error types that trigger retry |
backoff_factor | float | 2.0 | Multiplier for delay between attempts |
initial_delay_ms | int | 1000 | Initial delay before first retry (ms) |
jitter | bool | false | Add randomized jitter to delays |
Variables
Variables
{{variable_name}} syntax. Substitutions are applied in this order:| Placeholder | Resolves to | Notes |
|---|---|---|
{{your_variable}} | Value from variables: or an earlier step’s output_variable | Substituted first |
{{previous_output}} | Output of the immediately previous step | Auto-appended as "Context from previous step:" if omitted and a previous output exists |
{{step_name_output}} | Output of a specific named step (set via output_variable) | Resolved in the same pass as {{your_variable}} |
{{input}} | Value of the top-level input: field | Substituted last; available in every step |
{{item}} | Current loop item | Set by loop_over steps |
{{item.field}} | Field in loop item | Set by loop_over steps |
{{today}}, {{now}}, {{uuid}}), see Dynamic Variables — that is a separate mechanism.Runtime Selection
Runtime Selection
Model-scoped runtime configuration. Requires
framework: praisonai. See Runtime Selection.| Field | Type | Description |
|---|---|---|
providers.<name>.runtime_default | string | Provider-wide default runtime for all models from that provider |
models.<name>.runtime | string | Per-model runtime override (wins over provider default) |
runtime (agent-level) | string / dict | Per-agent override (wins over model and provider) |
Custom Models
Custom Models
Define custom models for model routing.
| Field | Required | Description |
|---|---|---|
provider | ✅ | openai, anthropic, google, openrouter |
complexity | ✅ | List: simple, moderate, complex, very_complex |
cost_per_1k | ✅ | Cost per 1,000 tokens in USD |
capabilities | ❌ | List: text, vision, function-calling |
context_window | ❌ | Max context window in tokens |
supports_tools | ❌ | Supports tool/function calling |
strengths | ❌ | List: reasoning, code-generation, etc. |
Callbacks
Callbacks
tools.py file.Agent Options
All options available for agent definitions.Core Fields
Core Fields
| Field | Required | Default | Description |
|---|---|---|---|
role | ✅ | - | Agent’s job title |
name | ❌ | Agent ID | Display name |
goal | ❌ | “Complete the task” | Agent’s objective |
instructions | ❌ | Generic | Direct behavior instructions (simple agents) |
backstory | ❌ | - | Personality/background context (advanced) |
LLM Configuration
LLM Configuration
| Field | Type | Default | Description |
|---|---|---|---|
llm | string | dict | gpt-4o-mini | Model to use |
function_calling_llm | string | dict | Same as llm | Model for tool calls |
reflect_llm | string | dict | Same as llm | Model for self-reflection |
system_template | string | - | Custom system prompt |
prompt_template | string | - | Custom prompt template |
response_template | string | - | Custom response template |
llm and function_calling_llm accept a model name as a string, or a dict when you also need to override base_url / api_key. Both shapes work identically across every supported framework (praisonai, crewai, autogen, autogen_v4, langgraph, openai_agents, google_adk).- String form (simplest)
- Dict form (when overriding endpoint / key)
If
llm is omitted, PraisonAI falls back to the MODEL_NAME environment variable, then to openai/gpt-4o-mini. This fallback is shared by every framework adapter.Rate Limiting & Execution
Rate Limiting & Execution
| Field | Default | Description |
|---|---|---|
max_rpm | Unlimited | Max requests per minute |
max_execution_time | 300 | Timeout in seconds |
max_iter | 3 | Maximum iterations |
min_reflect | 0 | Minimum reflection iterations |
max_reflect | 3 | Maximum reflection iterations |
cache | true | Enable response caching |
Advanced Features
Advanced Features
| Field | Default | Description |
|---|---|---|
planning | false | Enable agent-level planning |
reasoning | false | Enable reasoning mode |
allow_delegation | false | Allow task delegation |
verbose | false | Verbose output |
tools | [] | List of tool names |
web | false | Enable web search capabilities |
web_fetch | false | Enable web content fetching |
handoff | - | Handoff configuration (see below) |
Handoff Configuration
Handoff Configuration
Configure agent handoff with nested options:
| Field | Default | Description |
|---|---|---|
to | [] | List of agent names to handoff to |
policy | ”full” | Handoff policy: full, summary, none, last_n |
timeout | 30 | Timeout for handoff in seconds |
max_depth | 10 | Maximum depth of handoff chain |
max_concurrent | 5 | Maximum concurrent handoffs |
detect_cycles | false | Enable handoff cycle detection |
Specialized Agent Types
Specialized Agent Types
Use the
agent: field to specify specialized agent types:| Agent Type | Purpose | Key Options |
|---|---|---|
ImageAgent | Image generation | style, llm (dall-e-3) |
AudioAgent | TTS/STT | voice, audio config |
VideoAgent | Video generation | video config |
OCRAgent | Text extraction | ocr config |
DeepResearchAgent | Automated research | instructions |
Step Options
All options available for step definitions.Basic Step Fields
Basic Step Fields
| Field | Required | Default | Description |
|---|---|---|---|
agent | ✅* | - | Agent to execute (*not needed for patterns) |
action | ❌ | {{input}} | What the step does |
description | ❌ | - | Deprecated - use action |
name | ❌ | Auto-generated | Step identifier |
expected_output | ❌ | - | Description of expected output |
Output Options
Output Options
| Field | Description |
|---|---|
output_file | Save output to file path |
create_directory | Create output directory if needed |
output_json | JSON schema for structured output |
output_pydantic | Pydantic model name from tools.py |
output_variable | Store output in named variable |
Context & Dependencies
Context & Dependencies
| Field | Description |
|---|---|
context | List of dependent step names |
Execution Control
Execution Control
| Field | Default | Description |
|---|---|---|
async_execution | false | Run asynchronously |
max_retries | 3 | Maximum retry attempts |
guardrail | - | Guardrail function name |
callback | - | Callback function name |
Workflow Patterns
Advanced workflow patterns available in bothagents.yaml and workflow.yaml.
Parallel
Execute multiple agents concurrently
Route
Classify and route to specialized agents
Loop
Iterate over a list of items
Repeat
Repeat until condition is met
Include
Include modular recipes
- Parallel
- Route
- Loop
- Multi-Step Loop
- Repeat
- Include
Loop Options
| Field | Required | Default | Description |
|---|---|---|---|
over | ✅* | - | Variable name to iterate |
from_csv | ❌ | - | CSV file path to iterate |
from_file | ❌ | - | File path to iterate lines |
var_name | ❌ | “item” | Variable name for current item |
parallel | ❌ | false | Execute iterations in parallel |
max_workers | ❌ | - | Limit parallel workers |
output_variable | ❌ | - | Store all outputs in variable |
Repeat Options
| Field | Required | Default | Description |
|---|---|---|---|
until | ✅ | - | Condition string to match in output |
max_iterations | ❌ | 5 | Maximum iterations |
Include Options
| Field | Required | Default | Description |
|---|---|---|---|
recipe | ✅ | - | Recipe name or path |
input | ❌ | {{previous_output}} | Input for included recipe |
Feature Compatibility Matrix
What works where:| Feature | agents.yaml | workflow.yaml | Notes |
|---|---|---|---|
| Agent Definition | ✅ | ✅ | Use agents: (canonical) or roles: |
| Steps/Tasks | ✅ | ✅ | Use steps: (canonical) |
| Workflow Patterns | ✅ | ✅ | parallel, route, loop, repeat |
| Include Recipes | ✅ | ✅ | include: in steps |
| Variables | ✅ | ✅ | variables: section |
| Context Management | ✅ | ✅ | context: section |
| Planning Mode | ✅ | ✅ | workflow.planning: true |
| Reasoning Mode | ✅ | ✅ | workflow.reasoning: true |
| Memory Config | ✅ | ✅ | workflow.memory_config: |
| Custom Models | ✅ | ✅ | models: section |
| Callbacks | ✅ | ✅ | callbacks: section |
| Specialized Agents | ✅ | ✅ | agent: ImageAgent, etc. |
| Handoff Configuration | ✅ | ✅ | handoff: in agent definition |
| Web Search | ✅ | ✅ | web: true in agent definition |
| Web Content Fetching | ✅ | ✅ | web_fetch: true in agent definition |
| Structured Output | ✅ | ✅ | output_json, output_pydantic |
Full Feature Parity! Both file formats support all features. The only difference is naming conventions.
Framework LLM Configuration Parity: The
llm and function_calling_llm configuration shapes (string and dict forms) work identically across all supported frameworks (praisonai, crewai, autogen, autogen_v4, langgraph, openai_agents, google_adk). You can switch between frameworks without changing your LLM configuration syntax.What’s NOT Possible
| Limitation | Workaround |
|---|---|
| Nested loops | Use multi-step loop with sequential steps |
| Conditional branching mid-step | Use route: pattern instead |
| Dynamic agent creation | Pre-define all agents in agents: section |
| Cross-workflow state | Use include: with explicit input passing |
| Real-time streaming in loops | Streaming works per-step, not across loop |
Migration Guide
From agents.yaml to workflow.yaml
Validation
Validate your YAML configuration before running:- ✅ Valid configuration
- ⚠️ Non-blocking warnings (unknown fields, optional tool deps)
- ❌ Errors that would abort execution
praisonai workflow validate is the workflow-specific variant and remains available for backwards compatibility.
Best Practices
Use Canonical Names
Use Canonical Names
agents, instructions, action, steps, inputEnable Context Management
Enable Context Management
context: true for tool-heavy workflowsDefine Expected Output
Define Expected Output
Always specify
expected_output for clarityUse Variables
Use Variables
Centralize reusable values in
variables:Related
Set project-wide agent defaults in a config file.
Run and validate YAML configs from the command line.

