Flows
A Flow is the production backbone: event-driven, stateful, branchable. Official core decorators are @start(), @listen(...), and @router(). Combine listeners with or_ / and_. Persist with @persist (crewai.flow.persistence). Human gates use @human_feedback (≥ 1.8.0, crewai.flow.human_feedback). Do not invent decorator names that are absent from the docs.
Concept-page import:
The Quickstart also uses from crewai.flow import Flow, listen, start. Either import path is valid.
State and entry points
Every Flow instance gets a unique state id. Use a dict for unstructured state, or Flow[YourModel] with Pydantic.
@start()— entry point; multiple starts may run when their conditions match (often in parallel).@listen(method)or@listen("method_name")— runs when that method finishes; may take its return value as an argument.kickoff()returns the last completed method’s value.plot()/plot("name")writes an HTML diagram.
Run a Crew inside a step
This is the official composition: the Flow owns topic and artifacts; the Crew does autonomous research.
In CLI projects, load_crew(Path("crew.jsonc")) replaces a hand-built Crew(...). After a run, flow.usage_metrics aggregates every LLM call in that kickoff (Crews plus bare LLM.call in Flow methods).
@router, or_, and_
@listen(or_(a, b)) fires when either completes. @listen(and_(a, b)) waits for both.
@persist
kickoff(inputs={"id": ...}) resumes the same UUID. kickoff(restore_from_state_id=...) forks a new state.id. Do not combine that with from_checkpoint. You can also put @persist on a single method.
vs LangGraph
This site’s LangGraph chapter uses an explicit StateGraph, checkpoints, and interrupts. CrewAI Flows are decorator-based event graphs that embed Crew role teams natively. Existing LangGraph apps can follow official Moving from LangGraph to CrewAI. New work whose core is role collaboration should start with Flow + Crew.