Módulo 4: El workflow agentic: Explore → Plan → Code

Multi-turn Conversations: Iterar Efectivamente con Claude Code

Multi-turn Conversations: Iterar Efectivamente con Claude Code

Descripción

Claude Code no es un chatbot al que le lanzas un prompt y esperas magia. Es un agente conversacional: cada mensaje que envías construye sobre el anterior, y la calidad de tu resultado depende directamente de cómo conduces esa conversación.

La diferencia entre un developer que usa Claude Code de forma mediocre y uno que lo domina está aquí: en cómo itera. Los que obtienen resultados excepcionales no escriben un prompt perfecto de 50 líneas — escriben 5-8 mensajes cortos, dan feedback preciso, redirigen cuando algo se desvía, y construyen la solución incrementalmente. Esto es multi-turn conversation.

En esta cápsula vas a aprender los patterns que hacen que tus conversaciones con Claude Code sean productivas: cómo dar feedback, cuándo dividir tareas en múltiples mensajes, cómo usar comandos como /clear y /compact, y cómo CLAUDE.md proporciona contexto consistente a lo largo de toda la sesión.


Multi-turn: El Modelo Mental

Claude Code recuerda todo dentro de la sesión

Cuando inicias una sesión con claude, todo lo que escribes y todo lo que Claude responde se acumula en el context window. Esto significa:

  • Claude "recuerda" lo que le pediste hace 10 mensajes
  • Puede referirse a código que generó antes
  • Puede corregir errores basándose en tu feedback
  • Puede construir sobre decisiones previas
Tú: "Analiza la estructura de este proyecto"
Claude: [lee archivos, muestra estructura]

Tú: "Ahora crea un endpoint GET /users"
Claude: [usa lo que aprendió del proyecto para crear el endpoint correctamente]

Tú: "Agrega validación con Zod"
Claude: [toma el endpoint anterior y le agrega validación, sin que repitas nada]

Cada mensaje tiene contexto implícito. No necesitas repetir "el endpoint que creaste antes" — Claude lo sabe.

One-shot vs Multi-turn

AspectoOne-shot (un mensaje)Multi-turn (varios mensajes)
ControlBajo — todo o nadaAlto — ajustas en cada paso
RiesgoSi falla, empiezas de ceroSi falla un paso, corriges solo ese
Complejidad máximaMediaAlta
FeedbackNo hayContinuo
ContextSolo tu promptTu prompt + todo lo anterior

Regla práctica: Si tu tarea tiene más de 2 pasos lógicos o si no estás 100% seguro de lo que quieres, usa multi-turn.


Cómo Dar Feedback Efectivo

El feedback es tu herramienta principal

La habilidad más importante en Claude Code no es escribir prompts — es dar feedback. Cada respuesta de Claude es una oportunidad para ajustar el rumbo.

Feedback específico vs vago

Malo — vago e inútil:

Tú: "No, está mal"
Tú: "Hazlo mejor"
Tú: "No me gusta"

Claude no sabe qué está mal. Va a adivinar, y probablemente adivinará incorrectamente.

Bueno — específico y accionable:

Tú: "El endpoint devuelve 200 cuando debería devolver 201 para creación. 
     Además, falta el header Location con la URL del recurso creado."

Tú: "La validación está bien pero quiero que los errores de Zod se 
     transformen a este formato: { field: string, message: string }[]"

Tú: "El tipo de retorno está correcto, pero usa interface en vez de type 
     — es la convención de este proyecto (está en CLAUDE.md)."

Los 5 tipos de feedback

1. Corrección directa — algo está objetivamente mal:

Tú: "El puerto está hardcodeado a 3000. Debe leer de process.env.PORT 
     con fallback a 3000."

2. Redirección — no era lo que pediste:

Tú: "Eso no es lo que necesito. No quiero un ORM, quiero queries SQL 
     directas con el driver pg. Reescribe usando pool.query()."

