Skip to main content
Complete reference for all configuration options in agents.yaml and workflow.yaml files.

Quick Start

1

Load an agent from YAML

from praisonaiagents import Agent

agent = Agent(name="yaml-runner", instructions="Behaviour defined in agents.yaml")
agent.start("Run the workflow defined in YAML")
2

Run the YAML workflow

praisonai start agents.yaml
The user maintains YAML config; the agent loads it and executes the requested workflow.

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

framework: praisonai
topic: "Research AI trends"

roles:
  researcher:
    role: Research Analyst
    backstory: "Expert researcher"
    goal: Research topics
    tools:
      - tavily_search

  researcher:
    tasks:
      research_task:
        description: "Research {{topic}}"
        expected_output: "Research report"

Field Name Mapping

PraisonAI accepts both old and new field names. Use canonical names for new projects.
Canonical (Recommended)Alias (Also Works)Purpose
agentsrolesDefine agent personas
instructionsbackstoryAgent behavior/persona
actiondescriptionWhat the step does
stepstasks (nested in roles)Define work items
name-Workflow identifier
inputtopicData passed INTO the workflow
A-I-G-S Mnemonic - Easy to remember:
  • Agents - Who does the work
  • Instructions - How they behave
  • Goal - What they achieve
  • Steps - What they do
The validator automatically normalises these aliases — agentsroles, topicinput, and streamstreaming 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-form agents, roles, and tasks into dict form on load — you don’t need to convert legacy configs by hand.
agents:
  - name: researcher
    role: Research Analyst
    instructions: "Expert researcher"

tasks:
  - name: research_task
    agent: researcher
    description: "Research {{topic}}"
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 your agents.yaml before execution begins — unknown fields produce warnings and invalid configs abort immediately.
Configuration errors now fail fast. If any error is found (missing required field, bad cross-reference, unknown tool), the run aborts with a ValueError that lists every error at once — nothing runs with a broken config.Unknown-field warnings are still non-blocking: the unrecognised field is ignored and the workflow continues.
1

Create YAML with typo

# agents.yaml
framework: praisonai
topic: "Summarize Python history"
agents:
  researcher:
    role: Research Analyst
    goal: Provide a historical summary
    instrutions: "Focus ONLY on years 1989–2000."   # typo — warning
    backstory: Expert researcher.
2

Run workflow and see warning

praisonai start agents.yaml
Output (unknown field → warning, workflow still runs):
WARNING: Unknown agent field 'instrutions' in agent 'researcher'. This field will be ignored.
3

Validate before running

praisonai validate agents.yaml
Catch all errors upfront without running the workflow.

Fail-Fast Errors

These conditions abort the run immediately with an aggregated error message. Missing required field:
agents:
  researcher:
    role: Research Analyst
    # goal is required but missing
    backstory: Expert researcher.
Result:
Configuration validation failed with 1 error(s):
  1. Agent 'researcher': missing required field 'goal'
Bad cross-reference (task references undefined agent):
agents:
  researcher:
    role: Research Analyst
    goal: Research topics
    backstory: Expert researcher.

tasks:
  write_report:
    description: Write a report
    agent: writer      # 'writer' is not defined!
Result:
Configuration validation failed with 1 error(s):
  1. Task 'write_report': references unknown agent 'writer' (not defined in agents/roles)
Unknown tool:
agents:
  researcher:
    role: Research Analyst
    goal: Research topics
    backstory: Expert researcher.
    tools:
      - nonexistent_tool
Result:
Configuration validation failed with 1 error(s):
  1. Unknown tool 'nonexistent_tool'. Ensure it's properly installed or defined in your configuration.
Optional tools with extra dependencies produce a warning instead:
WARNING: Tool 'BrowserTool' requires additional dependencies. Install with: pip install 'praisonai[tools]'

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 both agents: and roles: sections:
FieldTypePurpose
rolestringAgent’s job title
goalstringAgent’s objective
instructionsstringBehavior instructions
backstorystringPersonality/background context
toolsarrayList of tool names
tasksobjectNested task definitions (legacy)
llmstring | dictModel to use
function_calling_llmstring | dictModel for tool calls
allow_delegationboolAllow task delegation
max_iterintMaximum iterations
max_rpmintMax requests per minute
max_execution_timeintTimeout in seconds
verboseboolVerbose output
cacheboolEnable response caching
system_templatestringCustom system prompt
prompt_templatestringCustom prompt template
response_templatestringCustom response template
tool_timeoutintPer-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_policyobjectTool retry configuration with exponential backoff. See example below.
planning_toolsarrayTools for planning
planningboolEnable planning
autonomystring/objectAutonomy configuration
guardrailsarrayGuardrail functions
streamingboolEnable streaming
streamboolAlias for streaming
approvalboolRequire human approval
skillsarraySkill definitions
runtimestring / dictPer-agent runtime override. Requires framework: praisonai. See Runtime Selection.
cli_backendstring / dictDeprecated — 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.
reflectionbool/objectReflection configuration

