Podcast Title

Author Name

0:00
0:00
Album Art

A Practical Guide to Using Claude's Sub-Agents for Real-World Development

By 10xdev team July 29, 2025

Anthropic has released sub-agents for Claude Code. This article is a great starting point if you want to learn what these things are and how to actually use them in your work. I'm going to be demonstrating a real-world use case where I develop a feature for my MCP server using sub-agents. As you'll see in this article, there are real benefits to using sub-agents.

I'm going to start by describing what those benefits are by referencing the Claude documentation. Then we're going to get into the demonstration. I'm going to share my thoughts on how I expect to be using these things in my work as an AI engineer.

The Core Benefits of Sub-Agents

According to the official documentation, Anthropic says sub-agents are "preconfigured AI personalities that Claude Code can delegate tasks to," but they are a lot more than that. These are the key benefits to focus on:

  • Context Preservation: This is a significant advantage. Each sub-agent maintains its own distinct context. I've previously explored keeping different chats going with the Gemini CLI to preserve context for each task. Sub-agents streamline this because each one has its own specialized expertise, which effectively comes down to a system prompt where each sub-agent has its own instructions for how it will operate.
  • Reusability: This allows you to use the same sub-agent on different projects or even with your team. Since they are just text files, you can easily share them with other people.
  • Flexible Permissions: The sub-agents are specifically designed to have different levels of access. This works really well with the principle of least privilege, a common security measure in software engineering.

That's all for the documentation. Now let's get into an example.

A Practical Demonstration with a Real Use Case

I'm in a unit-converter MCP folder, a project I'm working on. I'll just type claude. Looking at the available options, I have an agents command.

claude agents

Running that shows "No agents found," with an option to create a new one.

Before I do that, let me quickly show you what's going on here. This is the project's README.md file:

# Unit Converter MCP Server

An MCP server that performs various unit conversions, such as temperature, angles, etc.

This is the environment we're working in. I'm going to set up a few agents to help develop a new feature for this MCP server.

Creating Custom Sub-Agents

First, I'll create a new agent and select a "project level" agent. This creates the agent configuration right here in the current project, as opposed to a personal agent in the home directory. I'll choose to "generate with Claude recommended."

I'll describe the agent's purpose conversationally: "a product manager who can help me build new features in the app." Claude will use this to create the agent.

Next, I'm prompted to select tools. For a product manager, read-only access is sufficient. I'll unselect everything except "Read only tools." This grants access to tools like glob, grep, and ls, but not edit, write, or any MCP tools. After accepting the configuration, the product-feature-manager is created.

A new .claude folder appears in my project, containing the agent file. The agent itself is just a text file with front matter for its name and description, and a system prompt that dictates its behavior. The description is key for Claude to understand when to use this sub-agent.

# .claude/agents/product-feature-manager.md

name: product-feature-manager
description: A product manager who can help me build new features in the app.
tools: "ls, cat, grep, glob, find, man"
---
You are a product manager who can help the user build new features in their app.
...

Now, let's create a couple more agents.

  1. Software Engineer: I'll create another agent with the simple prompt "software engineer" and grant it access to all tools. Claude generates a verbose system prompt describing an engineer with over a decade of experience.
  2. Test Runner: This one is more specific: "test runner who runs tests according to the readme." This is important because the project's README.md specifies using uv for testing, and agents often default to pytest directly. For this agent, I'll grant "Execution tools" (which includes bash) and "Readonly tools," but not edit or MCP tools.

Now I have several sub-agents available in my project.

Putting the Agents to Work

These agents persist across sessions because they are stored in a local directory. Let's use them.

I'll start by asking the product manager for ideas.

Get the product manager sub-agent to recommend some features for me to build.

Claude correctly calls the product-feature-manager sub-agent. All the context of its work, like reading the pyproject.toml file, happens within the sub-agent's context. This is distinct from the main user chat. The final result, a list of feature suggestions, is then placed back into the general context of the chat. This mechanism allows for stitching together interactions between different sub-agents.

The agent provided a lot of feature ideas. The "batch conversion" feature sounds interesting. Let's build that one.

Get the software engineer sub-agent to build out the batch conversion feature.

The software-engineer agent is invoked and begins working. It creates a to-do list, a common and effective agentic pattern for coding tasks. After it finishes, it attempts to run tests, which is not what I want. The test runner should handle that.

This is a good opportunity to show how these agents can be modified. I can edit the software engineer's agent file and add a line like:

Do not attempt to run code or tests. That is not your job.

A more thought-out prompt would be better, but this illustrates that we can simply edit the text files to influence the agent's behavior. I'll cancel the test run and explicitly call the test runner.

Test the feature using the test sub-agent.