3. Refinamiento — está bien pero quieres más:

Tú: "Bien, ahora agrega rate limiting al endpoint. Usa express-rate-limit 
     con un máximo de 100 requests por minuto por IP."

4. Confirmación + siguiente paso — todo bien, avanza:

Tú: "Perfecto. Ahora crea los tests para ese endpoint con Vitest."

5. Exploración — quieres entender antes de decidir:

Tú: "Antes de implementar, ¿cuáles son los trade-offs entre usar JWT 
     y session cookies para este caso?"

Patterns de Conversación Efectivos

Pattern 1: Desarrollo Incremental

El pattern más común y más poderoso. Construyes una feature paso a paso.

# Paso 1: Estructura base
Tú: "Crea un módulo de autenticación con login y registro. 
     Solo la estructura de archivos y los tipos por ahora, sin implementación."

Claude: [crea src/auth/types.ts, src/auth/login.ts, src/auth/register.ts 
         con tipos e interfaces]

# Paso 2: Implementación core
Tú: "Implementa login. Usa bcrypt para comparar passwords y jsonwebtoken 
     para generar tokens. El secret viene de env."

Claude: [implementa login con bcrypt y jwt]

# Paso 3: Refinamiento
Tú: "Agrega manejo de errores: usuario no encontrado (404), 
     password incorrecto (401), error interno (500). Cada error con 
     un message descriptivo."

Claude: [agrega error handling al login existente]

# Paso 4: Testing
Tú: "Crea tests unitarios para login cubriendo los 3 casos de error 
     y el caso exitoso."

Claude: [crea tests con mocks de bcrypt y jwt]

# Paso 5: Registro
Tú: "Ahora implementa register siguiendo el mismo pattern que login."

Claude: [implementa register siguiendo las convenciones ya establecidas]

Por qué funciona: Cada paso es verificable. Si algo falla en el paso 3, no pierdes los pasos 1-2. Claude tiene todo el contexto de lo que ya construyó.

Pattern 2: Refinamiento Iterativo

Tienes algo que funciona pero quieres mejorarlo progresivamente.

# V1: Funcional
Tú: "Crea una función que parsee archivos CSV y devuelva un array de objetos."

Claude: [crea parseCSV básico]

# V2: Robusto
Tú: "Bien, pero no maneja comillas dentro de campos ni saltos de línea 
     dentro de campos entre comillas. Agrega soporte para RFC 4180."

Claude: [mejora el parser]

# V3: Performante
Tú: "Funciona, pero para archivos grandes (>100MB) se queda sin memoria 
     porque carga todo en un array. Convierte a un Readable stream que 
     emita objetos uno por uno."

Claude: [refactoriza a streaming]

# V4: Tipado
Tú: "Ahora hazlo genérico: parseCSV<T>(file, schema) donde schema 
     es un objeto Zod que valide y transforme cada fila."

Claude: [agrega genéricos y validación]

Pattern 3: Debugging Conversacional

Quizás el pattern más valioso. Usas Claude Code como par de debugging.

# Reporte del problema
Tú: "Tengo un error en producción: los usuarios con caracteres especiales 
     en el nombre (ñ, á, ü) generan un 500 al crear su perfil. 
     El error es 'SQLITE_CONSTRAINT: NOT NULL constraint failed: users.slug'."

Claude: [lee el código de creación de perfil, encuentra la función slugify]
Claude: "El problema está en src/utils/slugify.ts. La función usa un regex 
         que elimina todos los caracteres no-ASCII, dejando el slug vacío 
         para nombres como 'José García'."

# Verificación
Tú: "Muéstrame qué genera slugify('José García') actualmente."

Claude: [ejecuta el código]
Claude: "Genera '' (string vacío), que viola el NOT NULL constraint."

# Solución
Tú: "Corrígelo. El slug debe transliterar: é→e, ñ→n, á→a, etc. 
     Usa la librería transliteration."

