Pular para o conteúdo
Categoria: Desenvolvendo com IA14 min de leitura

O padrão ReAct: raciocínio e ação em agentes de IA

Por Schematize Blog ·

Entenda como o ciclo de pensar, agir e observar do padrão ReAct permite que LLMs resolvam tarefas complexas passo a passo usando ferramentas externas — com exemplos e armadilhas.

ReAct é um dos padrões mais influentes na construção de agentes de IA modernos. Seu nome combina Reasoning (raciocínio) e Acting (ação), e sua ideia central é elegante: em vez de fazer o modelo pensar OU agir, faça-o intercalar os dois em um ciclo. Neste artigo você vai entender como esse loop funciona, por que ele é tão eficaz, como implementá-lo na prática e quais armadilhas evitar.

O problema que o ReAct resolve

Um LLM puro tem duas limitações sérias. Primeiro, ele raciocina apenas sobre o que está no seu contexto — não pode buscar informação nova nem verificar fatos no mundo. Segundo, quando tenta resolver problemas complexos "de cabeça", acumula erros e alucinações sem oportunidade de se corrigir.

Pense em um modelo a quem você pergunta a cotação atual do dólar ou o status de um pedido no seu banco de dados. Por melhor que ele seja, a resposta correta simplesmente não está nos pesos da rede: é um dado externo, dinâmico, que muda a cada minuto. Sem uma forma de agir sobre o mundo, o modelo só pode adivinhar — e adivinhar com confiança é exatamente o que chamamos de alucinação.

A técnica de Chain-of-Thought, de Wei e colegas (2022), melhorou o raciocínio ao fazer o modelo pensar em voz alta, passo a passo — algo aprofundado em Chain-of-Thought: fazendo a IA pensar passo a passo. Mas o Chain-of-Thought sozinho ainda é um monólogo fechado: o modelo não consulta o mundo externo durante o raciocínio.

ReAct, proposto por Yao e colegas (2023), une as duas capacidades. O modelo raciocina E age, usando o resultado de cada ação para informar o próximo passo do raciocínio. Assim ele pode buscar dados reais, corrigir suposições erradas e fundamentar suas conclusões.

O ciclo: Thought, Action, Observation

