Multi-agent Patterns
Build Streaming Specialists
Create specialist agents and expose them as streaming tools on a coordinator.
Build multi-agent streaming around one coordinator and a small set of narrow specialists. Each specialist should have a clear role, stable agent id, and focused output.
Build Specialist Agents
import { AgentBuilder } from "@anvia/core";
import { model } from "./model";
export const supportAgent = new AgentBuilder("support", model)
.name("Support Specialist")
.description("Summarize customer impact and support next steps.")
.instructions("Return compact support triage bullets using only the provided facts.")
.build();
export const engineeringAgent = new AgentBuilder("engineering", model)
.name("Engineering Specialist")
.description("Summarize diagnostics and engineering next steps.")
.instructions("Return compact engineering triage bullets without unverified root-cause claims.")
.build();
export const commsAgent = new AgentBuilder("communications", model)
.name("Communications Specialist")
.description("Draft customer-facing incident communication guidance.")
.instructions("Return concise customer-safe communication notes.")
.build();Keep specialist instructions narrow. Each child agent should own one role and return a focused result that the coordinator can use.
Expose Specialists With Streaming
import { AgentBuilder } from "@anvia/core";
import { commsAgent, engineeringAgent, supportAgent } from "./specialists";
import { model } from "./model";
export const coordinator = new AgentBuilder("incident-coordinator", model)
.name("Incident Coordinator")
.instructions(
[
"Coordinate specialist agents through tools.",
"Call specialists only when their expertise is useful.",
"Combine specialist findings into one concise incident brief.",
"Do not expose internal-only notes in the final customer-facing summary.",
].join("\n"),
)
.tools([
supportAgent.asTool({ name: "ask_support_agent", stream: true }),
engineeringAgent.asTool({ name: "ask_engineering_agent", stream: true }),
commsAgent.asTool({ name: "ask_comms_agent", stream: true }),
])
.defaultMaxTurns(4)
.build();The coordinator should decide which specialists to call. Do not attach every possible specialist if the model cannot choose reliably.
Run the Coordinator Stream
const prompt = [
"Acme Co. reports webhook retries fail for payloads larger than 512 KB.",
"They have missed several order updates in the last hour.",
"Prepare an incident brief for support, engineering, and communications.",
].join(" ");
for await (const event of coordinator
.prompt(prompt)
.withToolConcurrency(3)
.withTrace({
name: "incident-multi-agent-stream",
metadata: {
incidentId: "inc_123",
tenantId: "tenant_123",
},
})
.stream()) {
renderEvent(event);
}Use .withToolConcurrency(...) only when specialist calls are independent. If one specialist must wait for another specialist's finding, keep concurrency at 1 or split the workflow into explicit stages.