Claude: [instala transliteration, actualiza slugify]

# Verificación post-fix
Tú: "Ahora muéstrame el resultado para estos nombres: 'José García', 
     'Müller Straße', '田中太郎'."

Claude: [ejecuta tests con los tres nombres, muestra resultados]

# Prevención
Tú: "Agrega tests unitarios para estos edge cases y un test de regresión 
     para el bug original."

Claude: [crea tests]

Pattern 4: Exploración Antes de Acción

Cuando no sabes exactamente qué quieres, explora primero.

# Exploración
Tú: "¿Cómo está organizado el manejo de errores en este proyecto? 
     Quiero entender el pattern antes de agregar el mío."

Claude: [analiza el codebase en modo Explore]
Claude: "El proyecto usa un pattern de error centralizado: 
         - Custom errors en src/errors/ extienden AppError
         - Un middleware en src/middleware/errorHandler.ts los captura
         - Cada error tiene code, message, y statusCode
         - Los controllers no hacen try/catch, solo lanzan errores"

# Decisión informada
Tú: "Ok, entonces crea un NotFoundError y un ConflictError siguiendo 
     ese pattern exacto."

Claude: [crea los errores siguiendo las convenciones existentes]

Cuándo Un Solo Mensaje vs Múltiples Mensajes

Usa un solo mensaje cuando:

  • La tarea es clara, atómica, y no ambigua
  • No necesitas verificar pasos intermedios
  • Ya sabes exactamente qué quieres
# Un solo mensaje está bien aquí:
Tú: "Agrega un campo 'updatedAt' tipo timestamp con default NOW() 
     a la tabla users y crea la migración."

Usa múltiples mensajes cuando:

  • La tarea tiene más de 2-3 pasos lógicos
  • Necesitas verificar antes de continuar
  • No estás seguro del approach
  • Estás debuggeando
  • Estás construyendo algo complejo
# Múltiples mensajes son mejores aquí:
Tú: "Necesito un sistema de notificaciones. ¿Qué opciones tenemos 
     considerando que usamos PostgreSQL y Node.js?"
Claude: [presenta opciones]

Tú: "Vamos con PostgreSQL LISTEN/NOTIFY + WebSockets. 
     Primero crea la infraestructura de DB."
Claude: [crea triggers y funciones PG]

Tú: "Ahora el WebSocket server."
Claude: [implementa WS server]
# ... etc

La regla del "¿necesito ver esto primero?"

Antes de cada paso pregúntate: ¿Necesito verificar el output de este paso antes de que Claude continúe?

  • Sí → Mensaje separado
  • No → Puede ir en el mismo mensaje

Comandos Esenciales para Multi-turn

/clear — Reset del contexto

Limpia toda la conversación. Claude olvida todo lo discutido. CLAUDE.md se recarga automáticamente.

# Cuándo usar /clear:
# - La conversación se desvió demasiado
# - El contexto se "contaminó" con intentos fallidos
# - Quieres empezar un tema completamente nuevo sin abrir nueva terminal

> /clear

# Después de /clear, Claude solo tiene:
# - CLAUDE.md
# - Acceso al filesystem
# - Nada de la conversación anterior

Tip: Antes de /clear, si hay algo valioso en la conversación, pídele a Claude que lo guarde en un archivo o en CLAUDE.md.

/compact — Comprimir sin perder

Comprime la conversación manteniendo los puntos clave. Libera espacio en el context window sin perder todo.

# Cuándo usar /compact:
# - La conversación es larga pero aún relevante
# - Claude empieza a "olvidar" cosas de hace varios mensajes
# - El indicador de contexto está alto (>70%)

> /compact

# Después de /compact:
# - Claude tiene un resumen de la conversación
# - Los detalles exactos se pierden
# - La dirección general se mantiene
# - CLAUDE.md sigue intacto

La diferencia con /clear: /compact preserva un resumen; /clear borra todo.

/effort — Controlar profundidad

No es exclusivo de multi-turn, pero afecta la calidad de cada respuesta.

> /effort high    # Razonamiento profundo, más lento
> /effort medium  # Balance (default)
> /effort low     # Respuestas rápidas, menos detalladas

Pattern multi-turn con /effort:

> /effort low
Tú: "¿Qué archivos tocan el manejo de pagos?"
Claude: [lista rápida de archivos]

> /effort high
Tú: "Ahora analiza src/payments/processor.ts. ¿Hay race conditions 
     en el manejo de webhooks concurrentes?"
Claude: [análisis profundo con reasoning extenso]

El Rol de CLAUDE.md en Multi-turn

Contexto persistente vs contexto conversacional

Hay dos tipos de contexto en Claude Code:

TipoFuenteDuraciónSobrevive a /clear
PersistenteCLAUDE.mdSiempreSí
ConversacionalTus mensajesSolo esta sesiónNo

CLAUDE.md es tu seguro. Si haces /clear, las convenciones del proyecto sobreviven porque están en CLAUDE.md, no en la conversación.

Qué poner en CLAUDE.md vs qué decir en la conversación

En CLAUDE.md — cosas que aplican siempre:

# Convenciones
- TypeScript strict, no any
- Tests con Vitest
- Errors extienden AppError
- Nombres de archivos en kebab-case

En la conversación — cosas específicas de esta tarea:

Tú: "Para este endpoint específicamente, quiero que el response 
     incluya paginación con cursor-based, no offset-based."

Anti-pattern: Repetir lo que ya está en CLAUDE.md

# MAL — repetir convenciones en cada mensaje:
Tú: "Crea un endpoint. Usa TypeScript strict, sin any, tests con Vitest, 
     errores que extiendan AppError, kebab-case para archivos..."

# BIEN — confiar en CLAUDE.md:
Tú: "Crea un endpoint GET /products con filtros por categoría y precio."

Claude ya leyó CLAUDE.md. No necesitas repetir lo que está ahí.


Comparaciones y Decisiones

"¿Cuántos mensajes debería tomar mi tarea?"

Complejidad de tareaMensajes típicosEjemplo
Trivial1Renombrar variable, agregar campo
Simple2-3CRUD endpoint, función utilitaria
Media4-8Feature completa con tests
Compleja8-15Sistema con múltiples componentes
Arquitectural10-20+Refactor grande, migración

Conversación productiva vs improductiva

Productiva:

Tú: "Crea endpoint POST /orders"         # Paso 1: acción clara
Claude: [crea endpoint]
Tú: "Agrega validación del body"          # Paso 2: refinamiento
Claude: [agrega validación]
Tú: "El campo total debe calcularse       # Paso 3: corrección específica
     server-side, no venir del cliente"
Claude: [corrige]
Tú: "Tests para happy path y 3 errores"   # Paso 4: testing
Claude: [crea tests]

4 mensajes, resultado completo, cada paso verificado.

Improductiva:

Tú: "Hazme un backend"                   # Demasiado vago
Claude: [hace algo genérico]
Tú: "No, eso no"                         # Sin feedback útil
Claude: [intenta de nuevo]
Tú: "Tampoco"                            # Sin dirección
Claude: [otro intento aleatorio]
Tú: "Olvídalo, voy a empezar de cero"   # Frustración

4 mensajes, ningún resultado, zero feedback accionable.


Patterns Comunes

Pattern: "Checkpoint and Continue"

Cuando llevas muchos mensajes, consolida antes de seguir.

Tú: "Antes de continuar, resume qué hemos hecho hasta ahora y qué falta."

Claude: "Hecho: 
         1. Endpoint POST /orders con validación
         2. Cálculo de total server-side
         3. Tests unitarios
         Falta:
         1. Endpoint GET /orders con paginación
         2. Endpoint GET /orders/:id
         3. Integration tests"

Tú: "Correcto. Continúa con GET /orders con cursor-based pagination."

