AI AGENTS TUTORIALCrewAI FlowsThat BehaveState, routing, and human approval for DevOps automationstartcrewhumanTHA-SHED.COM
Featured illustration: a Flow hands work to a crew, then pauses for a human (Illustration with example data)
the shed // CREWAI TUTORIAL

Stop wiring agents together with prayers. CrewAI Flows give you state, branching, and a human approval gate, so your DevOps and security automations run the same way every time.

See the workflow in action, tap through the tabs below:




crewai // triage_flow

$ install the CLI and scaffold a Flow

uv tool install crewai
crewai create flow triage-flow
cd triage_flow
crewai install
crewai run

# main.py: state, a start step, and a router

from typing import Literal
from pydantic import BaseModel
from crewai.flow.flow import Flow, listen, router, start

class AlertState(BaseModel):
    alert: str = ""
    severity: str = ""

class TriageFlow(Flow[AlertState]):
    @start()
    def load_alert(self):
        self.state.alert = "Disk 92 percent on db-example-01"

    @router(load_alert)
    def classify(self) -> Literal["page", "ticket"]:
        return "page" if "92" in self.state.alert else "ticket"

    @listen("page")
    def run_crew(self):
        print("Kick off the incident crew here")

# pause for a human before anything risky happens

@start()
@human_feedback(
    message="Approve this remediation plan?",
    emit=["approved", "rejected", "needs_revision"],
    llm="gpt-4o-mini",
    default_outcome="needs_revision",
)
def propose_fix(self):
    return "Rotate logs and expand volume on db-example-01"

@listen("approved")
def apply_fix(self, result):
    print("Approved:", result.feedback)

# read before you ship

Gotchas: pin your CrewAI version, keep agent tools read-only until a human approves, and never paste real credentials into prompts or example files. Use @persist so a crashed run resumes instead of restarting. Human feedback needs CrewAI 1.8.0 or later.

What CrewAI is, and why Flows matter

CrewAI is a Python framework for building teams of AI agents. A Crew is a group of agents with roles, goals, and tasks. A Flow is the layer above it: it owns state, decides what runs next, and calls crews to do the thinking. If you have shipped an agent that "mostly works," Flows are how you make it work on purpose.

For DevOps and security people this is the whole game. Alerts, access reviews, and patch decisions need repeatable steps and a clear place for a human to say no. If you want the same idea in a different stack, see our LangGraph approval gates tutorial or the OpenAI Agents SDK walkthrough.

Quick setup

CrewAI supports Python 3.10 up to 3.13 and uses uv for installs. Install the CLI, scaffold a Flow, and run it:

uv tool install crewai
crewai create flow triage-flow
cd triage_flow
crewai install
crewai run

The scaffold gives you a main.py for the Flow and a crews/ folder for the crew that does the work inside one step. Put model keys in .env and keep that file out of git. Check the install with uv tool list.

The mindset: the Flow is the boss, the crew is the specialist

The most common mistake is letting one giant crew decide everything. Do the opposite. Let plain Python and the Flow handle sequence, branching, and state. Hand a crew only the fuzzy part, like reading a log or drafting a summary. Three rules keep this honest:

  • Deterministic first. If an if statement can decide it, do not ask a model.
  • Typed state. Use a Pydantic model so every step reads and writes known fields.
  • Humans hold the keys. Any step that changes a system waits for approval.
Flow anatomy: alert to action@startload alert@routerpage or ticketCrewagents + tasksHumanapprove gateApplyticket: log onlyState lives on the Flow. Crews do the thinking. Humans hold the keys.THA-SHED.COM
Workflow diagram: where state, routing, crews, and approval sit (Illustration with example data)

Seven workflows worth building

1. Alert triage with a router

Use @router to send alerts down one of two paths. Declare the labels with Literal so flow.plot() can draw the branches. Example prompt for your coding assistant: "Add a router to my TriageFlow that returns 'page' when severity is high and 'ticket' otherwise."

2. Incident summary crew

Give a crew three agents: a log reader, a timeline builder, and a writer. Feed it the last 200 log lines and ask for a five-line summary with a suspected cause. Keep tools read-only.

3. Access review prep

Export a list of example service accounts and have a crew flag the ones with no recent use or with broad roles. The output is a review sheet for a human, never an automatic revoke.

4. Approval gate before remediation

The @human_feedback decorator pauses the Flow and routes on the answer (it needs CrewAI 1.8.0 or later). The reviewer types free-form feedback and an LLM maps it to approved, rejected, or needs_revision, which triggers the matching listener. Set a safe default_outcome.

crewai run // triage_flow // example runload_alert0.1sdoneclassify -> page0.2sdoneincident_crew (3 agents)41sdonepropose_fix2.0swaitinghuman_feedbackpendingneeds youapply_fix-blockedTHA-SHED.COM
Mockup: a Flow run paused at the approval gate (Illustration with example data)

5. Resumable long runs

Add @persist to the Flow class so state survives restarts. Resume with the same id, or fork a past run with restore_from_state_id to replay a bad day without touching the original history.

6. Dependency risk digest

Have a crew read your lockfile diff and the public advisories you point it at, then write a short risk digest for the pull request. Treat the model's claims as leads to verify, not facts.

7. Weekly runbook drafts

After an incident, run a Flow that turns the timeline into a draft runbook and opens it for review. The Flow stores the draft in state so an editor can request a revision.

Safety and gotchas

  • Least privilege. Give agents read-only tools until a human approves a write. A crew with shell access and a bad prompt is an incident.
  • Prompt injection. Logs, tickets, and web pages are untrusted input. Never let text inside them change what a tool is allowed to do.
  • Secrets. Keep keys in environment variables or a secrets manager. Do not paste them into prompts, task files, or state.
  • Pin versions. CrewAI moves fast. Pin the version in your project and read release notes before upgrading.
  • Test the sad path. Run the rejected and needs_revision branches on purpose before you trust the gate.

Usage and cost tips

Every agent step is a model call, so cost grows with crew size. Start with one or two agents, use a smaller model for routing and summaries, and reserve the strong model for the step that truly needs it. Cap the length of inputs, cache what you can, and log token counts per step so a surprise bill shows up in your own dashboard first. Pricing for hosted CrewAI services and for your model provider changes, so check their pricing pages before you commit.

FAQ

Is CrewAI free?

The open source framework is free to install. You pay your model provider for tokens, and any optional hosted deployment has its own pricing, so check the current docs.

Crew or Flow: which do I start with?

Start with a Flow. The current quickstart scaffolds a Flow and puts the crew inside one step, which gives you state and control from day one.

Can I add a human approval step?

Yes. Use @human_feedback with emit outcomes, available in CrewAI 1.8.0 and later, and route each outcome with @listen.

Your next move

Scaffold one Flow this week, wire in a single read-only crew, and put an approval gate in front of anything that writes. Want a guided path through agents, automation, and security? Browse our courses and build the habit with us.

Tha-Shed

Type a brief, get a finished film. Characters, voices and music included.

Start creating