In our previous lesson, we discussed the theory of agent orchestration. We learned that using one large AI for a long project often leads to context decay, where the AI starts making mistakes because it is trying to remember too much at once. The solution is to use a Main Agent that delegates work to specialized Subagents.
In this lesson, we move from theory to tools. We will learn how to actually build these specialized agents. On CodeSignal, these agents are defined as simple Markdown files stored in a specific folder: .claude/agents/. By creating these files, you are giving Claude a set of specialized "employees" it can hire to perform specific tasks with high precision.
Before we build a specific agent, we need to understand what goes inside an agent file. Every specialized agent has three main parts: the Identity, the Role, and the Completion Criteria.
First, we define the Identity using something called YAML frontmatter. This is a small block of text at the very top of the file that tells the system what the agent is named and what tools it can use.
name: How you will call this agent later.tools: The specific powers this agent has (like reading files or running terminal commands).model: The specific AI brain used for this agent (e.g.,Claude 3.5 Sonnet).
Next, we add the System Prompt. This is the instruction manual for the agent. It defines its Role and the Process it must follow.
Finally, we define Completion Criteria through a Standards section. This tells the agent exactly what it must do before it is allowed to say "I am finished." Standards typically include specific quality thresholds like code coverage percentages, test success requirements, and type-checking results.
These Standards act as the completion checklist—the agent cannot mark its work as done until all these criteria are satisfied. This usually involves running validation scripts or checking code coverage as part of the agent's process.
The Task Executor is your primary worker. Its job is to take a single task from your tasks.md file and turn it into working, tested code. Let's build this agent step-by-step.
We start with the identity and role we just saw, but we add a specific process that enforces a Test-First workflow. This is a production standard where we write the test before the code to ensure we are building exactly what is needed.
After the process, we define the Standards. These are the "laws" the agent must follow, such as requiring 90% code coverage. Notice how these standards are scoped to the specific module being worked on—this prevents the agent from failing due to unrelated legacy code or migration files.
By scoping validation to only the files you're changing, you avoid brittle checks that fail due to existing technical debt elsewhere in the codebase. This is especially important in production environments where you may be working with legacy code that hasn't been fully type-annotated yet.
By putting this all together in a file named .claude/agents/task-executor.md, you create an agent that can be summoned by typing: Task(task-executor): "Execute T001: Add priority field to Task model".
Sometimes, a developer moves too fast and misses edge cases. That is why we build a Test Enhancer. This agent doesn't write new features; it only looks at existing code and tries to break it with better tests.
We start by defining the agent's identity in .claude/agents/test-enhancer.md:
Next, we define its Role and Process. The core of this agent is its ability to check code coverage—a measurement of how much of your code is actually exercised by your tests. Notice how the coverage command explicitly targets the specific module you're enhancing (src/models/task in this example), not the entire codebase.
Finally, we set the Standards that define when the agent is done. These standards apply only to the module under enhancement—you're not responsible for fixing unrelated code.
In a production environment, you might run the task-executor first to build a feature, then immediately follow up with the test-enhancer to ensure no bugs are hiding in the "uncovered" lines of code. You would summon this agent by typing: Task(test-enhancer): "Enhance tests for Task model".
Once an agent finishes its work, it shouldn't just say "Done." It should provide a Structured Report. This allows the Main Agent (and you, the human) to quickly verify the work.
A good completion report looks like this:
To manage these reports across a large project, we use an Orchestration Template. This is a guide for the Main Agent on how to handle a feature with multiple tasks. It follows a simple loop:
- Delegate: Call the specialized agent (e.g.,
Task(task-executor)). - Receive Report: Look at the validation results.
- Wait for Approval: Ask the human if the work is acceptable.
- Track Progress: Update the
tasks.mdfile with a checkmark.
This "Delegate → Receive → Approve" flow is the secret to building massive APIs without the AI getting confused.
In this lesson, we moved from the idea of orchestration to the actual construction of specialized agents.
- You learned that agents are defined in
.claude/agents/using YAML frontmatter and System Prompts. - We designed a Task Executor to handle the heavy lifting of coding with a test-first approach.
- We designed a Test Enhancer to act as a quality auditor and push code coverage to 95%+.
- We explored the Orchestration Template, which defines how the Main Agent manages these specialists.
In the upcoming practice exercises, you will get hands-on experience building these .md files in the CodeSignal IDE. You will then use your new team of agents to implement a Task Tags feature consisting of 6 different tasks, moving through the entire orchestration workflow from start to finish!