Pattern: "Divide and Conquer"

Para tareas grandes, divide en mini-sesiones.

# Sesión 1: Diseño
Tú: "Estoy construyendo un sistema de facturación. 
     Diseña la estructura de datos y la API. Solo diseño, no código."
Claude: [diseña schema, endpoints, flujos]
Tú: "Ajusta: las facturas necesitan líneas de detalle, no solo un total."
Claude: [ajusta diseño]

# /clear o nueva sesión

# Sesión 2: Implementación del modelo
Tú: "Implementa el modelo de Invoice con las líneas de detalle. 
     Usa Prisma. El schema está en [referencia al diseño]."

# Sesión 3: Implementación de endpoints
# Sesión 4: Tests
# ...

Pattern: "Rubber Duck con Claude"

Usa Claude como rubber duck antes de pedirle que implemente.

Tú: "Necesito implementar retry logic para llamadas HTTP que fallen. 
     ¿Qué consideraciones debo tener?"

Claude: "Consideraciones:
         1. Exponential backoff vs fixed delay
         2. Qué errores son retryable (5xx, network) vs no (4xx)
         3. Máximo de reintentos
         4. Idempotency del request
         5. Circuit breaker para evitar cascading failures
         6. Logging de cada intento"

Tú: "Bien, implementa con exponential backoff, max 3 retries, 
     solo para 5xx y network errors. Sin circuit breaker por ahora."

Primero exploraste el espacio del problema. Ahora das instrucciones informadas.


Pitfalls y Edge Cases

Pitfall 1: El "sí, sí, sigue" sin verificar

# Peligroso:
Tú: "Crea la base de datos"
Claude: [crea schema con decisiones que no revisaste]
Tú: "Ok, ahora los endpoints"
Claude: [construye sobre un schema que podría estar mal]
Tú: "Ok, ahora el frontend"
Claude: [construye sobre endpoints que podrían estar mal]
# 30 minutos después descubres que el schema está mal → todo se cae

Solución: Verifica cada paso antes de continuar, especialmente los fundacionales (schema, arquitectura, estructura de datos).

Pitfall 2: Acumular contexto irrelevante

# La conversación empezó sobre auth, luego pasaste a payments, 
# luego a notifications. Claude tiene todo en contexto — y el 
# contexto de auth puede "contaminar" las decisiones de notifications.

# Solución: /clear o nueva sesión cuando cambias de tema significativamente

Pitfall 3: Prompts que anulan decisiones anteriores sin decirlo

Tú: "Usa PostgreSQL para la base de datos."
Claude: [implementa con pg]
# ... 5 mensajes después ...
Tú: "Ahora conecta a MongoDB."
# ¿Quieres reemplazar PostgreSQL o agregar MongoDB? Claude no sabe.

# Mejor:
Tú: "Reemplaza PostgreSQL por MongoDB. Migra todo el código de 
     acceso a datos que creamos antes."

Pitfall 4: No aprovechar CLAUDE.md para patterns repetitivos

Si cada vez le dices a Claude "usa async/await, no callbacks" o "pon los tests junto al archivo, no en carpeta separada" — eso debería estar en CLAUDE.md, no en cada conversación.

Pitfall 5: Conversaciones infinitas

Después de ~15-20 mensajes, la calidad tiende a degradar. El context window se llena, Claude pierde detalle de los mensajes iniciales. Si llegas a este punto:

  1. Usa /compact para comprimir
  2. O inicia nueva sesión con un resumen claro

Ejemplo Completo Integrado

Escenario: Construir un endpoint de búsqueda con filtros

Supón que tienes un proyecto Express + TypeScript + PostgreSQL y quieres agregar un endpoint GET /api/products/search.

# ─── Mensaje 1: Exploración ───
Tú: "Revisa cómo están implementados los endpoints existentes en 
     src/routes/ y src/controllers/. Quiero entender el pattern antes 
     de agregar uno nuevo."

