Command Palette

Search for a command to run...

Why More Than 30 Skills Kill Your AI Agent

🇫🇷FR

Past ~30 skills, an AI agent picks the right tool less and less. The real culprit is not a bloated context but broken routing. Numbers, mechanism, and concrete countermeasures.

11 min read
claude-codeagentsskillstool-callingcontext-engineeringanthropic
Pass-rate curve of an AI agent dropping as the number of skills grows: -8 at 52 skills, -14 at 102, -21 at 202

The more skills an agent has, the better it should work. That is the intuition. It is wrong. Past thirty or so skills or tools, adding one more capability often degrades the agent instead of improving it. And the problem is not the one you would expect: it is not the context bloating up, it is the routing breaking down.

I have about fifty skills installed in my Claude Code setup. This article explains why that is already in the red zone, what the measurements say, and how to take back control.

The paradox, measured

A 2026 study, More Skills, Worse Agents?, ran the experiment cleanly: start from a set of skills that are useful for the task (the oracle), then drown the agent under an ever-larger library, and measure the pass rate.

Library sizePass-rate points lost
Useful skills only (baseline)0
52 skills-8
102 skills-14
202 skills-21

The drop is monotonic and it is not marginal: 21 pass-rate points between a well-equipped agent and the same agent drowned under 202 skills, averaged across two models. The know-how is identical, the necessary tools are still there. Only the noise changed.

An even worse signal: the fraction of runs where the agent invokes no skill at all and does the work by hand rises from 12% (useful skill set) to 38.5% (202 skills). The agent does not just pick the wrong skill, it eventually gives up looking for one.

The three ways one skill too many degrades the agent

1. Context overheadthe prompt is heavierinference gets worse~1/3of the dropstatistically negligible2. Shadowingan irrelevant skillmasks the right one68%of the dropscales with size3. Abandonmentthe agent invokesno skill at all12 -> 38%of runsinvisible in the logs

Context overhead. Each skill adds its name and description to the startup prompt. At 200 skills, that is real volume, and a longer prompt degrades inference. Real effect but small: about one third of the drop, and statistically indistinguishable from zero in the study. It is the obvious suspect, and it is the wrong one.

Shadowing. This is the real culprit. When two skills have similar descriptions, the wrong one can “mask” the right one because its description happens to match the query slightly better. The agent chooses confidently, and it chooses wrong. This effect dominates: up to 68% of the degradation, and the only statistically significant effect. Crucially, it grows linearly with library size. The more look-alike skills you add, the more chances to be wrong you manufacture.

Abandonment. The endgame of shadowing: the agent, unable to decide, picks nothing and does the work with no skill. A third of runs at 202 skills. This is the most insidious one because it is invisible: in the logs, “no skill invoked” looks like a case where no skill was relevant, not like a routing failure.

The real problem: the router sees 8% of the signal

Why does routing get it so wrong? Because the decision is made on the wrong information.

Claude Code loads skills in three levels, a mechanism called progressive disclosure:

Level 1 - startupname + description~100 tokens / skillthe router decides here8.3% of signalLevel 2 - after choiceskill body< 5000 tokensthe useful signal is here91.7% of signalLevel 3bundledreferenceson demand

The router only sees level 1, the name and the description, to decide which skill to load. Yet the SkillRouter paper measured, through attention analysis on a cross-encoder, that 91.7% of the routing signal lives in the skill body, the level 2 content. The name and description, the very things the decision is made on, carry only a fraction of the signal.

The proof is in the ablation: removing the body drops routing quality by 29 to 44 points depending on the method. Distilling the body into better descriptions recovers part of the signal, but never all of it. You are asking the router to pick among 200 candidates with 8% of the relevant information. Shadowing is not a bug, it is the mathematical consequence of this design.

The same paper shows that a retrieve-and-rerank pipeline reading the full body reaches 74% Hit@1 on a library of ~80,000 skills, with a model 13 times smaller than the naive alternative. The signal exists. You just have to look at it.

Claude Code’s silent truncation

There is a second trap, specific to Claude Code. Skill descriptions go through a character budget, calibrated at around 1% of the context window. When that budget overflows, Claude Code truncates.

The consequences are nasty:

  • Truncation cuts the end of the description, often where the trigger keywords live. A skill that matched “open a merge request” no longer matches anything if the sentence is cut before it.
  • The least-invoked skills are truncated first. Your rare skills become unreachable, which makes them even rarer.
  • Installing skill N+1 can break the routing of skill N. Nothing in skill N changed, but it lost room in the shared budget.

In other words, each added skill is not neutral for the others. You do not only pay context overhead, you redistribute a finite budget between descriptions fighting for the same space. And a public study notes that 26.4% of public skills have no usable routing description at all, which guarantees shadowing from the start.

What operators at scale are doing

The industry’s answer converges: stop exposing everything at once, and route intelligently.

PlayerActionResult
GitHub Copilot (Nov. 2025)40 default tools cut to 13, the rest in virtual groups loaded on demand+2 to +5 success points, -400 ms latency
Anthropic (Nov. 2025)Tool Search Tool: Claude discovers tools dynamically instead of loading everythingOpus 4.5: tool-use accuracy from 79.5 to 88.1

GitHub documented how reducing the default toolset improved SWE-bench and SWE-Lancer on GPT-5 and Sonnet 4.5 alike. Their conclusion fits in one sentence: giving an agent more tools does not make it smarter, just slower.

Anthropic goes the same way with the Tool Search Tool: instead of loading all 200 tool definitions into the context, Claude fetches the relevant one on demand. It is the same principle as the MCP RTK proxy I wrote about here: do not pay in tokens and confusion for what you do not use.

Concrete countermeasures

ApproachEffortEvidence
Reduce the number of active skillsLowGitHub: -27 tools = +2 to +5 points
Move to on-demand (search-based) routingMediumAnthropic: +8.6 points on Opus 4.5
Route on the full body (encoder + re-ranker)HighSkillRouter: 74% top-1 on 80k skills

In practice, in my Claude Code config, three actions give the best effort-to-payoff ratio:

Audit the descriptions. Check that no critical skill has its description truncated, and that trigger keywords are at the start, not the end. A description that opens with its triggers survives truncation.

Consolidate skills with close triggers. I had qa-swarm variants per project (one per repo), with nearly identical descriptions. That is a textbook shadowing case: four skills fighting over the same query. Merging them into one parameterized skill removes four chances to misroute. It is exactly the work I described in my article on effective skills: a description must say when to fire, not just what the skill does.

Measure, do not guess. Compare the correct-match rate with the full set against a set reduced to the 15 most-used skills. If the reduced set routes better, you have your answer: half your skills cost more than they return.

The threshold, in practice

Degradation becomes measurable past ~30-50 skills. Below that, shadowing exists but stays absorbed by the model’s margin. Above it, each addition is paid twice: once in tokens, once in chances to misroute.

The rule I apply now: a skill enters my config only if its description can trigger nothing but itself. If I can imagine a query where it would compete with an existing skill, I either merge or rewrite both descriptions to make them disjoint. One more skill is never free. It is a bet on the router, and the router sees only 8% of the picture.