Designing a team of agents
I continue to experiment with AI in the context of software engineering.<br>I’m fortunate that my team supports me in exploring different ways to improve our daily work.<br>This week, I designed a team of autonomous agents to implement features, from design to implementation.
Why autonomous agents?
A long time ago, we were delighted when the IDE offered auto-completion.<br>In the previous two years, things have changed.<br>A lot.
Coding assistants have become our primary interfaces for coding.<br>We still use IDEs, at least I do.<br>Yet, I had an IDE licensing issue two weeks ago, and I continued to code even without it.<br>The assistant automatically compiles and tests after every change.<br>While it was forced on me, I believe it could be a valuable test for seasoned programmers:<br>can you replace your IDE with your coding assistant, or are they complementary?
That being said, chatting with your assistant is but a step in the AI maturity level.<br>In The 8 Levels of Agentic Engineering, the author mentions the following steps:
Levels 1 & 2: Tab Complete and Agent IDE<br>Level 3: Context Engineering<br>Level 4: Compounding Engineering<br>Level 5: MCP and Skills<br>Level 6: Harness Engineering & Automated Feedback Loops<br>Level 7: Background Agents<br>Level 8: Autonomous Agent Teams
Claude Code’s experimental Agent Teams feature is an early implementation: multiple instances work in parallel on a shared codebase, where teammates operate in their own context windows and communicate directly with each other. Anthropic used 16 parallel agents to build a C compiler from scratch that can compile Linux. Cursor ran hundreds of concurrent agents for weeks to build a web browser from scratch and migrate their own codebase from Solid to React.
Obviously, I have neither the resources nor the know-how to tackle such a huge undertaking.<br>However, I wanted to design a team to handle smaller tasks.
Subagents
I recently wrote about subagents.
Claude Code’s documentation lists several benefits:
Preserve context by keeping exploration and implementation out of your main conversation<br>Enforce constraints by limiting which tools a subagent can use<br>Reuse configurations across projects with user-level subagents<br>Specialize behavior with focused system prompts for specific domains<br>Control costs by routing tasks to faster, cheaper models like Haiku
— Create custom subagents
Claude Code provides several built-in subagents:<br>explore, plan, general purpose, status line, and Claude Code guidelines.<br>You can read more about each of them in the documentation.
However, and this is where it gets interesting, you can define a specialized subagent through a dedicated Markdown file with a specific front matter in a .claude/agents folder.<br>The front matter defines:<br>a name, a description, a model, and a list of available tools.<br>The body describes the subagent’s purpose, i.e., its instructions.<br>Here’s a sample:
name: code-reviewer<br>description: Reviews code for quality and best practices<br>tools: Read, Glob, Grep<br>model: sonnet
You are a code reviewer. When invoked, analyze the code and provide<br>specific, actionable feedback on quality, security, and best practices.
— Write subagent files
The team design
I asked Claude Code to come up with the team design.<br>It created a plan that included five subagents:<br>planner, challenger, coder, tester, and documenter.<br>Their names are pretty self-descriptive, but I’ll come back to them later.<br>In the meantime, I read that the optimal number of agents in a team is between three and five:<br>I removed the documenter.
"Regular" subagents do their tasks autonomously, but then come back to the main agent.<br>Subagents in teams communicate with each other directly.
After defining agents, you need to specify how subagents communicate with each other toward the accomplishment of a task.<br>You describe such interactions in a skill, which Claude also created for me.<br>Here’s a very simplified model.
States represent agent responsibilities in their respective agent file, while interactions represent communication between agents in the skill.<br>Note that I added extra communication constraints within agent descriptions.<br>I work as usual with Claude Code.<br>The only difference is when it’s time to implement; instead of telling it to proceed, I call the /implement skill from the command line.
Here’s how it looks (at the moment) in the console:
4 tasks (0 done, 4 open)<br>◻ Approve plan › blocked by #3<br>◻ Implement merged CSV hierarchy changes › blocked by #1<br>◻ Plan: materialize merged CSVs with new hierarchy across both repos<br>◻ Write tests for merged CSV changes › blocked by #2
Team agents beyond marketing
Agents' teams are amazing, but they come with issues.
The biggest one is the tension between autonomy and security.<br>In regular Claude Code sessions, it’s easy to grant permission when it asks for a command.<br>With regular subagents, I notice it gets a bit more tedious:<br>requests for permissions are much more frequent.<br>Agents' teams reach a...