CrewAI with PraisonAI
Guide for using CrewAI framework with PraisonAI, including installation, setup, and execution of agent-based tasks
CrewAI framework integration with PraisonAI provides collaborative multi-agent workflows with advanced configuration options for agents, tasks, and native async execution.
Quick Start
- Install
bash pip install "praisonai-frameworks[crewai]" - Create YAML file
yaml framework: crewai topic: Create Movie Script About Cat in Mars roles: researcher: role: Research Analyst goal: Gather information about Mars and cats backstory: Skilled in research, with a focus on gathering accurate and relevant information. tasks: research_task: description: Research about Mars environment and cat behavior for the movie concept expected_output: Research findings document with key facts - Run
bash export OPENAI_API_KEY=your-key praisonai agents.yaml --framework crewai
How CrewAI Works
YAML Format for CrewAI
CrewAI requires the roles format YAML (not the steps workflow format):
framework: crewai
topic: Create Movie Script About Cat in Mars
roles:
researcher:
role: Research Analyst
goal: Gather information about Mars and cats
backstory: Skilled in research, with a focus on gathering accurate and relevant information.
tasks:
research_task:
description: Research about Mars environment and cat behavior
expected_output: Research findings document with key factsAdvanced YAML Fields
PraisonAI’s CrewAI adapter supports extensive configuration options for the crew, agents and tasks:
Crew-Level Fields
Set these at the top level of the YAML, next to framework: and topic::
| YAML Key | Type | Default | Description | Maps to CrewAI | |
|---|---|---|---|---|---|
memory | bool | False | Enable CrewAI crew memory | memory=True | |
process | sequential \ | hierarchical | sequential | hierarchical lets a manager LLM delegate tasks to the agents | process=Process.hierarchical |
manager_llm | str \ | object | MODEL_NAME or openai/gpt-4o-mini | Manager model for process: hierarchical. Accepts a model name or an llm-style dict; its base_url / api_key win over the shared llm_config | manager_llm=LLM(...) |
verbose | bool | True | Crew-level verbose output | verbose= |
framework: crewai
topic: AI agents
process: hierarchical
manager_llm: gpt-4o # strong manager
memory: true
verbose: false
roles:
researcher:
role: Researcher
goal: Find facts about {topic}
backstory: Careful researcher
llm: gpt-4o-mini # cheaper workers
tasks:
research:
description: Research {topic}
expected_output: Key facts
writer:
role: Writer
goal: Write about {topic}
backstory: Clear writer
llm: gpt-4o-mini
tasks:
write:
description: Write a short article on {topic}
expected_output: A 300-word articleAgent-Level Fields
Configure advanced agent behavior under each roles.<name>:
| YAML Key | Type | Default | Description | Maps to CrewAI |
|---|---|---|---|---|
llm | object | inherits dispatcher | LLM configuration via PraisonAIModel | llm= |
function_calling_llm | object | inherits dispatcher | Separate LLM for function calls | function_calling_llm= |
allow_delegation | bool | False | Allow agent to delegate tasks | allow_delegation= |
max_iter | int | 15 | Maximum iterations per agent | max_iter= |
max_rpm | int | None | Requests per minute throttle. A positive int auto-builds a live RateLimiter(requests_per_minute=max_rpm) when no explicit rate_limiter is set, so CrewAI-style max_rpm now enforces throttling. max_rpm <= 0 raises ValueError. | max_rpm= |
max_execution_time | int | None | Execution timeout in seconds | max_execution_time= |
verbose | bool | True | Enable verbose output | verbose= |
cache | bool | True | Enable LLM response caching | cache= |
system_template | str | None | Override system prompt template | system_template= |
prompt_template | str | None | Override prompt template | prompt_template= |
response_template | str | None | Override response template | response_template= |
Task-Level Fields
Configure advanced task behavior under each roles.<name>.tasks.<task_name>:
| YAML Key | Type | Default | Description | Maps to CrewAI |
|---|---|---|---|---|
description | str | required | Task description | description= |
expected_output | str | required | Expected output format | expected_output= |
tools | list[str] | [] | Tool names from tools_dict | tools= |
async_execution | bool | False | Execute task asynchronously | async_execution= |
context | list[str] | [] | Task dependencies by name | context= (resolved to Task objects) |
config | object | {} | Free-form task configuration | config= |
output_json | type | None | Pydantic schema for JSON output | output_json= |
output_pydantic | type | None | Pydantic model class | output_pydantic= |
output_file | str | "" | Output file path | output_file= |
callback | callable | None | Task completion callback | callback= |
human_input | bool | False | Require human input | human_input= |
create_directory | bool | False | Create parent directories | create_directory= |
Advanced Configuration Example
framework: crewai
topic: Quarterly report
roles:
analyst:
role: Financial Analyst
goal: Extract Q3 numbers from the input docs
backstory: Senior analyst, CFA, 10y experience.
llm:
model: openai/gpt-4o
function_calling_llm:
model: openai/gpt-4o-mini
max_iter: 20
verbose: true
cache: true
system_template: "You are a precise financial analyst. Never invent figures."
tasks:
extract_numbers:
description: Pull revenue, COGS, opex for Q3 from {topic}
expected_output: A JSON table with revenue, cogs, opex.
tools: ["file_reader", "calculator"]
async_execution: false
writer:
role: Report Writer
goal: Write a narrative summary
backstory: Equity-research writer.
llm:
model: openai/gpt-4o
max_iter: 10
verbose: false
system_template: "You are a precise, hedge-friendly equity research writer."
tasks:
draft_summary:
description: Draft a 200-word summary of the extracted numbers.
expected_output: A 200-word markdown summary.
context: [extract_numbers]
output_file: out/q3_summary.md
create_directory: true
human_input: falseLLM Configuration
Model Resolution
The CrewAI adapter resolves LLM configuration in this order:
- Agent-level
llm:roles.<agent>.llm.*—base_urlandapi_keynested under a role’sllm:also win over the sharedllm_config, so a role can target its own endpoint - Global
llm_config: From CLI dispatcher - Environment:
MODEL_NAMEenvironment variable - Default:
openai/gpt-4o-mini
An unknown provider/model prefix (for example mistral/mistral-small) with no base_url / OPENAI_API_BASE raises ValueError instead of being sent to OpenAI. See Provider Prefix Validation.
Function Calling LLM
Use function_calling_llm to specify a different model for tool calls:
roles:
researcher:
role: Research Analyst
llm:
model: openai/gpt-4o # For reasoning
function_calling_llm:
model: openai/gpt-4o-mini # For tool calls (cheaper/faster)Task Dependencies
Use the context field to create task dependencies. Reference tasks by name:
roles:
researcher:
tasks:
research_phase:
description: Research the topic thoroughly
expected_output: Research findings
analyst:
tasks:
analysis_phase:
description: Analyze the research findings
expected_output: Analysis report
context: [research_phase] # Wait for research_phase to completeFile Output
Use output_file with create_directory to save task results:
tasks:
report_task:
description: Generate final report
expected_output: Comprehensive report
output_file: reports/final_report.md
create_directory: true # Creates 'reports/' directory if neededAgentOps Integration
When agentops is installed, the CrewAI adapter automatically calls finalize_observability(self.name, status=…) (from praisonai.observability.hooks) from a finally block after crew execution. status is derived from sys.exc_info(): "Success" on the happy path, "Failure" on any exception including cancellation. No configuration required. See Observability Hooks for details.
pip install agentops
# AgentOps tracking is automatically enabledFramework Selection Priority
- CLI flag (
--framework crewai) takes precedence - YAML file (
framework: crewai) is used if no CLI flag - Default: praisonai framework
Async Execution
The CrewAI adapter runs natively async via crew.kickoff_async() — no worker thread is pinned, asyncio.CancelledError propagates, and multiple crews fan out cooperatively under asyncio.gather.
import asyncio
import praisonai
async def main():
result = await praisonai.arun(
agent_file="agents.yaml",
framework="crewai",
)
print(result)
asyncio.run(main())See Async Crew Kickoff for the full FastAPI / Jupyter / concurrency patterns — everything on that page now applies to framework: crewai too.
Auto Mode
praisonai --framework crewai --auto "Create a Movie Script About Cat in Mars"Troubleshooting
Common Issues
Task context not found: If context: [some_task] fails, ensure some_task exists as a key under any role’s tasks: block in the same YAML file.
Function calling LLM inheritance: function_calling_llm falls back to MODEL_NAME environment variable or openai/gpt-4o-mini, not the agent’s main llm configuration.
Crew-level keys had no effect: Older releases silently ignored top-level memory, process, manager_llm and verbose (the crew always ran sequentially with verbose=True). Upgrade praisonai to have them honoured.
Direct prompt limitation: Direct prompts (praisonai "question" --framework crewai) always use the praisonai framework. Use YAML files with roles format for CrewAI.
Missing installation error: If the framework is not installed, PraisonAI now fails fast at CLI entry with:
Framework 'crewai' was requested but is not installed.
Install it with:
pip install 'praisonai-frameworks[crewai]' # or: pip install crewaiThe error appears immediately, before YAML parsing — so a typo in --framework is caught before any expensive setup runs.
Installation Errors
- Missing CrewAI:
pip install "praisonai-frameworks[crewai]" - Tool resolution issues: Ensure tool names in
tools: []exist in the globaltools_dict
Best Practices
Use function_calling_llm for cost optimization
Set a cheaper/faster model for function_calling_llm while using a more capable model for reasoning tasks.
Structure task dependencies clearly
Use descriptive task names in context: [] lists. The order doesn’t matter, but referenced tasks must exist.
Leverage output files for complex workflows
Use output_file with create_directory: true for tasks that produce artifacts other agents need to reference.
Configure timeouts appropriately
Set max_execution_time for long-running tasks and max_iter to prevent infinite loops.