The "Reflection" Pattern for Reducing Errors in Autonomous Agents

By Carlos Montiel | Enterprise AI Specialist
Leer en español →
Published: 2026-07-28 | By: Carlos Montiel | Reading time: ~5 minutes

An agent that executes a task and delivers the result without reviewing it has the same reliability as a developer pushing straight to production with no tests. The reflection pattern is, in essence, that verification step applied to agents.

What the reflection pattern actually is

Reflection (or self-critique) is an architectural pattern where, after an agent generates a result or completes an action, a separate step -- either the same model in another call, a different model, or a dedicated sub-agent -- evaluates that result against explicit criteria before treating it as final. If the evaluation finds a problem, the agent revises and retries; if not, the result gets delivered.

The key difference from "asking the model to review its own work in the same response" is that reflection happens in a separate context, with a different goal (critique, not generate) and often with a different model or effort level dedicated exclusively to that evaluation.

Why separating generation from critique matters

When you ask the same model, in the same generation pass, to "review its work before answering," the model tends to confirm its own reasoning -- the same bias that makes it hard for a human to find their own typos. Separating the critique into a distinct call, with a prompt focused solely on finding flaws (not on producing the result), breaks that confirmation bias.

def execute_with_reflection(task, max_iterations=3): result = generate(task) for i in range(max_iterations): critique = evaluate_result(task, result) if critique["approved"]: return result result = revise(task, result, critique["issues"]) # Iterations exhausted -- deliver with a warning, # don't fail silently return result, "incomplete_review_after_max_iterations"

The evaluation prompt needs verifiable criteria, not vibes

The most common mistake when implementing reflection: asking the evaluator to "check if this is good" with no explicit criteria. This produces inconsistent evaluations that sometimes approve bad results and sometimes reject good ones. The evaluation needs a rubric -- concrete criteria, each independently verifiable.

evaluator_prompt = f""" Evaluate this result against the following criteria. For each one, answer MEETS or DOES NOT MEET with a one-line justification. Don't evaluate criteria in aggregate -- each one separately. Original task: {task} Result to evaluate: {result} Criteria: 1. Does the answer use only data present in the provided context? 2. Does the output format exactly match what was requested? 3. Were all points of the task addressed, not just the main one? 4. Is there any claim that contradicts the context? Only mark "approved: true" if ALL criteria are met. """

Vague criteria ("is it well written?") produce noisy evaluations. Specific, verifiable criteria produce evaluations you can trust to automatically gate whether something gets retried or delivered.

Reflection in agents with tools: verify the action, not just the text

In agents that execute actions (API calls, database writes, system changes), reflection must verify the action's effect, not just the generated text. An effective pattern: after an action with side effects, the agent runs a verification step that reads the resulting state and confirms it matches what was expected -- before reporting success to the user.

def execute_action_with_verification(action, expected_result): execute(action) current_state = read_system_state(action.target) verification = client.messages.create( model="claude-haiku-4-5", max_tokens=256, messages=[{ "role": "user", "content": f""" This action was executed: {action} This result was expected: {expected_result} The system's current state is: {current_state} Does the current state confirm the action had the expected effect? Answer CONFIRMED or NOT_CONFIRMED with an explanation. """ }], ) return verification

This extra step, on an agent that deletes records, sends emails, or modifies configurations, is the difference between "the agent said it did it" and "the agent confirmed it actually happened."

When reflection isn't worth the extra cost

Reflection at least doubles the cost and latency of every task -- it isn't free, and not everything justifies the spend. Apply the same "is the agent worth it?" criteria you'd use for any architecture decision:

- **Cost of the error:** if an error is easily caught and fixed afterward (a typo in a draft), reflection adds little value. If an error is expensive or hard to reverse (a transaction, a message sent to a customer), reflection pays for itself. - **Task complexity:** for simple classification or deterministic extraction, the reflection step rarely finds anything worth the extra cost. - **Volume:** in high-volume pipelines, consider reflecting on only a sample percentage of outputs (for quality monitoring) instead of 100%, if reflecting on everything is prohibitively expensive.

Limit the iterations -- reflection isn't an infinite loop

Without an explicit limit, a generate-critique-revise cycle can spin indefinitely on a genuinely ambiguous or impossible-to-satisfy task. Define an explicit `max_iterations`, and have a clear exit path when it's exhausted -- never a silent, bottomless loop.

# The right pattern: explicit floor with quality metadata attached if iterations_used >= max_iterations and not critique["approved"]: deliver_result( result, metadata={"quality": "unverified", "reason": critique["issues"]}, ) alert_for_human_review(task, result)

Reflection as part of a larger architecture, not an isolated patch

The reflection pattern works best combined with the other techniques in this series -- not as a substitute for them. Well-structured context (precise RAG) reduces the need for reflection by minimizing errors at the source; explicit calibration instructions (having the model admit uncertainty) reduce false "approvals" at the critique stage; and a versioned regression set (from the versioned-prompts article) tells you whether the reflection step itself is degrading over time.

Well implemented, the reflection pattern isn't generically "making the agent think twice" -- it's building a second pair of eyes with explicit criteria, separate from the first generation step, exactly where the cost of the error justifies it.

Carlos Montiel
Enterprise AI Solutions Architect
Specialist in LLMs, Agents, and Orchestration
guatemalia.com/en/#contact · info@guatemalia.com

Need to implement AI at your company?

Carlos Montiel is an enterprise AI solutions architect. He implements LLMs, Agents, RAG, and orchestrators for companies across Guatemala and Latin America. Reach out for a consultation.

Contact Carlos Montiel

info@guatemalia.com