AIDive

Deja de repetir prompts en Claude Code: 4 tareas, 4 archivos

Por AIDive · Publicado el

Agentes de programaciónAutomatización y workflows

Cuatro prompts que reescribes pasan a ser cuatro archivos

Las extensiones de Claude Code son los archivos que un repo puede contener para que dejes de reescribir el mismo prompt: un skill, un hook, un subagent y un servidor MCP. Ejecutamos cuatro tareas recurrentes en un repo real, una pequeña API de facturación con un archivo JSON como base de datos. A cada tarea le dimos primero la extensión equivocada, y la elección equivocada falló en pantalla todas las veces. Después, cada una se convirtió en un archivo con commit. Esta página cubre los cuatro gestos y la tarjeta de decisión que dice qué tipo usar.

Dos resultados enmarcan todo lo que sigue. Se suele describir un hook como una garantía y una regla del archivo de memoria como una petición, y sin embargo nuestro primer hook se ejecutó, imprimió su aviso y la escritura pasó igualmente. Lo que convierte un hook que se ejecuta en un hook que bloquea se explica en la sección del hook. El primer servidor de docs que conectamos no cambió nada, y el que respondió fue el servidor de docs de la propia herramienta. La receta de hook que la mayoría copia además necesita un archivo de script aparte, pero la nuestra cabe entera en el archivo de ajustes.

Antes de escribir cualquiera de los cuatro archivos, necesitas saber qué carga ya tu sesión.

Qué son los cuatro y qué carga ya tu sesión

Una extensión de Claude Code es un archivo que añades a tu repo para dejar de reescribir las mismas instrucciones en la caja del prompt. Existen cuatro tipos, y los lectores que ya los conocen pueden saltar a la siguiente sección.

  • Un skill es un runbook archivado en tu repo. Claude carga sus pasos solo cuando surge esa tarea, y puedes iniciarlo escribiendo su nombre.
  • Un hook es como un hook de commit en git, pero para las acciones del propio Claude. Es un script que se ejecuta ante un evento, como una edición, sea cual sea la intención de Claude.
  • Un subagent es un contratista con el escritorio vacío. Recibe tu encargo, hace la lectura y te devuelve un informe en lugar del montón de archivos.
  • Un servidor MCP es un cliente de API al que Claude puede llamar, para datos que no están en tu disco, como una base de datos o la documentación de una herramienta.

Para medir cualquier cosa, primero necesitas una referencia. Abre una sesión nueva y ejecuta el comando de contexto. Imprime una tabla con todo lo que se carga antes de tu primera palabra. En nuestro banco de pruebas, el total fue de 26,2k tokens sobre una ventana de 1m, sin línea de archivos de memoria ni línea de MCP. Cada tarea que le des a Claude a partir de ahora añade una línea a esa tabla o la deja igual.

La primera tarea: la checklist de release pasa a ser un skill

Un skill es una checklist archivada en su propia carpeta que Claude solo lee cuando lo llamas. La primera tarea es una checklist de release que no paras de pegar en la caja del prompt: typecheck, tests, subir la versión, una línea de changelog, commit y tag.

El lugar obvio para ponerla es el archivo de memoria, y es la elección equivocada, porque todo lo que contiene se carga en cada turno de cada sesión. Pusimos los pasos ahí y volvimos a leer la tabla de contexto. Había ganado una línea Memory files de 210 tokens, cargada estés o no haciendo un release. La doc lo dice así: cuando una sección de ese archivo se ha convertido en un procedimiento, su sitio es un skill.

La elección correcta es una carpeta dentro del directorio de skills, con los pasos en .claude/skills/release/SKILL.md, una descripción corta arriba y una línea más de frontmatter, disable-model-invocation: true. Esa línea saca el skill de la lista de Claude, así que solo tú puedes iniciarlo, que es lo que quieres para algo que hace commit y tag. Después escribes una barra y su nombre, y la checklist se ejecuta.

Lectura del contexto Total Línea Memory files
Referencia, sesión nueva 26.2k / 1m ninguna
Checklist en el archivo de memoria 26.4k / 1m 210 tokens
Checklist como skill 26.2k / 1m ninguna, skill no listado

Al ejecutarlo, Claude completó los seis pasos en menos de un minuto: typecheck, 34 tests, subida de versión de 0.4.0 a 0.4.1, línea de changelog, commit y tag. También detectó un fallo de nuestra propia checklist. El comando de commit tal como estaba escrito se salta los archivos sin seguimiento, así que Claude añadió primero el nuevo changelog al área de preparación y lo dijo. El release ahora es un comando que escribes, vive en el repo para todo el equipo y no cuesta nada de contexto hasta que lo escribes.

La segunda tarea: la regla que debe cumplirse pasa a ser un hook

Un hook es un script que Claude Code ejecuta antes de que se dispare una herramienta, aquí antes de cualquier edición o escritura, y lo que responde ese script decide lo que ocurre después. La segunda tarea es una regla que nunca debe romperse: en este repo, el archivo de datos almacenados no se edita nunca a mano, y todo cambio pasa por una migración.

Escribir esa regla en mayúsculas en el archivo de memoria no la hace cumplir. La doc es directa: ese archivo es contexto, no configuración aplicada, y una instrucción como «nunca edites este archivo» es una petición, no una garantía, mientras que un hook que bloquea la edición es una aplicación estricta.

El primer hook obvio es el que escribimos. En el archivo de ajustes vigila las escrituras al archivo de datos, imprime un aviso y termina con el código cero, como un script de registro. Luego le pedimos a Claude que cambiara directamente un importe de factura en el archivo, sin migración. El hook se ejecutó y el aviso se imprimió, pero la escritura pasó: el precio unitario de la tercera factura pasó de 8000 a 12000. La respuesta de Claude nunca mencionó el hook, porque un hook que termina limpio sin imprimir nada no ha tomado ninguna decisión, y sus avisos nunca llegan a Claude.

La garantía no es que el hook se ejecute, sino la respuesta que devuelve. La solución mantiene el mismo hook y hace que devuelva una decisión deny: una línea JSON corta con el motivo que quieres que Claude lea. Terminar con el código dos bloquea igual. El hook entero es un comando en línea en .claude/settings.json, sin archivo de script:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c 'if (.tool_input.file_path // \"\") | test(\"data/.*\\\\.json$\") then {hookSpecificOutput: {hookEventName: \"PreToolUse\", permissionDecision: \"deny\", permissionDecisionReason: \"Stored data is never edited by hand: write a migration in src/store/migrations.ts (README § Conventions).\"}} else empty end'"
          }
        ]
      }
    ]
  }
}

Con la misma petición, la edición fue rechazada y el archivo de datos quedó intacto. Claude vio este error: PreToolUse:Edit hook error: Stored data is never edited by hand: write a migration in src/store/migrations.ts (README § Conventions). Dijo que no había cambiado nada y preguntó si debía saltarse la protección o escribir la migración.

El límite, que Claude nombró él mismo: este hook solo vigila las herramientas de edición y escritura, y en una prueba posterior Claude se ofreció a hacer el cambio a través del shell. Un hook tiene que cubrir también el shell, o el shell tiene que quedar fuera de tu lista de permitidos, porque una protección que cubre una sola puerta sigue siendo una petición. El hook no cuesta nada de contexto, porque se ejecuta fuera de tu conversación.

La tercera tarea: la auditoría que inunda pasa a ser un subagent

Un subagent es una sesión de Claude aparte con su propio contexto en blanco. Recibe tu encargo, lee lo que necesita y solo te vuelve un resumen. La tercera tarea es una auditoría que inunda tu hilo: comprobar cada archivo de la carpeta de código fuente contra las convenciones del README y listar cada infracción con archivo y línea.

Pedida en línea, Claude lee cada archivo dentro de tu conversación, y todo ese contenido se queda ahí durante el resto de la sesión, lo vuelvas a mirar o no. En nuestra prueba Claude leyó los 19 archivos fuente, la línea Messages de la tabla de contexto se infló y los hallazgos quedaron enterrados bajo el montón.