Unknown-Field Warnings

Unknown keys at the top level or in agent/role definitions produce warnings:
WARNING: Unknown agent field 'instrutions' in agent 'researcher'. This field will be ignored.
WARNING: Unknown agent field 'xyz_random_field' in agent 'test_agent'. This field will be ignored.
Warnings are non-blocking — the unrecognised field is ignored and the workflow continues. Only use --strict (or PRAISONAI_VALIDATE_STRICT=true) to promote them to errors.
Set your log level to WARNING or below (INFO, DEBUG) to see these messages. They are emitted via the standard praisonai logger.

Both Sections Covered

The validator inspects both agents: and roles: sections. The warning text changes from agent 'X' to role 'X' accordingly.

Strict Mode

Promote all warnings to errors globally:
export PRAISONAI_VALIDATE_STRICT=true
praisonai start agents.yaml
Or per-command:
praisonai validate agents.yaml --strict
Start the workflow once and grep logs for Unknown field to catch all typos at once.
Instead of disabling warnings, fix the typo or add a comment explaining the custom field. The validator helps catch configuration mistakes.
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.
FieldTypeDefaultDescription
namestring”Workflow”Workflow identifier
descriptionstring""Workflow description
inputstring""Data passed INTO workflow (use {{input}} in steps)
topicstring""Alias for input (legacy)
frameworkstring”praisonai”Framework: praisonai, crewai, autogen, langgraph, openai_agents, google_adk
processstring”sequential”Process type: sequential, hierarchical, workflow
manager_llmstring-LLM for hierarchical process manager
workflow:
  planning: true                    # Enable planning mode
  planning_llm: gpt-4o              # LLM for planning
  reasoning: true                   # Enable reasoning mode
  verbose: true                     # Verbose output
  default_llm: gpt-4o-mini          # Default LLM for all agents
  output: verbose                   # Output mode: silent, minimal, normal, verbose, debug
  memory_config:
    provider: chroma
    persist: true
FieldTypeDefaultDescription
planningboolfalseEnable planning mode
planning_llmstring-LLM for planning
reasoningboolfalseEnable reasoning mode
verboseboolfalseVerbose output
default_llmstring”gpt-4o-mini”Default LLM for agents
outputstring”normal”Output mode preset
memory_configobject-Memory configuration
Prevent token overflow errors with automatic context compaction.
# Simple enable
context: true

# Detailed configuration
context:
  auto_compact: true           # Enable auto-compaction
  compact_threshold: 0.8       # Trigger at 80% of context window
  strategy: smart              # smart | truncate | sliding_window | summarize | prune_tools
  tool_output_max: 10000       # Max tokens per tool output
FieldTypeDefaultDescription
auto_compact / enabledboolfalseEnable auto-compaction
compact_threshold / thresholdfloat0.8Trigger threshold (0-1)
strategystring”smart”Compaction strategy
tool_output_max / max_tool_output_tokensint10000Max tokens per tool
Always enable context: true for workflows with search/crawl tools to prevent “context_length_exceeded” errors.
Configure automatic retry for failed tool calls with exponential backoff:
agents:
  api_researcher:
    role: API Researcher
    instructions: "Research using external APIs"
    tools: [web_search, api_tool]
    tool_retry_policy:
      max_attempts: 4
      retry_on: [timeout, rate_limit, connection_error]
      backoff_factor: 2.0
      initial_delay_ms: 1000
      jitter: true
FieldTypeDefaultDescription
max_attemptsint3Total attempts including the first try
retry_onarray[“timeout”, “rate_limit”, “connection_error”]Error types that trigger retry
backoff_factorfloat2.0Multiplier for delay between attempts
initial_delay_msint1000Initial delay before first retry (ms)
jitterboolfalseAdd randomized jitter to delays
For detailed configuration options, see Tool Retry Policy.
variables:
  topic: AI trends
  max_results: 5
  categories:
    - Machine Learning
    - NLP
    - Computer Vision
