Verificando acesso...

MÓDULO 4.2 GA

🤖 Agentes single: ReAct e planner/executor

Agente é loop tool→pensa→tool. ReAct, planner/executor, controle de loop, e como debugar via tracing.

6
Tópicos
70
Minutos
Avançado
Nível
Hands-on
Tipo

Agente é o próximo passo após tool calling: loop autônomo de pensar→agir até concluir. ReAct é o padrão dominante; planner/executor é alternativa para tarefas estruturadas. Aqui você aprende a controlar o loop — sem isso, agente vira disaster de custo.

🔁 Anatomia de um agente robusto

Não é só 'modelo + tools'. É um sistema com instrumentação, limites e recovery — como qualquer sistema de produção.

📊 Yao et al. (2022) — ReAct

1

🧭 ReAct: Reason + Act

Yao et al. 2022

ReAct (Yao et al. 2022): a cada iteração, o modelo escreve Pensamento em texto livre, depois decide Ação (tool call), recebe Observação (resultado do tool), e continua. O pensamento explícito ajuda debug humano e melhora qualidade em tarefas multi-passo. Em HotpotQA (multi-hop QA), ReAct bate CoT puro em +34% (Yao 2022).

trace típico de ReAct
Pensamento: preciso buscar a janela do Claude 3.
Ação: buscar_em_corpus(query='janela contexto Claude 3', top_k=5)
Observação: [chunks com info sobre Claude 3 200k...]

Pensamento: agora preciso da janela do GPT-4.
Ação: buscar_em_corpus(query='janela contexto GPT-4', top_k=5)
Observação: [chunks com info GPT-4 128k Turbo...]

Pensamento: tenho ambos. Vou comparar.
Resposta final: Claude 3 tem 200k tokens; GPT-4 Turbo tem 128k. Claude 3 é maior.
📑 Resumo navegável
O que é: Loop: modelo pensa em texto livre ('Pensamento: preciso buscar X') → decide tool ('Ação: search(X)') → recebe resultado ('Observação: ...') → repete.
Por que aprender: Padrão simples e eficaz. Pensamento explícito facilita debug e melhora qualidade em tarefas multi-passo.
Conceitos-chave: ReAct (Yao 2022), Thought-Action-Observation, scratchpad, reasoning trace.
2

📐 Planner / Executor: separar plano de execução

Decomposição prévia

Planner/executor separa plano de execução. Primeiro passo: LLM gera plano em N steps. Segundo: executor segue passo por passo, sem o LLM redecidir. Mais auditável que ReAct para workflows conhecidos; menos flexível em casos novos.

estrutura planner/executor
plano = llm.generate(
    f'Decomponha em 3-5 passos. Saída JSON: [{step, tool, args}].\n'
    f'Tarefa: {tarefa}'
)

for passo in json.loads(plano):
    resultado = TOOLS[passo['tool']](**passo['args'])
    if not resultado.ok:
        # plano falhou — replanejar OU abortar
        break
📑 Resumo navegável
O que é: Primeiro passo: LLM gera plano em N passos. Segundo passo: executor segue passo por passo.
Por que aprender: Para tarefas estruturadas conhecidas (workflows), plano explícito é mais auditável que ReAct.
Conceitos-chave: Plan-and-execute, BabyAGI, hierarchical planning.
3

⛔ Controle de loop: max_iterations, max_tokens

Limites duros

Sem limites duros, agente loopa em produção e queima orçamento — bug clássico. Defina: max_iterations (10 default), max_tokens (orçamento total), timeout (wall clock). O primeiro que disparar para o agente. Sem isso, qualquer problema vira incidente de custo.

limites duros
def react_agent(query, tools, max_iter=10, max_tokens=50_000, timeout=60):
    inicio = time.time()
    tokens = 0
    for i in range(max_iter):
        if tokens > max_tokens or time.time() - inicio > timeout:
            return AbortReason.BUDGET_OR_TIMEOUT
        # ... step do agente ...
