Team
from loomflow.team import TeamTeam builds a multi-agent setup in one call: give it the member
agents, and it returns a regular Agent (the coordinator, or the
entry point) whose architecture is the matching multi-agent strategy.
Use it for single-level teams; it mirrors the builders other
frameworks have (create_supervisor, Crew, GroupChatManager).
For the conceptual page see Team facade.
Team is a namespace class: you don’t construct it, and every method
is a class-level builder.
Shared parameters
Every builder takes the same coordinator settings as Agent(...),
as flat keyword arguments, and forwards them to the Agent it
builds:
instructions, model, memory, runtime, budget,
permissions, hooks, tools, telemetry, audit_log,
max_turns, auto_consolidate, skills, workspace,
living_plan, run_until, stop_hooks, max_stop_hook_iterations,
prompt_caching, tool_result_summarizer,
tool_result_summary_threshold, persist_tool_transcripts,
tool_transcript_max_bytes, snip_window, auto_compact_at_tokens,
auto_compact_summariser, auto_compact_keep_recent_turns,
retry_policy, auto_extract, approval_handler, secrets,
response_tone, effort, strict_effort.
The knobs that live on Tuning for
a plain Agent (retry_policy, secrets, stop_hooks and so on)
are passed flat here; the builder packs them into a Tuning for you.
See the Agent reference for what each one does.
Every builder also takes persistent_subagents: bool = True. With it on, each member keeps
one stable session across delegations, handoffs or rounds, and across
separate run() calls, so members remember earlier work. Set it to
False to give each call a fresh conversation.
Member sessions are kept per user: each user_id gets its own
stable session of each member (anonymous runs share one), so a shared
team never replays one user’s work into another’s run. Member ids are
derived from the role and instructions, the same in every process, so
a team rebuilt after a restart finds its members’ memory and, on a
durable runtime, resumes a crashed run without repeating their side
effects.
The signatures below list only each builder’s own parameters.
Team.supervisor
@classmethod
def supervisor(
cls,
workers: dict[str, Agent],
*,
instructions: str = "",
# ...shared parameters...
instructions_template: str | None = None,
delegate_tool_name: str = "delegate",
forward_tool_name: str = "forward_message",
persistent_subagents: bool = True,
allow_spawn: bool = False,
max_spawned: int = 5,
spawn_template: Agent | None = None,
) -> Agent: ...Returns an Agent whose architecture is
Supervisor(workers=..., ...).
| Parameter | Default | Note |
|---|---|---|
workers | required | Role-name → Agent mapping. |
instructions | "" | Coordinator system prompt (prepended to the supervisor template). |
instructions_template / delegate_tool_name / forward_tool_name | Supervisor’s defaults | Forwarded to the architecture. |
allow_spawn / max_spawned / spawn_template | False / 5 / None | Let the coordinator create temporary workers during a run. See Supervisor. |
team = Team.supervisor(
workers={"researcher": researcher, "writer": writer},
instructions="manage the pipeline",
model="claude-opus-4-7",
)
result = await team.run("write me a blog post")Team.swarm
@classmethod
def swarm(
cls,
agents: dict[str, Agent | Handoff],
entry_agent: str,
*,
instructions: str = "",
# ...shared parameters...
max_handoffs: int = 8,
detect_cycles: bool = True,
pass_full_history: bool = True,
handoff_tool_name: str = "handoff",
persistent_subagents: bool = True,
) -> Agent: ...Returns an Agent whose architecture is Swarm(agents=..., entry_agent=..., ...).
team = Team.swarm(
agents={"triage": triage, "billing": billing, "tech": tech},
entry_agent="triage",
model="claude-opus-4-7",
)Team.router
@classmethod
def router(
cls,
routes: list[RouterRoute],
*,
instructions: str = "",
# ...shared parameters...
fallback_route: str | None = None,
require_confidence_above: float = 0.0,
classifier_prompt: str | None = None,
decider: Any | None = None,
persistent_subagents: bool = True,
conversation_scope: str = "per_route",
) -> Agent: ...Returns an Agent whose architecture is Router(routes=..., ...).
team = Team.router(
routes=[
RouterRoute(name="billing", agent=billing, description="..."),
RouterRoute(name="tech", agent=tech, description="..."),
],
instructions="customer support entry point",
model="claude-haiku-4-5",
)Team.debate
@classmethod
def debate(
cls,
debaters: list[Agent],
*,
judge: Agent | None = None,
instructions: str = "",
# ...shared parameters...
rounds: int = 2,
convergence_check: bool = True,
convergence_similarity: float = 0.85,
debater_instructions: str | None = None,
judge_instructions: str | None = None,
persistent_subagents: bool = True,
) -> Agent: ...Returns an Agent whose architecture is
MultiAgentDebate(debaters=..., judge=..., ...).
team = Team.debate(
debaters=[optimist, skeptic, analyst],
judge=cio,
rounds=2,
convergence_similarity=0.85,
model="claude-opus-4-7",
)Team.actor_critic
@classmethod
def actor_critic(
cls,
actor: Agent,
critic: Agent,
*,
instructions: str = "",
# ...shared parameters...
max_rounds: int = 3,
approval_threshold: float = 0.9,
critique_template: str | None = None,
refine_template: str | None = None,
persistent_subagents: bool = True,
) -> Agent: ...Returns an Agent whose architecture is ActorCritic(actor=..., critic=..., ...).
team = Team.actor_critic(
actor=Agent("Generate", model="claude-opus-4-7"),
critic=Agent("Critique", model="gpt-4o"),
max_rounds=3,
approval_threshold=0.9,
model="claude-opus-4-7",
)Team.blackboard
@classmethod
def blackboard(
cls,
agents: dict[str, Agent],
*,
coordinator: Agent | None = None,
decider: Agent | None = None,
instructions: str = "",
# ...shared parameters...
max_rounds: int = 10,
coordinator_instructions: str | None = None,
decider_instructions: str | None = None,
persistent_subagents: bool = True,
) -> Agent: ...Returns an Agent whose architecture is
BlackboardArchitecture(agents=..., coordinator=..., decider=..., ...).
team = Team.blackboard(
agents={"hypothesis": h, "evidence": e, "critic": c},
coordinator=coord,
decider=decider,
model="claude-opus-4-7",
)Why explicit kwargs (not **kwargs)?
Each Team builder spells out every coordinator kwarg plus the
architecture-specific ones rather than forwarding through
**kwargs. It is more verbose, but Pylance / Pyright / mypy can then
show the full parameter list with types, defaults and docstrings on
hover.
When to skip Team and use Agent(architecture=...)
The Team builders are for single-level teams: supervisors that
delegate to leaf workers, swarms of peers, and so on. For recursive
composition (Reflexion around a Supervisor, Supervisor of
Supervisors) use the explicit Agent(architecture=...) form, so you
can pass one architecture as a field of another.
# Single level: use Team
team = Team.supervisor(workers={...}, model="claude-opus-4-7")
# Nested: use the explicit form
agent = Agent(
"...",
model="claude-opus-4-7",
architecture=Reflexion(
base=Supervisor(workers={...}),
),
)Source
Team and Agent(architecture=...) build the same thing.
Team.supervisor(workers={...}) returns an Agent with a
Supervisor(workers={...}) architecture, plus the
persistent_subagents wiring described above. Use Team when you want
the familiar one-call builder, and the explicit form for composition.