21 Mar 2026 · 7 min read · Vivek Amethiya
Claude Code skills and subagents for real projects
How to teach Claude Code your project conventions with skills, delegate noisy work to subagents, and cut token usage on client projects.
- Claude Code
- AI agents
- Developer productivity
- LLM cost
The first week with an AI coding assistant on a real project usually goes the same way. It writes good code, but not your code. It forgets that the team uses a particular error format, it runs the wrong test command, and halfway through a long session it starts losing track of decisions made an hour earlier. You find yourself pasting the same instructions into every conversation.
Claude Code has two features built for exactly this: skills and subagents. Skills teach Claude how your project does things. Subagents hand a focused job to a separate assistant with its own memory. Used together, they make the assistant behave like a team member who knows the codebase, and they cut token usage at the same time. This article explains both, shows how I would set them up for a typical client project, and covers the token side in detail.
Three layers of project knowledge
It helps to see where each feature fits.
CLAUDE.mdholds facts that matter in almost every session: how to run the app, the folder structure, coding conventions, commands that must never be run. It is loaded at the start of every session, so keep it short.- Skills hold procedures that matter sometimes: how to add an API endpoint, how to write a database migration, how to prepare a release. Only a one-line description is loaded until the skill is needed.
- Subagents handle work that is large or noisy: searching a big codebase, reviewing a diff, investigating a failing test. They run in their own context and report back a summary.
The mistake I see most often is putting everything into CLAUDE.md. It grows to hundreds of lines, every request pays for those tokens, and the important rules get lost among the rarely needed ones.
Skills: procedures that load on demand
A skill is a folder containing a SKILL.md file. Project skills live in .claude/skills/ in the repository, so every developer who clones it gets them. Personal skills live in ~/.claude/skills/ and apply to all your projects.
Here is a skill for adding an endpoint to a NestJS service, written the way a senior developer would brief a new team member:
---
name: add-endpoint
description: Add a new REST endpoint to the API, including DTO validation, service logic, tests and OpenAPI docs. Use when the user asks for a new route or API method.
---
# Adding an endpoint
1. Create request and response DTOs in `src/<module>/dto/` with class-validator decorators.
Never accept raw objects in controllers.
2. Put business logic in the service, not the controller. Controllers only map HTTP to service calls.
3. Throw `DomainError` subclasses from `src/common/errors`; the global filter maps them to our
error format `{ code, message, details }`. Do not throw HttpException directly.
4. Every tenant-scoped query must filter by `tenantId` from the request context.
5. Add unit tests for the service and an e2e test in `test/<module>.e2e-spec.ts`.
6. Run `npm run test -- <module>` and `npm run lint` before finishing.
For the full error code list, see [errors.md](errors.md).Three details make skills work well in practice.
The description decides when the skill is used. Claude reads every skill's name and description at the start of a session and loads the full instructions only when a request matches. Write the description as "what it does, and when to use it", with the words a developer would actually type.
Supporting files keep the main file short. The skill above links to errors.md. That file is only read if Claude needs it. The documentation recommends keeping SKILL.md itself under about 500 lines and moving reference material into separate files.
Skills can be invoked directly. Each skill also becomes a slash command, so /add-endpoint runs it on purpose. For procedures that should never run on their own, such as a deployment checklist, add disable-model-invocation: true to the frontmatter so only a person can trigger them.
Subagents: delegate the noisy work
A subagent is a Markdown file in .claude/agents/ with a short frontmatter and a system prompt. When Claude delegates to it, the subagent starts with a fresh, separate context window, does its work, and returns a summary to the main conversation.
---
name: code-reviewer
description: Reviews a diff for bugs, security issues and violations of project conventions. Use proactively after significant code changes.
tools: Read, Grep, Glob, Bash
model: sonnet
---
You are a senior reviewer for this repository.
Review only the changes in `git diff main...HEAD`. For each finding give the file and line,
why it matters, and a concrete fix. Prioritise: correctness, security (tenant isolation,
injection, secrets), then performance, then style. Skip anything a linter would catch.
If there are no real issues, say so in one line.The tools line limits what the reviewer can do, which is both safer and more focused. The model line lets you choose a model per job. A codebase search does not need the most capable model; a careful architecture review might.
Claude delegates on its own when a task matches the description (adding "use proactively" encourages this), or you can ask for it by name: "have the code-reviewer agent check my changes".
How this saves tokens
Every request to the model includes the conversation so far. Token cost therefore depends less on what you ask than on how much context is carried along. Skills and subagents both attack that.
Skills defer cost until it is needed. With twenty procedures in CLAUDE.md, all twenty are paid for on every request. As skills, only twenty short descriptions are always present; the full text of a skill is added when it is used. Long reference material in supporting files may never be loaded at all.
Subagents keep exploration out of the main conversation. Searching a large codebase can mean reading dozens of files. Done in the main session, every one of those files stays in context for the rest of the conversation, making each later request more expensive and pushing out earlier decisions. Done in a subagent, the files are read in a separate context and only the conclusion comes back: "the tenant filter is applied in TenantGuard, used by 14 controllers, missing in two".
Cheaper models for routine work. Because each subagent can set its own model, searches, log summaries and test triage can run on a smaller, faster model such as Haiku, while the main session keeps a stronger model for design and implementation.
Longer, sharper sessions. A lean main context means the session reaches its limit later and the assistant keeps earlier decisions in view. That is a quality gain as much as a cost saving.
A rough rule I use: if the output of a step matters but the intermediate steps do not, it belongs in a subagent. If the instructions matter only for certain tasks, they belong in a skill.
Using this on a client project
Client work adds constraints that make this setup more valuable, not less. A practical starting kit for a new engagement looks like this:
CLAUDE.md: run commands, architecture overview, branching and commit rules, and the client's non-negotiables (for example, "no customer data in logs", "all queries tenant-scoped").- Skills for the repeated procedures of that codebase: new endpoint, new database migration, new UI screen following the client's design system, release notes in the client's format.
- Subagents for review and investigation: a code reviewer that knows the client's security rules, a test investigator that reproduces and explains failures, and a read-only explorer for unfamiliar modules.
Because everything lives in the repository, the knowledge survives team changes. A developer joining mid-project gets the same conventions as one who has been there for a year, and reviews become more consistent across the team.
Two cautions from the client side. First, never put secrets or customer data in skills or agent files; they are committed to the repository and sent to the model. Second, agree with the client on what code and data may be shared with AI tools before you start, and record that decision in CLAUDE.md so every session respects it.
Getting started in an afternoon
- Trim
CLAUDE.mdto what every session needs. Move the rest out. - Turn the two or three procedures you explain most often into skills, each with a precise description.
- Add one subagent for code review and one read-only explorer with a smaller model.
- Use them for a week, then tighten the descriptions that trigger too often or too rarely.
Field names and options keep evolving, so check the current Claude Code documentation when you set this up. The idea itself is stable: give the assistant your team's knowledge in small pieces that load only when needed, and give big jobs their own workspace. It is the same discipline good engineering teams already apply to people.