Sesión 5 · Planeación

Ejecuta el plan paso a paso

Analiza cada etapa en secuencia, conserva sus findings y envía el paso actual junto al contexto anterior.

30 min aprox.4 pasosPráctica + comprobación
Qué aprenderás
  • Recorrer los pasos con await secuencial.
  • Acumular los análisis anteriores en findings.
  • Evitar que un ternario omita el paso actual en iteraciones posteriores.

Referencias de código

Índice de esta lección

Paso 1

Construye el prompt de cada etapa

Cada llamada debe recibir la misión original, los resultados anteriores si existen y el paso actual. Aquí aislamos esa construcción para poder probarla sin un modelo.

La rama consultada coloca Paso actual dentro de la alternativa vacía del ternario. Así puede desaparecer cuando findings ya contiene elementos. La adaptación construye previous por separado y añade siempre el paso actual.

src/patterns/02-planning/context.ts
Paso 1 · typescript
export function buildStepPrompt(mission: string, findings: string[], step: PlanStep) {  const previous = findings.length    ? `Resultados anteriores (por verificar):\n${findings.join("\n---\n")}\n\n`    : "";  return `Misión original:\n${mission}\n\n${previous}Paso actual: ${step.goal}\nMotivo: ${step.reason}`;}

Qué deberías observar

El paso actual está presente tanto en la primera como en las siguientes iteraciones.

Paso 2

Espera cada resultado antes de avanzar

for...of con await termina una etapa antes de comenzar la siguiente. Los resultados del paso previo no están disponibles si lanzas todas las llamadas a la vez.

El modelo devuelve un análisis que se añade a findings. Es texto generado que requiere revisión: no lo tratamos como un hecho verificado solo por haberlo recibido.

Si una etapa falla, esta función propaga el error y no continúa silenciosamente con un resultado ausente.

src/patterns/02-planning/context.ts
Paso 2 · typescript
export async function executePlanSteps(  steps: PlanStep[],  mission: string,  runStep: (prompt: string, index: number) => Promise<string>,) {  const validated = planSchema.parse({ steps }).steps;  const findings: string[] = [];  for (const [index, step] of validated.entries()) {    const text = await runStep(buildStepPrompt(mission, findings, step), index);    findings.push(`[${step.goal}]\n${text.trim()}`);  }  return findings;}

Qué deberías observar

El siguiente prompt incluye los análisis completados hasta ese momento.

Paso 3

Limita el análisis al paso indicado

Las instrucciones piden resolver solo la etapa actual y conservar las reglas. La razón del paso aporta contexto sobre su posición.

La orden textual no garantiza obediencia. Revisa los findings por si el modelo se adelanta, contradice una restricción o reutiliza un error anterior.

src/patterns/02-planning/planning.ts
Paso 3 · typescript
const findings = await executePlanSteps(steps, mission, async (prompt, index) => {  console.log(`Analizando paso ${index + 1}`);  const { text } = await generateText({    model, prompt,    instructions: "Resuelve únicamente el paso indicado. No te adelantes ni presentes el operativo final. Mantén las reglas de la misión.",    onStepEnd: tracer.onStepFinish,  });  return text;});

Qué deberías observar

Puedes rastrear la llamada asociada a cada etapa.

Paso 4

Distingue acumulación de síntesis

findings.join lleva todos los resultados anteriores a la próxima llamada. Es acumulación explícita de contexto, no una compresión automática ni memoria permanente del chat.

Al crecer findings, los prompts pueden consumir más tokens. Los resultados se etiquetan con su objetivo para no perder su origen; la síntesis final se incorpora en la siguiente clase.

Registro de findings
Paso 4 · typescript
findings.push(`[${step.goal}]\n${text.trim()}`);// El resultado es texto de análisis; todavía hay que comprobarlo.

Qué deberías observar

Reconoces cómo se conserva el contexto y por qué puede crecer su consumo.

Ahora te toca

Prueba la idea por tu cuenta

Construye el prompt del segundo paso con un finding previo. Comprueba que incluya la misión, ese finding y el segundo objetivo. Explica por qué Promise.all no sirve para estas dependencias.

Necesito una pista

El paso actual se añade fuera del ternario y cada llamada espera a la anterior.

Comparar con una solución

buildStepPrompt siempre añade Paso actual. previous solo decide si incluir resultados previos. Promise.all iniciaría etapas antes de tener los análisis que necesitan.

Antes de seguir

Comprueba lo que aprendiste

No es una nota. Es una pausa para comprobar que la idea quedó clara.

1. ¿Qué debe contener el segundo prompt?
2. ¿Por qué se usa await dentro del bucle?
3. ¿Un finding es automáticamente correcto?

¿Terminaste la práctica?

Haz el ejercicio y comprueba tus respuestas antes de marcar la lección como completada.

Apuntes y código de esta lección