Start with the constraint that shapes everything else. At startup an agent loads only the name and description from each skill's frontmatter, which the documentation estimates at about 100 tokens per skill, and reads the full SKILL.md body only when a task matches that description (the Agent Skills overview). VS Code's documentation describes the same behavior from the client side: skills are loaded on demand, so "only relevant content loads into context when needed" (VS Code agent skills docs).
That design is usually called progressive disclosure, and it is a context-window decision, not a routing decision. The specification allows a description of up to 1,024 characters, so a description is both the entire advertisement for a skill and the only thing the selector has to work with (the same guide). The authoring guidance is blunt about the consequence: "the description carries the entire burden of triggering" (Agent Skills description guide).
A worked token budget makes the trade-off concrete. With 40 installed skills at roughly 100 tokens of metadata each, the agent spends about 4,000 tokens before the first user turn on names and descriptions alone. That is affordable. At 400 skills it is about 40,000 tokens, and at that point you are paying for the catalog on every request whether it helps or not. The practical rule: metadata cost scales linearly with catalog size, so every description you add is a recurring cost, while every description you cut can silently disable a capability.
There is a second asymmetry that matters more for routing. In production stacks, the component that picks the shortlist can often inspect full skill text, while the agent that finally uses the skill usually sees only name and description. Once the wrong shortlist is surfaced, "downstream planning and execution have little chance to recover" (SkillRouter paper). That sentence should reframe how you debug: a failed task may be a retrieval failure, not a reasoning failure.



