Anatomy of a Strong Agent
Three fields do 90% of the steering: role, goal, backstory. Get them right and you'll fight the model far less.
Full agent definition
from crewai import Agent
senior_dev = Agent(
role="Senior Python Engineer", # WHO they are
goal="Write clean, tested, production-ready Python", # WHAT they optimize for
backstory=( # WHY they behave that way
"You spent 8 years at a fintech where bugs cost real money. "
"You write small functions, type hints everywhere, and you "
"always add a test before shipping. You hate cleverness."
),
verbose=True,
allow_delegation=False,
max_iter=10,
memory=True,
tools=[],
)
Writing Effective Roles
The role is the model's primary identity. Vague roles produce vague outputs.
❌ Weak
role="Helper"
✓ Strong
role="Senior Backend Engineer specializing in PostgreSQL performance"
Key Options Explained
verbose
Print the agent's chain-of-thought. Always True in dev, False in prod.
allow_delegation
If True, this agent can hand sub-tasks off to other agents in the crew. Powerful but unpredictable — keep False until you understand it.
max_iter
Hard cap on the agent's reasoning iterations. Default 25. Set to 5–10 in dev to fail fast and save money.
memory
Enable per-agent memory across tasks. Off by default. Covered in detail in Page 9.
tools
List of tools the agent may call. Keep small (2–4) per agent — large toolsets confuse the model.
llm
Override the default LLM for this agent. Use a small model for cheap agents, a big one for hard reasoning. See Page 11.
Battle-Tested Patterns
Cheap classifier + expensive reasoner
from crewai import Agent
from langchain_openai import ChatOpenAI
cheap = ChatOpenAI(model="gpt-4o-mini", temperature=0)
smart = ChatOpenAI(model="gpt-4o", temperature=0.2)
triager = Agent(
role="Ticket Classifier",
goal="Tag the ticket as bug, feature, or question",
backstory="You categorize fast and never overthink.",
llm=cheap,
max_iter=2,
)
solver = Agent(
role="Senior Engineer",
goal="Diagnose and fix bugs from clear repro steps",
backstory="You think before you code.",
llm=smart,
max_iter=10,
)
Notes
Backstory is not a second system prompt
Long narrative backstories inflate tokens and can contradict task instructions. Keep backstory to durable facts and voice; put procedural steps into tasks and expected_output instead.
Tool access is a security boundary
Every tool you attach is available for the model to invoke. Prefer narrow tools with explicit parameters, and avoid giving research agents destructive or billing-capable integrations by default.
Delegation defaults matter in hierarchical crews
Turn delegation off until routing is stable, then enable it for a single lead agent. Multiple delegators tend to ping-pong work and amplify cost without improving quality.
max_iter is your circuit breaker
Higher iteration limits help exploration but worsen runaway loops. Pair higher limits with guardrails or evaluator tasks so retries stop when progress stalls.
CrewAI agents FAQ
What belongs in a CrewAI agent role?
The role names the job title for the worker, like research analyst or copy editor. Keep it specific enough that task prompts can refer to it without ambiguity.
How does backstory help CrewAI agents?
Backstory supplies tone, priorities, and domain bias so the model behaves consistently across turns. Avoid contradicting the goal field or tasks will pull the agent in two directions.
What does allow_delegation control?
It toggles whether an agent may ask another agent for help. Leave it off unless you understand the extra cost and coordination risk that delegation introduces.
What is max_iter in CrewAI?
max_iter caps internal reflection loops for an agent, which helps prevent runaway token usage when a task is ambiguous or a tool keeps failing.
Should every CrewAI agent have tools?
No. Give tools only when an agent truly needs external actions or retrieval. Fewer tools usually mean fewer failure modes and clearer accountability.
See also: DevShelfHub's CrewAI tool review for a product-level comparison, pricing notes, and links back into this tutorial series.