An autonomous AI engineering team built with CrewAI that takes high-level requirements and automatically generates a complete, production-ready Python application including backend code, Gradio UI, and comprehensive unit tests.
Give this AI crew your software requirements in plain English, and it will:
- Design a detailed software architecture
- Write production-quality Python code
- Build a Gradio web UI to demonstrate the functionality
- Test the code with comprehensive unit tests
All outputs are saved to the output/ directory, ready to run!
- Architecture Overview
- CrewAI Concepts
- Code Flow
- Installation
- Usage
- Example
- Project Structure
- Configuration
- Troubleshooting
- License
This project implements a Sequential Process Crew with four specialized AI agents that work together to deliver a complete software solution.
Input (YAML) β Engineering Lead β Backend Engineer β Frontend Engineer β Test Engineer β Output
β β β β
Design.md Code.py app.py test_code.py
| Role | Responsibility | LLM |
|---|---|---|
| Engineering Lead | Creates detailed software design from requirements | GPT-4o |
| Backend Engineer | Implements Python code following the design | Claude Sonnet 4 |
| Frontend Engineer | Builds Gradio UI to demonstrate the backend | Claude Sonnet 4 |
| Test Engineer | Writes comprehensive unit tests | Claude Sonnet 4 |
CrewAI is a framework for orchestrating role-playing, autonomous AI agents. Agents work together as a crew to accomplish complex tasks through collaboration.
Autonomous AI entities with:
- Role: Their job title/function (e.g., "Backend Engineer")
- Goal: What they're trying to achieve
- Backstory: Context that shapes their behavior
- Tools: Capabilities they can use (e.g., CodeInterpreterTool)
- LLM: The language model powering them (GPT-4, Claude, etc.)
In this project, we have 4 agents defined in config/agents.yaml.
Specific assignments given to agents:
- Description: What needs to be done
- Expected Output: The deliverable format
- Agent: Who does the work
- Context: Dependencies on previous tasks
- Output File: Where to save results
Our tasks are defined in config/tasks.yaml.
A collection of agents working together:
- Agents: The team members
- Tasks: The work to be done
- Process: How tasks are executed (Sequential or Hierarchical)
-
Sequential Process (Used in this project)
- Tasks execute one after another in a defined order
- Each task can access outputs from previous tasks via
context - Predictable, linear workflow
- Example: Design β Code β UI β Tests
-
Hierarchical Process (Alternative)
- A manager agent delegates and coordinates tasks
- More dynamic task allocation
- Agents can work in parallel
- Best for complex projects with interdependencies
Software development follows a natural sequence:
- Design before coding
- Code before building UI
- UI depends on the backend
- Tests need the final code
Each step builds on the previous, making sequential processing ideal.
1. Entry Point (main.py)
def run():
inputs = load_inputs("input.yaml") # Load requirements
result = EngineeringTeam().crew().kickoff(inputs=inputs) # Start the crew- Loads input requirements from
input.yaml - Creates output directory
- Initializes and kicks off the crew
2. Crew Definition (crew.py)
The @CrewBase decorator creates a structured crew:
@CrewBase
class EngineeringTeam:
agents_config = "config/agents.yaml" # Load agent configs
tasks_config = "config/tasks.yaml" # Load task configs
@agent
def engineering_lead(self) -> Agent:
# Creates the lead agent with LLM and config
@task
def design_task(self) -> Task:
# Creates design task assigned to engineering_lead
@crew
def crew(self) -> Crew:
# Assembles agents and tasks into a sequential crew
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential, # Sequential execution
verbose=True
)- Agent: Engineering Lead
- Input: Requirements from
input.yaml - Output:
output/{module_name}_design.md - Action: Creates detailed architecture and API design
- Agent: Backend Engineer
- Input: Requirements + Design from Task 1 (
context: [design_task]) - Output:
output/{module_name} - Tools: CodeInterpreterTool with Docker/Podman
- Action: Writes production Python code
- Agent: Frontend Engineer
- Input: Requirements + Code from Task 2 (
context: [code_task]) - Output:
output/app.py - Action: Creates Gradio UI for the backend
- Agent: Test Engineer
- Input: Requirements + Code from Task 2 (
context: [code_task]) - Output:
output/test_{module_name} - Tools: CodeInterpreterTool for running tests
- Action: Writes comprehensive unit tests
Tasks declare dependencies using context:
code_task:
context:
- design_task # Has access to design output
frontend_task:
context:
- code_task # Has access to code outputThis enables agents to build on previous work.
- Allows agents to execute Python code safely
- Uses Docker/Podman containers for isolation
- Configured with Podman pipe:
npipe:////./pipe/podman-machine-default - Max execution time: 500 seconds
- Max retries: 3
Only the Backend and Test engineers have code execution enabled for safety.
- Python: 3.10, 3.11, or 3.12
- Docker/Podman: For safe code execution (optional but recommended)
- Install Docker Desktop (easiest), or
- Install Podman Desktop (lightweight, free alternative)
- Windows Podman users: See Podman setup guide below
- API Keys: OpenAI and Anthropic
- Clone the repository
git clone <your-repo-url>
cd engineering_team- Install dependencies
Using uv (recommended):
uv pip install -e .Or using pip:
pip install -e .- Set up environment variables
Copy the example file:
cp .env.example .envEdit .env and add your API keys:
OPENAI_API_KEY=sk-your-openai-key
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
- Configure Docker/Podman (Optional but Recommended)
For code execution safety, install either:
- Docker Desktop (easiest)
- Podman Desktop (lightweight alternative)
Using Podman on Windows? See the complete Podman setup guide in the Troubleshooting section below β it requires 5 specific configuration steps.
Quick Podman Setup:
podman machine init
podman machine startThen follow the Podman troubleshooting guide to configure environment variables.
- Create your input file
Copy the example:
cp input.yaml.example input.yamlEdit input.yaml with your requirements:
module_name: accounts.py
class_name: Account
requirements: |
A simple account management system for a trading simulation platform.
The system should allow users to create an account, deposit funds, and withdraw funds.
# ... more requirements- Run the crew
engineering_teamOr:
python -m engineering_team.main- Check the output
All generated files will be in the output/ directory:
output/{module_name}_design.md- Design documentoutput/{module_name}- Backend Python codeoutput/app.py- Gradio web interfaceoutput/test_{module_name}- Unit tests
- Run the UI:
cd output
python app.py- Run the tests:
cd output
python -m pytest test_accounts.pyengineering_team/
βββ src/
β βββ engineering_team/
β βββ __init__.py
β βββ main.py # Entry point
β βββ crew.py # Crew definition
β βββ config/
β βββ agents.yaml # Agent configurations
β βββ tasks.yaml # Task definitions
β
βββ output/ # Generated code (created at runtime)
β βββ {module_name}_design.md
β βββ {module_name}
β βββ app.py
β βββ test_{module_name}
β
βββ output.example/ # Example outputs for reference
β βββ accounts.py_design.md
β βββ accounts.py
β βββ app.py
β βββ test_accounts.py
β
βββ input.yaml # Your requirements (create from example)
βββ input.yaml.example # Template for requirements
βββ .env # Your API keys (create from example)
βββ .env.example # Template for environment variables
βββ pyproject.toml # Project dependencies
βββ README.md # This file
Edit src/engineering_team/config/agents.yaml:
backend_engineer:
role: >
Python Engineer who can write code...
goal: >
Write a python module...
backstory: >
You're a seasoned python engineer...
llm: anthropic/claude-sonnet-4-5-20250929You can:
- Change the LLM model
- Adjust role descriptions
- Modify goals and backstories
- Add new agents
Edit src/engineering_team/config/tasks.yaml:
code_task:
description: >
Write a python module...
expected_output: >
A python module...
agent: backend_engineer
context:
- design_task
output_file: output/{module_name}You can:
- Add new tasks
- Change task order
- Modify output formats
- Adjust dependencies
In crew.py, change:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.hierarchical, # Changed from sequential
manager_llm="gpt-4o", # Required for hierarchical
verbose=True,
)Hierarchical mode lets a manager agent coordinate tasks dynamically.
The output.example/ directory contains a complete example:
Input (input.yaml.example):
module_name: accounts.py
class_name: Account
requirements: |
A simple account management system for a trading simulation platform...Generated Outputs:
accounts.py_design.md- Architectural designaccounts.py- Working Python class with methodsapp.py- Gradio UI with deposit, withdraw, buy/sell featurestest_accounts.py- Comprehensive unit tests
Try it out:
cd output.example
python app.py # Launch the trading simulator UIAgents don't directly talk to each other. Instead:
- Each agent produces an output (saved to a file)
- The next agent reads previous outputs via context
- CrewAI manages this flow automatically
graph TD
A[design_task] --> B[code_task]
B --> C[frontend_task]
B --> D[test_task]
code_taskwaits fordesign_task- Both
frontend_taskandtest_taskwait forcode_task - In sequential mode, they run one after another
The Backend and Test engineers use Docker/Podman:
- Code runs in isolated containers
- Can't access your file system
- Timeout protection (500s max)
- Automatic retry on failure (max 3 attempts)
If you're using Podman Desktop instead of Docker Desktop on Windows, you'll need to address 5 critical configuration issues. Here's the complete setup guide:
- Podman Desktop installed and machine running (
podman machine list) -
docker.exealias created (see Issue 1 below) -
DOCKER_HOSTenvironment variable set permanently (see Issue 3 below) -
.docker/config.jsoncleaned of Docker Desktop artifacts (see Issue 5 below) - Terminal/IDE restarted to pick up environment changes
- Verification:
docker psworks without errors
Problem: CrewAI validates Docker availability by checking for the docker command. With only Podman installed, there's no docker command, causing CrewAI to fail initialization.
Solution: Create a docker.exe alias to podman.exe:
# Create a local bin directory
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.local\bin"
# Copy podman.exe as docker.exe
Copy-Item "C:\Program Files\RedHat\Podman\podman.exe" "$env:USERPROFILE\.local\bin\docker.exe"
# Add to PATH permanently (User scope)
$currentPath = [System.Environment]::GetEnvironmentVariable("Path", "User")
[System.Environment]::SetEnvironmentVariable("Path", "$currentPath;$env:USERPROFILE\.local\bin", "User")
# Restart your terminal/IDE after thisNote: Don't use .bat files or PowerShell aliases β they don't work with Python's subprocess module.
Problem: The docker-py SDK (used internally by CodeInterpreterTool) defaults to tcp://127.0.0.1:2376, but Podman on Windows uses a named pipe: npipe:////./pipe/podman-machine-default.
Solution: Set the DOCKER_HOST environment variable permanently:
# Set permanently (User scope) - REQUIRED
[System.Environment]::SetEnvironmentVariable(
"DOCKER_HOST",
"npipe:////./pipe/podman-machine-default",
"User"
)
# Verify it's set (after restarting terminal)
echo $env:DOCKER_HOSTImportant: You must restart your terminal or IDE after setting this variable for it to take effect.
Problem: After uninstalling Docker Desktop, ~/.docker/config.json may still reference the Desktop credential store, causing authentication failures.
Error:
Error: docker-credential-desktop not found
Solution: Clean your Docker config file:
# Option 1: Reset to minimal config (recommended)
Set-Content "$env:USERPROFILE\.docker\config.json" '{"auths": {}}'
# Option 2: Delete the entire config (will be recreated)
Remove-Item "$env:USERPROFILE\.docker\config.json" -ForceProblem: Passing user_docker_base_url to CodeInterpreterTool in your code doesn't work because CrewAI creates its own internal tool instance when allow_code_execution=True is set.
Solution: The DOCKER_HOST environment variable (Issue 2) solves this. CrewAI's internal tool uses docker.from_env(), which reads from DOCKER_HOST.
Note: You can safely remove the user_docker_base_url parameter from crew.py once DOCKER_HOST is set at the system level.
After completing the setup:
# 1. Check docker command works
docker --version
# Should show: podman version X.X.X
# 2. Check DOCKER_HOST is set
echo $env:DOCKER_HOST
# Should show: npipe:////./pipe/podman-machine-default
# 3. Test connection
docker ps
# Should list containers without errors
# 4. Verify Podman and Docker show same containers
podman ps
docker ps
# Both commands should show identical outputIf you don't want to use Docker/Podman at all, you can disable code execution in crew.py:
@agent
def backend_engineer(self) -> Agent:
return Agent(
config=self.agents_config["backend_engineer"],
verbose=True,
allow_code_execution=False, # Disable
# Remove tools and code_execution_mode
)Note: This will prevent agents from running or testing code during generation.
Error: OPENAI_API_KEY not found
Make sure:
.envfile exists in the project root- API keys are valid and have credits
- Keys are in format:
KEY_NAME=sk-... - Restart your terminal/IDE after creating
.env
Check that output/ directory exists:
mkdir outputThe main script creates it automatically, but manual creation may help if you encounter permission issues.
Contributions are welcome! Feel free to:
- Add new agents or tasks
- Improve prompts and configurations
- Add support for other languages/frameworks
- Enhance the example outputs
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with CrewAI
- Powered by OpenAI GPT-4 and Anthropic Claude
- UI framework: Gradio
If you have questions or need help:
- Check the
output.example/folder for a working example - Review the CrewAI documentation
- Open an issue on GitHub
Happy Building! π Let AI do the heavy lifting while you focus on the big picture.
Let's create wonders together with the power and simplicity of crewAI.