π‘ AI Labo Benchmark Series β Experiment
E05(Multi-Agent vs. Folded Loop)This post is part of our empirical benchmark series testing AI coding agent harness patterns inside network-isolated Proxmox VMs against a hidden 20-case grading suite.
Metadata & Experiment Identity
- Experiment ID:
E05(Backlog CandidateC002) - Run ID:
e05-vm209-20261028-01 - Sandbox Environment: Proxmox Isolated VM
VM209(ai-e05-209, 0 NICs,virtio-serialQGA relay,systemdUID separation) - Model:
gemini-3.8-flash(thinkingLevel: LOW) - Pattern Under Test: Anthropic Engineering ("Building agents: When to fold subagents into your main agent loop", Diane Sarkis) β Role-Based Subagent Swarm vs. Single Folded Loop + Progressive Skill Disclosure
1. Executive Summary (TL;DR)
When developers try to scale an AI coding agent, a tempting pattern is to mirror a human org chart: split the workflow into Role-Based Subagents (Architect β Core Implementer β Ledger Implementer β QA Fixer) and pass natural-language handoff summaries down the chain.
On tightly coupled codebases, this creates three severe bottlenecks:
- The "Telephone Game" Effect (Handoff Context Loss): When an Architect's 1,400-character plan is compressed or summarized for downstream workers, subtle edge-case invariants (like formatting zero discounts as
-0instead of0) get dropped. - Downstream Rework Loops: Implementers guess at missing details, causing integration failures that force QA Fixer retries.
- Static Skill Preloading Bloat: Because the router doesn't know which domain rules each subagent will need, all company skill docs (SOAP/XML, Kubernetes, GDPR, UI tokens, SaaS billing) get stuffed into subagent system prompts upfront.
To test Anthropic's Subagent Folding + Progressive Skill Disclosure architecture, we benchmarked a 3-module SaaS usage-billing pipeline (normalizer.py, billing.py, ledger.py) inside isolated VM VM209:
- Mode A (
RoleSubagentSwarmRunner): Splits the task across 4 role-based subagents with 3 handoffs and preloads all 5 internal company skill documents into the prompt. - Mode B (
FoldedSkillLoopRunner): Folds planning, coding, and verification into one main agent loop with zero handoffs. The initial prompt shows only a 5-line Skill Catalog Index; the agent dynamically callsload_skill("saas_billing_spec")on Turn 1 and patches all 3 files in one coherent pass on Turn 2.
Key Result
Mode A suffered a classic Telephone Game bug: handoff truncation dropped the DISCOUNT: -0 formatting invariant, causing ledger.py to fail QA and trigger an extra rework turn (5 LLM calls, 36.36s). Mode B completed with zero handoffs and zero rework in 2 calls (13.68s)βrunning 2.66x faster (-62.4% time) while cutting input tokens by -67.0% (14,815 β 4,889), output tokens by -39.9% (2,397 β 1,440), and API cost by -54.9% ($0.0201 β $0.0091).
| Metric | Mode A: Role-Based Subagents (RoleSubagentSwarm) |
Mode B: Folded Loop + Skill Disclosure (FoldedSkillLoop) |
Delta / Improvement |
|---|---|---|---|
| Hidden Grading Suite Score (20 Cases) | 20 / 20 (100% after rework) |
20 / 20 (100% 1st-pass) |
Zero rework needed |
| Subagent Handoffs | 3 handoffs (with summary loss) |
0 handoffs (single shared context) |
Eliminated Telephone Game loss |
QA Failure Rework Retries (failed_check_retries) |
1 retry (DISCOUNT: -0 bug) |
0 retries |
-100% rework |
LLM Calls (model_calls) |
5 calls |
2 calls |
-60.0% fewer calls |
Total File Edits (file_edits) |
4 edits (ledger.py edited twice) |
3 edits (1 per file) |
-25.0% fewer edits |
| Turn 1 Input Tokens | 4,095 tokens (5 skills preloaded) |
1,220 tokens (5-line index only) |
-70.2% initial prompt bloat |
Cumulative Input Tokens (promptTokenCount) |
14,815 tokens |
4,889 tokens |
-67.0% reduction (~3x leaner) |
Cumulative Output Tokens (candidatesTokenCount) |
2,397 tokens |
1,440 tokens |
-39.9% (no handoff prose or rework) |
Elapsed Execution Time (elapsed_seconds) |
36.36 sec |
13.68 sec |
-62.4% (2.66x faster) |
Estimated API Cost (estimated_micro_usd) |
$0.0201 (20,101 micro-USD) |
$0.0091 (9,067 micro-USD) |
-54.9% cost reduction |
2. Architecture Comparison: Role Handoffs vs. Folded Skill Loop
+-------------------------------------------------------------------------+
| Proxmox Isolated VM209 (0 NICs, virtio-serial QGA, systemd UID split) |
| Target Task: 3-Module SaaS Usage Billing Pipeline |
| (normalizer.py β billing.py β ledger.py) |
| |
| +-------------------------------------------------------------------+ |
| | Mode A: RoleSubagentSwarmRunner (4 Roles + 5 Preloaded Skills) | |
| | - Turn 1 [Architect]: Writes 1,437-char plan β truncated (220c)| |
| | - Turn 2 [Impl Core]: Patches normalizer.py & billing.py | |
| | - Turn 3 [Impl Ledger]: Patches ledger.py (misses `-0` rule!) | |
| | - Turn 4 [QA Fixer]: run_tests β FAILS (`zero_discount_-0`) | |
| | - Turn 5 [QA Fixer]: Re-patches ledger.py β PASS & SUBMIT | |
| | --> 5 calls | 14,815 in | 2,397 out | 36.36s | |
| +-------------------------------------------------------------------+ |
| |
| +-------------------------------------------------------------------+ |
| | Mode B: FoldedSkillLoopRunner (Single Loop + Progressive Skills) | |
| | - Turn 1: Sees 5-line Skill Index β calls `load_skill` for only | |
| | `saas_billing_spec` (1,220 in / 21 out) | |
| | - Turn 2: Patches all 3 modules coherently in one context | |
| | + passes verifier on 1st try β AUTO_SUBMIT (3,669 in) | |
| | --> 2 calls | 4,889 in | 1,440 out | 13.68s (2.66x faster!) | |
| +-------------------------------------------------------------------+ |
+-------------------------------------------------------------------------+
3. Code-Level Postmortem: Catching the "Telephone Game" Bug in the Act
Inspecting actions.json and execution-traces.json from VM209 shows exactly how role-based handoffs break coupled invariants:
- On Turn 1 (
seq 0),role_1_architectread all files and all 5 preloaded skill docs (4,095input tokens) and authored a detailed1,437-characterhandoff_plan. However, the router's summary budget (220 chars) truncated the tail of the noteβcutting off theledger.pyformatting clause requiringDISCOUNT: -0when the discount is zero. - On Turn 3 (
seq 2),role_3_implementer_ledgerreceived only the truncated handoff summary and guessed a "reasonable" Python conditional:
# β Mode A β Turn 3 (`role_3_implementer_ledger`): Guessed from truncated handoff!
out.append(f"DISCOUNT: -{disc}" if disc > 0 else f"DISCOUNT: {disc}")
- On Turn 4 (
seq 3),role_4_qa_fixerran integration tests (3,293input tokens) and immediately hit{"error": "zero_discount_must_format_as_-0", "passed": false}, forcing Turn 5 (seq 4,4,213input tokens) to re-emitledger.pyfrom scratch.
In Mode B (FoldedSkillLoop), the single agent loaded saas_billing_spec directly into its working context (1,220 tokens on Turn 1) without loading the 4 irrelevant enterprise skills (SOAP/XML, K8s Helm, GDPR logging, React UI tokens), and wrote f"DISCOUNT: -{disc}" accurately on the very first pass.
Turn-by-Turn Token Breakdown (usage.json)
| Mode | Seq | Role / Action | Input Tokens | Output Tokens | Cost (micro-USD) |
What Happened |
|---|---|---|---|---|---|---|
| Mode A | 0 |
role_1_architect: handoff_plan |
4,095 |
412 |
4,617 |
5 skills preloaded; 1,437-char plan truncated |
| Mode A | 1 |
role_2_implementer_core: patch_core |
1,992 |
1,228 |
6,099 |
Implements normalizer.py & billing.py |
| Mode A | 2 |
role_3_implementer_ledger: patch_ledger |
1,222 |
402 |
2,424 |
Handoff loss: writes DISCOUNT: 0 bug |
| Mode A | 3 |
role_4_qa_fixer: run_tests (FAIL) |
3,293 |
8 |
2,500 |
Catches zero_discount_must_format_as_-0 |
| Mode A | 4 |
role_4_qa_fixer: fix_and_submit (PASS) |
4,213 |
347 |
4,461 |
Re-patches ledger.py to recover |
| Mode A Sum | β | 5 calls (3 handoffs, 1 rework) | 14,815 |
2,397 |
20,101 |
Extra output spent on prose + duplicate patch |
| Mode B | 5 |
folded_turn_1: load_skill("saas_billing_spec") |
1,220 |
21 |
994 |
Loads only the 1 relevant skill from 5-line index |
| Mode B | 6 |
folded_turn_2: patch_pipeline β AUTO_SUBMIT |
3,669 |
1,419 |
8,073 |
Patches all 3 modules in 1 shot; 0 rework |
| Mode B Sum | β | 2 calls (0 handoffs, 0 rework) | 4,889 |
1,440 |
9,067 |
2.66x faster, -54.9% cheaper |
4. All 20 Hidden Grading Suite Results (labjudge05)
| Stage | Test Case IDs | Invariants Verified | Mode A (Role Swarm) |
Mode B (Folded Loop) |
|---|---|---|---|---|
Stage 1 (normalizer.py) |
normalizer_01 to normalizer_06 |
Trim/uppercase tenant_id & metric, allow only API_CALLS/STORAGE_GB, reject units <= 0 & bool/float, non-mutation |
6 / 6 PASS |
6 / 6 PASS |
Stage 2 (billing.py) |
billing_01 to billing_08 |
First-seen order, rate conflict check, 9999 vs 10000 PRO/ENTERPRISE tier discount before credit_note, floor // 10, credit cap |
8 / 8 PASS |
8 / 8 PASS |
Stage 3 & E2E (ledger.py) |
e2e_01 to e2e_06 |
DISCOUNT: -0 signed zero, aggregated units, free-tier ledger, floor tax E2E, line order, error propagation |
6 / 6 PASS (fixed on Turn 5) |
6 / 6 PASS (1st try) |
| Total | 20 Hidden Cases | β | 20 / 20 (100%) |
20 / 20 (100%) |
5. Practical Takeaway: When to Split (E04) vs. When to Fold (E05)
Combining E04 (Loops vs. Graphs) and E05 (Subagent Folding) gives a crisp architectural rule for multi-agent design:
- Split by Module + Deterministic Verifier (
E04): Only isolate steps into separate contexts when each step produces a code artifact verified by a deterministic test suite and has a fixed interface contract. - Fold Sequential Roles (
E05): Never split Architect β Coder β Reviewer across separate subagents connected by natural-language summaries on coupled files. Keep them in one folded loop, and replace bloated system prompts with Progressive Skill Disclosure (a 5-to-10 line index + on-demandload_skill).
π Continue Reading the Series
- π Master Benchmark Hub (All 41 Patterns Ranked): I Benchmarked 41 AI Agent Harness Patterns in Isolated VMs: How to Cut Tokens by 90% Without Losing Accuracy
- π‘οΈ Methodology & Sandbox Architecture: How to Benchmark AI Agents Without Eval Cheating or API Key Leaks: Designing a Proxmox & systemd Sandbox
- πΈοΈ Previous (
E04): Single Loops vs. Directed Graphs for AI Coding Agents: Cutting Input Tokens by 74.4% Without Losing Accuracy - π§ͺ Next (
E06): Why AI Agents Write Weak Tests for Their Own Code: Single-Agent TDD vs. Two-Agent Blind TDD (0% vs. 100% Mutant Kill Rate)
Comments
Join the discussionNo comments yet. Be the first to comment.