Phase 14 - Lesson 03

Reflexion: Aprendizado por Reforço Verbal

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

O RL baseado em gradiente precisa de milhares de tentativas e de um cluster de GPUs para corrigir um modo de falha. O Reflexion (Shinn et al., NeurIPS 2023) faz isso em linguagem natural: após cada tentativa fracassada, o agente escreve uma reflexão, armazena-a na memória episódica e condiciona a próxima tentativa a essa memória. Este é o padrão por trás do sleep-time compute do Letta, dos aprendizados no CLAUDE.md do Claude Code e do learn-rule do pro-workflow.

Tipo: Build Linguagens: Python (stdlib) Pré-requisitos: Fase 14 · 01 (Agent Loop), Fase 14 · 02 (ReWOO) Tempo: ~60 minutos

Objetivos de Aprendizado

  • Nomear os três componentes do Reflexion (Actor, Evaluator, Self-Reflector) e o papel da memória episódica.
  • Implementar um loop de Reflexion com biblioteca padrão (stdlib) contendo um avaliador binário, buffer de reflexão e novas tentativas.
  • Escolher entre fontes de feedback escalar, heurístico e autoavaliado para uma determinada tarefa.
  • Explicar por que o reforço verbal detecta erros que o RL baseado em gradiente precisaria de milhares de tentativas para corrigir.

O Problema

Um agente falha em uma tarefa. No RL padrão, você executaria mais milhares de tentativas, calcularia gradientes e atualizaria pesos. Isso é caro, lento e a maioria dos agentes em produção não tem um orçamento de treinamento para cada falha.

O Reflexion (Shinn et al., arXiv:2303.11366) faz uma pergunta diferente: e se o agente apenas pensasse sobre o motivo de ter falhado e tentasse novamente com esse pensamento em seu prompt? Sem atualizações de pesos. Sem gradiente. Apenas linguagem natural armazenada entre as tentativas.

O resultado: no ALFWorld, ele supera o ReAct e outras baselines sem ajuste fino (fine-tuning). No HotpotQA, ele apresenta melhorias em relação ao ReAct. Na geração de código (HumanEval/MBPP), ele estabeleceu o estado da arte na época. Tudo isso sem um único passo de gradiente.

O Conceito

Os três componentes

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

Mais uma estrutura de dados:

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

Uma tentativa executa o Actor. O Evaluator a pontua. Se a pontuação for baixa, o Self-Reflector produz uma reflexão ("Eu escolhi a ferramenta errada porque interpretei mal a pergunta, achando que ela perguntava sobre X quando na verdade perguntava sobre Y"). A reflexão vai para a memória episódica. A próxima tentativa começa do zero, mas consegue ver a reflexão.

Três tipos de avaliadores

  1. Escalar — um sinal binário externo. ALFWorld tem sucesso ou falha. Os testes do HumanEval passam ou falham. É o sinal mais simples e de maior qualidade.
  2. Heurístico — assinaturas de falhas predefinidas. "Se o agente produziu a mesma ação duas vezes seguidas, marque como travado." "Se a trajetória exceder 50 passos, marque como ineficiente."
  3. Autoavaliado — o LLM avalia sua própria trajetória. Necessário quando nenhuma verdade fundamental (ground truth) está disponível. É um sinal mais fraco; funciona bem combinado com verificação baseada em ferramentas (Lição 05 — CRITIC).

O padrão em 2026 é uma mistura: escalar quando disponível, autoavaliado quando não, e heurísticas como salvaguardas.

Por que isso se generaliza

O Reflexion não é tanto um novo algoritmo, mas sim um padrão nomeado. Quase todo agente de "autocorreção" em produção executa alguma variante:

  • Sleep-time compute do Letta (Lição 08): um agente separado reflete sobre conversas passadas e escreve em blocos de memória.
  • Padrão do Claude Code com CLAUDE.md / "save memory": reflexões capturadas como aprendizados, incluídas no início de futuras sessões.
  • Comando /learn-rule do pro-workflow: correções capturadas como regras explícitas.
  • Nós de reflexão do LangGraph: um nó que avalia a saída e direciona para refinação se necessário.

Todos derivam da mesma percepção: a linguagem natural é um meio rico o suficiente para carregar "o que aprendi com a falha" entre execuções.

Quando funciona e quando não funciona

O Reflexion funciona quando:

  • Há um sinal de falha claro (falha em teste, erro de ferramenta, resposta errada).
  • A classe da tarefa é reproduzível (o mesmo tipo de pergunta pode ser feita novamente).
  • A reflexão tem espaço para melhorar a trajetória (orçamento de ações suficiente).

