Skill detail
getting-started
Guides starting a new CrewAI project: choosing abstractions, scaffolding with the CLI, and wiring YAML config, crews, and flows.
Inspect before use
Read the source instructions and check the requirements before you install this skill.
SKILL.md
The saved excerpt is a snapshot from when this skill was listed. The external source remains the complete and most current version.
---
name: getting-started
description: "CrewAI architecture decisions and project scaffolding. Use when starting a new crewAI project, choosing between LLM.call() vs Agent.kickoff() vs Crew.kickoff() vs Flow, scaffolding with 'crewai create flow', setting up YAML config (agents.yaml, tasks.yaml), wiring @CrewBase crew.py, writing Flow main.py with @start/@listen, building experimental conversational Flows with handle_turn()/chat(), or using {variable} interpolation."
---
# CrewAI Getting Started & Architecture
How to choose the right abstraction, scaffold a project, and wire everything together.
---
## MANDATORY WORKFLOW — Read This First
**NEVER manually create crewAI project files.** Always scaffold with the CLI:
```bash
crewai create flow <project_name>
```
This is **not optional**. Even if you only need one crew, even if you know the file structure by heart — run the CLI first, then modify the generated files. Do NOT write `main.py`, `crew.py`, `agents.yaml`, `tasks.yaml`, or `pyproject.toml` by hand from scratch.
> **Why:** The CLI sets up correct imports, directory structure, pyproject.toml config, and boilerplate that is easy to get subtly wrong when done manually. The reference material below teaches you how the pieces work so you can *modify* scaffolded code, not so you can *replace* the scaffolding step.
**Workflow:**
1. Run `crewai create flow <name>` (use **underscores**, not hyphens)
2. Edit the generated YAML and Python files to match your use case
3. Run `crewai install` then `crewai run`
---
## 1. Choosing the Right Abstraction
crewAI has five common abstraction choices. Pick the simplest one that fits your need:
| Level | When to Use | Overhead | Example |
|---|---|---|---|
| `LLM.call()` | Single prompt, no tools, structured extraction | Lowest | Parse an email into fields |
| `Agent.kickoff()` | One agent with tools and reasoning, no multi-agent coordination | Low | Research a topic with web search |
| `Crew.kickoff()` | Multiple agents collaborating on related tasks | Medium | Research + write + review pipeline |
| `Flow` wrapping crews/agents/LLM calls | Production app with state, routing, conditionals, error handling | Full | Multi-step workflow with branching logic |
| Conversational `Flow` | Multi-turn chat where each user line re-runs a Flow with the same session id | Full + experimental | Support assistant with routed chat, research, and escalation turns |
### Decision Flowchart
```
Do you need tools or multi-step reasoning?
├── No → LLM.call()
└── Yes
└── Do you need multiple agents collaborating?
├── No → Agent.kickoff()
└── Yes
└── Do you need state management, routing, or multiple crews?
├── No → Crew (but still scaffold as a Flow for future-proofing)
└── Yes → Flow + Crew(s)
Do users send multiple chat messages in one session?
└── Yes → Conversational Flow with handle_turn(message, session_id=...)
```
**Rule of thumb:** For any production application, **always start with a Flow**. You can embed `LLM.call()`, `Agent.kickoff()`, or `Crew.kickoff()` inside Flow steps. This gives you state management, error handling, and room to grow.
For chat applications, start with a conversational `Flow` rather than trying to make `Crew.kickoff()` or `Flow.kickoff()` act like a chat loop. The conversational surface is experimental, but it is the intended API for multi-turn sessions: call `flow.handle_turn(message, session_id=...)` for every user line, or `flow.chat()` for a local terminal REPL. Official guide: <https://docs.crewai.com/en/guides/flows/conversational-flows>.
---
## 2. LLM.call() — Direct LLM Invocation
Use for simple, single-turn tasks where you don't need tools or agent reasoning.
```python
from crewai import LLM
from pydantic import BaseModel
class EmailFields(BaseModel):
sender: str
subject: str
urgency: str
llm = LLM(model="openai/gpt-4o")
# Without response_format — returns a string
raw = llRead the full source on GitHub (opens external page)