Use variables in steps with {{variable_name}} syntax. Substitutions are applied in this order:
PlaceholderResolves toNotes
{{your_variable}}Value from variables: or an earlier step’s output_variableSubstituted first
{{previous_output}}Output of the immediately previous stepAuto-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: fieldSubstituted last; available in every step
{{item}}Current loop itemSet by loop_over steps
{{item.field}}Field in loop itemSet by loop_over steps
For date/time/UUID placeholders ({{today}}, {{now}}, {{uuid}}), see Dynamic Variables — that is a separate mechanism.
Model-scoped runtime configuration. Requires framework: praisonai. See Runtime Selection.
providers:
  anthropic:
    runtime_default: claude-code
  openai:
    runtime_default: codex-cli

models:
  claude-3-sonnet:
    runtime: claude-code
  gpt-4o:
    runtime: praisonai
FieldTypeDescription
providers.<name>.runtime_defaultstringProvider-wide default runtime for all models from that provider
models.<name>.runtimestringPer-model runtime override (wins over provider default)
runtime (agent-level)string / dictPer-agent override (wins over model and provider)
Define custom models for model routing.
models:
  cheap-fast:
    provider: openai
    complexity: [simple]
    cost_per_1k: 0.0001
    capabilities: [text]
    context_window: 16000
  
  premium:
    provider: anthropic
    complexity: [complex, very_complex]
    cost_per_1k: 0.015
    capabilities: [text, vision, function-calling]
    context_window: 200000
    supports_tools: true
    strengths: [reasoning, analysis]
FieldRequiredDescription
provideropenai, anthropic, google, openrouter
complexityList: simple, moderate, complex, very_complex
cost_per_1kCost per 1,000 tokens in USD
capabilitiesList: text, vision, function-calling
context_windowMax context window in tokens
supports_toolsSupports tool/function calling
strengthsList: reasoning, code-generation, etc.
callbacks:
  on_workflow_start: log_start
  on_step_start: log_step_start
  on_step_complete: log_step_complete
  on_step_error: handle_error
  on_workflow_complete: log_complete
Callbacks are resolved from your tools.py file.

Agent Options

All options available for agent definitions.
FieldRequiredDefaultDescription
role-Agent’s job title
nameAgent IDDisplay name
goal“Complete the task”Agent’s objective
instructionsGenericDirect behavior instructions (simple agents)
backstory-Personality/background context (advanced)
FieldTypeDefaultDescription
llmstring | dictgpt-4o-miniModel to use
function_calling_llmstring | dictSame as llmModel for tool calls
reflect_llmstring | dictSame as llmModel for self-reflection
system_templatestring-Custom system prompt
prompt_templatestring-Custom prompt template
response_templatestring-Custom response template
Both 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).
agents:
  writer:
    role: Writer
    llm: gpt-4o-mini
    function_calling_llm: gpt-4o-mini
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.
FieldDefaultDescription
max_rpmUnlimitedMax requests per minute
max_execution_time300Timeout in seconds
max_iter3Maximum iterations
min_reflect0Minimum reflection iterations
max_reflect3Maximum reflection iterations
cachetrueEnable response caching
FieldDefaultDescription
planningfalseEnable agent-level planning
reasoningfalseEnable reasoning mode
allow_delegationfalseAllow task delegation
verbosefalseVerbose output
tools[]List of tool names
webfalseEnable web search capabilities
web_fetchfalseEnable web content fetching
handoff-Handoff configuration (see below)
Configure agent handoff with nested options:
agents:
  coordinator:
    role: Coordinator
    handoff:
      to: [writer, reviewer]      # List of target agents
      policy: summary             # Handoff policy: full, summary, none, last_n
      timeout: 60                 # Handoff timeout in seconds
      max_depth: 5                # Maximum handoff chain depth
      max_concurrent: 3           # Maximum concurrent handoffs
      detect_cycles: true         # Enable cycle detection
FieldDefaultDescription
to[]List of agent names to handoff to
policy”full”Handoff policy: full, summary, none, last_n
timeout30Timeout for handoff in seconds
max_depth10Maximum depth of handoff chain
max_concurrent5Maximum concurrent handoffs
detect_cyclesfalseEnable handoff cycle detection
Use the agent: field to specify specialized agent types:
agents:
  image_creator:
    agent: ImageAgent          # Specialized type
    role: Image Generator
    llm: dall-e-3
    style: natural
  
  narrator:
    agent: AudioAgent
    role: Audio Narrator
    llm: tts-1
    voice: alloy
  
  video_maker:
    agent: VideoAgent
    role: Video Creator
    llm: openai/sora-2
  
  document_reader:
    agent: OCRAgent
    role: Document Reader
    llm: mistral/mistral-ocr-latest
  
  researcher:
    agent: DeepResearchAgent
    role: Deep Researcher
    llm: o3-deep-research
Agent TypePurposeKey Options
ImageAgentImage generationstyle, llm (dall-e-3)
AudioAgentTTS/STTvoice, audio config
VideoAgentVideo generationvideo config
OCRAgentText extractionocr config
DeepResearchAgentAutomated researchinstructions

