docs/en/quickstart.mdx
Install our coding agent skills (Claude Code, Codex, ...) to quickly get your coding agents up and running with CrewAI.
You can install it with npx skills add crewaiinc/skills
In this guide you will create a Flow that sets a research topic, runs a crew with one agent (a researcher using web search), and ends with a markdown report on disk. Flows are the recommended way to structure production apps: they own state and execution order, while agents do the work inside a crew step.
If you have not installed CrewAI yet, follow the installation guide first.
SERPER_API_KEY) for web search in this tutorial<CodeGroup>
```shell Terminal
crewai create flow latest-ai-flow
cd latest_ai_flow
```
</CodeGroup>
This creates a Flow app under src/latest_ai_flow/, including a starter crew under crews/content_crew/ that you will replace with a minimal single-agent research crew in the next steps.
</Step>
```yaml agents.yaml
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
researcher:
role: >
{topic} Senior Data Researcher
goal: >
Uncover cutting-edge developments in {topic}
backstory: >
You're a seasoned researcher with a knack for uncovering the latest
developments in {topic}. You find the most relevant information and
present it clearly.
```
```python content_crew.py
# src/latest_ai_flow/crews/content_crew/content_crew.py
from typing import List
from crewai import Agent, Crew, Process, Task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
@CrewBase
class ResearchCrew:
"""Single-agent research crew used inside the Flow."""
agents: List[BaseAgent]
tasks: List[Task]
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()],
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config["research_task"], # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
```python main.py
# src/latest_ai_flow/main.py
from pydantic import BaseModel
from crewai.flow import Flow, listen, start
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
class ResearchFlowState(BaseModel):
topic: str = ""
report: str = ""
class LatestAiFlow(Flow[ResearchFlowState]):
@start()
def prepare_topic(self, crewai_trigger_payload: dict | None = None):
if crewai_trigger_payload:
self.state.topic = crewai_trigger_payload.get("topic", "AI Agents")
else:
self.state.topic = "AI Agents"
print(f"Topic: {self.state.topic}")
@listen(prepare_topic)
def run_research(self):
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
self.state.report = result.raw
print("Research crew finished.")
@listen(run_research)
def summarize(self):
print("Report path: output/report.md")
def kickoff():
LatestAiFlow().kickoff()
def plot():
LatestAiFlow().plot()
if __name__ == "__main__":
kickoff()
```
- `SERPER_API_KEY` — from [Serper.dev](https://serper.dev/)
- Your model provider keys as required — see [LLM setup](/en/concepts/llms#setting-up-your-llm)
crewai run executes the Flow entrypoint defined in your project (same command as for crews; project type is "flow" in pyproject.toml).
</Step>
## Executive summary
…
## Key trends
- **Tool use and orchestration** — …
- **Enterprise adoption** — …
## Implications
…
```
Your actual file will be longer and reflect live search results. </Step> </Steps>
LatestAiFlow runs prepare_topic first, then run_research, then summarize. State (topic, report) lives on the Flow.ResearchCrew runs one task with one agent: the researcher uses Serper to search the web, then writes the structured report.output_file writes the report under output/report.md.To go deeper on Flow patterns (routing, persistence, human-in-the-loop), see Build your first Flow and Flows. For crews without a Flow, see Crews. For a single Agent and kickoff() without tasks, see Agents.
YAML keys (researcher, research_task) must match the method names on your @CrewBase class. See Crews for the full decorator pattern.
Push your Flow to CrewAI AMP once it runs locally and your project is in a GitHub repository. From the project root:
<CodeGroup> ```bash Authenticate crewai login ```crewai deploy create
crewai deploy status
crewai deploy logs
crewai deploy push
crewai deploy list
crewai deploy remove <deployment_id>