n4nAI

CrewAI sequential process tutorial: step-by-step tasks

Hands-on CrewAI sequential process tutorial: build a linear multi-agent pipeline with tasks that run in order, including runnable code and output.

n4n Team3 min read558 words

Audio narration

Coming soon — every post will get a voice note here.

A crewai sequential process tutorial needs to show more than toy snippets—you need a working pipeline where tasks execute in order, each feeding the next. In this guide we build a two-agent research-and-write crew that runs tasks back-to-back using Process.sequential, and verify outputs at each step. You’ll leave with a pattern you can copy into production.

Prerequisites

  • Python 3.10 or newer
  • crewai installed (>=0.28.0; Agent/Task/Crew APIs are stable here)
  • An LLM endpoint. OpenAI works out of the box; alternatively, point CrewAI at any OpenAI-compatible server. If you’d rather not juggle multiple provider keys, an OpenAI-compatible gateway like n4n.ai can serve as a drop-in base_url for CrewAI’s LLM config, with automatic fallback across providers.
  • OPENAI_API_KEY (or equivalent) exported in your shell

Install and configure

pip install crewai
export OPENAI_API_KEY=sk-...

If you use a gateway, configure the LLM wrapper before defining agents:

from crewai import LLM

llm = LLM(
    model="gpt-4o-mini",
    base_url="https://api.n4n.ai/v1",  # OpenAI-compatible endpoint
    api_key="your-gateway-key",
)

The LLM class mirrors LangChain’s chat model kwargs. Use the model name exactly as your provider expects.

Define agents

Two agents: one retrieves facts, one writes. Keep roles narrow.

from crewai import Agent

researcher = Agent(
    role="Senior Research Analyst",
    goal="Find concise, factual information about {topic}",
    backstory="You dig through sources and return bullet-point briefs.",
    llm=llm,
    verbose=True,
)
writer = Agent(
    role="Technical Writer",
    goal="Turn research briefs into a clean markdown summary",
    backstory="You write for engineers who want no fluff.",
    llm=llm,
    verbose=True,
)

verbose=True streams each agent’s internal steps to stdout, which makes the sequential handoff visible.

Define tasks with dependencies

Tasks are the units of work. In a sequential crew, order is the list order you pass to Crew. The output of task N is injected as context into task N+1 automatically.

from crewai import Task

research_task = Task(
    description="Research the topic: {topic}. Return 3 key facts with sources.",
    expected_output="Bullet list of 3 facts, each with a one-line source.",
    agent=researcher,
)

write_task = Task(
    description="Using the research brief, write a 150-word markdown summary.",
    expected_output="Markdown summary with a heading and the 3 facts woven in.",
    agent=writer,
)

You do not need to manually set context=; Process.sequential handles it. If you later move to Process.hierarchical, you’d need explicit context or a manager.

Assemble the crew with Process.sequential

from crewai import Crew, Process

crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, write_task],
    process=Process.sequential,
    verbose=True,
)

result = crew.kickoff(inputs={"topic": "vector databases"})
print(result)

That’s the whole crewai sequential process tutorial core: agents, ordered tasks, Process.sequential.

Run and inspect outputs

Execute the script. Checkpoint after the first task completes:

[Senior Research Analyst] Task output:
- Fact 1: Vector databases index embeddings for similarity search. (Source: Pinecone docs)
- Fact 2: HNSW graphs enable fast approximate nearest neighbor lookup. (Source: arXiv:1603.09320)
- Fact 3: Many support metadata filtering alongside vectors. (Source: Weaviate docs)

The writer then receives that text under a Context header and produces:

# Vector Databases
Vector databases index embeddings for similarity search. HNSW graphs enable fast
approximate nearest neighbor lookup. Many support metadata filtering alongside vectors.
These properties make them core to retrieval-augmented generation pipelines.

The final printed result is the writer’s markdown string.

Accessing intermediate results

After kickoff, each Task object holds its output. Use this for logging or downstream piping:

print("Research raw:", research_task.output.raw)
print("Write raw:", write_task.output.raw)

.raw is the string the agent returned. .json_dict or .pydantic are available if you set output_json/output_pydantic on the task, but for sequential text flows .raw suffices.

Expected output walkthrough

The sequential process guarantees research_task finishes before write_task starts. With verbose=True on the crew you’ll see a linear log:

├── Task 1: Research the topic...
│   └── Agent: Senior Research Analyst
├── Task 2: Using the research brief...
│   └── Agent: Technical Writer

No interleaving. That determinism is why a crewai sequential process tutorial matters: you can reason about data flow and cost. The second agent’s prompt automatically includes prior output. Override by setting context=[research_task] explicitly if you want to be declarative.

When to use sequential vs hierarchical

Sequential fits straight-line pipelines: research → draft → edit. Hierarchical (Process.hierarchical) adds a manager agent that delegates dynamically, better for ambiguous multi-step jobs. For batch content gen or LLM-ETL, sequential wins on predictability and token cost. Trade-off: no mid-flight re-planning. If research fails, the crew raises unless you catch it.

Common pitfalls

  1. Missing inputs. Tasks with {topic} require inputs= in kickoff. Omit it and CrewAI throws a template error.
  2. Assuming parallelism. Sequential is one-after-another. Multiple agents don’t run concurrently here.
  3. Bloated descriptions. Put the action in description, format rules in expected_output.
  4. Model name mismatch. With a gateway, the model string must be supported by the endpoint exactly as named.

Extending the pattern

Add a proofread step by appending a task:

proof_task = Task(
    description="Fix grammar in the summary without changing facts.",
    expected_output="Corrected markdown string.",
    agent=researcher,
)
crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, write_task, proof_task],
    process=Process.sequential,
)

This crewai sequential process tutorial would be incomplete without showing that scaling is just list appends. Because the process is sequential, the new task slots in last. You can also attach task_callback to persist each output.

Full script reference

from crewai import Agent, Task, Crew, Process, LLM

llm = LLM(model="gpt-4o-mini", base_url="https://api.n4n.ai/v1", api_key="key")

researcher = Agent(role="Senior Research Analyst", goal="Find facts about {topic}",
                   backstory="Concise briefs.", llm=llm, verbose=True)
writer = Agent(role="Technical Writer", goal="Summarize briefs",
               backstory="Engineer-focused.", llm=llm, verbose=True)

research_task = Task(description="Research {topic}. 3 facts with sources.",
                     expected_output="Bullet list.", agent=researcher)
write_task = Task(description="Write 150-word markdown summary from brief.",
                  expected_output="Markdown.", agent=writer)

crew = Crew(agents=[researcher, writer], tasks=[research_task, write_task],
            process=Process.sequential, verbose=True)
print(crew.kickoff(inputs={"topic": "vector databases"}))

Run it. You have a deterministic, observable linear crew.

Tagscrewaisequential-processtask-designtutorial

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All crewai sequential vs hierarchical crews posts →