Claude: [analiza el codebase]
Claude: "Pattern encontrado:
         - Rutas en src/routes/{resource}.routes.ts
         - Controllers en src/controllers/{resource}.controller.ts
         - Servicios en src/services/{resource}.service.ts
         - Validación con Zod en src/validators/{resource}.validator.ts
         - Todos usan el wrapper asyncHandler para errores"

# ─── Mensaje 2: Especificación ───
Tú: "Crea GET /api/products/search con estos filtros:
     - q (texto libre, busca en nombre y descripción)
     - category (enum: electronics, clothing, food)
     - minPrice, maxPrice (números)
     - sortBy (name, price, createdAt)
     - sortOrder (asc, desc)
     - page, limit (paginación offset)
     Solo crea el validator y los tipos por ahora."

Claude: [crea product-search.validator.ts con schema Zod]

# ─── Mensaje 3: Corrección ───
Tú: "Dos ajustes:
     1. category debe aceptar múltiples valores (array), no solo uno
     2. limit debe tener máximo 100 y default 20"

Claude: [ajusta el validator]

# ─── Mensaje 4: Service layer ───
Tú: "Ahora implementa el service. La búsqueda por texto debe usar 
     ILIKE de PostgreSQL, no full-text search (lo agregaremos después)."

Claude: [crea product-search.service.ts con query builder]

# ─── Mensaje 5: Revisión y mejora ───
Tú: "El query builder tiene SQL injection potencial en el campo sortBy. 
     No uses interpolación directa — valida contra una whitelist."

Claude: [corrige con whitelist de columnas permitidas]

# ─── Mensaje 6: Controller + Route ───
Tú: "Ahora el controller y la ruta. Sigue el pattern de asyncHandler 
     que usan los otros endpoints."

Claude: [crea controller y ruta]

# ─── Mensaje 7: Tests ───
Tú: "Tests con Vitest:
     - Búsqueda por texto (match y no match)
     - Filtro por categoría (una y múltiples)
     - Rango de precios
     - Paginación (primera página, segunda página, última página)
     - Sort en ambas direcciones
     - Validación: limit > 100, precio negativo"

Claude: [crea suite de tests completa]

# ─── Mensaje 8: Verificación final ───
Tú: "Ejecuta los tests."

Claude: [ejecuta vitest, muestra resultados]

8 mensajes. Resultado: Endpoint completo, validado, testeado, siguiendo las convenciones del proyecto. Cada paso fue verificado.


Ejercicios Prácticos

Ejercicio 1: Desarrollo incremental de un módulo

Abre Claude Code en un proyecto existente (o crea uno nuevo con npm init). Construye un módulo de logging en 4+ mensajes, usando el pattern de desarrollo incremental:

  1. Pide solo la interfaz/tipos primero
  2. Pide la implementación básica (console.log con formato)
  3. Agrega niveles (debug, info, warn, error)
  4. Agrega output a archivo además de consola
  5. Agrega rotación de archivos cuando supere 10MB

Verifica cada paso antes de continuar al siguiente.

Solución guiada
# Mensaje 1
"Crea un módulo de logging en src/logger/. Por ahora solo quiero 
la interfaz TypeScript: un tipo LogLevel (debug, info, warn, error), 
una interfaz LogEntry (timestamp, level, message, context optional), 
y la firma de la clase Logger con los métodos debug(), info(), warn(), error()."

# Mensaje 2
"Implementa Logger. Por ahora solo console.log con este formato:
[2026-02-28T10:30:00Z] [INFO] mensaje — {context}"

# Mensaje 3
"Agrega configuración: Logger debe aceptar { minLevel: LogLevel } 
en el constructor. Si minLevel es 'warn', debug e info se ignoran."

# Mensaje 4
"Agrega output a archivo. El constructor acepta { file?: string }. 
Si se pasa, escribe también a ese archivo con fs.appendFile."

