Agents vs Tasks in Multi-Agent Frameworks

In CrewAI an agent is who does the work and a task is what the work is. Other frameworks draw the same line with different names, or barely draw it at all. Here is the split, framework by framework, and how it maps onto a task board.

7 min read

In CrewAI, an agent is who does the work and a task is what the work is. An agent is defined by a role, a goal and a backstory, plus the tools it may use. A task is defined by a description, an expected output and, usually, the agent responsible for it. A crew puts agents and tasks together and runs the tasks in order or under a manager. Keeping the two apart lets you reuse one agent across many tasks, change a task without rewriting the agent, and check each result against what the task said it should be. Other frameworks draw the same line with different names, and some hardly draw it at all.

This page is about the vocabulary and what it implies. How to coordinate several agents on one job is in multi-agent workflows, and how to cut a goal into tasks is in AI agent task decomposition.

The agent in CrewAI: who

CrewAI’s agents documentation (opens in a new tab) makes three attributes required. The role defines the agent’s function and expertise within the crew. The goal is the individual objective that guides its decisions. The backstory provides context and personality. Optional attributes include the tools it can call, the model behind it, a maximum number of iterations, and allow_delegation, which is off by default and, when on, lets the agent hand work to other agents.

Notice what is not there: nothing about this particular job. An agent describes a colleague, not an assignment. A “release notes writer” agent can write this week’s notes and next week’s without changing.

The task in CrewAI: what

The tasks documentation (opens in a new tab) defines a task by its description, a clear, concise statement of what the task entails, and its expected output, a detailed description of what completion looks like. The agent responsible is optional. Other optional attributes carry the rest of the job: context names other tasks whose output this one uses, tools limits what the agent may use for this task, human_input asks a person to review the final answer, guardrail validates the output before the next task starts, and output_file saves the result.

Python: one agent, one task, one crew
from crewai import Agent, Task, Crew, Process

writer = Agent(
    role="Release notes writer",
    goal="Turn merged changes into notes customers understand",
    backstory="You write short, plain release notes for a small SaaS team.",
)

notes = Task(
    description="Write release notes for these merged changes: {changes}",
    expected_output="A markdown list, one line per change, grouped by feature, enhancement and bug.",
    agent=writer,
    human_input=True,
)

crew = Crew(agents=[writer], tasks=[notes], process=Process.sequential)
result = crew.kickoff(inputs={"changes": "..."})

expected_output is the field people skip and the one that matters most. It is the acceptance criterion: without it, the agent decides when it is finished.

Who decides which agent takes which task

The crew’s process does. CrewAI’s processes documentation (opens in a new tab) describes two. In a sequential process, tasks run in the order given and the output of one serves as context for the next, so each task normally names its agent. In a hierarchical process, a manager, either a manager_llm or a custom manager_agent, which must be specified, plans, delegates and reviews outputs, and a task without an agent is given to one based on roles and expertise.

So there are two ways to assign work: push, where you name the agent on the task, and delegate, where a manager chooses. The same two shapes appear in every framework, and on every team.

How other frameworks name the same idea

OpenAI Agents SDK: agents and runs

In the OpenAI Agents SDK (opens in a new tab), an agent is a model configured with a name, instructions, tools and optional handoffs, guardrails and a structured output type. There is no separate task object: work is the input you pass to Runner.run(agent, input). Handoffs let one agent delegate to another, and the documentation describes each handoff as a tool the model can call, such as transfer_to_refund_agent. The task lives in the input and the conversation, so anything like an expected output is written into the instructions or enforced with an output type.

LangGraph: nodes, state and a different kind of task

LangGraph thinks in graphs. Nodes are functions that encode the logic of your agents, edges decide which node runs next, and state is a shared snapshot passed between them. LangChain’s multi-agent guide describes patterns such as subagents, where a main agent calls others as tools, handoffs and routers; work flows through messages and state rather than task records. Beware the word: in LangGraph’s functional API (opens in a new tab), @task marks a discrete unit of work such as an API call or a processing step. That is a step inside a run, not a job someone assigned.

