Skill injection is O(n) per tool call — unusable at 100+ skills

Resolved 💬 3 comments Opened Feb 25, 2026 by grahama1970 Closed Mar 1, 2026

Problem

Every tool call response injects the full skill catalog as <system-reminder> blocks. With 160+ skills, this adds ~25K tokens to every single tool response. This is not a theoretical concern — it makes Claude Code unusable for power users with large skill libraries.

Impact

  • Token waste: ~25K tokens × ~50 tool calls per session = ~1.25M wasted tokens per session
  • Context pressure: Fills the context window with repeated skill descriptions instead of actual work
  • Latency: Every tool response is larger than it needs to be
  • Cost: Users on metered plans pay for tokens that provide zero value after the first injection

Reproduction

  1. Create 100+ skills in .claude/skills/ (each with a SKILL.md containing frontmatter)
  2. Start a conversation and use any tool (Read, Bash, Grep, etc.)
  3. Observe the full skill catalog injected into every tool response as <system-reminder> blocks

Current Workaround

Replace the skills directory symlink with a curated directory containing symlinks to only ~25 essential skills. This drops injection from 160+ to 25 skills. All skills remain accessible by path — they just aren't auto-injected.

Suggested Fixes (any one would help)

  1. Inject once, not per-tool-call: Load the skill catalog into the system prompt once at conversation start. Don't re-inject on every tool response.
  2. Lazy loading: Only inject skill descriptions when a trigger phrase is matched, not preemptively.
  3. Token budget cap: Allow users to set a max token budget for skill injection (e.g., skill_injection_budget: 5000 in settings).
  4. LRU / relevance filtering: Only inject the N most relevant skills based on conversation context.
  5. User config: Let users mark skills as auto-inject: false in frontmatter to exclude them from the catalog while keeping them invocable.
  6. Tiered injection: Inject skill names + triggers only (compact), and load full descriptions on-demand when a skill is actually invoked.

Environment

  • Claude Code CLI
  • 160+ skills across 7 domains (security, extraction, creative, ops, ML, compliance, persona)
  • Skills are composable — they reference each other via composes: frontmatter
  • This is a real production engineering platform, not a toy setup

Context

The skill system is a great idea — composable, specialized capabilities with trigger-based routing. The injection strategy just doesn't scale. A simple fix (inject once at session start, or lazy-load on trigger match) would make this work perfectly at any scale.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