…
Módulo 1 · Parte B de 3

O ciclo ReAct

Um agente baseado em um grande modelo de linguagem executa o mesmo ciclo perceber-raciocinar-agir que qualquer outra coisa, com um detalhe que dá nome ao padrão: o modelo raciocina em palavras entre as ações que ele toma. Yao et al. (2022) chamou isso de ReAct, de raciocinar e agir. Os autores descobriram que intercalar traços de raciocínio curtos com o uso de ferramentas lida com muitas tarefas de forma mais confiável do que planejar tudo primeiro ou agir sem um passo de raciocínio.

Uma ferramenta é um trecho de código que o harness de execução pode executar para o modelo: uma função nomeada com uma descrição, um esquema de entrada e um valor de retorno. Uma chamada de ferramenta é a solicitação estruturada do modelo para esse código. O harness de execução analisa a solicitação, executa a função, anexa o resultado e chama o modelo novamente.

Esse ciclo é a base sobre a qual a maioria dos frameworks de agentes de propósito geral é construída, incluindo o createReactAgent da LangChain, e o restante desse módulo trabalha em direção a ele.

O ciclo permanece o mesmo. Com um grande modelo de linguagem na etapa de raciocínio, o agente lê os resultados e age chamando ferramentas.

O único campo que informa ao ciclo o que fazer em seguida

Cada resposta de Chat Completions inclui finish_reason, que indica por que o modelo parou de gerar. No ciclo do agente, leia esse campo junto com o conteúdo e as solicitações de ferramentas para decidir se deve executar uma ferramenta, retornar a resposta ou tratar um erro. Antes de estudar os valores, faça duas chamadas e compare as respostas.

A primeira chamada não oferece ferramentas. Na segunda, o modelo recebe uma ferramenta e uma pergunta sobre a hora atual. Ele decide se solicita o relógio. Compare as perguntas, as respostas e finish_reason. Se ambas retornarem "stop", examine a segunda resposta: o modelo admite que não pode consultar a hora ou responde sem verificá-la? Altere o modelo ou a pergunta e execute novamente. Uma solicitação de ferramenta indica trabalho para seu código; esta prévia não o executa.

No ReAct moderno, um roteador curto lê esse campo. Se o modelo pediu uma ferramenta, o roteador executa a sua função, anexa o resultado e chama o modelo novamente. Se o modelo parou, o roteador retorna a resposta.

O modelo pode revisar seu plano depois de ler o resultado de uma ferramenta. Quando uma ferramenta retorna algo inesperado, o resultado entra na próxima rodada de raciocínio, e o modelo pode reavaliar a situação antes de decidir o que fazer.

Relacionar o modelo, a memória, as ferramentas e o roteador?

As peças de um agente de LLM

Amplie o agente e você encontrará a decomposição que Lilian Weng apresentou em 2023. Um grande modelo de linguagem está no centro. Ao redor dele estão memória, planejamento, ferramentas e as ações que interagem com o mundo.

No ciclo de ferramentas abaixo, essas responsabilidades se dividem assim:

  • Memória é o array messages[].
  • O planejamento ocorre quando o modelo usa o contexto fornecido para escolher sua próxima resposta ou solicitação de ferramenta.
  • Ferramentas são as funções que o harness de execução expõe.
  • Ação é a chamada de ferramenta que o harness de execução executa.

O harness de execução mantém as mensagens e executa as ferramentas. Seu roteador lê finish_reason para decidir se processa solicitações de ferramentas ou retorna uma resposta.

Depois de Lilian Weng (2023): o modelo é o controlador central do agente, com memória, planejamento, ferramentas e ação conectados ao redor dele.
Os módulos são independentes. Você pode substituir o modelo ou as ferramentas ou o roteador por conta própria, e desde que cada um ainda honre o contrato que os outros esperam dele, o resto do ciclo do agente continua funcionando.

Se esse ciclo falhar, inspecione os valores transmitidos entre seus componentes. Procure os seguintes problemas:

  • o modelo retornando o finish_reason errado,
  • uma mensagem ausente no array,
  • o executor de ferramentas devolvendo um valor inesperado,
  • ou o roteador lendo o sinal de forma errada.

Construindo o ciclo do agente a partir do zero com uma ferramenta

Como um exercício, podemos tentar criar um ciclo simples do agente a partir do zero. Tudo o que precisamos é de uma única ferramenta chamada get_current_time mais um prompt do sistema e um ciclo while. Execute-o com "Que horas são em UTC?" para começar e veja o que mais você pode perguntar:

Pense, aja, observe, repita. O ciclo termina quando finish_reason é "stop".
O que acabou de acontecer dentro do array de mensagens.
Quando o modelo solicita o relógio, o ciclo adiciona estes turnos a state.messages: A próxima chamada ao modelo recebe essas mensagens, incluindo o resultado do relógio. Examine a resposta para verificar se o modelo responde ou solicita outra ferramenta. O array crescente é a única "memória" que este agente tem. Salvar e recarregar esse array preserva o histórico de conversa fornecido; os fatos externos e o comportamento do modelo podem mudar.
Revisar evidências e mitigações da degradação do contexto?

Degradação do contexto: por que um ciclo mais longo lê pior

Degradação do contexto é a tendência de contradições, observações desatualizadas e convenções pobres se acumularem no histórico do prompt até prejudicar a próxima decisão do modelo. O efeito também tem um componente posicional: Liu et al. (2023) mostraram que os modelos podem subutilizar informações enterradas no meio de um contexto longo. Quanto mais um sinal importante se afasta do turno atual, mais fácil é para o ciclo ignorá-lo ou contradizê-lo.

Recriado a partir de Liu et al. (2023). À medida que o ciclo anexa turnos, a resposta que você precisa se afasta para o meio fraco.

Mitigações comuns mantêm cada decisão próxima às evidências de que precisa:

  • planeje antes que o ciclo acumule observações,
  • delegue subtarefas para que cada subagente trabalhe em um contexto curto,
  • ou resuma turnos anteriores antes que eles se tornem um passivo.

Aplicando o mesmo loop ao curso

O ciclo acima fixa diretamente uma pequena ferramenta. O createReactAgent da LangChain generaliza o mesmo mecanismo para oferecer suporte a mais ferramentas, interfaces padrão e integrações de observabilidade. O agente abaixo usa uma única ferramenta, read_course_page, que fornece ao agente qualquer página deste curso como markdown. O modelo decide quais páginas ler para responder à sua pergunta; experimente.

Execute a célula para abrir o chat e pergunte “Como o ciclo do relógio decide quando parar?” Você pode deixar a seleção de páginas vazia; o agente escolherá quais consultar. Para escolher o contexto, abra Opções de modelo e contexto e selecione um título em Páginas antes da primeira mensagem. A dica do título mostra o ID de origem, como 01b-react. Se mudar a seleção depois, inicie uma Nova conversa. Expanda um indicador de fonte para comparar a resposta com o que o agente leu.

Antes de continuar

Volte ao canvas do loop do relógio e edite as entradas para fazer essas comparações.

  1. Force o modelo a chamar a ferramenta mesmo quando não precisa. Tente uma pergunta que a ferramenta genuinamente não possa responder ("capital da França?") e observe finish_reason na etapa 1. Foi "stop" ou "tool_calls"? Agora edite o prompt do sistema para exigir uma chamada de ferramenta antes de responder ("Você deve sempre chamar get_current_time uma vez, então responder."). O modelo atende? O que isso revela sobre o quanto o prompt do sistema consegue direcionar um modelo que confia em seus dados de treinamento para outra resposta?
  2. Conte os passos de uma pergunta que precisa de uma ferramenta. "Quantos minutos faltam para as 17:00 UTC?" precisa de uma leitura do relógio e de um cálculo. Execute algumas vezes. O modelo chamou get_current_time uma, duas ou três vezes? Por que pediria novamente um resultado que já tem? Como você alteraria o prompt do sistema para evitar isso?
O que devo aprender com essas comparações?

A primeira comparação distingue as instruções do prompt do controle de fluxo imposto pelo programa. Compare a ferramenta solicitada e finish_reason antes de decidir se a instrução foi seguida. Uma solicitação, sozinha, não prova que o relógio foi executado.

A segunda comparação pergunta se cada chamada adicional traz evidências úteis. Examine os resultados do relógio e a ordem deles em messages. Se a sequência não estiver clara, volte ao diagrama do ciclo e expanda o registro de execução antes de alterar o prompt. O resultado pode variar entre execuções; explique-o a partir do seu próprio registro.

Rastrear esses mecanismos até as fontes primárias?

Referências

Lista abrangente em Ir Além · Referências.

← Módulo 1a: O Agente