# Mensaje 5
"Agrega rotación: si el archivo supera 10MB, renómbralo a 
app.log.1 y crea uno nuevo. Mantén máximo 3 archivos rotados."

Observa cómo cada mensaje es verificable y construye sobre el anterior.

Ejercicio 2: Dar feedback efectivo

Pide a Claude Code que cree una función formatCurrency(amount, locale). Intencionalmente no des mucho detalle en el primer mensaje. Luego practica los 5 tipos de feedback:

  1. Corrección: "El formato para MXN debe ser $1,000.00 no $1000"
  2. Redirección: "No uses Intl.NumberFormat, quiero implementación manual"
  3. Refinamiento: "Agrega soporte para criptomonedas (BTC con 8 decimales)"
  4. Confirmación: "Perfecto. Ahora los tests."
  5. Exploración: "¿Cómo manejamos monedas que no tienen decimales (JPY)?"
Solución guiada
# Primer mensaje (intencionalmente vago):
"Crea una función formatCurrency que formate números como moneda."

# Claude va a hacer algo genérico. Ahora practica feedback:

# Corrección:
"El resultado para formatCurrency(1000, 'es-MX', 'MXN') debería ser 
'$1,000.00' pero me da '$1000'. Agrega separador de miles."

# Redirección:
"Estás usando Intl.NumberFormat. Prefiero una implementación manual 
porque necesito control total del formato. Reescribe sin Intl."

# Refinamiento:
"Funciona bien para monedas fiat. Agrega soporte para criptomonedas: 
BTC con 8 decimales, ETH con 18 decimales (pero muestra max 6)."

# Confirmación + siguiente:
"Perfecto, eso es exactamente lo que necesitaba. Ahora crea tests 
para USD, MXN, EUR, JPY, BTC y ETH."

# Exploración:
"¿Cómo deberíamos manejar amounts muy pequeños en crypto? Por ejemplo, 
0.00000001 BTC — ¿notación científica o todos los decimales?"

El objetivo es notar la diferencia de calidad en las respuestas de Claude cuando das feedback específico vs vago.

Ejercicio 3: El pattern de debugging

Introduce intencionalmente un bug en tu código (o usa uno existente). Inicia una conversación de debugging con Claude Code:

  1. Describe el síntoma, no la causa
  2. Deja que Claude investigue
  3. Pide que explique la causa raíz
  4. Pide el fix
  5. Pide un test de regresión
Solución guiada
# Introduce un bug. Ejemplo: un off-by-one en paginación:
# En tu código, la página 2 repite el último item de la página 1.

# Mensaje 1: Síntoma
"Tengo un bug en la paginación de GET /products. Cuando pido 
page=2&limit=10, el primer item de la página 2 es el mismo que 
el último item de la página 1. El endpoint está en 
src/controllers/product.controller.ts."

# Mensaje 2: Pide investigación
"Revisa el cálculo del offset en el service y en la query SQL."

# Claude debería encontrar algo como:
# offset = (page - 1) * limit  ← correcto
# vs
# offset = page * limit - limit - 1  ← bug sutil
# vs
# OFFSET $1 con el valor equivocado

# Mensaje 3: Confirmación del diagnóstico
"¿Puedes confirmar ejecutando una query con page=1,limit=3 y 
page=2,limit=3 para ver el overlap?"

# Mensaje 4: Fix
"Corrígelo."

# Mensaje 5: Test de regresión
"Crea un test que específicamente verifique que no hay overlap 
entre páginas consecutivas."

Ejercicio 4: /clear vs /compact

Realiza este experimento para entender la diferencia:

  1. Inicia una conversación. Pide a Claude que analice un archivo
  2. Haz 3-4 mensajes de refinamiento
  3. Usa /compact. Pregúntale "¿qué hemos hecho?"
  4. Haz /clear. Pregúntale "¿qué hemos hecho?"

