← Blog

How to Build a Multi-Agent System with Claude

2026-10-30 · 5 min read · SubToAPI Team

A multi-agent system with Claude is an architecture where several independent Claude-powered agents, each with a narrow role and its own prompt, collaborate to complete a task that a single agent would handle poorly. You build one by defining distinct agent roles, giving each a focused system prompt and tool set, and writing an orchestration layer that routes messages, aggregates results, and decides when the task is done.

This article walks through the actual design decisions: how to split responsibilities between agents, how they communicate, how to avoid runaway loops and token costs, and what the orchestration code looks like in practice.

Why use multiple agents instead of one

A single Claude call with a long system prompt can handle a lot, but it starts to break down when a task requires:

If your task is a single well-defined transformation (summarize, classify, extract), skip multi-agent — it adds latency and cost for no benefit. Multi-agent systems earn their complexity when the task has distinct sub-tasks with different skills or tool requirements.

Core architecture patterns

1. Orchestrator-worker (hub and spoke)

One "orchestrator" agent receives the user request, breaks it into sub-tasks, and dispatches each to a specialized worker agent. Workers return results to the orchestrator, which synthesizes the final answer.

User → Orchestrator → Worker A (research)
                    → Worker B (code)
                    → Worker C (review)
     ← Orchestrator synthesizes → User

This is the easiest pattern to debug because all control flow goes through one place.

2. Pipeline

Agents run in a fixed sequence, each one consuming the previous agent's output. Good for tasks with a natural linear flow: draft → critique → revise → finalize.

3. Peer-to-peer debate / critique

Two or more agents exchange messages directly (often moderated by a thin controller) to refine an answer — e.g. a "generator" and a "critic" agent that iterate until the critic approves.

For most production use cases, orchestrator-worker is the right default. It's the easiest to reason about, log, and bill accurately per sub-task.

Defining agent roles

Each agent should have:

Example role definitions:

const AGENTS = {
  researcher: {
    system: "You research topics and return factual bullet points with sources. Do not write prose.",
    tools: ["web_search"],
  },
  writer: {
    system: "You turn research bullet points into a clear, well-structured article section.",
    tools: [],
  },
  reviewer: {
    system: "You check text for factual consistency against the provided research. Return APPROVE or a list of issues.",
    tools: [],
  },
};

Keeping roles narrow makes failures easier to diagnose — if the output is factually wrong, you know it's the researcher or the reviewer, not a tangled single prompt.

Orchestration code

The orchestrator is just a loop: call an agent, parse its structured output, decide the next step. Here's a simplified example using Claude via SubToAPI, which exposes Claude through a standard HTTPS API so each agent call is just a request with its own API key and model config:

async function callAgent(role, userMessage) {
  const res = await fetch("https://api.subtoapi.app/v1/messages", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "claude-opus-4",
      system: AGENTS[role].system,
      messages: [{ role: "user", content: userMessage }],
      max_tokens: 1024,
    }),
  });
  const data = await res.json();
  return data.content[0].text;
}

async function orchestrate(topic) {
  const research = await callAgent("researcher", `Research: ${topic}`);
  const draft = await callAgent("writer", research);
  const review = await callAgent("reviewer", `Research:\n${research}\n\nDraft:\n${draft}`);

  if (review.trim().startsWith("APPROVE")) return draft;

  // one revision pass using reviewer feedback
  return callAgent("writer", `${research}\n\nRevise based on:\n${review}`);
}

This is deliberately simple — no framework, no hidden abstractions. For production you'll want to add retries, timeouts, and logging around each callAgent call, plus a hard cap on revision loops so a disagreeing writer/reviewer pair can't run forever.

Handling cost, auth, and observability

Multi-agent systems multiply your API calls, so a few operational details matter more than in single-agent setups:

If you're running this across a team building the same system, /pricing has Team and Scale tiers with per-seat API keys, which maps cleanly onto "one key per developer working on one agent role."

A practical starting checklist

  1. Write down the sub-tasks in plain English before writing any code.
  2. Assign one agent per sub-task, with the narrowest possible system prompt.
  3. Define a strict output format (JSON or a clear sentinel like APPROVE) for every agent so the orchestrator never has to guess.
  4. Cap loops — pipelines and debate patterns need a max iteration count.
  5. Log token usage and latency per agent from day one, not after costs surprise you.

Questions

Do I need a framework like LangGraph or CrewAI to build a multi-agent system with Claude? No. For orchestrator-worker and pipeline patterns, a plain loop calling the Claude API per agent is often easier to debug than a framework's abstraction layer. Reach for a framework only if you need built-in state persistence or complex branching you don't want to hand-roll.

How many agents should a multi-agent system have? Start with the minimum that maps to distinct skills or tool needs — often 2-4. Each additional agent adds latency and failure points, so only split further if a single agent is genuinely struggling with conflicting instructions.

How do I prevent agents from looping forever on disagreement? Set a hard max iteration count (2-3 revision rounds is usually enough) and have the orchestrator force-accept the last draft if the cap is hit, logging it as a flagged case for human review.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →