Skills en Claude Code: Enseñando trucos nuevos al perro viejo

| Última modificación: 4 de mayo de 2026 | Tiempo de Lectura: 8 minutos
Premios Blog KeepCoding 2025

Co-Fundador de KeepCoding

El problema de repetir todo

¿Alguna vez has tenido que explicarle lo mismo a alguien veinte veces? Pues imagina eso, pero con un robot que además se queda sin memoria cada pocas horas.

«No, Claude, el commit tiene que pasar los tests primero.» «Claude, ya te dije que uses el formato tipo: descripción.» «¡Que no añadas emojis, coño!»

Esto era mi día a día hasta que descubrí los Skills. Dicho en cristiano: son instrucciones que escribes una vez y Claude sigue para siempre. Como entrenar a un perro, pero sin las croquetas.

Qué son los Skills

Desde la versión 2.1.3, Claude Code fusionó los antiguos slash commands con algo más potente: los Skills. Son archivos Markdown con instrucciones que Claude puede ejecutar de dos formas:

  1. Manualmente: cuando tú escribes /mi-skill
  2. Automáticamente: cuando Claude detecta que debería usarlo

Ese segundo punto es la magia. Ya no tienes que acordarte de invocar el comando. Si tienes un skill que dice «usar cuando el usuario termine una tarea y haya cambios sin commitear», Claude lo hará solo.

Es como tener un mayordomo que sabe cuándo recoger la mesa sin que se lo pidas.

Dónde viven

~/.claude/skills/          # Personales (todos tus proyectos)
.claude/skills/            # Del proyecto (compartidos con el equipo)
~/.claude/commands/        # Legacy, sigue funcionando
.claude/commands/          # Legacy, sigue funcionando

Si quieres que solo tú uses el skill, lo pones en tu home. Si quieres que todo el equipo lo tenga, lo commiteas al repo. Así de simple.

Anatomía de un Skill

Un skill es un archivo Markdown con un frontmatter YAML y luego el contenido:

---
name: mi-skill
description: Breve descripción de qué hace
---

# Instrucciones

Lo que Claude debe hacer cuando se invoque este skill.

Eso es lo mínimo. Pero el frontmatter tiene bastantes más opciones que vale la pena conocer.

Campos obligatorios

name

El identificador del skill. Solo minúsculas, números y guiones (máx. 64 caracteres). Debe coincidir con el nombre del archivo o directorio.

name: check-types      # ✓ válido
name: Check_Types      # ✗ inválido (mayúsculas y guión bajo)

description

Este es el campo más importante. Claude lo usa para dos cosas: 1. Decidir cuándo auto-invocar el skill 2. Entender qué debe hacer

Máximo 1024 caracteres. Incluye palabras clave que el usuario diría naturalmente.

# Mal - demasiado vago
description: Hace cosas con commits

# Bien - específico y con triggers
description: >
  Crea commits git verificando type-check, lint y tests.
  Usar cuando el usuario diga "commit", "commitea", o termine una tarea
  con cambios pendientes.

Campos opcionales

model

Fuerza un modelo específico para este skill. Útil para tareas que requieren más capacidad.

model: opus    # Para auditorías de seguridad, refactoring complejo
model: sonnet  # Balance entre capacidad y coste
model: haiku   # Para tareas simples y rápidas

Si no lo especificas, usa el modelo de la conversación actual.

allowed-tools

Restringe qué herramientas puede usar Claude. Crítico para skills de solo lectura o seguros.

# Solo puede leer, no modificar
allowed-tools:
  - Read
  - Grep
  - Glob

# Solo puede ejecutar comandos específicos
allowed-tools:
  - Bash(git:*)      # Solo comandos git
  - Bash(uv:*)       # Solo comandos uv
  - Read

Ejemplo práctico: un skill de análisis que NO debe tocar nada:

---
name: analyze-deps
description: Analiza dependencias del proyecto sin modificar nada
allowed-tools:
  - Read
  - Grep
  - Bash(uv pip list:*)
---

context: fork

Ejecuta el skill en un sub-agente aislado con su propio contexto. El historial de la conversación principal no se contamina.

context: fork

Útil para operaciones complejas de varios pasos donde no quieres llenar el chat de ruido.

agent

Solo funciona con context: fork. Define qué tipo de agente ejecuta el skill.

context: fork
agent: Explore    # Agente de exploración rápida
agent: Plan       # Agente de planificación

user-invocable

Controla si aparece en el menú de / (slash commands). Por defecto es true.

user-invocable: false  # Oculto del menú, pero Claude puede usarlo

Útil para skills internos que solo deberían activarse automáticamente.

disable-model-invocation

Bloquea que Claude invoque el skill por su cuenta. Solo tú puedes activarlo con /nombre.

disable-model-invocation: true

Útil para operaciones destructivas o costosas que requieren decisión humana explícita.

hooks

Define hooks que se ejecutan durante el ciclo de vida del skill. Soporta PreToolUse, PostToolUse y Stop.

hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "./scripts/validate-input.sh $TOOL_INPUT"
          once: true

