Workflows de Claude Code: Subagents, Revisión de Código y Depuración
Ya dominas lo básico. Tu CLAUDE.md está afinado, tus hooks disparan perfectamente, tus servidores MCP le dan a Claude acceso directo a tus herramientas. Pero sigues trabajando con un solo Claude a la vez. Una conversación, una tarea, un hilo de ejecución.
¿Y si pudieras ejecutar cinco?
Los setups con patrones de workflow explícitos y definiciones de agentes sacan 7.0/10 de media en nuestro análisis. La brecha entre usuarios casuales y power users no es la configuración — es cómo orquestan su trabajo. Esta guía cubre los patrones que producen los mejores resultados.
Subagents: delegar como un manager, no como un micromanager
Un subagent es una sesión separada de Claude Code que se encarga de una tarea específica. Tu sesión principal se mantiene enfocada mientras los subagents trabajan en piezas aisladas en paralelo. Piensa en ello como repartir tareas a compañeros de equipo — cada uno recibe un brief claro y entrega un resultado concreto.
Cuándo los subagents tienen sentido (y cuándo no)
Buenas tareas para subagents:
- Piezas independientes que no necesitan contexto compartido
- Múltiples archivos que necesitan cambios pero no dependen entre sí
- Tareas de exploración (investigar un enfoque) mientras sigues construyendo
- Trabajo repetitivo en archivos similares (actualizar 10 rutas API de la misma forma)
Malas tareas para subagents:
- Cualquier cosa que requiera el contexto completo de tu conversación actual
- Cambios donde el archivo A depende de lo que decidiste en el archivo B
- Ediciones rápidas que son más rápidas inline
La pregunta clave: si podrías darle la tarea a un colega con solo un brief escrito — sin contexto verbal — es un buen candidato para subagent.
Cómo delimitar una tarea de subagent
Tareas vagas producen resultados vagos. "Mejora la API de usuarios" no le da a Claude nada a qué agarrarse. Así se ve una tarea bien delimitada:
## Tarea: Agregar validación de entrada a endpoints de usuario
### Archivos a modificar
- src/api/users/route.ts
- src/api/users/[id]/route.ts
### Archivos a leer (para contexto)
- src/lib/schemas.ts
- src/types/user.ts
### Requisitos
- Agregar validación zod a todos los cuerpos de request POST/PUT
- Retornar 400 con mensajes de error estructurados para entradas inválidas
- NO modificar endpoints GET o DELETE
- NO cambiar la capa de base de datos
### Terminado cuando
- Archivos de rutas modificados con validación
- Esquemas zod nuevos o actualizados en src/lib/schemas.ts
Fíjate en el scope explícito de archivos, los requisitos claros y la definición de "terminado". El subagent sabe exactamente qué tocar, qué dejar en paz y cuándo parar.
El patrón Director: ejecutar subagents en paralelo
Para features más grandes, puedes usar a Claude como director — planificar el trabajo y luego despachar subagents para cada pieza:
Tú: "Necesito un sistema de notificaciones. Planifica el trabajo y usa subagents."
Claude (Director):
1. Fase de planificación: esquema de notificación, endpoints API, componentes UI
2. Subagent 1: Crear migración de BD y esquema Prisma
3. Subagent 2: Implementar endpoints API (GET /notifications, POST /mark-read)
4. Subagent 3: Construir el componente de campana de notificación y dropdown
5. Integración: unir todo y probar
Cada subagent recibe una tarea acotada. La sesión director maneja la integración y se asegura de que las piezas encajen. Este patrón funciona especialmente bien porque los subagents arrancan limpios — sin peso de contexto acumulado de una conversación larga.
Yo uso este patrón para cualquier feature que toque más de 3 archivos. Cinco terminales en paralelo, cada una con un subagent manejando una pieza, mientras la sesión principal guarda la visión general.
Revisión de código: el workflow diario de mayor valor
La revisión de código es uno de los usos más potentes de Claude Code — y uno de los menos aprovechados. En lugar de revisar tu propio código (que tu cerebro racionaliza como correcto) o esperar a un compañero, Claude encuentra problemas en segundos.
El método Fix-First
La mayoría de herramientas de revisión te dan una lista de problemas. Después tienes que arreglar cada uno manualmente. Eso es al revés.
El método Fix-First: Claude corrige los problemas mecánicos directamente y solo te pregunta sobre los ambiguos:
## Cómo revisar código (ponlo en un skill o CLAUDE.md)
1. Leer el diff COMPLETO primero — entender el cambio completo
2. AUTO-CORREGIR problemas mecánicos:
- Manejo de errores faltante → agregar try/catch
- Errores de tipos obvios → corregir el tipo
- Violaciones de estilo → corregirlas
3. Agrupar decisiones ambiguas en UNA pregunta:
- "Encontré 3 decisiones de diseño a confirmar: [A], [B], [C]"
4. Nunca señalar issues que ya están resueltos en el diff
5. Salida: CRÍTICO (debe corregir) e INFORMATIVO (vale considerar)
No quieres una lista de 15 nimiedades cuando 12 podrían haberse auto-corregido. El método Fix-First respeta tu tiempo.
Revisión pre-commit en la práctica
Configura un alias de shell para el uso diario:
alias ccreview='claude -p "Revisa los cambios staged (git diff --staged). Corrige problemas mecánicos. Marca lo crítico."'
O como un skill con más funcionalidad:
<!-- .claude/skills/pre-commit-review.md -->
---
name: pre-commit-review
description: Revisar cambios staged antes de hacer commit
---
1. Ejecutar `git diff --staged`
2. Para cada archivo:
- Manejo de errores: ¿operaciones async en try/catch?
- Seguridad: ¿secrets hardcodeados, inyección SQL, XSS?
- Tipos: ¿`any` que debería ser específico?
- Tests: ¿funciones modificadas tienen test updates?
3. AUTO-CORREGIR problemas mecánicos
4. Reportar CRÍTICO (bloquea commit) e INFORMATIVO
5. Si no hay críticos: sugerir un mensaje de commit
Escribe /pre-commit-review antes de cada commit. Claude revisa tu trabajo, arregla lo pequeño y marca los problemas reales. Tarda 15 segundos y atrapa cosas que pasarías por alto un viernes a las 6 PM.
Test-Driven Development: escribe la spec, deja que Claude implemente
El TDD con Claude Code funciona diferente al TDD en solitario. Tú describes lo que una función debe hacer. Claude escribe el test. Tú verificas que el test captura tu intención. Luego Claude escribe el código que lo pasa.
Funciona porque un test es una especificación inequívoca. Cuando describes un feature en palabras, Claude puede interpretarlo diferente a lo que querías. Cuando lo expresas como test, el comportamiento esperado es explícito — entradas, salidas, casos límite.
El loop
1. Tú describes lo que la función debe hacer
2. Claude escribe el test
3. Tú verificas que el test captura tu intención
4. Claude escribe la implementación para pasar el test
5. Claude ejecuta el test para confirmar
6. Repetir
Un ejemplo concreto: construir un rate limiter
Tú: "Necesito un rate limiter. 100 requests por minuto por IP. Retornar 429
cuando se exceda, incluir header Retry-After. Escribe el test primero."
Claude escribe:
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createRateLimiter } from './rate-limiter';
describe('Rate Limiter', () => {
beforeEach(() => {
vi.useFakeTimers();
});
it('should allow requests under the limit', () => {
const limiter = createRateLimiter({ maxRequests: 100, windowMs: 60000 });
const result = limiter.check('192.168.1.1');
expect(result.allowed).toBe(true);
expect(result.remaining).toBe(99);
});
it('should block requests over the limit', () => {
const limiter = createRateLimiter({ maxRequests: 2, windowMs: 60000 });
limiter.check('192.168.1.1');
limiter.check('192.168.1.1');
const result = limiter.check('192.168.1.1');
expect(result.allowed).toBe(false);
expect(result.retryAfter).toBeGreaterThan(0);
});
it('should reset after the window expires', () => {
const limiter = createRateLimiter({ maxRequests: 1, windowMs: 60000 });
limiter.check('192.168.1.1');
vi.advanceTimersByTime(61000);
const result = limiter.check('192.168.1.1');
expect(result.allowed).toBe(true);
});
it('should track IPs independently', () => {
const limiter = createRateLimiter({ maxRequests: 1, windowMs: 60000 });
limiter.check('192.168.1.1');
const result = limiter.check('192.168.1.2');
expect(result.allowed).toBe(true);
});
});
Lees el test. Cuatro casos: bajo el límite, sobre el límite, reset de ventana, aislamiento por IP. Se ve bien. Le dices a Claude que siga, y escribe la implementación que pasa los cuatro. El test sirvió como contrato que ambos acordaron antes de escribir una línea de código de producción.
Debugging: el enfoque sistemático que realmente funciona
Debuggear con Claude es poderoso, pero puede dar vueltas en círculos si lo dejas. Claude mantiene más contexto y explora más hipótesis que tú — pero necesita estructura para no derrapar.
El workflow de debugging de 7 pasos
Pon esto en tu CLAUDE.md o en un skill de debugging:
Al debuggear:
1. REPRODUCIR — ejecutar el caso que falla, capturar el error exacto
2. HIPÓTESIS — listar 3 posibles causas, ordenadas por probabilidad
3. INVESTIGAR — verificar la causa más probable primero
4. LOGUEAR — agregar logging en cada frontera async si no ves dónde para la ejecución
5. IDENTIFICAR — localizar la línea o función exacta
6. CORREGIR — aplicar el fix mínimo
7. VERIFICAR — ejecutar el caso que fallaba para confirmar que el fix funciona
La regla crítica: nunca saltar el paso 7. Nuestros datos muestran que el 40% de las sesiones de debugging que salen mal lo hacen porque un fix fue anunciado pero nunca verificado. "Debería funcionar ahora" no es evidencia. Ejecútalo.
La regla de tres intentos
Este patrón separa el debugging productivo de la pérdida de tiempo:
Si Claude no ha encontrado la causa raíz después de tres intentos, para. No lo dejes seguir adivinando — hipótesis cada vez más rebuscadas hacen el problema más difícil de diagnosticar. En cambio, elige uno de tres caminos:
Opción A: Nueva hipótesis. Retroceder completamente. Replantear el problema desde cero. A veces el tercer intento falló porque el primero envenenó el razonamiento.
Opción B: Revisión humana. Claude te muestra todo lo que ha encontrado y tú agregas contexto. Tal vez sabes algo del entorno de producción o de un deploy reciente que Claude no conoce.
Opción C: Instrumentar y esperar. Agregar logging comprensivo y reproducir el problema. Dejar que los logs te digan dónde para la ejecución en vez de adivinar.
Patrones de prompting que dan mejores resultados
Cómo formulas instrucciones importa más de lo que crees. Estos son los patrones que consistentemente producen mejor código.
Define cómo se ve "terminado"
Malo: "Mejora la autenticación."
Bueno: "Agrega rate limiting al endpoint de login. 5 intentos por email cada 15 minutos. Retorna 429 con header Retry-After. Escribe tests para el límite y el reset. No toques el endpoint de registro."
El segundo prompt no tiene ambigüedad. Claude puede ejecutarlo sin hacer una sola pregunta.
Declara restricciones explícitamente
- NO modificar archivos en src/legacy/ — ese código está congelado
- El build debe pasar con Node 18 (nada de APIs de Node 20+)
- Mantener bundle size bajo 200KB — verificar con `npm run analyze`
Pide un plan para cualquier cosa que toque 3+ archivos
Planifica cómo implementarías una capa de caché para respuestas API. Muéstrame:
1. Qué archivos crearías o modificarías
2. La estrategia de invalidación de caché
3. Cómo se integra con el middleware existente
No escribas código aún. Solo el plan.
Revisa el plan, ajústalo, luego deja que Claude ejecute. Esto atrapa errores estructurales antes de que se propaguen por múltiples archivos. Cambiar un plan no cuesta nada. Deshacer un enfoque equivocado a medio implementar cuesta horas.
Cómo se conecta todo
Tu configuración le da a Claude conocimiento del proyecto. Tu automatización aplica estándares. Tus integraciones le dan a Claude acceso a tu infraestructura. Los workflows determinan cómo opera Claude día a día.
Empieza con la revisión pre-commit — es la victoria más fácil y la que usarás todos los días. Después prueba subagents la próxima vez que tengas un feature que toque 4+ archivos. Analiza tu setup para ver dónde está tu orquestación de workflows.
Preguntas frecuentes
¿Cuántos subagents pueden ejecutarse al mismo tiempo?
Depende de tu máquina (RAM, CPU) y límites de tasa de la API. En una máquina de desarrollo típica, 3-5 subagents concurrentes funcionan bien. Cada uno es una sesión separada que consume tokens, así que vigila tu uso si pagas por API.
¿Debería usar subagents para todo?
No. Añaden overhead — cambio de contexto, creación de sesión, y el riesgo de que un subagent pierda contexto que la sesión principal tiene. Una buena prueba: si podrías darle la tarea a un colega con solo un brief escrito (sin explicación verbal necesaria), es candidato a subagent. Si necesitarías una conversación de 10 minutos para explicar el contexto, mantenlo en la sesión principal.
¿Qué hago cuando el fix de Claude no funciona?
Primero, asegúrate de que Claude realmente verificó el fix ejecutando el test que fallaba. Si genuinamente no funciona, no dejes que Claude intente el mismo enfoque otra vez. Di "ese enfoque no funcionó — propón una causa raíz diferente." Después de tres intentos fallidos, escala: nueva hipótesis, revisión humana, o agregar logging y recopilar datos.
¿Claude Code puede hacer pair programming?
Sí, y funciona mejor con una división específica: tú diriges las decisiones de arquitectura, Claude maneja la implementación. Describe lo que quieres a alto nivel, deja que Claude proponga el código, revisa, itera. El anti-patrón es dejar que Claude tome decisiones de arquitectura sin tu input — esas se acumulan, y para cuando notas un giro equivocado, Claude ha construido tres capas encima.
¿Cómo manejo refactorizaciones grandes?
Divídelas en fases, un subagent por fase. Fase 1: "Renombrar todas las ocurrencias de OldService a NewService." Fase 2: "Actualizar todos los llamadores a la nueva firma de API." Fase 3: "Eliminar métodos deprecados y actualizar tests." Cada fase está acotada y es testeable. La sesión principal rastrea el progreso y maneja la integración entre fases.