---
title: Quickstart
description: Build your first CrewAI Flow in minutes — orchestration, state, and an agent crew that produces a real report.
icon: rocket
mode: "wide"
---

### Watch: Building CrewAI Agents & Flows with Coding Agent Skills

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`

<iframe src="https://www.loom.com/embed/befb9f68b81f42ad8112bfdd95a780af" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style={{width: "100%", height: "400px"}}></iframe>

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](/en/installation) first.

## Prerequisites

- Python environment and the CrewAI CLI (see [installation](/en/installation))
- An LLM configured with the right API keys — see [LLMs](/en/concepts/llms#setting-up-your-llm)
- A [Serper.dev](https://serper.dev/) API key (`SERPER_API_KEY`) for web search in this tutorial

## Build your first Flow

<Steps>
  <Step title="Create a Flow project">
  From your terminal, scaffold a Flow project (the folder name uses underscores, e.g. `latest_ai_flow`):

    <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>

  <Step title="Configure one agent in JSONC">
  Create `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (create the `agents/` directory if needed). Variables like `{topic}` are filled from `crew.kickoff(inputs=...)`.

    ```jsonc agents/researcher.jsonc
    {
      "role": "{topic} Senior Data Researcher",
      "goal": "Uncover cutting-edge developments in {topic}",
      "backstory": "You're a seasoned researcher who finds relevant information and presents it clearly.",
      "tools": ["SerperDevTool"],
      "settings": {
        "verbose": true
      }
    }
    ```

  </Step>

  <Step title="Configure the crew in `crew.jsonc`">
  Create `src/latest_ai_flow/crews/content_crew/crew.jsonc`:

    ```jsonc crew.jsonc
    {
      "name": "Research Crew",
      "agents": ["researcher"],
      "tasks": [
        {
          "name": "research_task",
          "description": "Conduct thorough research about {topic}. Use web search to find recent, credible information.",
          "expected_output": "A markdown report with clear sections: key trends, notable tools or companies, and implications. Aim for 800-1200 words. No fenced code blocks around the whole document.",
          "agent": "researcher",
          "output_file": "output/report.md",
          "markdown": true
        }
      ],
      "process": "sequential",
      "verbose": true
    }
    ```

  </Step>

  <Step title="Load the JSON crew (`content_crew.py`)">
  Replace the generated `content_crew.py` with a small loader that turns `crew.jsonc` into a `Crew`.

    ```python content_crew.py
    # src/latest_ai_flow/crews/content_crew/content_crew.py
    from pathlib import Path

    from crewai.project import load_crew


    def kickoff_content_crew(inputs: dict):
      crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
      return crew.kickoff(inputs={**default_inputs, **inputs})
    ```

  </Step>

  <Step title="Define the Flow in `main.py`">
  Connect the crew to a Flow: a `@start()` step sets the topic in **state**, and a `@listen` step runs the crew. The task’s `output_file` still writes `output/report.md`.

    ```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 kickoff_content_crew


    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 = kickoff_content_crew(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()
    ```

  <Tip>
  If your package name differs from `latest_ai_flow`, change the `kickoff_content_crew` import to match your project’s module path.
  </Tip>
  </Step>

  <Step title="Set environment variables">
  In `.env` at the project root, set:

    - `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)
  </Step>

  <Step title="Install and run">
    <CodeGroup>
      ```shell Terminal
      crewai install
      crewai run
      ```
    </CodeGroup>

  `crewai run` executes the Flow entrypoint defined in your project (same command as for crews; project type is `"flow"` in `pyproject.toml`).
  </Step>




  <Step title="Check the output">
  You should see logs from the Flow and the crew. Open **`output/report.md`** for the generated report (excerpt):

  <CodeGroup>
    ```markdown output/report.md
    # AI Agents: Recent Landscape and Trends

    ## Executive summary
    …

    ## Key trends
    - **Tool use and orchestration** — …
    - **Enterprise adoption** — …

    ## Implications
    …
    ```
  </CodeGroup>

  Your actual file will be longer and reflect live search results.
  </Step>
</Steps>

## How this run fits together

1. **Flow** — `LatestAiFlow` runs `prepare_topic` first, then `run_research`, then `summarize`. State (`topic`, `report`) lives on the Flow.
2. **Crew** — `kickoff_content_crew` loads `crew.jsonc` and runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
3. **Artifact** — The task’s `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](/en/guides/flows/first-flow) and [Flows](/en/concepts/flows). For crews without a Flow, see [Crews](/en/concepts/crews). For a single `Agent` and `kickoff()` without tasks, see [Agents](/en/concepts/agents#direct-agent-interaction-with-kickoff).

<Check>
You now have an end-to-end Flow with an agent crew and a saved report — a solid base to add more steps, crews, or tools.
</Check>

### Naming consistency

The names in `crew.jsonc` must match the files and task references you use:

- `agents: ["researcher"]` loads `agents/researcher.jsonc`
- `tasks[].agent: "researcher"` assigns the task to that agent

## Deploying

Push your Flow to **[CrewAI AMP](https://app.crewai.com)** once it runs locally and your project is in a **GitHub** repository. From the project root:

<CodeGroup>
```bash Authenticate
crewai login
```

```bash Create deployment
crewai deploy create
```

```bash Check status & logs
crewai deploy status
crewai deploy logs
```

```bash Ship updates after you change code
crewai deploy push
```

```bash List or remove deployments
crewai deploy list
crewai deploy remove <deployment_id>
```
</CodeGroup>

<Tip>
  The first deploy usually takes **around 1 minute**. Full prerequisites and the web UI flow are in [Deploy to AMP](/en/enterprise/guides/deploy-to-amp).
</Tip>

<CardGroup cols={2}>
  <Card title="Deploy guide" icon="book" href="/en/enterprise/guides/deploy-to-amp">
    Step-by-step AMP deployment (CLI and dashboard).
  </Card>
  <Card
    title="Join the Community"
    icon="comments"
    href="https://community.crewai.com"
  >
    Discuss ideas, share projects, and connect with other CrewAI developers.
  </Card>
</CardGroup>
