Metacognition & Self-Correction

Agents that self-evaluate, self-correct, and continuously improve

What Is Metacognition?

Metacognition = “thinking about thinking”. For AI Agents, this means the ability to self-evaluate performance, recognize mistakes, and self-correct without human intervention.

Why Metacognition Matters

Without metacognition:
  User: "Find flights to Tokyo"
  Agent: Search → Return results (may be wrong/incomplete) → Done

With metacognition:
  User: "Find flights to Tokyo"
  Agent: Search → Evaluate results → "Are these prices reasonable?"
       → "Am I missing any airlines?" → Search more → Return better results

Self-Reflection Pattern

The agent asks itself after each step:

import { generateObject, generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

const SelfReflectionSchema = z.object({
  taskCompleted: z.boolean(),
  qualityScore: z.number().min(1).max(10),
  issues: z.array(z.object({
    type: z.enum(["accuracy", "completeness", "relevance", "format"]),
    description: z.string(),
    severity: z.enum(["low", "medium", "high"])
  })),
  shouldRetry: z.boolean(),
  improvementPlan: z.string().optional()
});

async function agentWithReflection(task: string) {
  // Step 1: Execute task
  const result = await generateText({
    model: openai("gpt-4o"),
    tools: { /* ... */ },
    maxSteps: 5,
    prompt: task
  });

  // Step 2: Self-reflection
  const { object: reflection } = await generateObject({
    model: openai("gpt-4o"),
    schema: SelfReflectionSchema,
    prompt: `Evaluate this output:
Task: ${task}
Output: ${result.text}

Ask yourself:
1. Is the output accurate?
2. Is any important information missing?
3. Is the output relevant to the question?
4. Is the format appropriate?`
  });

  // Step 3: Retry if needed
  if (reflection.shouldRetry && reflection.qualityScore < 7) {
    console.log(`🔄 Self-correcting: ${reflection.improvementPlan}`);

    const improved = await generateText({
      model: openai("gpt-4o"),
      prompt: `Improve the previous output:
Original: ${result.text}
Issues found: ${reflection.issues.map(i => i.description).join(", ")}
Improvement plan: ${reflection.improvementPlan}`
    });

    return improved.text;
  }

  return result.text;
}

Corrective RAG With Metacognition

Combining RAG + self-correction:

async function correctiveRAG(question: string, maxAttempts: number = 3) {
  let attempts = 0;
  let bestAnswer = "";
  let bestScore = 0;

  while (attempts < maxAttempts) {
    attempts++;

    const docs = await searchDocuments(question);

    const answer = await generateText({
      model: openai("gpt-4o"),
      system: "Answer based on documents. If insufficient info, say so clearly.",
      prompt: `Question: ${question}\nDocuments: ${docs.map(d => d.content).join("\n")}`
    });

    // Metacognitive evaluation
    const { object: evaluation } = await generateObject({
      model: openai("gpt-4o"),
      schema: z.object({
        relevanceScore: z.number().min(1).max(10),
        isGrounded: z.boolean().describe("Is the answer grounded in the documents?"),
        missingInfo: z.array(z.string()),
        suggestedQuery: z.string().optional()
      }),
      prompt: `Evaluate this answer:
Q: ${question}
A: ${answer.text}
Docs: ${docs.map(d => d.content).join("\n")}`
    });

    if (evaluation.relevanceScore > bestScore) {
      bestScore = evaluation.relevanceScore;
      bestAnswer = answer.text;
    }

    if (evaluation.relevanceScore >= 8 && evaluation.isGrounded) break;

    if (evaluation.suggestedQuery) {
      question = evaluation.suggestedQuery;
      console.log(`🔄 Attempt ${attempts}: Refining to "${question}"`);
    }
  }

  return bestAnswer;
}

Experience-Based Learning

Agents learn from experience across sessions:

interface Experience {
  task: string;
  approach: string;
  outcome: "success" | "failure";
  lesson: string;
  timestamp: Date;
}

async function saveExperience(exp: Experience) {
  await supabase.from("agent_experiences").insert(exp);
}

async function recallExperiences(currentTask: string): Promise<Experience[]> {
  const embedding = await getEmbedding(currentTask);
  const { data } = await supabase.rpc("match_experiences", {
    query_embedding: embedding,
    match_count: 5
  });
  return data;
}

async function agentWithExperience(task: string) {
  const pastExperiences = await recallExperiences(task);

  const result = await generateText({
    model: openai("gpt-4o"),
    system: `You are an agent with metacognitive capabilities.
    
Past experiences from similar tasks:
${pastExperiences.map(e => `- Task: ${e.task}, Outcome: ${e.outcome}, Lesson: ${e.lesson}`).join("\n")}

Use these experiences to avoid past mistakes and apply effective approaches.`,
    prompt: task
  });

  await saveExperience({
    task,
    approach: "...",
    outcome: "success",
    lesson: "...",
    timestamp: new Date()
  });

  return result.text;
}

Metacognition Checklist

A good agent asks itself these questions:

QuestionPurpose
Is my output accurate?Accuracy
Did I miss anything?Completeness
Is my approach optimal?Efficiency
Do I need more tools?Tool selection
Will the user be satisfied?User satisfaction
Should I stop or continue?Termination

Summary

  • Metacognition = agents that self-evaluate and self-correct
  • Self-reflection through structured evaluation after each step
  • Corrective RAG: evaluate → refine → retry automatically
  • Experience-based learning: save and recall past experiences
  • Agent knows when to stop — avoid infinite improvement loops