Team
The team package is a high-level way to run multiple Agents together.
It gives you two simple collaboration styles:
- Coordinator Team: one Agent stays in charge, calls member Agents as tools, then replies to the user.
- Swarm: no coordinator loop; the current Agent can hand off to another
Agent via
transfer_to_agent.
In the examples below, LLMAgent is an Agent implementation backed by a
Large Language Model (LLM).
Why do you need a Team?
An Agent is good at one role. Real applications often need multiple roles, for example:
- researching a problem
- writing code
- reviewing for mistakes
A Team lets you combine these roles with a small, clear Application Programming Interface (API).
Coordinator Team vs Swarm
Coordinator Team
- Best for: combining multiple outputs into one final answer (for example, consensus, summarization, "review then revise").
- How it works: the coordinator calls members as tools (using AgentTool). The coordinator can call multiple members in one run.
flowchart LR
U[User] --> T[Coordinator]
T -->|tool call| A[Member A]
T -->|tool call| B[Member B]
T -->|tool call| C[Member C]
T --> U
Swarm
- Best for: “handoff chains”, where each Agent decides who should act next.
- How it works: an entry Agent starts, then Agents transfer control to the
next Agent using
transfer_to_agent. The final Agent replies to the user. - When it ends: a Swarm ends when an Agent stops calling
transfer_to_agentand returns a normal final answer. The last Agent's reply is the result for that run. - Is there an automatic summary?: Swarm does not run an extra
“global summary” step. If you want a structured wrap-up (summary, decisions,
next steps), require it in member
instructions, or add a dedicated “finalizer” Agent and transfer to it at the end.
sequenceDiagram
participant U as User
participant A as Agent A
participant B as Agent B
participant C as Agent C
U->>A: prompt
A->>B: transfer_to_agent
B->>C: transfer_to_agent
C->>U: final answer
Quickstart: Coordinator Team
Notes:
- The Team name is derived from the coordinator name (here both are
"team";team.Newreusescoordinator.Info().Name), so the same session history and events don't end up with two different Agent author names. - The coordinator must support dynamic ToolSets (LLMAgent does).
- In most cases, you do not need to say “call members as tools” in the
coordinator
instruction. Team automatically wrapsmembersas tools and injects them into the coordinator; prefer describing responsibilities and the expected output. - If you want to stream member output in the parent transcript, enable streaming for both the coordinator and members, then set member tool configuration (see below).
Team Inside Team (Hierarchical Teams)
Because team.Team also implements the agent.Agent interface, you can
reuse it like any other Agent: one Team can be a member of another Team.
This “Team of Teams” structure is useful when you want a clear hierarchy, for example:
project_managerdev_teambackend_devfrontend_dev
doc_writer
Minimal example: the outer coordinator Team (project_manager) calls the
inner Team (dev_team) as a single member tool.
Notes:
- Within one Team, member
Info().Namevalues must be unique. - Prefer names that match
^[a-zA-Z0-9_-]+$for maximum tool name compatibility across models. - Swarm (
team.NewSwarm) requires every member to supportSetSubAgents.team.Teamdoes not implementSetSubAgents, so using a Team as a Swarm member is not supported.- If you want “outer coordination + inner handoffs”, make the outer layer
a coordinator Team (
team.New), and make the inner layer a Swarm Team (team.NewSwarm), then use the inner Team as an outer member.
- If you want “outer coordination + inner handoffs”, make the outer layer
a coordinator Team (
Member Tool Configuration (Coordinator Teams)
In a coordinator team, each member is wrapped as an AgentTool and installed on
the coordinator as a Tool (via a ToolSet). team.MemberToolConfig controls
how that wrapper behaves.
Under the hood, team.MemberToolConfig maps directly to AgentTool options:
agenttool.WithStreamInner, agenttool.WithHistoryScope, and
agenttool.WithSkipSummarization.
Quickstart
Start from defaults, then override what you need:
Defaults (from team.DefaultMemberToolConfig()):
StreamInner=falseHistoryScope=team.HistoryScopeParentBranchSkipSummarization=false
Options and When to Use Them
StreamInner
- Default:
false - What it does: forwards member streaming events to the parent flow.
- Use it when: you want a “live” transcript showing what each member is producing as it streams.
- How to use it: enable streaming for the coordinator and members (for
example,
GenerationConfig{Stream: true}), then setMemberToolConfig.StreamInner=true.
HistoryScope
HistoryScope controls whether a member run can see the coordinator's
conversation history.
team.HistoryScopeParentBranch(default)- What it does: the member inherits the coordinator's history (user input, coordinator messages, prior member tool results), but still writes its own events into a sub-branch.
- Use it when: members need shared context and handoffs like “research first, then write using research”.
team.HistoryScopeIsolated- What it does: the member is isolated; it primarily sees the tool input for this call, not the coordinator's prior history.
- Use it when: you want stronger isolation, smaller prompts, or to avoid leaking earlier context into a specialist member.
SkipSummarization
- Default:
false - What it does: ends the coordinator invocation right after the member tool returns, skipping the coordinator's post-tool LLM call.
- Use it when: you want “members respond directly” behavior (no coordinator synthesis). This can be useful for router/passthrough-style teams where the coordinator only selects who should answer.
- Avoid it when: you need the coordinator to combine multiple member outputs into one final answer (the default coordinator team pattern).
Parallel Member Calls (Coordinator Teams)
Because members are exposed as tools, you can enable parallel tool execution on the coordinator:
This runs multiple tool calls concurrently only when the model emits multiple tool calls in a single response. Use this when:
- member tasks are independent (for example, “analyze market”, “analyze risk”, “analyze competitors”)
- you want to reduce end-to-end latency
Quickstart: Swarm
Notes:
entryNameis the Swarm entrypoint: a run starts from this member. It must exist inmembers(it must match the member'sInfo().Name).- Members must support
SetSubAgents(LLMAgent does). This is required so members can discover and transfer to each other.
Swarm Guardrails
Swarm-style handoffs can loop if Agents keep transferring back and forth.
team.SwarmConfig provides optional limits (a zero value means "no limit" or
"disabled"):
MaxHandoffs: maximum transfers in one run (across the whole Team; eachtransfer_to_agentcounts as 1)NodeTimeout: maximum runtime for the target Agent after a transfer (only applies to transfer targets)RepetitiveHandoffWindow+RepetitiveHandoffMinUnique: loop detection (sliding window)
Tip: set either RepetitiveHandoffWindow or RepetitiveHandoffMinUnique to 0
to disable loop detection (no "last N transfers" check).
Defaults come from team.DefaultSwarmConfig(): MaxHandoffs=20,
RepetitiveHandoffWindow=8, RepetitiveHandoffMinUnique=3, and
NodeTimeout=0 (no timeout).
Loop detection meaning: with a window size N and a minimum unique count M, if the last N transfer targets (toAgent) contain fewer than M unique Agents, the transfer is rejected. This is a coarse but efficient heuristic: it only looks at recent target Agent names, not the full transfer path.
Example: if RepetitiveHandoffWindow=8 and RepetitiveHandoffMinUnique=3,
and transfers keep bouncing between A and B (A => B, B => A, ...), then the
last 8 transfer targets contain only 2 unique Agents, which is less than 3,
so the transfer is rejected.
Note: if you set M to 2, the A↔B "ping-pong" will NOT be blocked (because the unique count is exactly 2, not fewer than 2). To cover this case, set M to 3 or higher.
Example
See examples/team/coord (Coordinator Team) and examples/team/swarm (Swarm)
for runnable demos.
Design Notes
- Coordinator teams expose members as tools by installing AgentTool wrappers on the coordinator.
- Swarm teams wire members together via
SetSubAgentsand rely ontransfer_to_agentfor handoffs. team.SwarmConfigis enforced by a transfer controller stored inRunOptions.RuntimeStateduring a run.