ai
3 мин
25 августа 2026 г.
Источник: Dev.to AI Feed

How not to use sub-agents!

Atul Joshi
Atul Joshi
RSS AI Ingest
How not to use sub-agents!

What a 500-script migration taught me about when agent parallelism actually makes sense I recently started working on a migration involving roughly 500 scripts. The goal was to migrate legacy logging calls to a newly implemented structured...

What a 500-script migration taught me about when agent parallelism actually makes sense I recently started working on a migration involving roughly 500 scripts. The goal was to migrate legacy logging calls to a newly implemented structured logging engine, with unique logging channels for tracing and observability through Grafana, Loki, Tempo, and Alloy. The new logging engine was already implemented and available through a common include path. What remained was the tedious part: updating hundreds of existing scripts. My first thought was simple: "There are 500 files. Why not use 10 sub-agents and finish this faster?" It sounded like a perfect use case for agentic coding. It wasn't. The problem wasn't the number of files. It was what I was asking the agents to do. 1. The Initial Approach: More Agents = More Speed? The idea was to divide the files into batches and give each batch to a mini-model. Main Agent │ ┌─────────────┼─────────────┐ ▼ ▼ ▼ Agent 1 Agent 2 Agent 3 50 files 50 files 50 files │ │ │ └─────────────┼─────────────┘ ▼ Migration Each agent received essentially the same instructions: find legacy logging replace it with the new structured logger use the correct channel preserve business logic complete its assigned files The files were independent, so the approach looked reasonable. But each agent was doing much more than the actual migration. It was also rediscovering the repository, figuring out what needed changing, deciding channel names, and keeping track of its own progress. That repeated work became the real cost. 2. What Actually Happened The problems were not primarily with the code changes. They were with the work surrounding them. Problem 1: Tracking completed work With multiple agents, someone needs to know: which files are pending which are being processed which are completed which failed which should be skipped That is workflow state. A JSON file, database, or task queue is designed for this. An LLM context isn't. Problem 2: Finding what actually needs to change Each agent had to discover the logging statements itself. The process looked something like: Open file ↓ Understand file ↓ Search for logging ↓ Find legacy calls ↓ Inspect context ↓ Decide what to change ↓ Perform migration But if a simple command can already tell us: ExampleScript.py:42 ExampleScript.py:87 ExampleScript.py:131 ExampleScript.py:164 there is little value in asking ten different model contexts to discover those same locations. That is a job for tooling. Problem 3: Channel generation consumed reasoning Each script needed a unique channel. For example: ExampleScript.py ↓ example_channel This was another decision I had unnecessarily delegated to the model. Channel generation can be deterministic: file path ↓ channel generator ↓ validated channel map Once generated, the channel can simply be given to the model. No need to make the model reconsider naming conventions and uniqueness for every file. 3. The Important Distinction: Work vs. Reasoning This was the point where my thinking changed. I initially saw: 500 independent files But that doesn't necessarily mean: 500 independent reasoning problems. Those are different things. The migration itself was mostly: Find legacy logging ↓ Replace with known API ↓ Use known channel ↓ Preserve everything else The work was repeated hundreds of times, but the reasoning was mostly the same. Now compare that with a debugging problem: Why did API latency increase? ├── Database? ├── Cache? ├── Network? ├── AWS infrastructure? └── Application code? Those are genuinely different reasoning paths. That is where sub-agents become useful: Problem │ ┌──────────┼──────────┐ ▼ ▼ ▼ Agent A Agent B Agent C Database Network Application │ │ │ └──────────┼──────────┘ ▼ Synthesis Each agent can investigate a substantial hypothesis independently. That is meaningful parallelism. In my migration, I was parallelizing work, not reasoning. 4. The Better Approach: Remove Decisions Before Calling the Model The obvious improvement was to move deterministic work outside the model. Instead of asking agents to discover everything, preprocess the repository first. Repository │ ▼ Preprocessing │ ┌──────────────┼──────────────┐ ▼ ▼ ▼ Inventory Log locations Channel map │ │ │ └──────────────┼──────────────┘ ▼ index.json │ ▼ Single Claude Code │ ▼ Migration │ ▼ Verification The preprocessing stage determines: which files contain legacy logging which files contain no logging where the legacy calls are what channel belongs to each file what has already been completed For example: { "file": "ExampleScript.py", "status": "pending", "legacy_log_count": 4, "channel": "example_channel" } Now the model doesn't need to discover the problem. It receives the problem. 5. The Model's Task Becomes Much Smaller Instead of: Explore the repository and migrate this file. the model can receive: File: ExampleScript.py Channel: example_channel Legacy logging locations: 47 82 119 153 Expected migrations: 4 Task: Replace the identified legacy logging statements with the structured logging implementation. Do not modify business logic. Do not change the assigned channel. Do not modify unrelated code. The model now focuses on the part that actually benefits from reasoning: How should this existing logging statement be expressed using the new API while preserving its meaning? Everything else has already been established. This is a much better task boundary. 6. Why the Single Session Is Better Here For this migration, a single Claude Code session has some simple advantages: one shared migration context no duplicated instructions no inter-agent coordination external state for progress deterministic tools for deterministic work The workflow becomes: index.json │ ▼ Next pending file │ ▼ Prepare file context │ ├── locations ├── channel └── rules │ ▼ Single agent │ ▼ Verification │ ┌─────┴─────┐ ▼ ▼ PASS FAIL │ │ ▼ ▼ completed review This isn't less sophisticated than a multi-agent system. It's simply better matched to the problem. 7. So When Are Sub-Agents Actually Useful? The experience led to a better question. Instead of asking: "How many tasks do I have?" ask: "How many independent reasoning problems do I have?" That distinction makes the useful cases much clearer. Independent research For an architectural investigation, different agents can explore different areas: Agent A → AWS architecture Agent B → database architecture Agent C → observability Agent D → security The main agent can then combine the findings. Competing debugging hypotheses For a performance problem: Performance issue │ ┌────────────┼────────────┐ ▼ ▼ ▼ Database Network Application hypothesis hypothesis hypothesis │ │ │ └────────────┼────────────┘ ▼ Synthesis Each agent investigates a different explanation. Independent code reviews A change can be reviewed from different perspectives: Agent A → correctness Agent B → security Agent C → performance Agent D → maintainability These agents aren't simply doing the same job. Each has a different analytical objective. Independent feature implementation If a system has clearly separated components: API Worker Infrastructure Observability and their interfaces are already defined, separate agents can work independently. The important condition is low coupling. 8. The Cost of Sub-Agents Sub-agents aren't free parallel threads. Every additional agent brings its own: context instructions tool calls reasoning coordination result synthesis failure handling Conceptually: Single agent: shared context + sequential reasoning N agents: N × context + N × reasoning + coordination + synthesis So parallelism only helps when the reasoning saved is greater than the overhead introduced. A useful way to think about it is: Sub-agent benefit = parallel reasoning saved - duplicated context - coordination cost - synthesis cost If the difference is small, adding agents is mostly adding machinery. 9. A Practical Decision Framework Before creating a sub-agent, ask: Is the task deterministic? If yes: Use a script or tool. Does it require substantial reasoning? If no: A single agent is usually enough. Is the reasoning independent? If no: Keep it in one session. Would a fresh context provide meaningful value? If yes: A sub-agent may be worthwhile. A simple decision tree: Is it deterministic? │ ┌─────┴─────┐ YES NO │ │ TOOL Substantial reasoning? │ ┌────┴────┐ NO YES │ │ SINGLE AGENT Independent? │ ┌─────┴─────┐ NO YES │ │ SINGLE SUB-AGENTS SESSION 10. What I Learned From the 500-File Migration The migration changed how I think about agent orchestration. 1. The number of files doesn't determine the number of agents. Five hundred files can still represent one reasoning pattern. 2. Context is a resource. Duplicating the same context across ten agents has a cost. 3. Preprocessing can be more valuable than parallelism. Finding the relevant information before invoking the model can save more effort than adding more workers. 4. External state beats model memory. A model shouldn't have to remember the status of hundreds of files. 5. Deterministic decisions belong outside the LLM. Channel generation, classification, searches, counts, and validation can be automated. 6. Agent orchestration has a cost. More agents do not automatically mean faster or cheaper execution. 7. Agents are best used for reasoning. Not bookkeeping. Not counting. Not maintaining workflow state. Not performing searches that a deterministic tool can perform more reliably. 11. The General Principle The biggest lesson wasn't: "Don't use sub-agents." It was: Don't parallelize merely because work can be divided. Parallelize when reasoning can be divided. A hundred deterministic transformations may be better handled by a script. A hundred small reasoning tasks may still be better handled by one well-contextualized agent. Five difficult, independent investigations may be perfect for five sub-agents. The number of tasks is only one part of the problem. The structure of the reasoning should determine the architecture. Conclusion My initial assumption was: 500 files ↓ many agents ↓ faster migration The better approach turned out to be: 500 files ↓ deterministic preprocessing ↓ external state ↓ bounded context ↓ single agent ↓ deterministic verification The lesson is not that sub-agents are bad. It's that parallelism should have a reason. Before spawning another agent, ask: Where is the independent reasoning? If there isn't much, more agents may simply mean more context, more tokens, more coordination, and more things to clean up afterward. Use sub-agents when they let you explore different substantial reasoning paths at the same time. Otherwise, fewer agents with better boundaries usually win.

Хотите внедрить ИИ в ваш бренд?

Спроектируем и развернем автономных агентов и современный цифровой стек под ваши задачи.

Рассчитать проект