📑 Resumo navegável
O que é: Agente tem budget explícito: máximo de iterações, máximo de tokens, timeout total.
Por que aprender: Sem isso, agente loopa em produção e queima orçamento. Limite duro é seguro.
Conceitos-chave: Max iterations, token budget, wall-clock timeout, infinite loop detection.
4

🔍 Tracing por step: a chave para debug

Cada decisão fica registrada

Tracing por step é a ferramenta mais valiosa de debug em agentes. Cada step vira span estruturado: timestamp, tool chamada, args sanitizados, resultado, próximo step. OpenTelemetry tem semconv específica para GenAI desde 2024. Local: salve em traces/<run_id>.jsonl.

step trace estruturado
{
  'run_id': 'run-2026-05-03-abc',
  'step': 2,
  'ts': '2026-05-03T14:23:45Z',
  'tool': 'buscar_em_corpus',
  'args': {'query': '<redacted-len-23>', 'top_k': 5},
  'result': {'ok': true, 'n_chunks': 5, 'tokens_in': 1234, 'tokens_out': 0},
  'cost_usd': 0.0023,
  'wall_ms': 487,
  'next_action': 'continue'
}
📑 Resumo navegável
O que é: Cada step do agente vira entry estruturada (timestamp, tool, args, result, next). Salvo em traces/.
Por que aprender: Sem tracing, debugar agente em produção é impossível. P2 do curso exige.
Conceitos-chave: Step trace, OpenTelemetry, structured logging, step replay.
5

🛡️ Recovery: tool error, JSON inválido, loop

Padrões de robustez

Em produção, ferramentas falham e modelos respondem fora do schema. Sem recovery, agente quebra no primeiro hiccup. Padrões: retry com backoff em erros transitórios; fallback para LLM puro em tool down prolongado; abort com mensagem ao usuário quando recovery não é possível.

padrões de recovery

  • Tool retorna retry_able=True → tentar 3× com backoff exponencial.
  • JSON malformado de output → pedir ao modelo 'reformate em JSON válido'.
  • Tool consistente em fail (3+ runs) → abrir issue + degradar para resposta sem tool.
  • Loop sem progresso (mesma ação 3×) → abortar com 'agent stuck'.
📑 Resumo navegável
O que é: Estratégias para quando algo dá errado: retry com fix, abort com mensagem, fallback para LLM puro.
Por que aprender: Em produção, ferramentas falham, JSON vem malformado, modelos respondem fora do schema. Sem recovery, agente quebra.
Conceitos-chave: Retry policies, JSON repair, graceful degradation, partial success.
6

💸 Orçamento de custo por agente

Budget cap antes de loop

Cap nativo do provedor é última linha de defesa. Você quer budget explícito por tarefa: antes de iniciar o agente, declare 'esta tarefa custa no máximo X tokens / $Y'. Aborta cedo, antes de virar incidente. Especialmente importante em agentes lançados por usuário externo.

budget por tarefa
@dataclass
class TaskBudget:
    max_tokens: int = 20_000
    max_cost_usd: float = 0.50
    max_wall_seconds: int = 60

def run_with_budget(task, budget: TaskBudget):
    metrics = ResourceTracker()
    # incrementa metrics em cada step; aborta quando estoura
    if metrics.cost_usd > budget.max_cost_usd:
        raise BudgetExceeded(metrics)
📑 Resumo navegável
O que é: Antes de iniciar o agente, declarar 'esta tarefa custa no máximo X tokens / Y dólares'. Aborta se atingir.
Por que aprender: Cap nativo de provedor é última linha; cap explícito no agente é controle real.
Conceitos-chave: Per-task budget, cost estimation, soft limit, hard limit.

📑 Resumo navegável dos tópicos