La elección correcta es un archivo en .claude/agents/, aquí .claude/agents/conventions-auditor.md, con un nombre, una descripción de cuándo usarlo, las herramientas que puede emplear y un modelo fijado. Fijar el modelo importa, porque si no un subagent hereda el que use tu sesión, y la mayoría de las tareas de lectura no necesitan el grande.

Hicimos exactamente la misma pregunta otra vez, y Claude leyó los archivos él mismo. En los dos intentos nunca llamó al agent, aunque estaba listado: 0 delegaciones de 2. Lo que funcionó fue nombrarlo al inicio del prompt: «use the conventions auditor subagent». Salió una sola llamada y volvió un resumen corto.

Prueba Contexto total Línea Messages
Auditoría en línea 46.1k 19.3k
Subagent nombrado 34.1k 7.2k

Los hallazgos fueron igual de buenos: el subagent detectó un bug de ruta que la prueba en línea se había dejado, y se dejó uno que la prueba en línea sí encontró. Así que el archivo hace que el subagent exista, y tu prompt hace que Claude lo use; hasta que Claude lo elija solo, lo nombras. Un límite: la factura no se movió. Las dos pruebas costaron lo mismo, porque la lectura sigue ocurriendo, solo que no en tu ventana.

La cuarta tarea: los datos fuera de alcance pasan a ser un servidor MCP

Un servidor MCP es un cliente de API al que Claude puede llamar, y el trabajo para el que existe son datos más nuevos que el modelo o que viven fuera de tu disco. El reflejo aquí es la elección equivocada, así que la hicimos primero.

Conectamos un servidor de docs público para nuestra librería de tests y le pedimos a Claude un test con fake timers. No cambió nada: Claude ya conocía esa librería, y solo llamó al servidor cuando lo nombramos. Unas docs que el modelo ya conoce no son datos fuera de su alcance.

