Saltar al contenido
Lección 4 de 12

Prompting para Depuracion

9 min read

Por Que los Prompts de Depuracion Son Diferentes

La depuracion es la tarea donde la calidad del prompt importa mas. Cuando generas codigo, un prompt mediocre aun te da algo con lo que trabajar. Cuando depuras, un prompt vago te da el diagnostico equivocado -- y la correccion equivocada puede introducir nuevos bugs mientras enmascara el original.

El desafio fundamental con los prompts de depuracion es que estas describiendo una brecha entre el comportamiento esperado y el actual. La IA necesita entender ambos lados de esa brecha, mas el codigo que los conecta, para identificar la causa raiz. Omite cualquier pieza y la IA adivinara -- y adivinar la causa de un bug es como pasas horas persiguiendo el problema equivocado.

La Plantilla de Prompt para Depuracion

Cada prompt efectivo de depuracion incluye cinco piezas de informacion:

1. COMPORTAMIENTO ACTUAL: Que pasa ahora mismo (el bug)
2. COMPORTAMIENTO ESPERADO: Que deberia pasar en su lugar
3. PASOS PARA REPRODUCIR: Como disparar el bug
4. MENSAJE DE ERROR: El texto exacto del error, stack trace o log
5. CONTEXTO DE CODIGO RELEVANTE: El codigo involucrado en el bug

Veamos cada componente en accion.

Comportamiento Actual

Malo:

La app esta rota

Bueno:

Cuando un usuario envia el formulario de registro con un email y password
validos, la API devuelve un codigo de estado 500 en lugar de crear la cuenta
de usuario.

Se especifico sobre lo que pasa: la pagina se rompe? Muestra un error? Se cuelga? Devuelve datos incorrectos? Falla silenciosamente?

Comportamiento Esperado

Malo:

Deberia funcionar

Bueno:

La API deberia crear un nuevo registro de usuario en la base de datos, hashear
el password con bcrypt, y devolver un codigo de estado 201 con el objeto de
usuario (sin el campo de password).

Definir el comportamiento esperado ayuda a la IA a entender tu intencion. A veces el "bug" es en realidad el codigo funcionando como fue disenado pero no coincidiendo con tus expectativas -- la IA necesita conocer tus expectativas para distinguir entre ambas situaciones.

Pasos para Reproducir

Pasos para reproducir:
1. Navegar a /register
2. Ingresar email: test@example.com, password: "ValidPass123!"
3. Hacer clic en "Crear Cuenta"
4. Observar la pestana de red: POST /api/auth/register devuelve 500

Esto sucede con cada email nuevo. Los emails existentes correctamente
devuelven 409.

Los pasos de reproduccion ayudan a la IA a rastrear la ruta de ejecucion exacta. Incluir lo que funciona (emails existentes devuelven 409) es tan importante como lo que no funciona porque reduce donde vive el bug.

Mensaje de Error

Siempre incluye el texto exacto del error. Copia y pega -- no parafrasees.

Malo:

Muestra algun tipo de error de base de datos

Bueno:

Error de los logs del servidor:

PrismaClientKnownRequestError:
Invalid `prisma.user.create()` invocation:
The required column `user.email_verified` has no default value, and no value
was provided in the create data.

at src/routes/auth.ts:47:28
at processTicksAndRejections (node:internal/process/task_queues:95:5)

El mensaje de error exacto le dice a la IA precisamente que salio mal. En este caso, la IA puede identificar inmediatamente que la columna email_verified es requerida pero no se esta estableciendo en la llamada create -- una correccion de una linea.

Contexto de Codigo Relevante

Proporciona el codigo involucrado en el bug. No copies el archivo completo -- enfocate en la funcion relevante y sus dependencias inmediatas.

Aqui esta el handler de registro (src/routes/auth.ts, lineas 35-55):

