TAI BUI
Back to curriculum
BuildPython

Reflexion: Verbal Reinforcement Learning

Gradient-based RL needs thousands of trials and a GPU cluster to fix one failure mode. Reflexion (Shinn et al., NeurIPS 2023) fixes it in plain language: after each failed trial the agent writes a reflection, stores it in episodic memory, and conditions the next trial on it. Letta's sleep-time compute, Claude Code's CLAUDE.md learnings, and pro-workflow's learn-rule are all this pattern.

TIME: ~60 minutesPREREQUISITES: Phase 14 · 01 (Agent Loop), Phase 14 · 02 (ReWOO)

Learning Objectives

  • Name the three components of Reflexion (Actor, Evaluator, Self-Reflector) and the role of episodic memory.
  • Implement a stdlib Reflexion loop with binary evaluator, reflection buffer, and fresh re-attempts.
  • Choose between scalar, heuristic, and self-evaluated feedback sources for a given task.
  • Explain why verbal reinforcement catches errors that gradient-based RL would need thousands of trials to fix.

The Problem

When an agent fails a task, standard RL says to run thousands more trials, compute gradients, and update weights. That is slow and expensive, and most production agents have no training budget for every failure.

Reflexion (Shinn et al., arXiv:2303.11366) takes a cheaper route. The agent reads its own failed attempt, writes down why it failed, and retries with that note in its prompt. No weight updates, no gradients, just natural language carried between trials.

It works. On ALFWorld it beats ReAct and the other non-fine-tuned baselines. On HotpotQA it improves over ReAct. On code generation (HumanEval/MBPP) it set state of the art at the time. Not one gradient step involved.

Warm-up0/3
1. An agent fails a task and you cannot retrain the model. What is the cheapest way to improve its next attempt?Warm-up
2. In the agent loop from Lesson 01, what does a single run leave behind that you can inspect afterward?Warm-up
3. Why are unit tests a good automatic check for code that an AI wrote?Warm-up
Check: The Problem0/1
1. Why can one written reflection fix an error that gradient-based RL would need thousands of trials to fix?Explain

The Concept

Reflexion is a pattern for learning from failure without touching model weights: after a failed trial, the agent writes a natural-language reflection on what went wrong, stores it, and reads it at the start of the next trial. The paper calls this verbal reinforcement learning, because the reflection plays the role the gradient plays in ordinary RL.

The three components

Actor         : generates a trajectory (ReAct-style loop)
Evaluator     : scores the trajectory — binary, heuristic, or self-eval
Self-Reflector: writes a natural-language reflection on the failure

Plus one data structure:

Episodic memory: list of prior reflections, prepended to the next trial's prompt

A trial runs the Actor, and the Evaluator scores the result. On a low score the Self-Reflector produces a reflection ("I picked the wrong tool because I read the question as asking about X when it asked about Y"). That reflection goes into episodic memory. The next trial starts fresh, with no leftover trajectory, but it sees the reflection.

Three evaluator types

  1. Scalar. An external binary signal: ALFWorld succeeds or fails, HumanEval tests pass or fail. The simplest option and the highest-signal one.
  2. Heuristic. Predefined failure signatures. "Same action twice in a row means stuck." "More than 50 steps means inefficient."
  3. Self-evaluated. The LLM scores its own trajectory. You need this when no ground truth exists, but the signal is weaker, so pair it with tool-grounded verification (Lesson 05, CRITIC).

The 2026 default is a mix: scalar when you have it, self-eval when you don't, heuristics as safety rails.

Why this generalizes

Reflexion is less a new algorithm than a named pattern, and almost every production "self-healing" agent runs some variant of it:

  • Letta's sleep-time compute (Lesson 08): a separate agent reflects on past conversations and writes to memory blocks.
  • Claude Code's CLAUDE.md and "save memory" flow: learnings are captured and prepended to future sessions.
  • pro-workflow's /learn-rule command: corrections become explicit rules.
  • LangGraph's reflection nodes: a node scores the output and routes to a refine step when needed.

They all rest on one insight. Natural language is rich enough to carry "what I learned from failure" from one run to the next.

When it works and when it does not

Reflexion works when:

  • There is a clear failure signal (a failing test, a tool error, a wrong answer).
  • The task class is reproducible, so the same type of question can come up again.
  • The agent has enough action budget to actually act on the reflection.

It does not help when:

  • The agent already succeeds on the first try.
  • The failure is external. A network outage or a broken tool teaches nothing about the next run.
  • The reflection hardens into superstition, a story built around one flaky run.

The 2026 pitfall is memory rot. Reflections pile up, some go stale or were wrong to begin with, and every re-run gets slower as the episodic buffer grows. The fixes are periodic compaction (Lesson 06), a TTL on reflections, or a separate sleep-time cleanup agent (Letta).

