O ReAct prompting é um padrão em que o modelo de linguagem alterna entre raciocinar e agir: ele escreve um pensamento sobre o que fazer, executa uma ação, como uma busca ou uma chamada de ferramenta, lê o resultado e só então decide o próximo passo. O nome é a abreviação de Reason + Act (raciocinar e agir) e vem de Yao et al. 2022, "ReAct: Synergizing Reasoning and Acting in Language Models". Ele não tem relação com o React, a biblioteca JavaScript para criar interfaces.
A maioria dos agentes de IA que navegam, rodam código ou editam arquivos executa alguma versão desse loop. Depois que você percorre o loop à mão, o comportamento dos agentes fica muito mais fácil de prever e de depurar.
O loop Thought, Action, Observation
Um prompt ReAct pede ao modelo que escreva três tipos de linha.
- Thought (pensamento): raciocínio sobre a situação atual e sobre que informação está faltando.
- Action (ação): uma chamada de ferramenta em um formato fixo, como
search[query],read_file[path]oufinish[answer]. - Observation (observação): o resultado dessa ação. O modelo não escreve essa linha. O seu programa (ou você) executa a ação e acrescenta a saída real à transcrição.
Depois a transcrição inteira volta para o modelo, que escreve o próximo pensamento. O loop termina quando o modelo escolhe a ação de encerramento. O modelo nunca executa uma ferramenta sozinho; ele só pede, e o código em volta dele decide se atende ao pedido.
Por que raciocinar e agir é melhor do que só um dos dois
O artigo comparou o ReAct com prompts que só raciocinam (chain of thought) e prompts que só agem (chamadas de ferramenta sem raciocínio escrito). Em perguntas e respostas e em checagem de fatos com uma ferramenta de busca na Wikipédia, o raciocínio sozinho muitas vezes construía um argumento confiante sobre um fato que o modelo tinha inventado, enquanto o ReAct podia pesquisar o fato; os melhores resultados em perguntas e respostas vieram de combinar o ReAct com o chain of thought, passando de um para o outro quando o primeiro não produzia uma resposta confiante. A ação sozinha tinha dificuldade para decompor o objetivo e juntar o que encontrava em uma resposta; os pensamentos escritos mantinham o plano visível. Em duas tarefas interativas, um jogo doméstico em texto e um site de compras simulado, o ReAct com um ou dois exemplos no prompt foi melhor do que os modelos treinados com que os autores compararam.
A lição geral: o chain of thought ajuda o modelo a planejar, as ferramentas dão fatos a ele, e nenhum dos dois basta para uma tarefa que precisa dos dois.
Um agente ReAct, turno a turno
O bloco abaixo é um pequeno agente de programação com duas ferramentas. Cada aba é a mesma conversa um passo depois: as linhas Observation são o que o programa colou de volta depois de executar a ação anterior. Leia as respostas em ordem. Os rótulos Thought, Action e Observation ficam em inglês porque são o formato que o código mais abaixo procura.
Thought: Não sei qual teste falha nem como. Rodar os testes vai mostrar a asserção exata antes de eu ler qualquer código. Action: run_tests[tests/test_cart.py]
Repare em duas coisas. A primeira ação é rodar os testes, não um palpite: o modelo juntou evidências antes de ler o código. E cada pensamento se refere à última observação, que é a parte que o chain of thought não consegue fazer.
Teste o ReAct em um app de chat
Você não precisa de código para ver o loop. No ChatGPT, no Claude ou no Gemini, você pode ser a ferramenta: o modelo pede uma ação, você a executa e cola o resultado de volta.
Pensamento: um cooler barulhento com o computador parado normalmente significa que algo está usando a CPU em segundo plano, ou que o cooler está com dificuldade para resfriar (poeira, saídas de ar bloqueadas). Conferir o uso da CPU primeiro separa esses dois casos.
Ação: abra o Gerenciador de Tarefas (Ctrl+Shift+Esc no Windows) ou o Monitor de Atividade (Aplicativos > Utilitários no Mac). Ordene os processos por CPU, espere 30 segundos e me diga os três primeiros processos e a porcentagem de CPU de cada um.
As mesmas instruções, com uma função de verdade por trás de cada ação, são um agente.
Um loop ReAct mínimo em Python
No código, o programa envia a transcrição, encontra a linha Action na resposta, executa a função correspondente, acrescenta a Observation e repete. Este esboço usa o SDK Python da OpenAI e o prompt de sistema do agente de programação acima.
import re
import subprocess
from pathlib import Path
from openai import OpenAI
client = OpenAI()
MODEL = "your-model-id" # e.g. from your provider's model list
PROJECT = Path.cwd().resolve()
READABLE = {".py", ".md", ".txt", ".toml", ".cfg"}
def inside_project(arg):
# The model chooses arg: resolve it and refuse anything outside the project.
path = (PROJECT / arg).resolve()
if not path.is_relative_to(PROJECT):
raise ValueError(f"{arg} is outside the project")
return path
def run_tests(arg):
path = inside_project(arg)
if not (path.is_file() and path.name.startswith("test_") and path.suffix == ".py"):
raise ValueError(f"{arg} is not a test file")
result = subprocess.run(["pytest", str(path), "-q"], capture_output=True, text=True)
return result.stdout[-2000:]
def read_file(arg):
path = inside_project(arg)
if not path.is_file() or path.suffix not in READABLE:
raise ValueError(f"{arg} is not a file this agent may read")
return path.read_text()[:20000]
TOOLS = {"run_tests": run_tests, "read_file": read_file}
def react(task, system_prompt, max_steps=8):
transcript = f"Task: {task}\n"
for _ in range(max_steps):
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": transcript},
],
temperature=0,
)
text = response.choices[0].message.content
match = re.search(r"Action: (\w+)\[(.*)\]", text)
if not match:
return text
transcript += text[: match.end()] + "\n"
tool, arg = match.groups()
if tool == "finish":
return arg
try:
observation = TOOLS[tool](arg) if tool in TOOLS else f"Unknown tool: {tool}"
except Exception as error: # a missing file becomes an observation, not a crash
observation = f"Error: {error}"
transcript += f"Observation:\n{observation}\n"
return "Stopped after max_steps without an answer."
Quatro detalhes importam. A transcrição é cortada logo depois da Action, porque os modelos às vezes continuam escrevendo e inventam a própria Observation. Uma ferramenta que falha (um nome de arquivo errado, por exemplo) vira uma Observation à qual o modelo pode reagir, em vez de derrubar o loop. O limite de passos para um modelo que ficaria girando para sempre. E a saída dos testes é aparada, já que um log de testes enorme encheria a janela de contexto; decidir o que entra nessa janela é engenharia de contexto.
As duas ferramentas também verificam o argumento antes de fazer qualquer coisa. Quem escolhe esse argumento é o modelo, então os limites ficam na ferramenta: inside_project recusa qualquer caminho que termine fora da pasta do projeto (inclusive truques com ../), run_tests só aceita arquivos test_*.py e read_file só abre alguns tipos de arquivo de código e texto e devolve no máximo 20.000 caracteres, para que um arquivo .env ou uma chave SSH nunca cheguem à próxima requisição. Rodar o pytest ainda executa o código do seu projeto, então rode um agente assim em um contêiner ou em uma cópia descartável, nunca em uma máquina que guarda segredos.
As APIs atuais da OpenAI, da Anthropic e do Google também oferecem chamada de ferramentas nativa: você descreve cada ferramenta com um nome e um JSON schema, e o modelo devolve uma chamada de ferramenta estruturada em vez de uma linha Action:. O loop é idêntico; só a extração do texto desaparece.
Segurança em um loop ReAct
Um agente lê textos que ele não escreveu: páginas web, arquivos, saídas de ferramentas. Qualquer um deles pode conter instruções dirigidas ao modelo, o que é prompt injection. Dê a cada ferramenta o menor acesso de que ela precisa (só leitura sempre que possível), peça a uma pessoa que confirme qualquer coisa que apague, envie ou pague, e trate as ações pedidas pelo modelo como uma entrada não confiável a ser conferida, não como comandos para executar às cegas.
Perguntas frequentes
O que é ReAct prompting?
ReAct (abreviação de Reason + Act, raciocinar e agir) é um padrão de prompt em que o modelo de linguagem escreve um trecho curto de raciocínio, depois uma ação, como uma busca ou uma chamada de ferramenta, e lê o resultado antes de raciocinar de novo. Ele vem de Yao et al. 2022, "ReAct: Synergizing Reasoning and Acting in Language Models". Não tem nada a ver com a biblioteca JavaScript React.
O que são Thought, Action e Observation no ReAct?
Um Thought (pensamento) é o raciocínio do modelo sobre o que fazer a seguir. Uma Action (ação) é uma chamada de ferramenta em um formato fixo, por exemplo search[python 3.13 release notes]. A Observation (observação) é a saída da ferramenta, que o seu programa obtém executando a ação e acrescenta ao prompt. O loop se repete até o modelo escolher uma ação de encerramento com a resposta.
Qual é a diferença entre ReAct e chain of thought?
O chain of thought raciocina a partir do que o modelo já sabe, então um fato errado no início da cadeia continua errado. O ReAct intercala o raciocínio com ações que buscam informação real, então o modelo pode conferir um fato, ver um teste falhar ou ler um arquivo antes de continuar. O artigo do ReAct descobriu que apoiar o raciocínio em resultados de busca reduzia os fatos inventados que o chain of thought sozinho produzia.
Os agentes de IA ainda usam ReAct?
O loop, sim. A maioria dos agentes hoje raciocina, chama uma ferramenta, lê o resultado e decide de novo, que é o ciclo do ReAct. O que mudou foi o formato: em vez de extrair linhas Action: do texto, as APIs atuais têm chamada de ferramentas nativa, em que o modelo devolve um pedido de ferramenta estruturado e o seu código envia o resultado de volta.
Dá para usar ReAct no ChatGPT sem programar?
Dá, fazendo você mesmo o papel da ferramenta. Peça ao modelo que responda com um pensamento e uma ação e depois pare. Você executa a ação (pesquisa, abre um arquivo, roda um comando), cola o resultado como observação e repete. É lento, mas mostra exatamente como um agente decide o que fazer a seguir.