Custodian Squads (Multi-Agent)
A squad is several Custodian Agents behind one chat app. Each member is a full
Custodian (own model, prompt, tools, examples, files); the squad routes between them.
Reach for a squad when different topics need different instructions, one member needs
a file the others don't, or you want the response to show who handled it. One prompt,
one set of files → use the Custodian class.
from custodian_labs import Custodian, CustodianSquad
squad = CustodianSquad(
custodians=[
Custodian(name="billing", model="gpt-4o", system_prompt="Answer billing questions.",
topics=["billing", "invoice", "refund", "payment"]),
Custodian(name="data", model="gpt-4o", system_prompt="Answer from the uploaded CSV.",
topics=["data", "csv", "customer"]).add_data_source_file("sample_pii_data.csv"),
],
routing_mode="single",
)
app = squad.deploy()
reply = app.chat("How many people are in the file, and which cities?")
print(reply.response, reply.selected_agent)
| Object | |
|---|---|
Custodian | A member. |
CustodianSquad | Groups members, sets the routing mode. |
CustodianSquadApp | Returned by .deploy(); chat with it. |
Routing modes
| Mode | Behavior |
|---|---|
single | Picks one member per message (from topics). Start here. |
chain | Members hand off via can_handoff_to, up to max_handoffs. |
workflow | Members run in a fixed workflow_order; each output feeds the next. |
Handoffs are
chain-only.can_handoff_toandmax_handoffsare ignored insingleandworkflow.
# chain
CustodianSquad(
custodians=[
Custodian(name="triage", model="gpt-4o", system_prompt="Classify the issue.",
topics=["billing", "support"], can_handoff_to=["expert"]),
Custodian(name="expert", model="gpt-4o", system_prompt="Resolve it."),
],
routing_mode="chain", max_handoffs=3,
)
# workflow
CustodianSquad(
custodians=[
Custodian(name="Researcher", model="gpt-4o", system_prompt="Gather facts."),
Custodian(name="Writer", model="gpt-4o", system_prompt="Write the report."),
],
routing_mode="workflow", workflow_order=["Researcher", "Writer"],
)
reply.handoff_path shows the members that participated.
Per-member config
Members are full Custodians — each can set its own tools, examples,
response_schema, output_key, and data source files. See
Built-in Tools.
The squad-level response_schema on CustodianSquad governs the final output,
independent of any member schema.
Requirements
At least one member · unique name per member · workflow_order when
routing_mode="workflow". Misconfigured squads raise a ValidationError before
deploy.
Sharing
Set at deploy time on the squad:
squad.deploy(share_mode="password", share_password="s3cret")