The readme-test-runner is triggered. However, because I canceled the software engineer's last step, its output wasn't added to the general context. The test runner knows we were working on a batch conversion feature from the previous chat history, but it has to figure out for itself what the software engineer actually did.

The test runner correctly tries to run uv run pytest. It encounters errors. The test runner's job is to report these errors so the software engineer can fix them. However, the process can sometimes go wrong. In this instance, the test runner executed but didn't return any output, and the global context started doing its own work, which was not the desired behavior. This highlights a potential fault line in how sub-agents operate.

Refining Agents for Better Performance

The initial implementation cost around $1.50 and resulted in a broken half-feature. To get this working better, I'm going to strip out the fancy, verbose prompts Claude generated and create very basic, bare-bones sub-agents.

The product manager agent worked well, so I'll leave it. The test runner and software engineer had problems. I'll replace their long system prompts with simple, direct instructions.

For the Test Runner:

Your job is to run tests. Only use this command: uv run pytest. Output any errors so that the software engineer sub-agent can implement fixes. You two will work together.

For the Software Engineer:

Your job is to write code and then hand it off to the test-runner sub-agent to test that code.

With these simplified agents, I'll try again. I had to restart the Claude session for it to pick up the "hot reloaded" changes to the agent files.

Test the batch functionality with the test runner sub-agent.

This time, it works much better. The test runner executes uv run pytest, finds an error (a unit name mismatch), and explains the output. I still had to manually prompt the next step:

Okay, go do it.

Now, the software engineer picks up the context and fixes the test. What's really neat is that it then figures out it should work in a loop. It automatically re-runs the tests, finds another error (a data unit mismatch), fixes it, and continues this cycle until all tests are passing. This is the experience I was hoping for out of the box.

After a few iterations, all tests are passing. The process felt a bit inefficient and likely cost more time and money than it should have, but it did work. Running pytest manually confirms all tests now pass.

I can even test the new feature in the Claude Desktop app. I have a tool set up for my unit converter. I'll enable the dev version, and the convert_batch tool is now available. I can give it a list of temperatures, and it correctly calls the batch conversion function and returns the parsed results. The feature works.

The agents successfully: - Reused existing logic for consistency. - Created a working MCP tool. - Wrote new tests. - Updated the README.md file.

Automating Releases with a Custom Agent

This inspires another idea: creating a sub-agent to handle releases. My project is available on PyPI, and I have a release checklist. I'll create a new agent from scratch to automate this.

I'll create a new file: .claude/agents/changelog-updater.md.

name: changelog-updater
description: Use this agent when the user requests it.
# No tools specified means it has access to all tools
---
Your task is to prepare the project for release by doing the following:

1.  In `pyproject.toml` and `__init__.py`, update the version number.
2.  Update the `CHANGELOG.md` with a summary of changes since the last release. You can use `git diff` to see the changes.
3.  Draft the release notes.

After these steps are done, remind the user how to finalize the release:
1.  Commit changes to the main branch.
2.  Create the release tag on GitHub.

After creating this file and restarting Claude, the new changelog-updater agent is available.

Run the changelog updater agent.

It runs and updates the version to 0.2.0, which is wrong. I wanted 0.1.2. I can simply correct it:

No, use 0.1.2.

It fixes the version number in __init__.py and pyproject.toml and also updates the changelog. This kind of documentation and release management is not fun to do manually, and the fact that AI can handle it is a huge productivity boost.

From Development to Deployment

Now, to actually release this. The agent files themselves could be committed to git, but for now, I'll add the .claude directory to my .gitignore.

I'll commit the changes:

git add .
git commit -m "feat: Add batch tool and upgrade to 0.1.2"
git push

Pushing to the main branch triggers my GitHub Actions CI pipeline. The initial push fails due to linting and formatting errors. I have a specific checklist I need to run.

I'll use Claude to fix these issues. I won't explicitly call a sub-agent, just to see if Claude uses them implicitly.

Run some tests and fix any errors. First, run mypy.

Claude runs mypy and immediately finds and fixes the type-checking errors. It then fixes ruff formatting issues as well. After running pytest one last time to be sure, I commit the fixes.

git commit -m "fix: Fix ruff, format, and mypy errors"
git push

This time, the GitHub Actions all pass. Now I can draft the release on GitHub. I'll create a new release with the tag v0.1.2, use the changelog notes generated by the agent, and publish it.

Publishing the release on GitHub triggers another action: a PyPI deployment. After a minute, the action completes successfully. The new version, 0.1.2, is now live on PyPI.

System-Wide Patterns and Future Possibilities

I've been thinking of several ways to use Claude sub-agents on a system-wide level, creating patterns that can be used between different projects. These reusable, specialized agents offer a powerful paradigm for development workflows, and it will be interesting to see how others adopt and innovate with them.

Join the 10xdev Community

Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.

Recommended For You

Up Next