1 🧭 ReAct: Reason + Act — Yao et al. 2022
O que é: Loop: modelo pensa em texto livre ('Pensamento: preciso buscar X') → decide tool ('Ação: search(X)') → recebe resultado ('Observação: ...') → repete.
Por que aprender: Padrão simples e eficaz. Pensamento explícito facilita debug e melhora qualidade em tarefas multi-passo.
Conceitos-chave: ReAct (Yao 2022), Thought-Action-Observation, scratchpad, reasoning trace.
2 📐 Planner / Executor: separar plano de execução — Decomposição prévia
O que é: Primeiro passo: LLM gera plano em N passos. Segundo passo: executor segue passo por passo.
Por que aprender: Para tarefas estruturadas conhecidas (workflows), plano explícito é mais auditável que ReAct.
Conceitos-chave: Plan-and-execute, BabyAGI, hierarchical planning.
3 ⛔ Controle de loop: max_iterations, max_tokens — Limites duros
O que é: Agente tem budget explícito: máximo de iterações, máximo de tokens, timeout total.
Por que aprender: Sem isso, agente loopa em produção e queima orçamento. Limite duro é seguro.
Conceitos-chave: Max iterations, token budget, wall-clock timeout, infinite loop detection.
4 🔍 Tracing por step: a chave para debug — Cada decisão fica registrada
O que é: Cada step do agente vira entry estruturada (timestamp, tool, args, result, next). Salvo em traces/.
Por que aprender: Sem tracing, debugar agente em produção é impossível. P2 do curso exige.
Conceitos-chave: Step trace, OpenTelemetry, structured logging, step replay.
5 🛡️ Recovery: tool error, JSON inválido, loop — Padrões de robustez
O que é: Estratégias para quando algo dá errado: retry com fix, abort com mensagem, fallback para LLM puro.
Por que aprender: Em produção, ferramentas falham, JSON vem malformado, modelos respondem fora do schema. Sem recovery, agente quebra.
Conceitos-chave: Retry policies, JSON repair, graceful degradation, partial success.
6 💸 Orçamento de custo por agente — Budget cap antes de loop
O que é: Antes de iniciar o agente, declarar 'esta tarefa custa no máximo X tokens / Y dólares'. Aborta se atingir.
Por que aprender: Cap nativo de provedor é última linha; cap explícito no agente é controle real.
Conceitos-chave: Per-task budget, cost estimation, soft limit, hard limit.

✓ O que FAZER

  • max_iterations sempre declarado (ex.: 10)
  • Tracing estruturado por step
  • Tools com erro tipado para recovery inteligente
  • Budget de custo explícito por tarefa

✗ O que NÃO fazer

  • Loop sem limite — disaster em produção
  • Print debug ad hoc
  • Exceção genérica que para o agente
  • Confiar só no cap do provedor

🚫 Quando NÃO usar

💻 Exemplo de código

from fec_sdk import Message, MessageRole
from fec_sdk.adapters import get_adapter

def react_agent(query: str, tools, max_iter: int = 10) -> str:
    msgs = [Message(role=MessageRole.USER, content=query)]
    client = get_adapter("mock")
    trace = []

    for step in range(max_iter):
        resp = client.chat(msgs, tools=tools)
        trace.append({"step": step, "content": resp.content,
                      "tool_calls": [tc.model_dump() for tc in resp.tool_calls]})

        if not resp.tool_calls:
            return resp.content  # agente decidiu parar

        # Executa cada tool e adiciona resultado
        for call in resp.tool_calls:
            result = executar_tool(call)  # com sandbox, retry, etc.
            msgs.append(Message(role=MessageRole.TOOL, content=str(result), name=call.name))

    return "max_iterations excedido"  # fallback explícito

🏋️ Exercício hands-on

Implemente ReAct agent com 3 tools + max_iterations + tracing estruturado. Bateria de 30 traços-canário (golden FEC-GS-AGENT-v1) deve passar 30/30 sem loop infinito. Em exercicios/modulo-4-2/.

📚 Bibliografia

🎯 Resumo do Módulo

  • Agente é loop: ReAct (pensa-age) ou planner/executor.
  • max_iterations obrigatório — sem isso, loop em produção.
  • Tracing por step é pré-requisito de debugability.
  • Recovery: retry, abort, fallback — não exceção crua.
  • Budget de custo explícito por tarefa.

Próximo Módulo:

Multi-agente e MCP (beta)