async function register(req: Request, res: Response) {
  const { email, password } = req.body;
  const hashedPassword = await bcrypt.hash(password, 10);
  const user = await prisma.user.create({
    data: {
      email,
      passwordHash: hashedPassword,
    },
  });
  res.status(201).json({ id: user.id, email: user.email });
}

Y aqui esta el esquema Prisma para User:

model User {
  id             String   @id @default(uuid())
  email          String   @unique
  passwordHash   String
  emailVerified  Boolean
  createdAt      DateTime @default(now())
}

Con los cinco componentes, la IA puede ver inmediatamente que emailVerified es un Boolean requerido sin valor por defecto, y la llamada create no lo incluye. Solucion: agregar emailVerified: false a los datos de creacion o agregar @default(false) al esquema.

Poniendolo Todo Junto

Aqui hay un prompt de depuracion completo que combina los cinco componentes:

Bug: El endpoint de registro devuelve 500 para nuevos usuarios.

Comportamiento actual: POST /api/auth/register devuelve 500 con un error de
Prisma al crear un nuevo usuario con email y password validos.

Comportamiento esperado: Deberia crear el usuario y devolver 201 con el
objeto de usuario.

Pasos para reproducir: POST a /api/auth/register con body
{ "email": "new@test.com", "password": "ValidPass123!" }. Sucede para cada
email nuevo. Email existente correctamente devuelve 409 Conflict.

Mensaje de error:
PrismaClientKnownRequestError: Invalid `prisma.user.create()` invocation:
The required column `user.email_verified` has no default value.
at src/routes/auth.ts:47:28

Codigo relevante: El handler register en src/routes/auth.ts crea un usuario
con solo los campos email y passwordHash, pero el esquema Prisma requiere
emailVerified (Boolean sin valor por defecto).

Por favor corrige este bug y explica la causa raiz.

La Tecnica de Alcance Estrecho

Una de las tecnicas de depuracion mas valiosas es estrechar el alcance de tu descripcion. Cuanto mas amplio el alcance, mas tiene que buscar la IA. Cuanto mas estrecho el alcance, mas enfocada la correccion.

Alcance amplio (lento, frecuentemente incorrecto):

El sistema de autenticacion no esta funcionando correctamente. Los usuarios
tienen problemas para iniciar sesion.

Alcance estrecho (rapido, preciso):

El formulario de login en src/pages/Login.tsx se envia exitosamente
(POST /api/auth/login devuelve 200 con un JWT valido), pero el hook useAuth()
en AuthContext no actualiza isAuthenticated a true. El router.push('/dashboard')
en la linea 42 de Login.tsx se dispara antes de que la actualizacion de estado
se complete, asi que el guard de autenticacion de la ruta del dashboard
redirige de vuelta a login. Esto crea un bucle de redireccion infinito entre
/login y /dashboard.

El prompt de alcance estrecho le da a la IA una imagen completa de la cadena del bug. Sabra inmediatamente que debe mirar el timing de la actualizacion de estado asincrono, no la validacion de JWT, la respuesta de la API, ni el envio del formulario.

Patrones Comunes de Prompts de Depuracion

Patron 1: Explica Este Error

Explica este error en el contexto de mi proyecto Express + Prisma + TypeScript:

TypeError: Cannot read properties of undefined (reading 'id')
    at getUserOrders (src/routes/orders.ts:23:35)
    at Layer.handle (node_modules/express/lib/router/layer.js:95:5)

La funcion getUserOrders intenta acceder a req.user.id, pero req.user es
undefined. El authMiddleware deberia adjuntar el objeto usuario a req. Aqui
esta el codigo del middleware: [pegar middleware]. Aqui esta el registro de
la ruta: [pegar configuracion de ruta].

Patron 2: Por Que X Devuelve Y en Lugar de Z

En src/utils/dateFormatter.ts, la funcion formatRelativeDate('2026-03-25')
devuelve "en 0 dias" en lugar de "ayer" cuando se llama el 26 de marzo de 2026.

