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
- 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.
- 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."
- 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-ruledo 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
- 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?
- Adicione um TTL de 10 tentativas às reflexões. Reflexões mais antigas prejudicam ou ajudam após esse ponto?
- Implemente um avaliador heurístico: marque a tentativa como travada se a mesma ação for repetida. Como isso interage com o Self-Reflector?
- 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?
- 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
- Shinn et al., Reflexion: Language Agents with Verbal Reinforcement Learning (arXiv:2303.11366) — o artigo canônico
- Letta, Sleep-time Compute — reflexão assíncrona em produção
- Anthropic, Effective context engineering for AI agents — gerenciamento de buffer episódico como parte do contexto
- LangGraph overview — padrão de nó de reflexão