Compara las respuestas. Después de /compact, Claude tiene un resumen. Después de /clear, no sabe nada.

Qué observar

Después de /compact:

  • Claude recuerda el tema general
  • Puede referirse a decisiones tomadas
  • Pierde detalles específicos de código
  • CLAUDE.md sigue disponible

Después de /clear:

  • Claude NO recuerda nada de la conversación
  • Solo tiene CLAUDE.md como contexto
  • Es como empezar de cero (pero sin cerrar la terminal)
  • Útil cuando la conversación se "contaminó"

Conclusión: Usa /compact cuando quieres preservar contexto pero liberar espacio. Usa /clear cuando quieres borrón y cuenta nueva.

Ejercicio 5: Conversación productiva vs improductiva

Haz este ejercicio con cualquier tarea real. Primero, intenta completarla de la peor forma posible (prompts vagos, sin feedback, sin dirección). Anota cuántos mensajes tomó y si el resultado fue bueno. Luego, hazla de la mejor forma posible (incremental, feedback específico, verificación). Compara:

  • Número de mensajes
  • Calidad del resultado
  • Tiempo total
  • Frustración
Qué esperar

Típicamente:

  • Mal approach: 8-12 mensajes, resultado mediocre, mucho retrabajo, frustración alta
  • Buen approach: 4-6 mensajes, resultado bueno, progresión limpia, satisfacción

El buen approach suele tomar MENOS mensajes para un MEJOR resultado. No es más lento ser específico — es más rápido.

Ejercicio 6: Multi-turn con CLAUDE.md

  1. Crea o actualiza CLAUDE.md con 5 convenciones específicas de tu proyecto
  2. Inicia una nueva sesión de Claude Code
  3. Pide que cree algo sin mencionar las convenciones
  4. Verifica que Claude siguió las convenciones de CLAUDE.md
  5. Haz /clear
  6. Pide lo mismo de nuevo — verifica que las convenciones siguen aplicando
Qué observar

Esto demuestra que CLAUDE.md es contexto persistente. No importa si haces /clear o /compact o empiezas nueva sesión — CLAUDE.md siempre está ahí.

Si Claude NO siguió una convención de CLAUDE.md, puede ser porque:

  • La convención está redactada de forma ambigua
  • Hay un conflicto con otra instrucción
  • CLAUDE.md es demasiado largo y la convención se "pierde"

Esto es feedback para mejorar tu CLAUDE.md.


Resumen

  • Multi-turn conversations son la forma natural de trabajar con Claude Code. No intentes meter todo en un solo prompt.
  • El feedback es tu herramienta principal. Sé específico, da dirección, corrige con contexto.
  • 5 tipos de feedback: Corrección, redirección, refinamiento, confirmación, exploración.
  • Patterns clave: Desarrollo incremental, refinamiento iterativo, debugging conversacional, exploración antes de acción.
  • Un mensaje vs muchos: Si necesitas verificar un paso antes del siguiente, usa mensajes separados.
  • /clear borra todo. /compact resume y comprime. Úsalos estratégicamente.
  • CLAUDE.md es contexto persistente que sobrevive a /clear y /compact. Pon ahí lo que aplica siempre.
  • Verifica pasos fundacionales (schema, arquitectura) antes de construir sobre ellos.
  • ~15-20 mensajes es el límite práctico. Después, compacta o inicia nueva sesión.

Recursos Adicionales

  1. Claude Code Best Practices — Anthropic Docs — Workflows recomendados y gestión de contexto
  2. Claude Code Interactive Mode — Shortcuts, task management, y gestión de sesiones
  3. Claude Code CLI Reference — Comandos, flags, y opciones disponibles
  4. Claude Code Memory System — CLAUDE.md, auto memory, jerarquía de 6 niveles
  5. Prompting Best Practices — Anthropic Docs — Cómo estructurar instrucciones para Claude
  6. Claude Code Overview — Qué es, cómo funciona, plataformas disponibles