Saltar al contenido
Lección 10 de 12

Prompting Multi-Paso — Tareas Complejas

10 min read

Cuándo un Solo Prompt No Es Suficiente

Algunas tareas son demasiado complejas para un solo prompt. Si necesitas más de tres párrafos para describir lo que quieres, es probable que la IA pierda o malinterprete alguna parte. El prompting multi-paso divide tareas complejas en una cadena de prompts más simples, donde cada paso produce un resultado intermedio revisable antes de que el siguiente paso construya sobre él.

Esto no es un parche para limitaciones del modelo. Es un mejor flujo de trabajo incluso con modelos perfectos. Las tareas complejas tienen modos de fallo complejos. Cuando algo sale mal en una tarea de 10 pasos ejecutada como un solo prompt, tienes que depurar toda la salida. Cuando algo sale mal en el paso 4 de una cadena de 10 pasos, sabes exactamente dónde buscar y puedes corregir solo ese paso.

El Principio de Descomposición

El principio de descomposición es simple: si una tarea tiene múltiples fases distintas, cada fase debe ser su propio prompt. Las señales de que una tarea necesita descomposición:

  • Involucra múltiples archivos o componentes
  • Tiene una fase de planificación y una fase de ejecución
  • Requiere decisiones que dependen de resultados intermedios
  • Tomaría más de 3 párrafos describirla completamente
  • Diferentes partes requieren diferentes tipos de razonamiento (análisis vs. generación vs. revisión)

Prompt Único (Frágil)

Analiza nuestro codebase de autenticacion, encuentra todas las vulnerabilidades
de seguridad, propone correcciones para cada una, implementa las correcciones,
escribe tests para el nuevo codigo y actualiza la documentacion.

Este prompt le pide a la IA que haga seis cosas diferentes. Probablemente apresurará el análisis, pasará por alto vulnerabilidades, implementará parches rápidos en lugar de correcciones apropiadas y producirá tests superficiales.

Multi-Paso (Confiable)

Paso 1 -- Analizar:

Analiza el codigo de autenticacion en src/auth/ y src/middleware/auth.ts.
Lista cada vulnerabilidad de seguridad potencial que encuentres. Para cada
una, describe: el tipo de vulnerabilidad, la ubicacion especifica en el
codigo, el nivel de riesgo y el escenario de explotacion potencial. No
sugiera correcciones aun.

Paso 2 -- Priorizar (después de revisar Paso 1):

Basandote en las 7 vulnerabilidades que encontraste, priorízalas. Cuales
necesitan correcciones inmediatas y cuales pueden esperar? Considera:
explotabilidad, impacto y esfuerzo para corregir. Dame una lista ordenada.

Paso 3 -- Corregir (una a la vez):

Corrige la vulnerabilidad #1: el token JWT no se valida por expiracion en
el authMiddleware. Implementa la correccion en src/middleware/auth.ts. No
toques otros archivos aun.

Cada paso es simple, revisable y construye sobre la salida verificada del paso anterior.

El Patrón Planificar-Luego-Ejecutar

Este es el patrón multi-paso más común para desarrolladores. Le pides a la IA que cree un plan, revisas y apruebas el plan, y luego lo ejecutas paso a paso.

Paso 1 -- Planificar:

Necesito agregar un sistema de notificaciones a nuestra app Express.js. Los
usuarios deben recibir notificaciones in-app y notificaciones opcionales por
email para: nuevos comentarios en sus posts, nuevos seguidores y cambios de
estado de ordenes.

Antes de escribir codigo, crea un plan que cubra:
1. Cambios en el esquema de base de datos (que tablas/columnas agregar)
2. Nuevos archivos a crear (servicios, rutas, middleware)
3. Archivos existentes a modificar
4. El orden en que implementar estos cambios
5. Dependencias entre cambios (que debe hacerse antes de que)

Presenta el plan como una lista numerada que pueda revisar.