La prueba real es una pregunta sobre el propio Claude Code, sobre un ajuste de hook más nuevo que el modelo: qué ajuste hace que un hook fallido bloquee, qué versión lo añadió y cuál es el JSON exacto. Sin servidor, Claude leyó el esquema de ajustes de su propia instalación, no encontró nada y respondió que no podía encontrar el ajuste y que no se lo inventaría («I won't guess one»). Esa respuesta es honesta e inútil, porque el ajuste existe; llegó después del conocimiento del modelo.

La solución es añadir al repo el servidor de docs del propio Claude Code, con alcance de proyecto para que la configuración caiga en un archivo en la raíz del repo que recibe todo tu equipo:

claude mcp add --transport http claude-docs --scope project https://code.claude.com/docs/mcp

Esto escribe .mcp.json. Claude Code lista el servidor como pendiente hasta que lo apruebes en tu próxima sesión, y a partir de ahí sus herramientas están disponibles para Claude. Hicimos la misma pregunta con palabras sencillas, sin nombrar el servidor. Claude buscó en las docs, encontró la página y respondió con el ajuste, la versión y el JSON que añadir, con el enlace.

El ajuste es "onFailure": "block", que hace que un hook fallido bloquee la acción en lugar de dejarla pasar. Llegó en la v2.1.295, mientras que nuestra instalación seguía en la 2.1.294. Ese es el límite: Claude nunca dijo que nuestra instalación no pudiera usarlo, porque no comprobó la versión, así que la versión la compruebas tú. En la tabla de contexto, el servidor aparece solo con los nombres de sus herramientas, cargadas bajo demanda hasta que Claude recurre a una.

Cuatro archivos, una tarjeta de decisión

Tras las cuatro tareas, git status muestra exactamente cuatro archivos, porque el hook no necesita un script propio:

  • .claude/skills/release/SKILL.md
  • .claude/settings.json
  • .claude/agents/conventions-auditor.md
  • .mcp.json

Haz commit de ellos, y la próxima sesión en este repo los tendrá todos, igual que cualquiera que lo clone.

Cada elección fue correcta por una tabla que publica la doc, y que puedes guardar como tarjeta de decisión:

Situación Extensión
Un procedimiento que vuelves a pegar Skill
Algo que debe ocurrir siempre, sin preguntar Hook
Una tarea secundaria que inunda tu conversación con una salida que no volverás a leer Subagent
Datos que no paras de copiar desde un sitio que Claude no puede ver Servidor MCP

Los tipos también se combinan. La doc empareja un skill con un servidor MCP: el servidor aporta la conexión, y el skill enseña a Claude a usarla bien. Un skill también puede ejecutarse dentro de un subagent bifurcado, para que su lectura quede fuera de tu ventana. Cuando otro repo necesita la misma configuración, un plugin es la caja que los envía todos juntos.

La tarjeta decide el tipo, no la calidad. Un hook que solo registra, un subagent que nunca nombras y un servidor para docs que el modelo ya conoce estaban cada uno en el tipo correcto y aun así fallaron. Elige el tipo con la tarjeta, y luego haz que el archivo responda, no solo que exista.

Veredicto: cuándo cada uno, cuándo ninguno, la regla única

Las cuatro tareas que reescribías se probaron primero de la forma equivocada, fallaron en pantalla y ahora son archivos del repo que funcionan. El release es un comando que escribes. La regla de datos es un hook que rechaza la edición y hace que Claude pregunte. La auditoría vuelve como un resumen. La pregunta de docs obtiene el ajuste y la versión que Claude no encontraba solo.

El hook con el que empezamos, el que se ejecutó y dejó pasar la escritura, enseñó la regla que hay debajo de todo esto: un hook decide solo por lo que devuelve su comando, así que un hook que solo registra es una petición disfrazada.

Hay casos que no requieren nada de esto:

  • Una convención que Claude sigue haciendo mal sigue perteneciendo al archivo de memoria, como una línea, no como un procedimiento.
  • Una tarea que necesitas dirigir de un lado a otro, con tu historial a la vista, se queda en el hilo principal y no en un subagent.
  • Un servidor de docs para una librería que el modelo ya conoce cuesta contexto y no cambia nada. Conecta lo que el modelo no puede tener, no lo que ya tiene.

La regla que recordar: da a cada tarea que reescribes su propio archivo, elige el tipo con la tarjeta y ten presente que, de entre ellos, solo el hook nunca pregunta.

Recursos gratuitos

Fuentes

Preguntas frecuentes

¿Debo usar un skill, un hook, un subagent o un servidor MCP en Claude Code?
Un skill para un procedimiento que pegas una y otra vez, un hook para lo que debe ocurrir siempre sin preguntar, un subagent para una tarea secundaria que inunda tu conversación y un servidor MCP para datos que Claude no ve. La doc lo ofrece como tabla de decisión.
¿Por qué mi hook de Claude Code se ejecutó pero no bloqueó la edición?
Un hook solo decide por lo que devuelve su comando. Un hook que imprime un aviso y termina con el código 0 no ha tomado ninguna decisión, así que la edición pasa; devolver un permissionDecision deny, o terminar con el código 2, la bloquea.
¿Debo poner una checklist de release en CLAUDE.md o en un skill?
En un skill. Todo lo que hay en el archivo de memoria se carga en cada turno de cada sesión (210 tokens para nuestra checklist de seis pasos), mientras que un skill con disable-model-invocation no cuesta nada de contexto hasta que escribes su nombre.
¿Por qué Claude Code no llama a mi subagent automáticamente?
Incluso con una descripción casi idéntica a nuestro prompt, Claude leyó los archivos por su cuenta en 2 de 2 pruebas. Nombrar el subagent al inicio del prompt hizo que delegara, y la línea Messages bajó de 19.3k a 7.2k tokens.
¿Cuándo vale la pena añadir un servidor MCP a Claude Code?
Cuando los datos son más nuevos que el modelo o están fuera de tu disco. Un servidor de docs para una librería que el modelo ya conoce no cambió nada, mientras que el servidor de docs de Claude Code respondió a una pregunta sobre un ajuste de hook que el esquema de la instalación no contenía.
¿Cómo añado el servidor MCP de docs de Claude Code a un repo?
Ejecuta claude mcp add --transport http claude-docs --scope project https://code.claude.com/docs/mcp. Escribe .mcp.json en la raíz del repo, y el servidor aparece como pendiente hasta que lo apruebes en tu próxima sesión.

Vídeos relacionados