Aqui esta la funcion:
[pegar codigo de la funcion]

Espero que devuelva "ayer" para fechas exactamente un dia en el pasado.
Parece que el calculo de diferencia de dias esta redondeando hacia abajo en
lugar de usar el limite del dia calendario.

Patron 3: Rastrear el Flujo de Datos

Rastrear el flujo de datos de la orden de un usuario desde la creacion hasta
la visualizacion:

1. Usuario hace clic en "Realizar Pedido" en src/components/Checkout.tsx
2. Esto llama a createOrder() en src/services/orderService.ts
3. Que hace POST a /api/orders
4. El handler en src/routes/orders.ts crea la orden con Prisma
5. La respuesta regresa al frontend
6. La orden deberia aparecer en src/pages/OrderHistory.tsx

La orden se crea en la base de datos (puedo verla en psql), pero no aparece
en la pagina OrderHistory. En que punto de esta cadena se estan perdiendo
los datos?

[pegar codigo relevante de la consulta de lista de ordenes y el componente]

Incluyendo Contexto de Entorno

A veces los bugs son especificos del entorno. Cuando sospechas esto, incluye los detalles del entorno:

Este bug solo sucede en produccion, no en desarrollo local.

Entorno:
- Node.js 20.11.0 (produccion), 20.10.0 (local)
- PostgreSQL 15 en AWS RDS (produccion), PostgreSQL 15 Docker local
- Detras de AWS ALB con terminacion SSL
- Variables de entorno configuradas via AWS Secrets Manager

La API devuelve datos correctos localmente pero devuelve arrays vacios en
produccion para la misma consulta de base de datos. La base de datos tiene
datos (verificado con conexion directa psql).

Sospecho que el string de conexion a la base de datos o la configuracion
SSL podrian diferir. Aqui esta nuestra configuracion de conexion a la base
de datos: [pegar codigo]

Anti-Patron: El Volcado de Logs

No pegues 200 lineas de logs y digas "encuentra el bug." La IA se perdera en informacion irrelevante y podria enfocarse en advertencias o ruido en lugar del error real.

Malo:

Aqui estan los logs, encuentra que esta mal:
[200 lineas de logs mezclados de info, warning y error]

Bueno:

Aqui esta el error relevante de los logs (filtrado de la salida completa):

[ERROR] 2026-03-26T10:15:32Z OrderService.createOrder: Foreign key constraint
failed on field `customerId`. Customer ID "cust_abc123" does not exist in the
customers table.

Este error ocurre al procesar ordenes desde nuestro webhook handler. El
webhook recibe eventos de Stripe, y el customerId viene del metadata del
cliente en Stripe. Creo que el problema es que no estamos creando el registro
del cliente antes de procesar la primera orden.

Filtra tus logs. Resalta el error relevante. Proporciona tu hipotesis. Esto convierte una investigacion de 10 minutos en una correccion de 30 segundos.

La Tecnica de la Hipotesis

Cuando tienes una teoria sobre lo que esta mal, incluyela. Incluso si tu hipotesis es incorrecta, le da a la IA un punto de partida y le muestra donde ya has investigado.

Bug: La conexion WebSocket se cae cada 60 segundos.

Mi hipotesis: Nuestro proxy inverso Nginx tiene un proxy_read_timeout por
defecto de 60 segundos, y los frames WebSocket no se estan enviando con
suficiente frecuencia para mantener la conexion viva. Creo que necesitamos
ya sea un heartbeat ping/pong o un timeout aumentado.

Configuracion relevante: [pegar config de Nginx]
Configuracion de WebSocket: [pegar codigo WS del servidor]

Es correcta mi hipotesis? Si no, que mas podria causar desconexiones
exactamente cada 60 segundos?

Esto evita que la IA explore caminos sin salida y enfoca el analisis en las causas mas probables. Y si tu hipotesis es incorrecta, la IA explicara por que y sugerira alternativas.