Check: The Concept0/20
1. What three components define a Reflexion system?Define
2. What is verbal reinforcement in Reflexion?Define
3. What does the episodic memory hold in Reflexion?Define
4. Which evaluator type uses an external binary signal like a unit test or a known correct answer?Define
5. Which evaluator type flags a trial as stuck using a predefined failure signature, like the same action repeating twice, without needing ground truth or an LLM to judge itself?Define
6. What is a self-evaluator?Define
7. What is memory rot in the Reflexion pattern?Define
8. What does Reflexion replace in standard reinforcement learning?Explain
9. After a failed trial, what does the next Reflexion trial carry over from it?Explain
10. Why is self-evaluation a weaker signal than scalar feedback?Explain
11. How does a heuristic evaluator differ from a scalar evaluator?Explain
12. Which case does the lesson list as a place where Reflexion does NOT help?Explain
13. Per the lesson, which condition must hold for Reflexion to actually help?Explain
14. Which production pattern is the lesson's clearest match for Reflexion?Explain
15. A task has no unit tests or other ground truth to score against. Which evaluator setup does the lesson suggest?Apply
16. Your agent's buffer fills with entries like "be more careful next time", and trials get slower with no accuracy gain. What is the right fix?Analyze
17. An agent's backing API is down for an hour, every trial fails, and the buffer fills with reflections about its "mistakes". What went wrong in applying Reflexion?Analyze
18. The buffer holds sharp, specific reflections, yet every new attempt is identical to trial 1. Which component is most likely at fault?Analyze
19. A task has no tests, and the agent scores its own wrong answer 9 out of 10, so no reflection is ever written. Which ingredient was missing?Analyze
20. A coding agent runs against tests that sometimes fail for no code reason. How do you keep its buffer from filling with superstitions?Design

Build It

code/main.py implements Reflexion on a toy puzzle: produce a 3-element list that sums to a target. The Actor emits candidate lists, the Evaluator checks the sum, and the Self-Reflector writes a line about what went wrong. That line goes into episodic memory for the next trial.

Components:

  • Actor: a scripted policy that improves when it sees reflections.
  • Evaluator.binary(): pass/fail on the target sum.
  • SelfReflector: generates a one-line diagnosis of the failure.
  • EpisodicMemory: a bounded list with TTL semantics.

Run it:

python3 code/main.py

The trace shows three trials. Trial 1 fails and a reflection is stored. Trial 2 sees the reflection and improves but still fails. Trial 3 succeeds. Compare that with the baseline run, which has no reflection and stays stuck on trial 1's answer.

Check: Build It0/5
1. In the toy puzzle (three integers from 1 to 9, target 20), the Actor's first attempt is [1, 2, 3]. What does the binary evaluator return as (success, delta)?Apply
2. For the first attempt [1, 2, 3] with target 20, what text does the SelfReflector store in memory?Apply
3. With one reflection in memory, what does the scripted Actor try on trial 2, and how does that trial end?Apply
4. The baseline run has no episodic memory and is allowed four trials. How does it end?Apply
5. An EpisodicMemory has max_len 6 and already holds six reflections. What happens when a seventh is added?Apply

Use It

LangGraph ships reflection as a node pattern. Claude Code's /memory command and pro-workflow's /learn-rule externalize the episodic buffer as a markdown file. Letta's sleep-time compute runs the Self-Reflector during downtime, so the primary agent keeps its latency budget. The OpenAI Agents SDK has no built-in Reflexion. You assemble it from a custom Guardrail that rejects trajectories by score and a memory Session that survives across runs.

Check: Use It0/3
1. What is sleep-time reflection?Define
2. You are on the OpenAI Agents SDK, which has no built-in Reflexion. What do you assemble it from?Apply
3. A chat agent has a strict per-reply latency budget but should learn from its past failures. Which design fits?Design

Ship It

outputs/skill-reflexion-buffer.md creates and maintains an episodic buffer with reflection capture, TTL, and deduplication. Given a task class and a failure, it emits a reflection that helps the next trial, not a generic "be more careful."

Author's Note

The most common way this pattern fails is the reflection that says nothing. "Be more careful next time" costs tokens on every future trial and changes no behavior. A reflection earns its place in the buffer only if it names the specific mistake and what to do differently, something like "I summed before checking the list length, so recheck length first." If you can't imagine the Actor acting differently because of the line, don't store it. Treat the buffer like a codebase: every entry should justify its upkeep.

Exercises

  1. Switch from the binary evaluator to a scalar one that returns a distance metric (how far the sum is from the target). Does it converge faster?
  2. Add a TTL of 10 trials to reflections. Do older reflections hurt or help after that point?
  3. Implement a heuristic evaluator that marks a trial as stuck when the same action repeats. How does it interact with the Self-Reflector?
  4. Run Reflexion with an adversarial Actor that ignores reflections. What is the least reflection-prompt engineering that forces the Actor to notice them?
  5. Read Section 4 of the Reflexion paper on ALFWorld. Reproduce the 130% success-rate improvement conceptually: what is the key delta versus vanilla ReAct?

Key Terms

TermWhat people sayWhat it actually means
Reflexion"Self-correction"Shinn et al. 2023: Actor, Evaluator, Self-Reflector plus episodic memory
Verbal reinforcement"Learning without gradients"Natural-language reflection prepended to the next trial's prompt
Episodic memory"Per-task reflections"Bounded buffer of prior reflections for one task class
Scalar evaluator"Binary success signal"Pass/fail or numeric score from ground truth
Heuristic evaluator"Pattern-based detector"Predefined failure signatures (e.g. stuck-loop, too-many-steps)
Self-evaluator"LLM-as-judge on own trace"Lower-signal fallback when no ground truth, so pair with tool-grounded verification
Memory rot"Stale reflections"Episodic buffer fills with obsolete entries; fix with compaction/TTL
Sleep-time reflection"Async self-reflection"Run Self-Reflector off the hot path so primary agent stays fast

Further Reading

Code

Ships With