Skip to main content

Getting Started with Claude Code CLI: Setup & Multi-Agent Workflows

 You installed the Claude Code CLI, authenticated with your API key, and successfully ran a simple prompt. It works great for one-off refactoring tasks or explaining a regex string. But when you attempt to implement the much-hyped "Claude Squad"—a workflow involving multiple specialized agents (Architect, Reviewer, Coder)—the documentation evaporates.

Most developers hit a wall here. They try to stuff multiple personas into a single system prompt, leading to context drift and degraded code quality. Or, they manually copy-paste outputs between terminal windows, defeating the purpose of automation.

This guide provides a rigorous, programmatic approach to setting up a multi-agent orchestration layer on top of the Claude CLI (via the SDK). We will move beyond basic chat loops to build a deterministic "Squad" pipeline.

The Root Cause: Why Single-Session Agents Fail

The struggle to configure multi-agent workflows usually stems from a misunderstanding of Context Window Topology.

When you run a standard CLI session, you are operating within a linear context stream. If you tell Claude, "Act as an Architect, then act as a QA," you are forcing the model to hold two conflicting personas in the same attention span.

  1. Token Pollution: The "Architect" logic remains in the context window while the "QA" tries to work. This causes the QA agent to "hallucinate" agreement with the Architect because the Architect's tokens have high attention weights in the history.
  2. System Prompt Dilution: A generic "You are a helpful coding assistant" system prompt is insufficient for specialized tasks. A Code Review agent needs a strict, negative-bias system prompt, while an Ideation agent needs a creative, positive-bias prompt.

To fix this, we must decouple the agents. We need an orchestrator that instantiates separate API calls with distinct system prompts, passing only the necessary artifacts (code or specs) between them, not the entire conversation history.

The Fix: Implementing the "Claude Squad" Orchestrator

We will build a lightweight Node.js/TypeScript wrapper around the Anthropic SDK. This wrapper acts as the "Manager," dispatching tasks to specific agents defined in a configuration map.

Prerequisites

  • Node.js v20+ (for latest fetch/stream capabilities)
  • @anthropic-ai/sdk
  • dotenv

Initialize your project:

npm init -y
npm install @anthropic-ai/sdk dotenv typescript tsx
npx tsc --init

Step 1: Define the Squad Configuration

Create a file named agent-config.ts. This acts as the registry for your specialized agents. Unlike a standard CLI config, we define strict persona boundaries here.

// agent-config.ts
export type AgentRole = 'ARCHITECT' | 'frontend-dev' | 'backend-dev' | 'sec-ops';

interface AgentProfile {
  name: string;
  model: string;
  temperature: number;
  systemPrompt: string;
}

export const CLAUDE_SQUAD: Record<AgentRole, AgentProfile> = {
  'ARCHITECT': {
    name: "System Architect",
    model: "claude-3-7-sonnet-20250219", // Use latest stable
    temperature: 0.2, // Low temp for consistency
    systemPrompt: `You are a Principal Software Architect. 
    Output Requirement: JSON only.
    Your goal: Analyze requirements and output a tech spec.
    Do not write code. Focus on scalability, database schema, and interface contracts.`
  },
  'frontend-dev': {
    name: "React Specialist",
    model: "claude-3-5-sonnet-20241022",
    temperature: 0.1,
    systemPrompt: `You are a Senior React Developer.
    Stack: Next.js 14, Tailwind CSS, TypeScript, Shadcn UI.
    Constraint: Use Server Actions for data mutation.
    Output: clean, complete TSX files.`
  },
  'backend-dev': {
    name: "API Engineer",
    model: "claude-3-5-sonnet-20241022",
    temperature: 0.1,
    systemPrompt: `You are a Backend Engineer.
    Stack: Node.js, Prisma, PostgreSQL.
    Focus: Error handling, Zod validation, and correct HTTP status codes.`
  },
  'sec-ops': {
    name: "Security Auditor",
    model: "claude-3-opus-20240229", // Opus for deep reasoning
    temperature: 0.0,
    systemPrompt: `You are a Security Researcher.
    Analyze the provided code for OWASP Top 10 vulnerabilities.
    Focus on: Injection flaws, broken auth, and data exposure.
    If code is safe, output "PASS". Otherwise, list remediation steps.`
  }
};

Step 2: Build the Orchestrator

Create squad-runner.ts. This script manages the state transfer. It takes a user requirement, passes it to the Architect, pipes the JSON spec to the Developers, and finally sends the code to Security.

