Cuándo usar skills en Claude Code: el mapa completo
Skills, hooks, CLAUDE.md: el mapa completo de las 8 herramientas de Claude Code y cuándo usar cada una. Guía práctica para quienes empiezan.
Colaboradores: Ivan Garcia Villar
LLevas semanas creando skills para todo.
Una para hacer code review, otra para seguir la arquitectura DDD del proyecto, otra para que Claude pase los tests antes de hacer commit.
Hasta que Claude hace el commit sin pasar los tests y te preguntas ¿Por qué no me hace caso?.
¿Qué salió mal?: Que usé una skill para algo que necesitaba un hook.
Las skills son probabilísticas: Claude lee su descripción y decide si activarlas según el contexto de la conversación. A veces se equivoca, o simplemente no conecta las piezas. Los hooks son deterministas: se ejecutan siempre que ocurre el evento que configuraste, sin que Claude “decida” nada.
Hasta que no entiendas esa diferencia, tu configuración de Claude Code es una ruleta rusa.
¿Por qué todo el mundo usa skills pero nadie habla de hooks?
En LinkedIn, la semana en que aparecieron las skills, todo el mundo publicaba sus “setups de productividad” con veinte skills para cada cosa imaginable. Compartir una skill es fácil: copias el archivo, lo pegas en un hilo, consigues likes.
Los hooks son archivos JSON y scripts bash. No quedan bien en un screenshot.
Antes, todo iba en CLAUDE.md. Cuando alguien publicó que un CLAUDE.md de 500 líneas “destruye el contexto”, todo el mundo empezó a meter todo en skills. Sin pasar por hooks. Sin explorar subagentes. Sin preguntarse cuándo tiene sentido cada herramienta.
Este post es el mapa que falta en esa conversación.
El mapa completo: 8 herramientas de Claude Code
| Herramienta | ¿Cuándo carga? | ¿Determinista? | Coste de tokens |
|---|---|---|---|
| CLAUDE.md | Inicio de sesión, siempre | No (el modelo interpreta) | Alto (cada request) |
| .claude/rules/ | Al abrir archivos con match | No | Bajo |
| Skills | Descripciones al inicio + contenido al invocar | No, probabilístico | Bajo hasta invocar |
| Hooks | Solo al ocurrir el evento | Sí, siempre | Cero |
| MCP | Inicio de sesión, siempre | No | Alto (carga esquemas) |
| Subagentes | Bajo demanda | No | Aislado del contexto principal |
| Agent Teams | Bajo demanda | No | Alto (instancias separadas) |
| Plugins | Al instalar | Depende del contenido | Variable |
Y la estructura de directorios donde vive cada cosa:
.claude/
├── settings.json ← configuración de hooks y permisos del proyecto
├── rules/ ← reglas condicionales por tipo de archivo
├── agents/ ← subagentes (un archivo .md por agente)
└── skills/ ← skills locales de este proyecto
└── pr-review/
└── SKILL.md ← cada skill es una carpeta con su SKILL.md
~/.claude/
└── skills/ ← skills globales (disponibles en todos tus proyectos)
MCP merece un post aparte, hoy no hablaremos mucho de esto, peroo si quieres aprender más te dejo este post: Qué es MCP: el protocolo que conecta agentes IA con herramientas.
El árbol de decisión: ¿qué herramienta debo usar?
Cada vez que vayas a configurar algo nuevo en Claude Code, hazte esta pregunta: ¿necesita que ocurra el 100% de las veces, sin que Claude decida?
Si la respuesta es sí, es un hook. Si es contexto permanente, es CLAUDE.md. Si es un flujo que invocas cuando lo necesitas, es una skill. Aquí está el árbol completo:
Un concepto nuevo cada semana
La diferencia que importa: probabilístico vs determinístico
Imagina que le das a un compañero la instrucción “siempre pasa los tests antes de hacer un commit”. Ese compañero puede olvidarse. Puede interpretar que en este caso concreto no aplica. Puede estar distraído. Eso es probabilístico: depende de que alguien lo recuerde y decida hacerlo.
Ahora imagina que configuras el sistema de control de versiones para que bloquee cualquier commit si los tests no han pasado. Sin excepciones. Sin interpretación. Sin “bueno, esta vez…” Eso es determinístico.
Las skills funcionan como el compañero humano. Claude lee la descripción de la skill al inicio de la sesión y decide si activarla según el contexto de la conversación. Si estás hablando de archivos CSS y tienes una skill de “pasar tests antes del commit”, Claude puede no conectar las dos cosas. En proyectos donde he monitoreado activaciones, una skill con descripción bien escrita puede no disparar cuando la conversación llega por un ángulo inesperado.
Los hooks no interpretan nada. Cuando Claude intenta ejecutar un commit, el hook pre-commit corre. Punto.
La diferencia no es de calidad de instrucción: es arquitectural.
Las 3 herramientas esenciales en detalle
CLAUDE.md: el manual de empleado
CLAUDE.md es el archivo que Claude lee al inicio de cada sesión. Piénsalo como el manual de bienvenida que le das a alguien nuevo en el equipo: convenciones del proyecto, stack tecnológico, restricciones importantes.
Qué va aquí: convenciones de arquitectura, el stack, comandos de build y test, restricciones permanentes del proyecto.
Qué no va aquí: workflows paso a paso, documentación de referencia larga, instrucciones que solo aplican en situaciones específicas. Eso va en skills o en rules.
Los tokens que ocupa CLAUDE.md se restan del espacio disponible para el código y la conversación en cada sesión. Además, los modelos de lenguaje tienen dificultad con instrucciones enterradas en textos muy largos: tienden a seguir lo que aparece al principio y al final, e ignorar lo del medio. Un CLAUDE.md de 500 líneas puede hacer que Claude siga las primeras instrucciones y olvide el resto sin que tú lo notes [3].
Aquí tienes un ejemplo bien estructurado:
# Proyecto: API de facturación
## Stack
- TypeScript + Node.js 20
- PostgreSQL 16 (sin ORMs, queries directas con pg)
- pnpm como gestor de paquetes
## Arquitectura
- DDD: domain/, application/, infrastructure/
- Un caso de uso por archivo en application/
- Nunca lógica de negocio en infrastructure/
## Comandos
- Tests: pnpm test
- Build: pnpm build
- Lint: pnpm lint
## Restricciones permanentes
- No modifiques src/legacy/ bajo ningún concepto
- Los tests van en __tests__/ junto al módulo que testean
Para profundizar en cómo evitar el anti-patrón del CLAUDE.md inflado, el post AGENTS.md: La configuración que puede arruinar tu agente entra en mucho más detalle sobre qué pasa cuando el archivo crece sin control.
Skills: las macros de tu flujo de trabajo
Una skill vive en su propia carpeta dentro de .claude/skills/ del proyecto, o en ~/.claude/skills/ si quieres que esté disponible en todos tus proyectos. Dentro de esa carpeta hay un archivo SKILL.md con el contenido y el frontmatter (las líneas de configuración entre --- al inicio del archivo).
La pieza más importante del frontmatter es la descripción. Es lo que Claude usa para decidir si activa la skill automáticamente. Si es vaga, Claude no la conecta con tu intención:
# ❌ Esta descripción casi nunca dispara
---
name: analizar-ventas
description: Helps with data tasks
---
# ✅ Esta sí dispara cuando tiene sentido
---
name: analizar-ventas
description: >
Analiza archivos CSV de ventas cuando el usuario menciona datos de revenue,
márgenes, churn o KPIs de negocio. Invoca con /analizar-ventas para control
manual, o espera que Claude lo active automáticamente en contexto de análisis.
---
El campo disable-model-invocation: true le dice a Claude que nunca intente activar la skill por su cuenta. Solo se ejecuta cuando tú escribes /analizar-ventas. Útil para deploys u otras acciones que no quieres que Claude active por error.
Cuándo usar skills: flujos de trabajo repetibles que invocas cuando los necesitas (/deploy, /pr-review, /changelog). Cuándo no: para comportamiento que debe ocurrir el 100% de las veces. Para eso existe el hook.
Las skills también pueden tener scripts ejecutables que le permiten tener un comportamiento más determinista, pero eso no implica que el hecho de cargar la skill adecuada en el momento adecuado de forma automática por claude funcione siempre.
Hooks: los guardias de seguridad
Un hook es un script externo que corre automáticamente cuando ocurre un evento en Claude Code. Se configuran en .claude/settings.json y no consumen tokens porque se ejecutan completamente fuera del loop del modelo.
Claude Code dispara hooks en distintos momentos del ciclo. Los cuatro más relevantes para empezar:
-
PreToolUse: antes de que Claude use una herramienta (ideal para bloquear acciones) -
PostToolUse: después de que Claude usa una herramienta (ideal para validaciones) -
Notification: cuando Claude necesita tu atención o esperando permiso -
Stop: cuando Claude termina de responder
Veamos cómo configurar el hook de ESLint (ESLint es una herramienta que revisa errores y estilo en tu código JavaScript o TypeScript). Primero, la entrada en .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/eslint-check.sh"
}
]
}
]
}
}
Y el script que ejecuta. Nota que los hooks reciben la información del evento como JSON por la entrada estándar (stdin), y usamos jq (una herramienta para leer JSON desde la terminal) para extraer la ruta del archivo:
#!/bin/bash
# .claude/hooks/eslint-check.sh
# Leer el JSON que Claude Code envía por stdin (entrada estándar)
INPUT=$(cat)
# Extraer la ruta del archivo que Claude acaba de editar
# jq -r lee el campo file_path del JSON recibido
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# Solo ejecutar ESLint en archivos JavaScript o TypeScript
if [[ "$FILE" == *.js || "$FILE" == *.ts || "$FILE" == *.tsx ]]; then
npx eslint "$FILE"
# Si ESLint falla, Claude Code ve el error y puede corregirlo
fi
El hook para bloquear rm -rf funciona de forma similar pero con PreToolUse. La configuración en .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/block-dangerous.sh"
}
]
}
]
}
}
El bloqueo se comunica con el código de salida del script: exit 2 cancela la acción y Claude recibe el mensaje de error como retroalimentación:
#!/bin/bash
# .claude/hooks/block-dangerous.sh
INPUT=$(cat)
# Extraer el comando que Claude quiere ejecutar
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
# Si el comando contiene rm -rf, bloquearlo
if echo "$COMMAND" | grep -q "rm -rf"; then
# >&2 envía el mensaje al canal de error (stderr)
echo "Bloqueado: rm -rf no está permitido en este proyecto" >&2
# exit 2 cancela la acción; Claude ve el mensaje y ajusta su enfoque
exit 2
fi
# exit 0 permite que el comando se ejecute con normalidad
exit 0
Para un deep-dive completo en hooks con más patrones, el post Claude Code Hooks: calidad determinista para garantizar proyectos mantenibles tiene todos los detalles.
Un ejemplo real combinado
Aquí está cómo quedaría la configuración para un equipo de backend con TypeScript y PostgreSQL. Cada herramienta hace una cosa:
CLAUDE.md (~100 líneas): stack tecnológico, convenciones DDD, estructura de carpetas, “usa pnpm”, nombres de test en inglés. Nada más.
Hooks: ESLint tras cada edición de archivo .ts; tests antes de commit (si alguno falla, el commit no ocurre); bloqueo de rm -rf y otros comandos destructivos.
Skills: /pr-review con el checklist de revisión del equipo; /deploy con los pasos del pipeline de despliegue; /changelog que genera la entrada de changelog en el formato del equipo.
MCP (avanzado): servidor PostgreSQL para que Claude pueda consultar el schema de la base de datos en producción cuando lo necesite. Ver el post sobre MCP.
Fíjate en el reparto: las convenciones permanentes van en CLAUDE.md. Lo que debe ocurrir siempre va en hooks. Lo que invocas cuando lo necesitas va en skills. No se solapan.
Errores comunes
El CLAUDE.md de 1000 líneas
Cada línea de CLAUDE.md consume parte de los tokens disponibles en cada sesión. Cuando el archivo supera un cierto tamaño, Claude empieza a ignorar instrucciones. No porque sean malas, sino porque los modelos de lenguaje tienen dificultad con textos muy largos: prestan atención al principio y al final, e ignoran el medio [3]. La señal de alarma es cuando Claude empieza a “olvidar” convenciones que ya le has dado, o cuando te pide información que ya está en el archivo.
Solución: bajo 200 - 300 líneas. Documentación de referencia o workflows específicos van a skills o a .claude/rules/.
La skill para comportamiento permanente
“Siempre usa DDD”. “Siempre pasa los tests antes del commit”. Si metes esto en una skill, estás apostando a que Claude conecte la skill con cada acción relevante. Las probabilidades no son del 100%, y eso significa que antes o después Claude hará el commit sin tests. Las convenciones permanentes van en CLAUDE.md. Las acciones garantizadas van en hooks.
La skill con descripción vaga
"Helps with data tasks" no dispara. Claude no puede saber qué significa “tasks” en este contexto ni cuándo debería activar esta skill. Una buena descripción nombra situaciones concretas, palabras clave específicas y el comando manual como alternativa. Si tu skill lleva semanas instalada y nunca la ves activarse, la descripción es el primer lugar donde mirar.
Skills de terceros copiadas sin revisar
El ecosistema público tiene skills de calidad muy variable. Algunas añaden tokens innecesarios. Otras incluyen instrucciones que hacen que Claude ejecute cosas que tú no pediste. Eso se llama prompt injection: instrucciones ocultas en el contenido de la skill que redirigen el comportamiento del modelo. Antes de instalar una skill de terceros, revisa que no incluya instrucciones maliciosas cultas en el contenido, que no pida acceso a archivos fuera del proyecto, y que no use URLs externas sin que tú lo hayas pedido.
Checklist de implementación
-
CLAUDE.md tiene menos de 300 líneas y contiene solo convenciones permanentes y stack
-
Las acciones que deben ocurrir el 100% de las veces están en hooks, no en skills
-
Cada skill tiene una descripción con situaciones concretas y palabras clave específicas
-
Las skills sensibles (deploy, borrado de datos) usan
disable-model-invocation: true -
Los scripts de hooks son ejecutables (
chmod +x .claude/hooks/tu-script.sh) -
Las skills de terceros pasan una revisión siempre
Fuentes
- Hooks Guide: Claude Code Docs: formato oficial de configuración de hooks en
.claude/settings.json, eventos de ciclo de vida, entrada por stdin y códigos de salida. - Skills: Claude Code Docs: frontmatter de SKILL.md, campo
disable-model-invocation, cómo funciona la activación automática. - Best Practices: Claude Code Docs: recomendación oficial de mantener CLAUDE.md por debajo de un tamaño manejable.