Skip to main content

Multi-Agent Collaboration

Run multiple agents in parallel, each working on a different part of the codebase, then merge their work together. Each agent gets its own isolated sandbox but works on the same repo.

Prerequisites

  • Caged CLI installed
  • API key configured
  • Agent API keys in Caged secrets

Pattern: Divide and Conquer

Split a large task into independent sub-tasks, run agents in parallel, merge results:
#!/bin/bash
# multi-agent.sh — Parallel agents on isolated branches

REPO="https://github.com/your-org/project"
BASE_BRANCH="main"

# Define agent tasks (each gets its own branch)
declare -A TASKS
TASKS[frontend]="Redesign the dashboard with better charts and responsive layout"
TASKS[backend]="Add rate limiting and input validation to all API endpoints"
TASKS[tests]="Add integration tests for the user authentication flow"
TASKS[docs]="Update all README files and add JSDoc to exported functions"

# Launch a sandbox per agent
declare -A SANDBOXES
for area in "${!TASKS[@]}"; do
  BRANCH="agent/$area-$(date +%s)"

  SANDBOX_ID=$(caged run \
    --template node-20 \
    --cpus 2 \
    --memory 2048 \
    --repo "$REPO" \
    --budget 8 \
    --env "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" \
    --json | jq -r '.id')

  # Create a branch for this agent's work
  caged exec "$SANDBOX_ID" "git checkout -b $BRANCH"

  SANDBOXES[$area]="$SANDBOX_ID"
  echo "[$area] Sandbox: $SANDBOX_ID → branch: $BRANCH"
done

# Run all agents in parallel
for area in "${!TASKS[@]}"; do
  SANDBOX_ID="${SANDBOXES[$area]}"
  TASK="${TASKS[$area]}"
  echo "[$area] Starting: $TASK"
  caged exec "$SANDBOX_ID" "claude '$TASK. Commit your changes when done.'" &
done

# Wait for all agents to finish
wait

# Push branches and report
echo ""
echo "=== Results ==="
for area in "${!TASKS[@]}"; do
  SANDBOX_ID="${SANDBOXES[$area]}"

  # Push the agent's branch
  caged exec "$SANDBOX_ID" "git push origin HEAD"

  # Report status
  COMMITS=$(caged exec "$SANDBOX_ID" "git log --oneline $BASE_BRANCH..HEAD | wc -l")
  COST=$(caged list --json | jq -r ".[] | select(.id == \"$SANDBOX_ID\") | .cost")
  echo "[$area] $COMMITS commits, cost: \$$COST"

  # Cleanup
  caged destroy "$SANDBOX_ID" --force
done

Pattern: Agent Pipeline (Sequential)

Chain agents where one’s output feeds the next:
#!/bin/bash
# pipeline.sh — Sequential agent handoff

REPO="https://github.com/your-org/project"

# Step 1: Architecture agent plans the changes
PLANNER=$(caged run --template node-20 --cpus 2 --memory 1024 \
  --repo "$REPO" --budget 3 \
  --env "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" --json | jq -r '.id')

caged exec "$PLANNER" "claude 'Analyze this codebase and write a PLAN.md with step-by-step instructions to add a WebSocket notification system. Be specific about files to create/modify.'"
caged exec "$PLANNER" "git add -A && git commit -m 'docs: add implementation plan' && git push origin HEAD:agent/plan"

# Step 2: Implementation agent executes the plan
BUILDER=$(caged run --template node-20 --cpus 4 --memory 4096 \
  --repo "$REPO" --budget 10 \
  --env "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" --json | jq -r '.id')

caged exec "$BUILDER" "git fetch origin agent/plan && git merge origin/agent/plan"
caged exec "$BUILDER" "claude 'Read PLAN.md and implement everything described. Run tests after each major change.'"
caged exec "$BUILDER" "git push origin HEAD:agent/implement"

# Step 3: Review agent validates the implementation
REVIEWER=$(caged run --template node-20 --cpus 2 --memory 1024 \
  --repo "$REPO" --budget 3 \
  --env "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" --json | jq -r '.id')

caged exec "$REVIEWER" "git fetch origin agent/implement && git checkout agent/implement"
caged exec "$REVIEWER" "claude 'Review this branch vs main. Run all tests. Report any issues in REVIEW.md. Fix any bugs you find.'"
caged exec "$REVIEWER" "git push origin HEAD:agent/reviewed"

# Cleanup
caged destroy "$PLANNER" "$BUILDER" "$REVIEWER" --force

echo "Final branch: agent/reviewed — ready for human review"

Pattern: Specialist Agents

Use different agent configurations for different tasks:
# .caged-frontend.yaml
template: node-20
resources:
  cpu: 2
  memory: 2048
budget: 5.00
secrets:
  - ANTHROPIC_API_KEY
init_script: npm install
network_mode: allowlist
allowed_hosts:
  - api.anthropic.com
  - registry.npmjs.org
# .caged-backend.yaml
template: go-122
resources:
  cpu: 4
  memory: 4096
budget: 8.00
secrets:
  - ANTHROPIC_API_KEY
init_script: go mod download
network_mode: allowlist
allowed_hosts:
  - api.anthropic.com
  - proxy.golang.org
  - github.com
# Launch specialists in parallel
caged up --config .caged-frontend.yaml &
caged up --config .caged-backend.yaml &
wait

Monitoring Multi-Agent Runs

# Watch all sandboxes
watch -n 5 'caged list'

# Total cost across all agents
caged list --json | jq '{
  total_cost: ([.[].cost] | add),
  total_budget: ([.[].budget] | add),
  running: ([.[] | select(.status == "running")] | length),
  completed: ([.[] | select(.status == "completed")] | length)
}'

Tips

Isolate by branch: Each agent works on its own git branch. This avoids merge conflicts during execution and gives you clean diffs to review.
Use network allowlists: Multi-agent setups multiply risk. Lock each sandbox to only the hosts its agent needs.
Budget per agent, not total: Set individual budgets so one runaway agent doesn’t consume the entire batch budget.
Review before merging: Always have a human (or a review agent) validate the combined output before merging to main.