Variables de sustitución

Dentro del contenido del skill puedes usar:

Variable Qué contiene
$ARGUMENTS Los argumentos pasados al invocar /skill arg1 arg2
${CLAUDE_SESSION_ID} ID de la sesión actual (útil para logs)

Tabla resumen

Campo Obligatorio Propósito
name Identificador del skill
description Cuándo y para qué usarlo
model Forzar modelo específico
allowed-tools Restringir herramientas
context fork para sub-agente aislado
agent Tipo de agente (con context: fork)
user-invocable Mostrar/ocultar en menú /
disable-model-invocation Bloquear auto-invocación
hooks Hooks del ciclo de vida

Ejemplo completo

---
name: security-audit
description: >
  Auditoría de seguridad OWASP. Usar cuando el usuario pida revisar
  seguridad, buscar vulnerabilidades, o antes de deployar a producción.
model: opus
allowed-tools:
  - Read
  - Grep
  - Glob
user-invocable: true
disable-model-invocation: true  # Solo manual, es costoso
---

# Auditoría de Seguridad

[instrucciones...]

Para la referencia completa, consulta la documentación oficial de Agent Skills.

¿Texto libre o código determinista?

Esta es la pregunta del millón: si los skills son Markdown, ¿significa que Claude siempre «interpreta» lo que escribes? ¿Puedo hacer algo realmente predecible?

La respuesta corta: los skills son tan deterministas como tú los escribas.

Piensa en un espectro:

Vago/Flexible ──────────────────────────► Determinista
"revisa el código"        "ejecuta estos 3 comandos en orden"

Skill flexible (Claude decide)

---
name: review
description: Revisa el código en busca de problemas
---

Analiza el código y sugiere mejoras.

Aquí Claude tiene libertad total. Puede mirar lo que quiera, sugerir lo que le parezca. Útil para exploración, peligroso para procesos críticos.

Skill determinista (script disfrazado)

---
name: check
description: Verificaciones de calidad obligatorias
allowed-tools:
  - Bash
---

Ejecutar **exactamente** estos comandos en orden:

1. `uv run basedpyright src/`
2. `uv run ruff check src/`
3. `uv run pytest -x`

## Reglas

- **NO interpretar** los errores creativamente
- **NO continuar** si alguno falla
- **NO sugerir** fixes automáticamente
- Reportar solo: ✓ pasó / ✗ falló con output

Esto es básicamente un script de 3 líneas. Claude no tiene margen para ser creativo. Ejecuta, reporta, punto.

Skill con lógica condicional

---
name: release
description: Prepara release del proyecto
---

## Paso 1: Verificar rama

```bash
git branch --show-current
  • Si NO es mainABORTAR con «Solo desde main»

Paso 2: Estado limpio

git status --porcelain
  • Si hay output → ABORTAR con «Cambios sin commitear»

Paso 3: Bump + push

uv run bump2version patch
git push && git push --tags

Aquí hay lógica de branches, pero sigue siendo determinista: las condiciones están explícitas.

### Skill que invoca un script real

Si necesitas lógica compleja de verdad (loops, parsing, APIs), pon el código en un script y que el skill solo lo ejecute:

.claude/skills/deploy/ ├── SKILL.md └── deploy.sh


**SKILL.md:**
```markdown
---
name: deploy
description: Despliega a producción
---

Ejecutar:

```bash
bash .claude/skills/deploy/deploy.sh

Reportar el resultado. NO modificar el script.


**deploy.sh:**
```bash
#!/bin/bash
set -e
uv run pytest || exit 1
hugo --minify
rsync -avz public/ user@server:/var/www/

Lo mejor de ambos mundos: la lógica compleja vive en Bash/Python donde pertenece, y el skill es solo el gatillo.

Cuándo usar cada enfoque

Necesidad Enfoque
Comandos fijos, siempre iguales Skill determinista
Lógica compleja con muchos branches Script externo
Análisis que requiere criterio Skill flexible con guardrails
Operaciones peligrosas allowed-tools restrictivo

Ejemplo real: el skill de commit

Este es el que más uso. Antes tenía que recordar: «vale, ejecuta los tests, luego el linter, luego el type-check, y solo entonces commitea». Ahora simplemente digo «commitea» y Claude hace todo solo.

---
name: commit
description: Crea commits git con verificación obligatoria de calidad.
  Ejecuta type-check, lint y tests antes de commitear.
---

# Commit

## Cuándo Usar (Automático)

Aplicar cuando:
- El usuario dice "commit", "commitea", "guarda los cambios"
- El usuario termina una tarea y hay cambios sin commitear

## Prohibido

- Commitear sin ejecutar verificaciones
- Pedir confirmación (simplemente hazlo)
- Añadir Co-Authored-By
- Usar emojis en mensajes de commit

## Proceso

### Fase 1: Detectar cambios