// squad-runner.ts
import Anthropic from '@anthropic-ai/sdk';
import { config } from 'dotenv';
import { CLAUDE_SQUAD, AgentRole } from './agent-config';

config();

const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

async function callAgent(role: AgentRole, inputContext: string): Promise<string> {
  const agent = CLAUDE_SQUAD[role];
  
  console.log(`\n🤖 Activation: ${agent.name} (${agent.model})...`);
  
  try {
    const msg = await anthropic.messages.create({
      model: agent.model,
      max_tokens: 4096,
      temperature: agent.temperature,
      system: agent.systemPrompt,
      messages: [
        { role: "user", content: inputContext }
      ],
    });

    // Handle block content safely
    const textBlock = msg.content.find(c => c.type === 'text');
    if (!textBlock || textBlock.type !== 'text') {
      throw new Error('No text returned from agent');
    }

    return textBlock.text;
  } catch (error) {
    console.error(`Error invoking ${agent.name}:`, error);
    process.exit(1);
  }
}

async function runSquadWorkflow(featureRequest: string) {
  console.log(`Starting Workflow for: "${featureRequest}"`);

  // Phase 1: Architecture
  const spec = await callAgent('ARCHITECT', `Design the schema and API contract for: ${featureRequest}`);
  console.log("✅ Architecture Spec Generated.");

  // Phase 2: Parallel Development (Simulated async)
  // We pass the Architect's output (spec) to the devs, NOT the original prompt.
  const [frontendCode, backendCode] = await Promise.all([
    callAgent('frontend-dev', `Implement the UI based on this spec:\n${spec}`),
    callAgent('backend-dev', `Implement the API based on this spec:\n${spec}`)
  ]);
  
  console.log("✅ Code Generation Complete.");

  // Phase 3: Security Review
  const fullCodebase = `
    // FRONTEND
    ${frontendCode}
    
    // BACKEND
    ${backendCode}
  `;

  const auditResult = await callAgent('sec-ops', `Audit this codebase:\n${fullCodebase}`);
  
  console.log("\n====== SECURITY REPORT ======");
  console.log(auditResult);
  console.log("=============================");
}

// Execute
const feature = process.argv[2] || "A secure file upload system with expirations";
runSquadWorkflow(feature);

Step 3: Execution

Run the squad with a specific feature request.

npx tsx squad-runner.ts "A specialized dashboard for monitoring Redis latency"

Deep Dive: Why This Architecture Works

Context Isolation

By instantiating a new anthropic.messages.create call for every step, we ensure Context Isolation. The Frontend Developer agent does not know about the security concerns of the Architect unless explicitly passed in the spec. This prevents "instruction creep," where constraints from early in a conversation accidentally limit the creativity or implementation details of later steps.

Deterministic Temperature Control

Notice in agent-config.ts that we vary the temperature by role.

  • Architect (0.2): Needs to be structured but slightly creative to imagine the system.
  • Devs (0.1): Code must be syntactically strict. High temperature here breaks JSON/TSX syntax.
  • Security (0.0): Absolute determinism required. We do not want creative security advice; we want factual vulnerability assessment.

Asynchronous Parallelism

In the runSquadWorkflow function, we utilize Promise.all. This mimics a real engineering team where frontend and backend work happens simultaneously based on an agreed-upon contract (the Architect's JSON output). A standard linear CLI chat cannot do this—it must generate the backend before it can even think about the frontend.

Handling Common Edge Cases

1. The Truncation Hazard

If the Architect generates a massive spec, it might eat into the context window of the Developer agents.

  • Solution: Enforce JSON output in the Architect's system prompt. JSON is token-efficient compared to natural language paragraphs.

2. The "Lazy Coder" Syndrome

Sometimes Claude returns // ... rest of code to save tokens.

  • Solution: Update the system prompt for Dev agents with: "CRITICAL: Do not use placeholders. Output full, working code only. If the file is too long, output it in multiple chunks."

3. Rate Limits (429 Errors)

Running parallel agents (Promise.all) can trigger Anthropic's rate limits if you are on Tier 1.

  • Solution: If you encounter 429s, switch Promise.all to a sequential await loop or implement a simple exponential backoff wrapper around the callAgent function.

Conclusion

The "Claude Squad" isn't a hidden feature in the CLI binary; it is an architectural pattern you must implement yourself. By moving logic out of a single chat window and into a code-defined orchestration layer, you gain control over context, role separation, and output consistency.

This setup transforms Claude from a conversational assistant into a headless, automated engineering pipeline capable of handling complex, multi-file feature requests without constant human hand-holding.