DEV Community

Hamid Shoja
Hamid Shoja

Posted on

Coding agents: Your skill bodies are fine, your descriptions are broken

Hi friends

This is a follow-up to my post about structuring CLAUDE.md, skills and agents. A comment on that post pointed at a failure layer I had completely skipped, and it deserves its own write-up: your skill bodies can be perfect and the agent still never reads them.

The invisible bottleneck

Skills load lazily, that's the whole point. Until one triggers, the only thing the model can see is the one-line description in the frontmatter. Which means routing accuracy is bounded by how well a single sentence discriminates between neighboring skills.

You can audit every body, verify every code example against the codebase, run retrieval tests on the content... and none of it matters if the model picks the wrong skill, or no skill, or decides the sentence already told it everything it needs.

Two failure modes to check for.

Failure 1: the description that replaces the skill

# BAD - the description IS a procedure
description: Verifies finished work by running tests, checking the diff
  for weakened assertions, and reporting pass/fail
Enter fullscreen mode Exit fullscreen mode

The model reads that sentence, feels it already knows the procedure, and executes a shallow version from memory: run tests, glance at diff, report. It never opens the body, where the actual teeth live ("diff each changed assertion against the base branch; a widened tolerance counts as failure").

The skill "fired", but the one check that mattered didn't happen. And it looks like success in your logs.

# GOOD - trigger only, zero procedure
description: Use when a refactor or bugfix is complete and you are about
  to report it as done. NOT for doc-only changes.
Enter fullscreen mode Exit fullscreen mode

Now the sentence contains nothing executable, so the model has to read the body to know what to do. The description's only job is routing.

Failure 2: skills that shadow each other

# skill A
description: Testing best practices for this repo
# skill B
description: Testing best practices - integration harness, DB fixtures, fake upstreams
Enter fullscreen mode Exit fullscreen mode

Both start with the same phrase. Every testing task matches A first, and the deeper B never loads. Here's the trap: rewriting the bodies changes nothing, the model never gets past the sentence. You can polish skill B forever and it stays invisible.

Fix it at the description level, with discriminating triggers:

# skill A
description: Use when writing or fixing unit tests for components or pure
  functions. NOT for endpoint or database tests.
# skill B
description: Use when testing HTTP endpoints against a real database or
  faked upstream services (integration tests).
Enter fullscreen mode Exit fullscreen mode

Test descriptions like you test docs

In the previous post I ran retrieval tests against doc bodies: give a subagent only the docs, no repo access, make it answer implementation questions, grade against the codebase. The extension: run a second version against the descriptions alone.

Give a subagent just the list of skill descriptions, nothing else, and feed it real task prompts:

"Write an integration test for the orders endpoint."
"A refactor is done, wrap it up."
"Fix this flaky unit test."
Enter fullscreen mode Exit fullscreen mode

Ask one question: which skill would you load, and why? Grade the routing. If the wrong skill wins, or none triggers, or the model says "no need to load anything, the description tells me what to do" - your descriptions failed the test. Fix the sentences, not the bodies.

The rule of thumb

The description answers "should I load this skill right now?", never "what will it do once loaded?"

If you can execute the description, it's carrying content that belongs in the body. A quick checklist for each skill:

  • starts with "Use when ..." (a trigger, not a capability)
  • says what it's NOT for, if a neighboring skill is close
  • contains no procedure verbs (run, check, verify, generate)
  • no two skills in the folder could match the same task prompt

One sentence of frontmatter is doing the routing for everything underneath it. Test it like it matters, because it does.

Hope that helped!
Hash

Top comments (1)

Collapse
 
topstar_ai profile image
Luis Cruz

I particularly appreciated the distinction between a description that replaces the skill and one that serves as a trigger, as seen in the examples of "BAD" and "GOOD" descriptions. The idea that a description should answer "should I load this skill right now?" and not "what will it do once loaded?" is a crucial one, as it highlights the importance of separating the routing logic from the actual skill implementation. The suggestion to test descriptions like we test docs, by running retrieval tests against the descriptions alone, is also a valuable insight - have you found any specific challenges or trade-offs when implementing this approach in your own projects, particularly in terms of balancing description brevity with routing accuracy?