Step Options

All options available for step definitions.
FieldRequiredDefaultDescription
agent✅*-Agent to execute (*not needed for patterns)
action{{input}}What the step does
description-Deprecated - use action
nameAuto-generatedStep identifier
expected_output-Description of expected output
FieldDescription
output_fileSave output to file path
create_directoryCreate output directory if needed
output_jsonJSON schema for structured output
output_pydanticPydantic model name from tools.py
output_variableStore output in named variable
steps:
  - agent: researcher
    action: "Find topics"
    output_json:
      type: array
      items:
        type: object
        properties:
          title: { type: string }
          url: { type: string }
    output_variable: topics
FieldDescription
contextList of dependent step names
steps:
  - name: research_step
    agent: researcher
    action: "Research {{input}}"
  
  - name: writing_step
    agent: writer
    action: "Write based on: {{previous_output}}"
    context:
      - research_step    # Explicit dependency
FieldDefaultDescription
async_executionfalseRun asynchronously
max_retries3Maximum retry attempts
guardrail-Guardrail function name
callback-Callback function name

Workflow Patterns

Advanced workflow patterns available in both agents.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
steps:
  - name: parallel_research
    parallel:
      - agent: market_analyst
        action: "Research market trends"
      - agent: tech_analyst
        action: "Research technology"
  
  - agent: aggregator
    action: "Combine findings: {{previous_output}}"

Loop Options

FieldRequiredDefaultDescription
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
parallelfalseExecute iterations in parallel
max_workers-Limit parallel workers
output_variable-Store all outputs in variable

Repeat Options

FieldRequiredDefaultDescription
until-Condition string to match in output
max_iterations5Maximum iterations

Include Options

FieldRequiredDefaultDescription
recipe-Recipe name or path
input{{previous_output}}Input for included recipe

Feature Compatibility Matrix

What works where:
Featureagents.yamlworkflow.yamlNotes
Agent DefinitionUse agents: (canonical) or roles:
Steps/TasksUse steps: (canonical)
Workflow Patternsparallel, route, loop, repeat
Include Recipesinclude: in steps
Variablesvariables: section
Context Managementcontext: section
Planning Modeworkflow.planning: true
Reasoning Modeworkflow.reasoning: true
Memory Configworkflow.memory_config:
Custom Modelsmodels: section
Callbackscallbacks: section
Specialized Agentsagent: ImageAgent, etc.
Handoff Configurationhandoff: in agent definition
Web Searchweb: true in agent definition
Web Content Fetchingweb_fetch: true in agent definition
Structured Outputoutput_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

These limitations apply to both agents.yaml and workflow.yaml:
LimitationWorkaround
Nested loopsUse multi-step loop with sequential steps
Conditional branching mid-stepUse route: pattern instead
Dynamic agent creationPre-define all agents in agents: section
Cross-workflow stateUse include: with explicit input passing
Real-time streaming in loopsStreaming works per-step, not across loop

Migration Guide

From agents.yaml to workflow.yaml

1

Rename container

roles:agents:
2

Rename agent fields

backstory:instructions:
3

Extract tasks to steps

Move nested tasks: to top-level steps:
4

Rename step fields

description:action:
5

Update input reference

topic:input: (optional but recommended)
framework: praisonai
topic: "Research AI"

roles:
  researcher:
    role: Analyst
    backstory: "Expert researcher"
    goal: Research
    tasks:
      research_task:
        description: "Research {{topic}}"
name: Research Workflow
input: "Research AI"

agents:
  researcher:
    role: Analyst
    instructions: "Expert researcher"
    goal: Research

steps:
  - agent: researcher
    action: "Research {{input}}"

Validation

Validate your YAML configuration before running:
praisonai validate agents.yaml
Output shows:
  • ✅ Valid configuration
  • ⚠️ Non-blocking warnings (unknown fields, optional tool deps)
  • ❌ Errors that would abort execution
Scan an entire directory:
praisonai validate check . --strict --json
See the Validate CLI page for all flags, JSON output format, and CI integration examples. praisonai workflow validate is the workflow-specific variant and remains available for backwards compatibility.

Best Practices

agents, instructions, action, steps, input
context: true for tool-heavy workflows
Always specify expected_output for clarity
Centralize reusable values in variables:
Run praisonai validate <file.yaml> to check for all schema errors, cross-reference problems, and unknown tool references before starting a workflow. Use praisonai validate schema to print all recognised fields and their types.

Set project-wide agent defaults in a config file.

Run and validate YAML configs from the command line.