O coração do ReAct é um loop de três etapas que se repete até a tarefa terminar:

    O resultado da observação volta para o contexto, e o ciclo recomeça. O modelo pode então pensar de novo, agir de novo, observar de novo — até concluir que tem a resposta final.

    Veja um traço simplificado de execução para a pergunta "Qual a população da capital do Japão?":

    Thought: Preciso descobrir qual é a capital do Japão.
    Action: buscar("capital do Japão")
    Observation: A capital do Japão é Tóquio.
    
    Thought: Agora preciso da população de Tóquio.
    Action: buscar("população de Tóquio")
    Observation: Tóquio tem cerca de 14 milhões de habitantes.
    
    Thought: Já tenho a resposta.
    Final Answer: A capital do Japão é Tóquio, com cerca de 14 milhões de habitantes.

    Repare como cada observação alimenta o próximo pensamento. O modelo não adivinhou — ele consultou, observou e raciocinou sobre fatos reais.

    Por que a observação é o ingrediente secreto

    A grande diferença em relação ao Chain-of-Thought está na linha Observation. No Chain-of-Thought, o modelo escreveria algo como "a população de Tóquio é provavelmente uns 13 ou 14 milhões" — um chute educado. No ReAct, esse número vem de fora, de uma fonte real, e o modelo apenas o incorpora. É a diferença entre lembrar e consultar. Quando o modelo erra uma suposição no primeiro passo, a observação do passo seguinte frequentemente revela o erro, dando a chance de corrigir o rumo.

    Por que intercalar raciocínio e ação funciona tão bem

    Yao e colegas (2023) demonstraram que essa sinergia traz benefícios concretos:

      Em outras palavras, o raciocínio torna as ações mais inteligentes, e as ações tornam o raciocínio mais fundamentado. É um ciclo virtuoso.

      No artigo original, ReAct superou tanto o Chain-of-Thought puro (que alucinava mais por não ter como verificar) quanto agentes que só agiam sem raciocinar (que se perdiam por não planejar). A combinação venceu em benchmarks de pergunta-e-resposta com busca (HotpotQA) e em ambientes interativos de texto (ALFWorld, WebShop). A lição é que nenhuma das duas metades sozinha basta.

      ReAct e function calling

      Na implementação prática, a etapa de "Action" depende de o modelo conseguir invocar ferramentas de forma estruturada. É aqui que entra o function calling: como dar ferramentas ao seu LLM. Em vez de o modelo escrever uma string como buscar("Tóquio") em texto livre, os provedores modernos oferecem uma saída estruturada em que o modelo retorna o nome da função e os argumentos em formato parseável.

      Essa evolução é importante. Na formulação original do ReAct, a "Action" era texto livre que o sistema precisava parsear com expressões regulares frágeis — qualquer variação na forma como o modelo escrevia quebrava o parser. Com function calling nativo, o provedor garante uma estrutura JSON validada, eliminando boa parte dessa fragilidade.

      Um esqueleto de loop ReAct com function calling fica assim:

      def agente_react(pergunta, ferramentas, max_passos=10):
          mensagens = [{"role": "user", "content": pergunta}]
          for _ in range(max_passos):
              resposta = modelo.chamar(mensagens, tools=ferramentas)
              if resposta.tem_chamada_de_ferramenta():
                  ferramenta = resposta.chamada_de_ferramenta
                  observacao = executar(ferramenta.nome, ferramenta.args)
                  mensagens.append(resposta)            # o "Thought + Action"
                  mensagens.append(observacao_como_msg(observacao))  # a "Observation"
              else:
                  return resposta.texto                 # resposta final
          return "Limite de passos atingido."

      O max_passos é importante: ele evita loops infinitos quando o modelo não converge para uma resposta.

      Definindo boas ferramentas

      A qualidade de um agente ReAct depende menos do prompt e mais das ferramentas que você oferece. Uma boa definição de ferramenta tem:

        ferramenta_clima = {
            "name": "obter_clima",
            "description": "Retorna o clima atual de uma cidade. "
                           "Use quando o usuário perguntar sobre temperatura ou tempo.",
            "parameters": {
                "type": "object",
                "properties": {
                    "cidade": {"type": "string", "description": "Nome da cidade"}
                },
                "required": ["cidade"]
            }
        }

        Uma descrição vaga é a causa número um de um agente escolher a ferramenta errada. Trate as descrições como parte do prompt: elas são o que o modelo lê para decidir.

        Onde o ReAct se encaixa na construção de agentes

        ReAct é, em essência, o motor de decisão dentro de um agente. Em como construir um agente de IA que executa tarefas e em o que é um agente de IA? Definição e exemplos, o ciclo pensar-agir-observar é exatamente o que dá ao agente sua autonomia: a capacidade de decidir os próprios passos em vez de seguir um roteiro fixo.

        Praticamente todos os frameworks de agentes — LangChain, LlamaIndex, AutoGPT e similares — implementam alguma variante do ReAct sob o capô. Entender o padrão ajuda a depurar e a otimizar qualquer um deles.

        ReAct versus fluxos fixos

        Nem toda tarefa precisa de um loop ReAct. Se o caminho é conhecido e linear — "extraia estes campos, valide, salve no banco" — um fluxo fixo (uma sequência codificada de chamadas) é mais barato, mais rápido e mais previsível. O ReAct brilha quando o caminho não é conhecido de antemão: o modelo precisa decidir, a cada passo, qual a próxima ação com base no que descobriu. Essa é a regra prática: use ReAct quando há genuína incerteza sobre a sequência de passos; use um fluxo fixo quando a sequência é determinística.

        Limitações e cuidados

        ReAct é poderoso, mas não é mágico. Alguns pontos de atenção:

          Estratégias para os loops improdutivos

          O loop improdutivo é a falha mais comum em produção. O modelo chama buscar("X"), recebe uma observação que não resolve, e chama buscar("X") de novo, repetindo indefinidamente. Mitigações práticas:

            Variações do padrão

            Desde 2023, surgiram extensões do ReAct que vale conhecer:

              Todas mantêm o núcleo do ReAct — pensar, agir, observar — e adicionam camadas por cima.

              Um exemplo de implementação mais concreta

              O esqueleto anterior esconde detalhes que importam na prática. Veja uma versão um pouco mais completa, com tratamento de erro na execução da ferramenta e uma mensagem de sistema que estabelece o comportamento do agente:

              SISTEMA = """Você é um agente que resolve tarefas usando ferramentas.
              Pense passo a passo. Use uma ferramenta de cada vez. Quando tiver a
              resposta final, responda em texto sem chamar nenhuma ferramenta."""
              
              def executar_ferramenta(nome, args, registro):
                  fn = registro.get(nome)
                  if fn is None:
                      return f"Erro: ferramenta '{nome}' não existe."
                  try:
                      return str(fn(**args))
                  except Exception as e:
                      # A observação descreve a falha; o modelo pode se ajustar.
                      return f"Erro ao executar {nome}: {e}"
              
              def agente_react(pergunta, ferramentas, registro, max_passos=12):
                  mensagens = [
                      {"role": "system", "content": SISTEMA},
                      {"role": "user", "content": pergunta},
                  ]
                  ultima_acao = None
                  for passo in range(max_passos):
                      resposta = modelo.chamar(mensagens, tools=ferramentas)
                      if not resposta.tem_chamada_de_ferramenta():
                          return resposta.texto
              
                      chamada = resposta.chamada_de_ferramenta
                      assinatura = (chamada.nome, str(chamada.args))
                      if assinatura == ultima_acao:
                          # Repetição detectada: força o modelo a mudar de estratégia.
                          obs = "Você repetiu a mesma ação. Tente uma abordagem diferente."
                      else:
                          obs = executar_ferramenta(chamada.nome, chamada.args, registro)
                      ultima_acao = assinatura
              
                      mensagens.append(resposta)
                      mensagens.append(observacao_como_msg(obs))
                  return "Limite de passos atingido sem resposta final."

              Repare em três decisões de projeto: a mensagem de sistema deixa explícito como terminar (texto sem ferramenta), a execução nunca derruba o loop por uma exceção (o erro vira observação), e a detecção de repetição quebra o loop improdutivo mais comum. Esses três detalhes resolvem a maioria dos problemas que você encontra ao colocar um agente ReAct em produção.

              Depurando um agente ReAct

              Quando um agente se comporta mal, o traço de Thought/Action/Observation é o seu melhor amigo. Imprima ou registre cada passo e procure por padrões:

                A regra geral: quase todo problema de um agente ReAct se manifesta de forma visível no traço. Resista à tentação de só olhar a resposta final; o valor está no caminho.

                Além do ReAct: rumo a múltiplos agentes

                Quando uma tarefa fica grande demais para um único loop ReAct gerenciar, uma alternativa é dividir o trabalho entre agentes especializados que colaboram — tema explorado em sistemas multi-agentes com LLMs: quando vários modelos colaboram. Cada agente pode rodar seu próprio ciclo ReAct, e um orquestrador coordena o conjunto.

                Um exemplo realista de ponta a ponta

                Para fixar, imagine um agente de suporte que responde "Meu pedido 4821 já foi enviado?". Ele tem duas ferramentas: buscar_pedido(id) e consultar_rastreio(codigo). Um traço possível:

                Thought: O usuário quer saber o status de envio do pedido 4821.
                         Primeiro preciso buscar os dados do pedido.
                Action: buscar_pedido(id="4821")
                Observation: {"id": "4821", "status": "enviado", "rastreio": "BR9912"}
                
                Thought: O pedido foi enviado e tem código de rastreio BR9912.
                         Vou consultar o rastreio para dar uma resposta mais útil.
                Action: consultar_rastreio(codigo="BR9912")
                Observation: {"situacao": "em trânsito", "previsao": "2026-07-02"}
                
                Thought: Tenho status e previsão. Posso responder.
                Final Answer: Sim! O pedido 4821 foi enviado (código BR9912) e está em
                              trânsito, com previsão de entrega para 02/07/2026.

                Note como o agente não respondeu na primeira observação, embora já soubesse que o pedido fora enviado. O raciocínio decidiu que valia a pena enriquecer a resposta com o rastreio — uma decisão que um fluxo fixo não tomaria sozinho. É exatamente essa capacidade de decidir o próximo passo com base no que descobriu que justifica o ReAct para tarefas com incerteza.

                Repare também que as observações são JSON estruturado. Devolver dados estruturados em vez de prosa livre ajuda o modelo a extrair os campos certos sem ambiguidade, e é uma boa prática geral no design de ferramentas.

                Perguntas frequentes

                ReAct e Chain-of-Thought são a mesma coisa? Não. Chain-of-Thought é só a parte do raciocínio em voz alta. ReAct adiciona ações e observações: o modelo pode consultar o mundo durante o raciocínio, não só pensar isoladamente.

                Preciso de um framework para usar ReAct? Não. O loop é simples o bastante para você escrever à mão em algumas dezenas de linhas, como no exemplo acima. Frameworks ajudam com tooling, mas entender o loop cru é o que permite depurar quando algo dá errado.

                Quantos passos um agente ReAct costuma levar? Depende da tarefa. Consultas simples resolvem em 1 a 3 passos; tarefas de pesquisa multietapa podem levar 5 a 10. Definir um teto entre 8 e 15 costuma ser um bom ponto de partida.

                ReAct funciona com qualquer modelo? Funciona melhor com modelos capazes de seguir instruções e de usar ferramentas de forma estruturada. Modelos menores ou antigos podem ter dificuldade em manter o formato e em decidir bem entre ferramentas.

                Conclusão

                O padrão ReAct resolveu um problema fundamental dos LLMs ao unir raciocínio e ação em um único ciclo iterativo. Em vez de pensar isoladamente (como no Chain-of-Thought de Wei et al., 2022) ou agir cegamente, o agente pensa, age, observa o resultado e recomeça — fundamentando cada decisão em evidência real (Yao et al., 2023). Esse loop simples é o coração da maioria dos agentes de IA atuais. As variações modernas — reflexão, plan-and-execute, multi-agente — apenas estendem esse núcleo. Compreendê-lo bem, incluindo suas armadilhas de custo, loops e contexto, é o que separa quem apenas usa um framework de quem entende, depura e estende o comportamento de um agente.

                Referências

                  Leituras relacionadas

                  Nenhum comentário ainda

                  Seja o primeiro a comentar.

                  Deixe seu comentário

                  Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

                  Entrar com Canverly