Menu

ReAct prompting: o loop de raciocinar e agir

O ReAct prompting faz o modelo alternar entre raciocinar sobre uma tarefa e chamar uma ferramenta, lendo cada resultado antes de decidir o próximo passo. É o loop por trás da maioria dos agentes de IA.

Você pode editar cada prompt desta página e depois abri-lo no ChatGPT, no Claude ou em outro app de IA.

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] ou finish[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.

System prompt
Resolva a tarefa repetindo Thought, Action e Observation. Thought: raciocine sobre o que você sabe e o que fazer a seguir. Action: exatamente uma destas run_tests[path] roda o pytest em um arquivo e retorna a saída read_file[path] retorna o conteúdo de um arquivo finish[answer] encerra a tarefa com a sua resposta Escreva um Thought e uma Action e pare. A Observation será fornecida a você.
Tarefa: tests/test_cart.py começou a falhar depois do merge de ontem. Encontre a causa.
Try it
Chat apps receive the system prompt as the start of your message, so this tries its wording, not its priority. To test it as standing instructions, put it in the app's custom instructions or the API's system field.
Example replyReplies vary between models and runs.

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.

Seja as ferramentas do modelo
Fill in
Quero responder a esta pergunta: Por que o cooler do meu notebook faz barulho mesmo quando não estou fazendo nada? Me ajude trabalhando em um loop. Cada resposta sua tem exatamente um Pensamento (o que você sabe até agora e o que está faltando) e uma Ação: algo específico para eu conferir, rodar ou pesquisar, com os passos exatos. Depois pare e espere. Eu vou responder com o resultado no formato "Observação: ...". Quando tiver evidências suficientes, responda com "Resposta:" e a sua conclusão. Não chute uma resposta antes de ter evidências.
Try it
Example replyReplies vary between models and runs.

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.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR