Adrienne Vermorel
Claude Code - Skills vs. Commands
Claude Code Skills vs. Commands: When to Use Each for Data Work
You’ve set up a skill for your dbt project conventions. You expect Claude to use it automatically when you ask it to create a base model. It doesn’t. You end up typing “and use the skill” at the end of every prompt. After a few days of this, you wonder: what’s the point?
This confusion is common, and it comes from how skills are marketed versus how they actually behave.
They’re both markdown files, but they work in opposite directions
Commands are straightforward. You type /audit-model, Claude runs it. You’re in control of when it happens.
Skills work differently. Claude reads each skill’s description at startup and is supposed to decide when to apply them based on your request. The idea is that you describe your dbt conventions once, and Claude automatically follows them whenever relevant. Elegant in theory.
In practice, community testing shows skills activate automatically only about 20% of the time. One practitioner summed it up: “I have to always say ‘update process notes and use your skill.’ This is too verbose for me. So I simply created a slash command.” That’s been my experience too. You set up a skill expecting magic, then end up prompting it explicitly anyway, which defeats the purpose.
The issue is keyword matching. Claude loads each skill’s name and description from the YAML frontmatter and checks for matches when you make a request. If your description doesn’t include the right trigger words, or if you phrase things differently than expected, the skill sits there unused.
For data work, this matters more than it might seem
When I’m running a dbt audit or generating lineage documentation, I want the same checks every time. Consistency isn’t optional—it’s the whole point. A workflow that works 20% of the time isn’t a workflow, it’s a gamble.
That’s why I’ve shifted toward commands for anything I do repeatedly. A /audit-model command that checks documentation coverage, test presence, and naming compliance. A /document-lineage command that generates Mermaid diagrams. A /pre-commit command for the standard validation sequence before I push changes.
These run the same way every time because I’m explicitly triggering them. No hoping Claude decides to apply the right context.
Skills still have a place, but it’s narrower than the marketing suggests. They work better for domain knowledge that should inform Claude’s work across different tasks—warehouse-specific quirks, team conventions, reference documentation you want available but don’t need invoked explicitly. The kind of background context that shapes how Claude approaches problems rather than specific workflows you want to trigger.
What this looks like in practice
Here’s a command for model audits. It lives in .claude/commands/audit-model.md:
---allowed-tools: Bash(dbt:*), Bash(cat:*), Bash(grep:*)description: Audit a dbt model for documentation and test coverage---
Audit the model at $ARGUMENTS:
1. Check schema.yml exists and has descriptions for model and columns2. Verify unique + not_null tests on primary key3. Check naming follows our convention (base__, int__, mrt__)4. List any undocumented columns5. Show the model's direct upstream dependencies
Output a summary with pass/fail for each check.I run it with /audit-model models/marts/mrt__daily_revenue.sql and can get consistent results every time.
Compare that to a skill approach. You could create a skill with all your audit criteria, hoping Claude applies it when you say “check this model.” Sometimes it will. Often it won’t. And when it doesn’t, you’re back to typing out what you wanted anyway.
For something like lineage documentation, I actually use both. The skill bundles my Mermaid templates and conventions for generating diagrams. The command gives me a reliable trigger when I specifically want lineage docs. The skill’s presence means Claude might pick it up automatically in other contexts; the command ensures I can force it when that fails.
If you do rely on skills, description engineering helps. The pattern that works best includes explicit trigger words and exclusions:
description: Generate data lineage documentation and Mermaid diagrams. Use when user asks about lineage, dependencies, upstream models, or documentation for model relationships. Do NOT use for general dbt questions unrelated to lineage.Specific beats generic. “Lineage” and “dependencies” work better than “documentation utilities.”
Where I’ve landed
My setup now is pretty simple. Commands handle any workflow I run more than a couple of times. Skills hold reference knowledge that informs multiple commands. And CLAUDE.md captures project-wide context that applies to everything—naming conventions, SQL style, warehouse-specific patterns.
The fancier feature isn’t always the better one. For data work, I’ll take predictable over automatic.
This is part of my series on Claude Code for analytics engineering. If you’re just getting started, Claude Code for Data People covers what it actually is, and How I Use Claude Code for dbt Development walks through the workflows that have stuck.