The Agent Loop and Acting
Reflection and self-correction
Reflexion, self-critique loops
An agent's first attempt is a draft. Reflection is the discipline of turning that draft into a better one: the model reads its own previous attempt plus a signal about what went wrong, and produces a fix. Done right, it is how a coding agent goes from red tests to green with no human in the loop. Done wrong, it is a model cheerfully congratulating itself on a broken answer. The whole difference is one ingredient, an external verifier.
Reflection is sequential self-improvement
In the canonical anatomy of an LLM agent, planning has three sub-capabilities: decomposition (break the goal into steps), reasoning (think each step through), and reflection (critique past actions and refine).[1] You met the first two in the previous lesson. This one is the third leg, the loop that lets an agent learn from its own mistakes within a single task, without any training.
Reflection is sequential: attempt to feedback to better attempt, each one conditioned on the last. That makes it fundamentally different from simply retrying from scratch (which throws the mistake away) and from (which votes across independent samples and never reads a result). Reflection's power, and its danger, is that the model is grading and revising its own work.
The evaluator-optimizer loop
The simplest useful shape is a two-role workflow that Anthropic calls : one LLM generates a candidate, another evaluates it against explicit criteria and returns feedback, and the loop repeats until the criteria are met.[2]
Tap a node to see what it does.
The catch is in that last clause. This pattern earns its cost only when you have clear evaluation criteria and refinement demonstrably improves the result.[2] If "the criteria" is just the same model's opinion, you have built a machine for agreeing with yourself. Hold that thought, it is the crux of this lesson.
Reflexion: write the post-mortem, then retry
(Shinn et al., 2023) is the canonical algorithm that makes reflection concrete and gives it a memory.[3] Four moving parts:
- Actor. An LLM (often a ReAct-style loop) attempts the task and produces a trajectory.
- Evaluator. Turns the outcome into a reward signal: binary/scalar, from unit tests, or from environment feedback.
- Self-reflection model. Converts that sparse signal plus the trajectory into verbal feedback: a natural-language note on what went wrong and how to fix it.
- Episodic memory. Stores that reflection (the working buffer holds ~3 recent ones) and prepends it as context on the next trial. Then the actor retries.
No weights are updated, the model improves purely by reading its own written post-mortems. The authors call this "verbal reinforcement learning."[3] On code generation it reached 91% pass@1 on HumanEval, beating the then-GPT-4 baseline of 80%, precisely because the evaluator was a suite of unit tests, i.e. ground truth.[3]
Tap a node to see what it does.
Two built-in failure detectors
Worked example: a coding agent fixing itself
Here is the loop on one concrete task, implement median(nums). The evaluator is a unit test, so the feedback is ground truth, and the reflection is carried forward in memory.
def median(nums):
s = sorted(nums)
return s[len(s) // 2] # takes the upper-middle element only
# run tests -> FAILED test_median::even
# assert median([1,2,3,4]) == 2.5 (got 3)Reflection stored in episodic memory
median([1,2,3,4]) returned 3, not 2.5. For an even-length list the median is the average of the two central elements, not a single index. Fix: branch on parity and average s[mid-1] and s[mid]."def median(nums):
s = sorted(nums)
mid = len(s) // 2
if len(s) % 2: # odd length -> single middle
return s[mid]
return (s[mid - 1] + s[mid]) / 2 # even -> average the middle pair
# run tests -> PASSED 4 / 4 (exit loop)Notice what actually did the work: the failing assertion named the exact input, the exact wrong output, and (implicitly) the exact contract. The reflection is a translation of a hard signal into a plan. Swap the unit test for a vague "does this look right?" and the same loop degrades into guessing.
Why does self-reflection reliably help this coding agent but often fail on closed-book reasoning?
The honest part: reflection needs a verifier
Here is the finding the demos gloss over. When the "evaluator" is the same model with no external ground truth, reflection frequently reinforces the error instead of fixing it, the model rationalizes its first answer, or sycophantically agrees that its own reasoning was fine.[2] Models are genuinely weak at self-correcting pure reasoning without a ground-truth signal to push against. Reflection is not magic introspection; it is a control loop, and a control loop with no sensor just amplifies noise.
Reflect against a real signal
- Unit tests, a type-checker, a compiler, a linter.
- An environment/tool that returns a real error or reward.
- An independent checker, a different model, a rubric, or a judge with the reference.
- A structural heuristic (loop detected, step budget blown).
Reflect against vibes
- "Is this answer correct?" asked to the same model.
- Self-scores with no reference to compare against.
- Unbounded "keep improving" with no stopping condition.
- Longer, thrashing reasoning mistaken for progress.[6]
Two ways the loop hurts you
max_trials cap a "self-improving" agent can burn tokens forever. Always bound the loop and always give reflection a sensor it doesn't control.Where does Self-Refine fit?
Self-consistency: the parallel cousin (and why it is fading)
People often lump reflection together with , don't. Self-consistency samples many independent chains of thought and takes a majority vote on the final answer.[4] There is no feedback and no memory; it just bets that a correct answer is reachable by many valid paths and so it clusters. On 2022-era models it was a big win (+17.9% on GSM8K).[4] On modern reasoning models the edge has largely eroded: gains plateau around 5 to 10 samples and are often only +1 to 3%, while cost scales linearly with the sample count.[5]
| Reflexion / self-reflection | Self-consistency | |
|---|---|---|
| Shape | Sequential: attempt to feedback to better attempt | Parallel: N independent samples, then vote |
| Uses feedback? | Yes, an external signal drives the critique | No, it never inspects any result |
| Memory | Episodic buffer of past reflections | None |
| Best for | Tasks with a checkable signal (tests, env, rubric) | Tasks with one discrete, votable answer |
| Cost | x number of trials | x number of samples |
| 2026 note | Persists where signals are cheap[3] | Gains plateau ~5 to 10 samples[5] |
How does self-consistency differ from Reflexion-style self-reflection?
When to reach for it
Anthropic's number-one rule applies here as everywhere: use the simplest thing that passes your eval, and add reflection only when it measurably helps.[2] A useful checklist before you bolt on a reflect to retry loop:
- Do you have a cheap, reliable signal? Unit tests, a validator, an environment reward, an independent judge. If not, build one first, reflection without it is theater.
- Does iteration actually improve the metric? Measure attempt-2 vs attempt-1 on real cases. Sometimes it doesn't move, or it regresses.
- Is the loop bounded? A hard
max_trialsand the stuck-loop detectors from Reflexion keep cost and runaway behavior in check. - Is the memory managed? Long trajectories plus accumulated reflections eat the context window, which is exactly the discipline of context engineering (next lesson), and why the buffer holds only the last few reflections.
The one-line model
Check yourself
Match each source of feedback to what it grounds the critique on.
the model re-reading its own output
a test suite, compiler, or type checker
observed effect of an action in the world
a separate model or rubric scoring it
The four moving parts of the Reflexion loop, and the one thing it never updates.
Why is it called verbal reinforcement learning? Try to state it, then check.
Lock it in
- Reflection is sequential self-improvement: attempt to feedback to better attempt, carried forward in memory, distinct from a blind retry and from a parallel vote.
- Reflexion is verbal reinforcement learning: actor, evaluator, a verbal self-critique, and an episodic buffer that is re-read on the next trial. No weight updates; 91% pass@1 on HumanEval because the evaluator was unit tests.
- The verifier is everything. Models are weak at self-correcting pure reasoning; without external ground truth, reflection can reinforce the mistake or sycophantically agree with it.
- Wire reflection to a real signal, tests, tools, an independent judge, or structural heuristics (loop / step-budget), not to the same model's opinion.
- Bound the loop: a
max_trialscap plus stuck-loop detection; and add it only when it measurably beats the simpler baseline.
Primary source
Shinn et al., Reflexion: Language Agents with Verbal Reinforcement Learning (NeurIPS 2023)The canonical algorithm behind this lesson: the actor/evaluator/self-reflection/memory loop, the "verbal RL" framing, the stuck-loop heuristics, and the HumanEval results where a real test suite is the verifier.
Sources
- 1.Lilian Weng, LLM Powered Autonomous Agents (2023)
- 2.Anthropic, Building Effective Agents
- 3.Shinn et al., Reflexion: Language Agents with Verbal Reinforcement Learning (2023)
- 4.Wang et al., Self-Consistency Improves Chain of Thought Reasoning (2022)
- 5.On the diminishing returns of majority voting in reasoning models (2025)
- 6.Wang et al., Thoughts Are All Over the Place: Underthinking in o1-like LLMs (2025)