```bash
git diff --name-only HEAD

Fase 2: Verificaciones OBLIGATORIAS

uv run basedpyright src/
uv run ruff check src/
uv run pytest

Si falla alguna, NO continuar.

Fase 3: Crear commit

  1. git add -A
  2. Analizar cambios
  3. Generar mensaje: tipo: descripción
  4. git commit

¿Ves la sección "Cuándo Usar"? Eso es lo que permite la auto-invocación. Claude lee eso y piensa: "ah, el usuario acaba de decir 'ya está', hay cambios pendientes, debería usar este skill".

## Otro ejemplo: archivado de tareas

Si usas un archivo `TASKS.md` para trackear lo que haces (yo lo hacía antes de Beads), este skill te limpia las tareas completadas automáticamente:

```markdown
---
name: archive-tasks
description: Archiva tareas completadas de TASKS.md a TASKS-DONE.md.
  Usar automáticamente cuando TASKS.md tenga muchas tareas completadas
  o supere los 20K tokens.
---

# Archive Tasks

## Cuándo Usar (Automático)

- TASKS.md tiene más de 50 tareas completadas `[x]`
- TASKS.md supera los 20,000 tokens
- El usuario menciona que TASKS.md es muy grande

## Proceso

1. Leer `docs/llm/TASKS.md`
2. Identificar tareas completadas (`[x]`)
3. Mover a `docs/llm/TASKS-DONE.md` con fecha
4. Eliminar de TASKS.md
5. Reportar cuántas fueron archivadas

## Reglas

- **NO eliminar** tareas pendientes `[ ]`
- **PRESERVAR** el contexto (sección padre)
- **AÑADIR** fecha de archivado

Lo bonito es que no tienes que acordarte. Claude ve que TASKS.md está enorme y actúa.

Tips para escribir buenos skills

1. Descripciones específicas

# Mal
description: Hace cosas con commits

# Bien
description: Crea commits git verificando type-check, lint y tests.
  Bloquea si hay errores.

2. Define cuándo aplicar

## Cuándo Usar Este Skill (Automático)

Aplicar automáticamente cuando:
- El usuario dice "commit" o "guarda los cambios"
- Hay cambios staged listos
- El usuario termina una tarea

3. Sé explícito con las prohibiciones

Claude tiende a querer ser educado y pedir confirmación. Si no quieres eso, dilo claramente:

## Prohibido

- Pedir confirmación (JAMÁS)
- Añadir Co-Authored-By
- Usar emojis

4. Usa model: opus para lo importante

Si el skill hace algo crítico (auditoría de seguridad, refactoring complejo), fuerza el modelo más capaz:

---
name: owasp
description: Auditoría de seguridad OWASP
model: opus
---

5. Restringe herramientas si hace falta

A veces quieres un skill que solo lea, sin modificar nada:

---
name: readonly-analysis
description: Analiza código sin modificarlo
allowed-tools:
  - Glob
  - Grep
  - Read
---

Skills simples vs complejos

Un skill simple es un solo archivo:

.claude/skills/review.md

Un skill complejo es un directorio con recursos:

.claude/skills/deploy/
├── SKILL.md                 # Instrucciones
├── templates/
│   └── k8s-deployment.yaml
└── scripts/
    └── healthcheck.sh

Claude puede leer los archivos del directorio como contexto adicional.

Lo que uso yo

Skill Para qué Auto-invocación
commit Commit con verificaciones Cuando digo «commit» o termino algo
check-diagnostics Verificar tipos y lint Antes de commits
owasp Auditoría de seguridad Manual (es costoso)
archive-tasks Limpiar TASKS.md Cuando está muy grande

La diferencia con los commands legacy

Aspecto Skills Commands
Auto-invocación No
Estructura Directorio o archivo Solo archivo
Recomendación Usar para todo nuevo Legacy

Los commands siguen funcionando, pero los skills son estrictamente mejores. Si tienes commands viejos, no hace falta migrarlos, pero para cosas nuevas usa skills.

Conclusión

Los skills son básicamente programación, pero en lenguaje natural. Defines qué quieres que pase, cuándo, y con qué restricciones. Claude hace el resto.

Lo mejor es que se versionan con tu código. Si trabajas en equipo, todos tienen los mismos skills. Si cambias algo, queda en el historial de git.

¿Vale la pena el esfuerzo de escribirlos? Si repites lo mismo más de tres veces, absolutamente. Cada skill que escribes es una conversación que no tendrás que tener nunca más.

Ahora si me disculpas, tengo que ir a enseñarle a Claude que «refactorizar» no significa «reescribir todo desde cero».


TL;DR: Los skills son instrucciones en Markdown que Claude Code ejecuta manual o automáticamente. Pueden ser tan flexibles o deterministas como necesites: desde «analiza esto» hasta scripts disfrazados de prosa. Si necesitas lógica compleja, invoca scripts externos. Viven en .claude/skills/ y se versionan con tu código.


Read this article in English.

Noticias recientes del mundo tech


¡CONVOCATORIA ABIERTA!

Desarrollo de apps móviles ios & Android

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado

Descárgate también el informe de tendencias en el mercado laboral 2026.

Fórmate con planes adaptados a tus objetivos y logra resultados en tiempo récord.
KeepCoding Bootcamps
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.