O Reflexion não ajuda quando:

  • O agente já tem sucesso na primeira tentativa.
  • A falha é externa (rede fora do ar, ferramenta quebrada) — refletir sobre "a rede estava fora do ar" não ajuda em execuções futuras.
  • A reflexão se transforma em superstição — armazenar uma narrativa sobre uma execução instável isolada.

Armadilha de 2026: deterioração da memória (memory rot). As reflexões se acumulam; algumas tornam-se obsoletas ou erradas; as reexecuções ficam mais lentas à medida que o buffer episódico cresce. Mitigação: compactação periódica (Lição 06), TTL em reflexões ou um agente de limpeza separado em tempo de sono (Letta).

Build It

O code/main.py implementa o Reflexion em um quebra-cabeça simples: produzir uma lista de 3 elementos que somam um valor alvo. O Actor emite listas candidatas; o Evaluator verifica a soma; o Self-Reflector escreve uma linha sobre o que deu errado. A reflexão vai para a memória episódica para a próxima tentativa.

Componentes:

  • Actor — uma política em script que melhora ao ver as reflexões.
  • Evaluator.binary() — sucesso/falha com base na soma alvo.
  • SelfReflector — gera um diagnóstico de uma linha sobre a falha.
  • EpisodicMemory — uma lista limitada com semântica de TTL.

Execute-o:

python3 code/main.py

O rastreamento (trace) mostra três tentativas. A tentativa 1 falha, uma reflexão é armazenada, a tentativa 2 vê a reflexão e melhora, mas ainda falha, a tentativa 3 tem sucesso. Compare com uma execução de baseline (sem reflexão) — ela permanece travada na resposta da tentativa 1.

Use It

O LangGraph entrega a reflexão como um padrão de nó. O comando /memory do Claude Code e o /learn-rule do pro-workflow externalizam o buffer episódico como um arquivo markdown. O sleep-time compute do Letta executa o Self-Reflector em segundo plano para que o agente principal permaneça dentro dos limites de latência. O OpenAI Agents SDK não fornece o Reflexion diretamente; você o constrói com um Guardrail personalizado que rejeita trajetórias com base na pontuação e uma sessão (Session) de memória que sobrevive entre as execuções.

Ship It

O outputs/skill-reflexion-buffer.md cria e mantém um buffer episódico com captura de reflexão, TTL e deduplicação. Dada uma classe de tarefa e uma falha, ele emite uma reflexão que realmente ajuda na próxima tentativa (não um genérico "seja mais cuidadoso").

Exercícios

  1. Mude de um avaliador binário para um avaliador escalar que retorna uma métrica de distância (o quão longe está do alvo). Isso converge mais rápido?
  2. Adicione um TTL de 10 tentativas às reflexões. Reflexões mais antigas prejudicam ou ajudam após esse ponto?
  3. Implemente um avaliador heurístico: marque a tentativa como travada se a mesma ação for repetida. Como isso interage com o Self-Reflector?
  4. Execute o Reflexion com um Actor adversário que ignora reflexões. Qual é a engenharia de prompt mínima para a reflexão que força o Actor a notá-las?
  5. Leia a Seção 4 do artigo do Reflexion sobre o AlfWorld. Reproduza conceitualmente a melhoria de 130% na taxa de sucesso: qual é a diferença crucial em relação ao ReAct padrão?

Key Terms

Termo O que as pessoas dizem O que realmente significa
Reflexion "Autocorreção" Shinn et al. 2023 — Actor, Evaluator, Self-Reflector mais memória episódica
Verbal reinforcement "Aprendizado sem gradientes" Reflexão em linguagem natural incluída no início do prompt da próxima tentativa
Episodic memory "Reflexões por tarefa" Buffer limitado de reflexões anteriores para uma classe de tarefa
Scalar evaluator "Sinal de sucesso binário" Sucesso/falha ou pontuação numérica a partir da verdade fundamental
Heuristic evaluator "Detector baseado em padrões" Assinaturas de falha predefinidas (ex: loop travado, passos excessivos)
Self-evaluator "LLM como juiz de seu próprio trace" Alternativa de sinal mais fraco quando não há verdade fundamental — combine com verificação baseada em ferramentas
Memory rot "Reflexões obsoletas" O buffer episódico enche de entradas obsoletas; resolva com compactação/TTL
Sleep-time reflection "Autorreflexão assíncrona" Executa o Self-Reflector fora do caminho crítico para que o agente principal permaneça rápido

Further Reading

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).