39.4 Multi-step reasoning with enforced intermediate artifacts

Overview and links for this section of the guide.

The Concept

Complex reasoning is more reliable when you force the model to produce intermediate artifacts. Instead of jumping from question to answer:

Question → [black box] → Answer

Break it into explicit steps:

Question → Plan → Analysis → Draft → Verification → Answer

Each artifact is checkable and provides a checkpoint for error detection.

Intermediate Artifacts

// Define the artifacts for a code analysis task
interface AnalysisArtifacts {
  // Step 1: Understanding
  problemStatement: {
    summary: string;
    constraints: string[];
    successCriteria: string[];
  };
  
  // Step 2: Research
  relevantCode: {
    file: string;
    excerpt: string;
    relevance: string;
  }[];
  
  // Step 3: Analysis
  findings: {
    observation: string;
    implication: string;
    confidence: number;
  }[];
  
  // Step 4: Conclusion
  recommendation: {
    action: string;
    rationale: string;
    risks: string[];
  };
}

Implementation

// multi-step-reasoning.ts
export async function analyzeWithArtifacts(
  question: string
): Promise {
  const artifacts: Partial = {};
  
  // Step 1: Problem Understanding
  artifacts.problemStatement = await model.generate({
    prompt: `
      Given this question, produce a structured problem statement.
      
      Question: ${question}
      
      Output JSON:
      {
        "summary": "One sentence problem summary",
        "constraints": ["constraint 1", "constraint 2"],
        "successCriteria": ["what must be true for success"]
      }
    `,
    schema: ProblemStatementSchema
  });
  
  // Validate before proceeding
  if (!artifacts.problemStatement.summary) {
    throw new Error('Failed to understand problem');
  }
  
  // Step 2: Research
  artifacts.relevantCode = await model.generate({
    prompt: `
      Based on this problem statement, identify relevant code sections.
      
      Problem: ${JSON.stringify(artifacts.problemStatement)}
      Codebase: ${codebaseContext}
      
      Output: Array of relevant code excerpts with explanations.
    `,
    schema: RelevantCodeSchema
  });
  
  // Step 3: Analysis
  artifacts.findings = await model.generate({
    prompt: `
      Analyze the code in the context of the problem.
      
      Problem: ${JSON.stringify(artifacts.problemStatement)}
      Relevant Code: ${JSON.stringify(artifacts.relevantCode)}
      
      For each finding, include confidence level 0-1.
    `,
    schema: FindingsSchema
  });
  
  // Step 4: Synthesize
  artifacts.recommendation = await model.generate({
    prompt: `
      Based on all previous analysis, provide a recommendation.
      
      Problem: ${JSON.stringify(artifacts.problemStatement)}
      Findings: ${JSON.stringify(artifacts.findings)}
      
      Be specific about actions, rationale, and risks.
    `,
    schema: RecommendationSchema
  });
  
  return artifacts as AnalysisArtifacts;
}

// The power: you can inspect/override any intermediate step
const result = await analyzeWithArtifacts(question);

console.log('Problem understood as:', result.problemStatement);
console.log('Found relevant code:', result.relevantCode.length, 'excerpts');
console.log('Key findings:', result.findings);
console.log('Recommendation:', result.recommendation);
Show Your Work

Intermediate artifacts serve as "showing your work" for AI. Users can verify reasoning step by step, and you can pinpoint exactly where reasoning goes wrong.

Where to go next