DEV Community

Vikram Ray
Vikram Ray

Posted on Edited on

Skill-in-Skill: How to Support 1,000+ Skills

~5 minute read

TL;DR

  • Every skill you install costs context on every turn, and past a point the agent gets worse, not better.
  • Approach 1 — curate: fewer, stronger skills, with the detail in references/.
  • Approach 2 — skill-in-skill: when you can't curate (skills from other repos you don't want to rewrite), nest them under one router skill per area, so the agent only sees the router.
  • Both produce the same directory shape. The only difference is whether you rewrite the content or copy it as-is.

1. The problem: every skill costs context, every turn

  • Agent Skills use progressive disclosure: the agent sees each skill's name and description up front, and loads the full instructions only when a task matches (Anthropic engineering).
  • Cheap per skill — but paid for every skill, on every turn.
  • It adds up fast. One Hermes Agent user reports (issue #22620, still open):
    • 243 skills: the agent "injects ALL installed skills … into the system prompt on every turn" — about 10–15K tokens per call.
    • 130 skills: about 4K tokens per turn.
    • These are one person's numbers, not a benchmark — but the order of magnitude is what you'd expect at ~40 tokens per description.
  • It's not just cost. PostHog: "The agent's effectiveness declined as skill descriptions filled the agent's context window" (PostHog).

Picture a coding agent your whole team shares (numbers are hypothetical, for illustration):

Area Skills
YouTube / content 20
Backend 30
Frontend 50
Architecture 50
Testing 40
DevOps 40
Data 30
Security 25
Personal 30+
  • That's 300+ descriptions in front of the model on every turn.
  • Many are close cousins: react-component, react-form, component-library-docs.

What about letting the agent search?

  • A natural option: list a few core skills and give the agent a way to search the rest — a tool, a CLI, a lookup file.
  • It works, and it scales to any number of skills.
  • The trade-off: the agent has to decide when to search. It already knows how to write an endpoint, so does it stop and look for your team's add-rest-endpoint skill first?
  • Models differ: some search eagerly, some rarely, so the instructions need tuning per model.
  • Some harnesses are starting to do this natively — lazy-loading skill or tool descriptions behind a search step. If yours already does, you may not need anything below. Most don't yet.

To be clear: the approaches below don't remove the "when do I look?" decision. They make it deterministic and
cheap
— a short, static list the agent reads in one hop, with no search tool to call and nothing to miss.

2. Approach 1: curate — fewer skills, deeper references

  • Don't create 100+ skills for your org. Most of those 50 frontend skills are variations on a few real workflows.
  • Keep a handful of strong skills — frontend, backend, testing.
  • Move the detail into references/, which the agent reads only when it needs it.
  • xtrace puts it well: "A thin router at the top. Not content — pointers, plus the condition under which each one is worth reading" (xtrace).
  • If you own your skills, start here. It's the cheapest and cleanest fix.

3. When you can't curate

Curation assumes you control the skills. Increasingly you don't:

  • Skills come from other repos and marketplaces.
  • Other teams maintain their own, on their own release cycle.
  • Users bring personal skills.

And you don't want to rewrite them:

  • Every upstream update would mean merging again.
  • You want to install them as they are and still keep the agent's list short.

4. Approach 2: skill-in-skill

Install skills as they are, but nest them inside one router skill per area:

skills/
│
├── git-workflow/                      🔹 always listed (cross-cutting)
│
├── frontend/                          📁 router skill — the only frontend entry the agent sees
│   ├── SKILL.md                       ←  description + index of what's inside
│   └── references/
│       ├── react-component/
│       │   └── NESTED-SKILL.md        📄 original skill, renamed so the harness won't list it
│       ├── react-form/
│       │   └── NESTED-SKILL.md
│       └── vue-store/
│           └── NESTED-SKILL.md
│
├── backend/                           📁 router skill (30 skills inside)
└── youtube/                           📁 router skill (20 skills inside)
Enter fullscreen mode Exit fullscreen mode

(references/ is reused on purpose: to the harness, a nested skill is reference material for the router. Call it
nested/ if that reads clearer to your team.)

Two small moves:

  1. Rename SKILL.md to NESTED-SKILL.md.
    • Harnesses discover a skill by a file named exactly SKILL.md. Some only look one level deep, in which case nesting alone hides it; others may recurse into subfolders. The rename makes the result the same everywhere.
    • Every file it needs stays in place; its paths stay relative to its own folder.
  2. Add an index to the router's SKILL.md — one line per nested skill: name, description, path.

The router description does the heavy lifting. Progressive disclosure matches on the description, and you've just
replaced 50 specific descriptions with one. If it's vague, the agent won't open it.

❌ frontend: React, Vue, styling (50 skills inside)

✅ frontend: use for any UI work — React/Vue components, forms, state stores,
   styling, component docs, accessibility. Contains team conventions the
   model does not know. 50 skills inside; read the index first.
Enter fullscreen mode Exit fullscreen mode

Two things the good version does: it lists the trigger words a task would contain, and it tells the agent why
it can't skip this
(team conventions it doesn't already know).

What the agent sees on every turn — one entry per area instead of 300:

- git-workflow: commit, branch and PR conventions
- frontend: use for any UI work — components, forms, stores, styling… (50 inside; read the index first)
- backend: use for any API/DB/queue work — endpoints, migrations, workers… (30 inside)
- youtube: uploads, descriptions, thumbnails (20 inside)
Enter fullscreen mode Exit fullscreen mode

The walk for "add a signup form to the settings page":

roster ──▶ frontend/SKILL.md ──▶ references/react-form/NESTED-SKILL.md ──▶ write the form
 (4 lines)    (the index)            (the original instructions)
Enter fullscreen mode Exit fullscreen mode

What it costs:

  • One extra hop: the router's index (one line per nested skill) is read on every task in that area. Fifty lines is cheap; three hundred is not. That's an argument for more routers, not bigger ones — keep each under ~30–40 entries.
  • A task that spans two areas (a frontend change plus its tests) walks two routers. Fine, but it's why cross-cutting skills stay at the top level instead of inside a router.

Automate it:

  • Nobody should rearrange skills by hand.
  • A small script — or a skill-in-skill skill the agent runs itself — can do it on every install or update: move the skill under its router's references/, rename its SKILL.md, rebuild the router's index.
  • Upstream updates stay a copy-and-rename away — no rewriting.

Rules that keep it healthy:

  • Keep cross-cutting skills at the top — git-workflow or code-review apply everywhere.
  • Stay shallow — one router level is usually enough; each level is another step for the agent.
  • Name areas clearly — a "misc" router is just the long list again.
  • Write the router description like a trigger, not a label.

5. The bottom line

  • More skills don't make a better agent.
  • Curate the skills you own.
  • Nest the ones you don't — if they're instruction-only.
  • Keep the list the agent sees short, and make each entry on it specific enough to fire.

References

Top comments (0)