Claude Code subagents: descriptions and prompts

A Claude Code subagent is a Markdown file with a name, a description, optional tools and a model, and a body that becomes its system prompt. According to the subagents documentation (opens in a new tab), Claude uses each description to decide when to delegate, and when you name a subagent, Claude still writes the subagent’s task prompt from what you asked. The agent is a file; the task is a prompt written on the fly. Examples are in Claude Code subagent examples.

The split side by side

  • CrewAI: agent (role, goal, backstory, tools) and task (description, expected output, agent) are separate objects. Assignment is named on the task or made by a manager.
  • OpenAI Agents SDK: agent (name, instructions, tools, handoffs) is an object; the task is the input to a run. Assignment is by which agent you run, or by handoff.
  • LangGraph: agents are nodes; the work is state and messages. @task means a step, not an assignment.
  • Claude Code subagents: the agent is a Markdown file; the task is a prompt Claude writes when it delegates.

The pattern: the more a framework treats the task as a first-class object, the easier it is to check the result against a stated expectation, and to see afterwards what was asked of whom.

The same split on a task board

Inside a framework, a task lasts as long as the run. On a team, work outlives any run: a person files it, an assistant does it, someone else checks it next week. A task board is where the task becomes a durable record, and the CrewAI fields map onto it closely. On fenbs:

CrewAI field and its place on a fenbs task
description      -> Problem (note over MCP): what and why, written once
expected_output  -> acceptance criteria in the Problem, checked in Testing
                    (testStatus, testNotes)
agent            -> the assistant that picks the task up; its work is
                    recorded as "Claude via <person>"
context          -> related tasks, linked with relatesTo
tools            -> the limits line on the approval, inside the
                    token's scopes: read, write, comment
human_input      -> "AI done · check it" until a person presses
                    "I've checked it"
(the plan)       -> Plan (plan over MCP): how it will be done

Assignment works by pull rather than push. fenbs’s MCP tools do not take an assignee. Instead, a person with a plan they are happy with presses “Let AI do this” on the task, with an optional limits line such as “web only, no API change”. An assistant with nothing else to do calls fenbs_next_approved_task, gets the most urgent approved task in its project, and the task is held for it for a few hours so two assistants never take the same one. If it cannot finish, fenbs_release_task gives it back with a reason.

Two rules mirror what a hierarchical manager does in CrewAI, but with a person as the manager. Only a person can approve a task for AI, never an assistant. And the approval is of the task as it was read: if its title, problem or plan changes afterwards, no assistant takes it until someone approves it again. Comments added later are information for the assistant, not new instructions.

What makes a good description and expected output for an assistant, with a template, is in how to write a task for an AI agent.

Related

Coordinating several assistants on one board: multi-agent workflows. Passing work between assistants and people: handing work between AI agents and people. A board set up for assistant work: the AI assistant work log template. Connecting one: the MCP docs.

Questions people ask.

What is the difference between an agent and a task in CrewAI?

An agent is who does the work, defined by a role, a goal, a backstory and the tools it may use. A task is what the work is, defined by a description, an expected output and usually the agent responsible. One agent can carry out many tasks.

Does every CrewAI task need an agent?

No. The agent is optional on a task. In a hierarchical process, a manager model or manager agent, which must be specified for that process, gives unassigned tasks to agents based on their roles. In a sequential process, tasks normally name their agent.

Does the OpenAI Agents SDK have tasks?

Not as a separate object. You define agents with instructions, tools and handoffs, and the work is the input you pass when you run an agent. An expected result goes into the instructions or is enforced with a structured output type.

How do I assign a task to an AI assistant on a board?

On fenbs, a person approves a task that has a plan with Let AI do this, and a connected assistant picks it up with fenbs_next_approved_task, which holds it for that assistant for a few hours. The assistant records its result, fills in Testing, and a person checks it.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.