Paso 2 -- Revisar y ajustar:

Buen plan. Dos ajustes:
- Usar una tabla de notificaciones separada en lugar de agregar columnas a
  la tabla de usuarios
- Saltar notificaciones por email por ahora, las agregaremos en la fase 2
- Agregar integracion WebSocket para entrega en tiempo real en el paso 6

Actualiza el plan con estos cambios.

Paso 3 -- Ejecutar paso a paso:

Ejecuta el paso 1 del plan: Crea el esquema Prisma para la tabla de
notificaciones. Incluye la migracion.
El paso 1 se ve bien. Ejecuta el paso 2: Crea el NotificationService en
src/services/NotificationService.ts.
Veo un problema en el paso 2 -- el metodo createNotification tambien deberia
aceptar un campo metadata para datos JSON arbitrarios. Corrige eso, luego
pasa al paso 3.

Este patrón te da un punto de verificación entre cada paso. Si el plan de la IA tiene un defecto, lo atrapas antes de que se escriba código. Si el paso 3 introduce un bug, no necesitas rehacer los pasos 1 y 2.

Prompting Secuencial: La Salida Alimenta la Entrada

En el prompting secuencial, la salida de un paso se convierte en la entrada explícita del siguiente paso. Esto es útil para tareas donde cada paso transforma datos.

Ejemplo: Migración de Base de Datos

Paso 1: Analiza el esquema actual de la tabla orders y lista todas las
columnas con sus tipos, restricciones e indices.

Después de obtener el análisis del esquema:

Paso 2: Basandote en el esquema anterior, disena la migracion para dividir
la tabla orders en orders (info del encabezado) y order_items (items de
linea). Muestrame los nuevos esquemas lado a lado con la estrategia de
migracion de datos.

Después de aprobar el diseño del esquema:

Paso 3: Escribe el archivo de migracion Prisma que:
1. Cree la tabla order_items
2. Migre datos de la columna JSON items en orders a filas individuales
   en order_items
3. Elimine la columna items de orders
4. Agregue la restriccion de clave foranea

Usa una transaccion para asegurar atomicidad.

Después de la migración:

Paso 4: Actualiza el OrderService para usar el nuevo esquema. Los metodos
del servicio deben devolver la misma forma de datos que antes (ordenes con
array anidado de items) para mantener compatibilidad hacia atras con la
capa API.

Cada paso depende de la salida verificada del paso anterior. El diseño del esquema no puede escribirse sin el análisis. La migración no puede escribirse sin el esquema aprobado. La actualización del servicio no puede escribirse sin la migración completada.

Listas de Tareas y Checkpoints

Para tareas multi-paso más largas, mantiene una lista de tareas en ejecución que rastrea el progreso. Esto mantiene tanto a ti como a la IA alineados en lo que se ha hecho y lo que queda.

Aqui esta nuestra lista de tareas para la migracion del sistema de
notificaciones. Marca los items a medida que los completamos:

[x] 1. Crear esquema de tabla de notificaciones
[x] 2. Crear NotificationService
[x] 3. Crear rutas de notificaciones (GET /notifications, PATCH /read)
[ ] 4. Agregar triggers de notificacion en CommentService
[ ] 5. Agregar triggers de notificacion en FollowerService
[ ] 6. Agregar integracion WebSocket para entrega en tiempo real
[ ] 7. Escribir tests para NotificationService
[ ] 8. Escribir tests de integracion para triggers de notificacion

Acabamos de terminar el paso 3. Ahora implementa el paso 4: Agregar triggers
de notificacion en CommentService. Cuando se crea un nuevo comentario en un
post, crea una notificacion para el autor del post. Usa el metodo
NotificationService.create() del paso 2.

Esta lista de tareas sirve como estado compartido entre tú y la IA. Previene que la IA pierda el rastro de lo que se ha completado y qué patrones se establecieron en pasos anteriores.

