Saltar al contenido
Lección 10 de 12

Prompting Multi-Paso — Tareas Complejas

10 min read

Cuando un Solo Prompt No Es Suficiente

Algunas tareas son demasiado complejas para un solo prompt. Si necesitas mas de tres parrafos 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 mas simples, donde cada paso produce un resultado intermedio revisable antes de que el siguiente paso construya sobre el.

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 donde buscar y puedes corregir solo ese paso.

El Principio de Descomposicion

El principio de descomposicion es simple: si una tarea tiene multiples fases distintas, cada fase debe ser su propio prompt. Las senales de que una tarea necesita descomposicion:

  • Involucra multiples archivos o componentes
  • Tiene una fase de planificacion y una fase de ejecucion
  • Requiere decisiones que dependen de resultados intermedios
  • Tomaria mas de 3 parrafos describirla completamente
  • Diferentes partes requieren diferentes tipos de razonamiento (analisis vs. generacion vs. revision)

Prompt Unico (Fragil)

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 apresurara el analisis, pasara por alto vulnerabilidades, implementara parches rapidos en lugar de correcciones apropiadas y producira 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 (despues de revisar Paso 1):

Basandote en las 7 vulnerabilidades que encontraste, priorizalas. 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 Patron Planificar-Luego-Ejecutar

Este es el patron multi-paso mas comun 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 patron te da un punto de verificacion entre cada paso. Si el plan de la IA tiene un defecto, lo atrapas antes de que se escriba codigo. 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 explicita del siguiente paso. Esto es util para tareas donde cada paso transforma datos.

Ejemplo: Migracion 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.

Despues de obtener el analisis 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.

Despues de aprobar el diseno 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.

Despues de la migracion:

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 diseno del esquema no puede escribirse sin el analisis. La migracion no puede escribirse sin el esquema aprobado. La actualizacion del servicio no puede escribirse sin la migracion completada.

Listas de Tareas y Checkpoints

Para tareas multi-paso mas largas, mantiene una lista de tareas en ejecucion 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 tu y la IA. Previene que la IA pierda el rastro de lo que se ha completado y que patrones se establecieron en pasos anteriores.

El Patron Checkpoint-y-Verificar

Despues de cada paso, verifica explicitamente el resultado antes de proceder. Esto atrapa errores temprano y previene que se propaguen a traves 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 verificacion atrapan bugs a nivel de paso en lugar de descubrirlos despues durante la integracion o el testing. Son especialmente importantes para requisitos de logica de negocio que son faciles 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 esta correcto (pasos anteriores) y lo que necesita correccion (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 esta 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.

Descomposicion 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 patron correcto antes de replicarlo. Una vez aprobada la Tarea A, las Tareas B y C pueden seguir la misma plantilla con revision minima.

Cuando 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 revision (no necesitas aprobar la interfaz TypeScript antes de ver la implementacion)
  • Los pasos son tan pequenos 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 pequenos para que puedas verificar la correctitud en menos de un minuto. Para la mayoria de tareas de desarrollo, esto significa un archivo o una unidad logica por paso.