Receta · Intermedio · 10 min
Subagentes de Claude Code: divide el trabajo y ahorra contexto
Crea un subagente en .claude/agents/ con name, description, tools y model, y úsalo como revisor de solo lectura del diff antes de cada commit.
Probado con Claude Code 2.1.316 · revisado
El problema
Le pides a Claude Code que revise tus cambios, que busque algo en todo el repositorio o que corra los tests, y la conversación se llena de diffs, resultados de búsqueda y registros que no vuelves a mirar. El contexto se gasta rápido y Claude empieza a olvidar lo que habían hablado al principio. Además, para una revisión no quieres que pueda editar archivos «de paso».
La solución
Un subagente es un asistente especializado con su propia ventana de contexto, sus propias instrucciones y su propia lista de herramientas. Claude le pasa la tarea, el subagente trabaja aparte y solo vuelve a tu conversación su resumen.
1. Elige dónde guardarlo
| Ubicación | Alcance |
|---|---|
.claude/agents/<nombre>.md | Este proyecto (se sube a git y lo comparte el equipo) |
~/.claude/agents/<nombre>.md | Todos tus proyectos |
Desde la versión 2.1.198, /agents ya no abre un asistente. En 2.1.316 muestra esto:
The /agents wizard has been removed.
Ask Claude to create or update subagents for you (e.g. "create a code-reviewer subagent that ..."),
or edit the files directly:
• .claude/agents/ (this project)
• ~/.claude/agents/ (all projects)
Puedes pedirle a Claude «crea un subagente que…» o escribir tú el archivo, como en esta receta.
2. Conoce los campos del frontmatter
Solo name y description son obligatorios.
| Campo | Para qué sirve |
|---|---|
name | Identificador único (sin :). Es lo que cuenta, no el nombre del archivo. |
description | Cuándo debe usarlo Claude. Claude decide si delega según este texto. |
tools | Lista de herramientas permitidas. Si lo omites, hereda todas las de la conversación. |
disallowedTools | Herramientas prohibidas (se aplica antes que tools). |
model | sonnet, opus, haiku, fable, un ID completo o inherit (el modelo de tu conversación). |
Hay más campos opcionales (hooks, permissionMode, maxTurns, effort, isolation…). Los campos mal escritos se ignoran sin avisar.
3. Crea el subagente «revisor» de solo lectura
En la raíz de tu proyecto:
mkdir -p .claude/agents .claude/hooks
Guarda esto en .claude/agents/revisor.md:
---
name: revisor
description: Revisa el diff sin commitear (git diff) antes de hacer commit y reporta bugs, riesgos de seguridad y tests que faltan. Úsalo cuando el usuario pida revisar sus cambios o antes de commitear. No modifica archivos.
tools: Read, Grep, Glob, Bash
model: sonnet
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/solo-git-lectura.py\""
---
Eres un revisor de código exigente y de solo lectura. Nunca modificas archivos.
Cuando te invoquen:
1. Ejecuta `git status --short` y después `git diff HEAD`, cada uno en su propia llamada a Bash (sin `&&` ni `|`).
2. Lee con Read el archivo completo de cada cambio si necesitas contexto.
3. Busca, en este orden: bugs de lógica, errores de seguridad (secretos, inyecciones), casos límite sin manejar y tests que faltan.
Responde en español con este formato:
- **Bloqueante** (hay que arreglarlo antes del commit): archivo:línea, qué falla y cómo arreglarlo.
- **Mejorable**: lo mismo, más breve.
- **Veredicto**: «Listo para commit» o «No commitear todavía».
Si no encuentras problemas, dilo en una línea. No inventes problemas.
4. Limita Bash a comandos git de lectura
tools sin Write ni Edit impide editar con esas herramientas, pero el revisor necesita Bash para ver el diff, y con Bash se puede escribir. El campo tools no acepta reglas como Bash(git diff *), así que la documentación recomienda un hook PreToolUse. Guarda esto en .claude/hooks/solo-git-lectura.py:
#!/usr/bin/env python3
"""Hook PreToolUse del revisor: deja pasar solo git diff/status/log/show; bloquea lo demás (exit 2)."""
import json, re, sys
cmd = json.load(sys.stdin).get("tool_input", {}).get("command", "")
if "--output" not in cmd and re.fullmatch(r"git (diff|status|log|show)( [^;&|<>`$]*)?", cmd.strip()):
sys.exit(0)
print("Bloqueado: el revisor solo puede usar git diff, status, log o show.", file=sys.stderr)
sys.exit(2)
chmod +x .claude/hooks/solo-git-lectura.py
El código de salida 2 bloquea el comando y le devuelve el mensaje al subagente. También se bloquean ;, &&, |, las redirecciones y --output, para que no se pueda colar una escritura detrás de un git diff.
5. Úsalo
Si .claude/agents/ no existía cuando abriste la sesión, reinicia Claude Code. Después:
claude -p "usa el subagente revisor para revisar mis cambios"
En una sesión interactiva también puedes escribir @"revisor (agent)" revisa mis cambios para obligar a que se use ese subagente.
Compruébalo
Antes de usarlo en tu proyecto, comprueba el hook a mano:
echo '{"tool_input":{"command":"git diff HEAD"}}' | python3 .claude/hooks/solo-git-lectura.py; echo $?
echo '{"tool_input":{"command":"git diff; rm -rf src"}}' | python3 .claude/hooks/solo-git-lectura.py; echo $?
Salida esperada: 0 para el primero; el mensaje «Bloqueado…» y 2 para el segundo.
Prueba real con 2.1.316 en un repositorio con este cambio sin commitear en precio.py:
def total_con_iva(precio, iva=0.21):
"""Devuelve el precio con IVA incluido."""
return precio * iva
def descuento(precio, porcentaje):
return precio - precio * porcentaje / 10
Claude delegó en revisor (herramienta Agent, subagent_type: "revisor"). Dentro del subagente, el hook bloqueó ls -la . y git status && ls ... con el mensaje Bloqueado: el revisor solo puede usar git diff, status, log o show., dejó pasar git diff HEAD, y la respuesta final empezó así:
**Fallos graves**
1. precio.py:3, total_con_iva: devuelve solo el IVA, no el total. Hace precio * iva,
así que total_con_iva(100) da 21.0 en vez de 121.0. [...] Se arregla con precio * (1 + iva).
2. precio.py:7, descuento: divide entre 10 en vez de entre 100. descuento(100, 10) da 0.0
en vez de 90.0 [...] Se arregla con / 100.
A tu conversación solo llegó ese resumen, no el diff completo ni las lecturas de archivos.
Por qué funciona
Cada subagente empieza con una ventana de contexto nueva: no ve tu historial, solo su prompt de sistema, la tarea que le escribe Claude, los CLAUDE.md y una foto de git status. Trabaja aparte y devuelve solo su resumen, así que el ruido (diffs, búsquedas, registros de tests) no llena tu contexto. Claude decide cuándo delegar según la description, y tools más el hook limitan lo que puede hacer. Fuente: documentación oficial de subagentes.
Cuándo usarlos: investigación que lee muchos archivos, revisión de código, correr tests y resumir los fallos, y cualquier tarea autocontenida que deba devolver un resumen o tener herramientas limitadas.
Cuándo no: tareas con mucho ida y vuelta contigo, fases que comparten mucho contexto (planear, implementar y probar lo mismo), cambios pequeños y rápidos, o cuando la latencia importa: el subagente empieza de cero y tarda en reunir contexto.
Errores típicos
- El hook no bloquea nada y el revisor ejecuta cualquier comando → la carpeta del proyecto no está marcada como de confianza, y Claude Code omite sin avisar los
hooksde los subagentes del proyecto (la confianza de una carpeta padre no cuenta) → abreclaudeen esa carpeta y acepta el diálogo de confianza. Nos pasó en la prueba: sin confianza, el revisor ejecutógit status --short && git diff HEAD && cat -n precio.py && lssin que el hook lo frenara. - «Subagente no encontrado» o Claude no lo usa → creaste
.claude/agents/con la sesión abierta → reinicia Claude Code. - El subagente no aparece → falta
nameodescription, el---inicial no está en la primera línea o el YAML no es válido → revísalo conclaude plugin validate .claude/agents. - El hook falla en vez de bloquear → el script no es ejecutable o
python3no está en el PATH →chmod +xy prueba el script a mano como en «Compruébalo». - El revisor dice que el hook le bloqueó
git status && git diff→ el hook solo acepta un comando por llamada → déjalo así: el prompt ya le pide un comando por llamada.
Preguntas frecuentes
¿Dónde se guardan los subagentes de Claude Code?
En .claude/agents/ para el proyecto y en ~/.claude/agents/ para todos tus proyectos. Si dos tienen el mismo name, gana el del proyecto.
¿Un subagente gasta menos tokens?
No necesariamente: trabaja en su propia ventana y también consume tokens. Lo que ahorras es contexto en tu conversación principal, porque solo vuelve su resumen.
¿Puedo usar un modelo más barato para el subagente?
Sí, con model: haiku o model: sonnet. Con inherit usa el mismo modelo que tu conversación.
¿Los subagentes pueden lanzar otros subagentes?
Sí, hasta tres niveles por defecto. Para impedirlo, no incluyas Agent en tools; en el revisor ya no está.
¿Qué pasó con el asistente de /agents?
Se quitó en la versión 2.1.198. Ahora /agents solo te recuerda que se lo pidas a Claude o que edites los archivos en .claude/agents/.