El Patrón Checkpoint-y-Verificar

Después de cada paso, verifica explícitamente el resultado antes de proceder. Esto atrapa errores temprano y previene que se propaguen a través de la cadena.

Antes de pasar al paso 5, dejame verificar el paso 4. Revisa estas
verificaciones:

1. El metodo CommentService.createComment() llama a
   NotificationService.create() despues de crear exitosamente el comentario?
2. La notificacion solo se crea si el comentarista NO es el autor del post?
   (sin auto-notificaciones)
3. La notificacion incluye la vista previa del texto del comentario
   (primeros 100 caracteres)?
4. Si la creacion de la notificacion falla, el comentario aun se crea?
   (el fallo de notificacion no debe bloquear el comentario)

Verifica el codigo que escribimos en el paso 4 contra estos requisitos.

Los prompts de verificación atrapan bugs a nivel de paso en lugar de descubrirlos después durante la integración o el testing. Son especialmente importantes para requisitos de lógica de negocio que son fáciles de pasar por alto.

Manejando Fallos en Cadenas

Cuando un paso en la cadena produce salida incorrecta, necesitas corregirlo sin rehacer todos los pasos anteriores. La clave es proveer a la IA contexto claro sobre lo que está correcto (pasos anteriores) y lo que necesita corrección (el paso actual).

El paso 4 tiene un problema. El trigger de notificacion se dispara incluso
cuando el comentarista es el autor del post, creando auto-notificaciones.

Corrige solo este problema especifico en src/services/CommentService.ts. La
correccion debe agregar una verificacion: si comment.authorId === post.authorId,
omitir la creacion de la notificacion. No modifiques nada de los pasos 1-3.

Si un paso está fundamentalmente mal y no puede parchearse:

El paso 4 necesita rehacerse. El enfoque de llamar a NotificationService
directamente desde CommentService crea acoplamiento fuerte. En su lugar, usa
un patron de emisor de eventos:

- CommentService emite un evento 'comment:created' con los datos del comentario
- Un nuevo NotificationListener en src/listeners/ se suscribe a 'comment:created'
  y crea la notificacion

Reescribe el paso 4 con este enfoque. Los pasos 1-3 permanecen sin cambios.

Descomposición en Paralelo

No todas las tareas multi-paso son secuenciales. A veces los pasos pueden ejecutarse en paralelo porque son independientes.

Necesitamos agregar tres nuevos recursos de API. Son independientes y no
dependen entre si:

Tarea A: Crear el recurso Tags (endpoints CRUD + servicio + schema)
Tarea B: Crear el recurso Categories (endpoints CRUD + servicio + schema)
Tarea C: Crear el recurso Comments (endpoints CRUD + servicio + schema)

Para cada uno, seguir el mismo patron que nuestro recurso Products existente
en src/routes/products.ts, src/services/ProductService.ts y
src/schemas/product.ts.

Empecemos con la Tarea A. Despues de revisarla, haremos B y C.

Aunque las tareas son independientes, hacerlas secuencialmente te permite verificar que la primera establece el patrón correcto antes de replicarlo. Una vez aprobada la Tarea A, las Tareas B y C pueden seguir la misma plantilla con revisión mínima.

Cuándo Fusionar Pasos

A veces sobre-descompones y creas overhead innecesario. Fusiona pasos cuando:

  • Dos pasos son muy simples y naturalmente pertenecen juntos (crear un archivo y agregar su import)
  • El resultado intermedio de un paso no tiene valor para revisión (no necesitas aprobar la interfaz TypeScript antes de ver la implementación)
  • Los pasos son tan pequeños que el overhead de revisar cada uno excede el beneficio

El punto ideal son pasos lo suficientemente grandes para producir un artefacto significativo y revisable pero lo suficientemente pequeños para que puedas verificar la correctitud en menos de un minuto. Para la mayoría de tareas de desarrollo, esto significa un archivo o una unidad lógica por paso.