Skip to main content

Advanced: editorial pipeline with a crew (CrewAI)

One agent asked to "research this and write a well-checked article" will do all four jobs in a single pass and grade its own work. The failure is specific and predictable: the fact-check never happens, because the model that just wrote a claim is the worst available reviewer of it.

This guide builds four specialists instead, and the thing that makes it work is not the number of agents — it is that each one has a different toolset.

Source: examples/agents/crewai-editorial.

What you need

  • A project, and platformctl login done once.
  • About 20 minutes.
  • Optional: one or more MCP servers in the project. The crew runs without them.

The shape

AgentToolsWhy those
Researchermemory, sandbox, research MCPNeeds to look things up.
Writermemory onlyA writer that can look things up mid-sentence drifts off the brief.
Fact checkermemory, research MCPNeeds sources; is given no writing task, so it reports rather than quietly rewrites.
Editormemory, publishing MCPResolves findings and produces the final text.

The writer's missing tools are not tidiness. They are the mechanism.

Per-agent toolsets

mcp_tools(names=...) narrows an agent to named MCP servers:

crew.py
research_tools = crusoe.mcp_tools(names=_research_names) if _research_names else []
publishing_tools = crusoe.mcp_tools(names=_publishing_names) if _publishing_names else []
Naming a server you do not have is a hard error

mcp_tools(names=[...]) raises UnknownMCPServer and the agent fails to start, restarting in a loop. It does not return the subset it found.

That is the right default — an agent that quietly loses half its tools looks like a model that suddenly got worse — but it means a literal names=["research"] in an example would break for every reader whose project has no server by that name. So this example reads the names from the environment:

platformctl agents env set editorial RESEARCH_MCP=research,docs
platformctl agents env set editorial PUBLISHING_MCP=publishing

Unset means "no MCP tools for that role", and the crew still runs.

The default — mcp_tools() with no names — attaches every server the project has. That is right for a general assistant, because publishing a new tool then needs no agent change, and wrong here, where the whole point is that the writer cannot research.

Shared memory

Every agent gets the same SearchMemory, reading the project's VectorDB:

crew.py
memory = crusoe.SearchMemory()

So a fact established in an earlier run is available to all four, and the fact checker can recognise a claim the team already verified instead of re-deriving it. The researcher's task says to call it first, for the same reason a lookup beats a search.

The tasks

Each task names its context — the earlier tasks whose output it may read:

crew.py
check = Task(
description=(
"Check the draft against the findings. List every claim the findings do "
"not support, quoting the sentence. Do NOT rewrite the draft - a rewrite "
"hides the problem instead of reporting it. If everything checks out, say "
"so in one line."
),
expected_output="A list of unsupported claims, each quoted, or a one-line all-clear.",
agent=fact_checker,
context=[research, draft],
)

"Do NOT rewrite" is load-bearing. Without it a checking model edits the draft and reports success, and the reader never learns which claims were weak.

Sequential, not hierarchical
process=Process.sequential

The order is the editorial process. Under Process.hierarchical a manager agent re-decides that order on every run, which turns four specialists back into one prompt with extra steps.

Deploy and run it

platformctl deploy ./examples/agents/crewai-editorial \
--name editorial --framework crewai

platformctl invoke editorial \
'Write 300 words on how our retention policy changed this year.'

The numbers to compare against

Measured on a warm instance, asking for a 120-word piece:

WhatNumber
Four stages, brief to finished text~17 s
Same job as a single prompt5-8 s
Tool calls in the runsearch_memory first, then run_python to count the words

That is the trade this guide is making, and it is worth being explicit: four specialists is roughly 2-3x the latency and 3-4x the tokens of one prompt doing the job badly. What you get is a fact-check that actually ran, and a word count the writer verified rather than estimated - the run above hit exactly 120. For a chat assistant it is the wrong trade; for anything published under your name it is usually the right one.

Cold start adds 8-12 seconds — more than the LangGraph agent, because the CrewAI base image is larger.

Traps, at the point you hit them

TrapWhat you seeWhy
names= a server you do not haveThe agent fails to start, in a restart loopUnknownMCPServer. Fail-closed on purpose. Check platformctl mcp list.
Writer given research toolsDrafts wander off the brief and runs get slowerIt looks things up mid-sentence. Keep its toolset to memory.
Fact checker allowed to rewriteEvery run reports "all clear"It fixed the problems silently. The "Do NOT rewrite" line is what stops it.
Process.hierarchicalStage order changes run to runA manager agent re-plans the pipeline. Use sequential.
No {message} in the first taskThe crew ignores what you askedThe harness substitutes {message} and {history}; a task without them gets no input.
Timeout at 60 s504 on a long pieceFour stages exceed the default request timeout. Raise it: platformctl agents config set editorial --timeout 300.

That last one is the trap most people hit first. A single-agent prompt fits comfortably inside the 60-second default; a four-stage pipeline often does not.

Teardown

platformctl delete editorial

What it costs to leave running. The agent scales to zero, so an idle crew costs no compute. Its memory bank holds VectorDB storage until the agent is deleted, and each revision holds two entries against the Services quota. The attached MCP servers are separate resources with their own lifecycle — deleting this agent does not delete them.

Where next