# Agentes de IA por Dentro (2/3): Catálogo de Padrões — de ReAct a Multi-Agente

A segunda aula da série mapeia o catálogo completo de padrões de arquitetura de agentes de IA: dos loops single-agent (ReAct, Reflexion, Plan-and-Execute) à orquestração multi-agente, passando por memória como decisão de arquitetura, guardrails e human-in-the-loop. O objetivo é dar ao arquiteto uma linguagem precisa para escolher — e justificar — o padrão certo para cada problema, sem cair nos anti-patterns clássicos.

- URL: https://fernando.moretes.com/studies/agentes-de-ia-por-dentro-2-padroes-de-arquitetura

- Markdown: https://fernando.moretes.com/studies/agentes-de-ia-por-dentro-2-padroes-de-arquitetura/study.md?lang=pt

- Type: Guia / Deep Dive

- Domain: IA / Agentes

- Date: 2026-06-26

- Tags: ai-agents, ReAct, multi-agent, memory, guardrails, orchestration, LLM, architecture-patterns

- Reading time: 8 min

---

Na Parte 1 desta série você entendeu o que é um agente de IA: um loop que percebe, raciocina, age e observa resultados — diferente de um simples pipeline de prompt. Agora vem a pergunta que realmente importa para quem projeta sistemas: *qual padrão usar?* ReAct? Plan-and-Execute? Multi-agente com supervisor? A resposta errada custa dinheiro (tokens são caros), latência (loops encadeados somam segundos) e confiabilidade (cada salto é um ponto de falha). Este guia é o catálogo que eu gostaria de ter tido quando comecei a projetar agentes em produção: cada padrão explicado do zero, com quando usar, quando evitar, e os anti-patterns que aparecem toda vez.

## O que você vai aprender

- Os 5 padrões single-agent (ReAct, Reflexion, Plan-and-Execute, Tool Use, Agentic RAG) e quando cada um se encaixa
- Memória como decisão de arquitetura: contexto, sessão, longo prazo — e por que memória mal projetada vira custo e alucinação
- Os 4 topologias multi-agente (supervisor, hierárquico, swarm, roteamento por especialista) e o critério real para escolher
- Guardrails e segurança como camada de arquitetura — não como afterthought
- Human-in-the-loop: quando exigir aprovação humana e como modelar checkpoints sem travar o fluxo
- Anti-patterns clássicos: multi-agente prematuro, tool sprawl, memória sem TTL, loop infinito

## Glossário Rápido — Termos que aparecem nesta aula

- **LLM:** Large Language Model — o modelo de linguagem que faz o raciocínio central do agente (ex: Claude, GPT-4, Titan).
- **Tool / Ferramenta:** Função externa que o agente pode chamar: API REST, query SQL, busca vetorial, calculadora, etc.
- **Context Window (janela de contexto):** Limite de tokens que o LLM consegue 'ver' de uma vez. Tudo fora da janela é invisível ao modelo — como RAM de processo.
- **RAG:** Retrieval-Augmented Generation — buscar documentos relevantes e injetá-los no prompt antes de gerar resposta.
- **Guardrail:** Camada de validação que filtra entradas/saídas do agente — análogo a um WAF para LLMs.
- **Prompt Injection:** Ataque onde dados externos (ex: conteúdo de um e-mail) contêm instruções maliciosas que sequestram o comportamento do agente.
- **Orquestrador / Supervisor:** Agente ou processo que divide tarefas e delega para sub-agentes especializados.
- **TTL (Time-to-Live):** Tempo de validade de um dado em cache/memória. Sem TTL, memória de agente cresce indefinidamente.

## O Loop Fundamental: por que todo padrão começa aqui

Se você leu a Parte 1, você sabe que um agente é essencialmente um loop: o LLM recebe uma observação, raciocina, decide uma ação, executa, observa o resultado e repete. O que diferencia os padrões arquiteturais não é esse loop em si — é *como* o raciocínio é estruturado dentro dele e *quantos* agentes participam.

Pense como um desenvolvedor de software. Você já escreveu um `while` com condição de parada. Um agente é exatamente isso, mas a condição de parada é decidida pelo LLM ('a tarefa está completa?'), e o corpo do loop pode chamar ferramentas externas. O problema de engenharia é: como você estrutura o raciocínio dentro do loop para que ele seja confiável, auditável e não entre em loop infinito?

O **ReAct** (Reasoning + Acting, Yao et al., 2022) foi o primeiro padrão a formalizar isso: o modelo alterna explicitamente entre um passo de *Thought* (raciocínio em linguagem natural), um passo de *Action* (chamada de ferramenta) e um passo de *Observation* (resultado da ferramenta). Essa alternância explícita é poderosa porque torna o raciocínio auditável — você pode ler o log e entender *por que* o agente tomou cada decisão. É o equivalente a escrever código com comentários inline em vez de um bloco monolítico.

## Diagrama 1 — Agente Single-Agent ReAct com Tools

Um único agente LLM num loop ReAct (Thought → Action → Observation). As ferramentas são chamadas síncronas; o guardrail inspeciona entrada e saída. O loop termina quando o LLM emite 'Final Answer' ou o orçamento de passos é esgotado.

### 👤 User / Client

- User request (user)

### 🛡️ Security Layer

- Input Guardrail prompt injection / PII filter (security)
- Output Guardrail toxicity / data leak filter (security)

### 🤖 Agent Core (ReAct Loop)

- LLM Claude / GPT-4 / Titan (ai)
- Thought reasoning step (ai)
- Action tool selection + args (ai)
- Observation tool result injected (ai)

### 🔧 Tools

- Vector Search Agentic RAG (data)
- External API REST / GraphQL (external)
- Calculator deterministic fn (compute)

### 💾 Memory

- Context Window in-prompt (ephemeral) (storage)
- Session Memory short-term store (storage)

### Fluxos

- user -> guardrail_in: entrada bruta
- guardrail_in -> llm: input validado
- llm -> thought: 1. Thought
- thought -> action: 2. Action
- action -> tool_search: tool call
- action -> tool_api: tool call
- action -> tool_calc: tool call
- tool_search -> observation: resultado
- tool_api -> observation: resultado
- tool_calc -> observation: resultado
- observation -> llm: 3. loop back
- llm -> guardrail_out: Final Answer
- guardrail_out -> user: resposta filtrada
- llm -> ctx_window: lê/escreve
- llm -> session_mem: persiste

## Além do ReAct: Reflexion, Plan-and-Execute e Agentic RAG

**Reflexion** (Shinn et al., 2023) adiciona um segundo loop interno de autocrítica: após cada tentativa, o agente gera uma reflexão sobre o que deu errado e armazena essa reflexão na memória de sessão antes de tentar novamente. É como um desenvolvedor que escreve um teste, vê falhar, anota o diagnóstico e então corrige — em vez de simplesmente tentar de novo no escuro. O custo é claro: mais tokens por tentativa. Use quando a tarefa tem critério de correção verificável (ex: código que deve compilar, SQL que deve retornar resultado não-vazio).

**Plan-and-Execute** separa o raciocínio em duas fases distintas: um *Planner* LLM gera um plano de passos (pense num `Makefile`), e um *Executor* LLM executa cada passo independentemente. A vantagem é que o plano pode ser inspecionado e aprovado por um humano antes da execução — excelente para fluxos de alto risco. A desvantagem é rigidez: se o ambiente muda durante a execução, o plano pode ficar obsoleto.

**Agentic RAG** é o upgrade do RAG estático que todo arquiteto deveria conhecer. No RAG tradicional, você sempre busca documentos antes de gerar. No Agentic RAG, o agente *decide* quando buscar, *formula* a query de busca como parte do raciocínio, e pode fazer múltiplas buscas iterativas ('não encontrei, vou reformular a query'). Isso reduz ruído no contexto — você não injeta documentos irrelevantes — mas exige que o agente saiba quando ele *não sabe* algo, o que é um problema de calibração do modelo.

## Padrões Single-Agent — Quando usar cada um
| Critério | Padrão | Analogia de código | Melhor para | Custo principal | Evitar quando |
| --- | --- | --- | --- | --- | --- |
| ReAct | while loop com log | Tarefas exploratórias com ferramentas | Tokens por iteração | Tarefa tem resposta direta sem tools | — |
| Reflexion | TDD com autocrítica | Geração de código, SQL, lógica verificável | 2-3x mais tokens por tentativa | Sem critério de correção claro | — |
| Plan-and-Execute | Makefile + executor | Fluxos longos com aprovação humana | Latência de planejamento + rigidez | Ambiente muda durante execução | — |
| Tool Use / Function Calling | SDK com métodos tipados | Integração com APIs externas | Latência de I/O da ferramenta | Mais de 15-20 ferramentas (tool sprawl) | — |
| Agentic RAG | Lazy loading de conhecimento | Bases de conhecimento grandes e heterogêneas | Calibração do modelo para saber quando buscar | Base pequena e estável (RAG estático é suficiente) | — |

## Memória como Arquitetura: o problema que ninguém modela direito

Memória em agentes é análoga a storage em microsserviços: você tem RAM (rápida, cara, volátil), disco local (mais barato, persistente por sessão) e banco de dados distribuído (lento, barato, compartilhado). Cada camada tem um trade-off diferente.

A **janela de contexto** é a RAM do agente: tudo que está no prompt ativo. É a memória mais rápida, mas tem custo linear em tokens — cada token a mais que você injeta no contexto aumenta o custo de inferência e a latência. O erro clássico é jogar tudo na janela de contexto ('vou colocar todo o histórico da conversa') e descobrir que a conta de API triplicou.

A **memória de sessão** (curto prazo) é o equivalente a um cache Redis por sessão: você persiste o histórico da conversa atual fora do prompt e injeta apenas o resumo ou os últimos N turnos. Isso resolve o problema de custo, mas exige uma estratégia de sumarização — e sumarização feita pelo LLM tem custo também.

A **memória de longo prazo** — vetorial, episódica, semântica — é o banco de dados distribuído. Você armazena fatos, preferências do usuário, episódios passados em um vector store (ex: OpenSearch, pgvector) e recupera por similaridade semântica quando relevante. O risco aqui é duplo: memória sem TTL cresce indefinidamente (custo de storage e latência de busca), e memória desatualizada gera alucinações — o agente 'lembra' de um fato que mudou.

## Diagrama 2 — Camadas de Memória do Agente

Três camadas de memória com custo e latência crescentes. O agente escolhe qual camada consultar/escrever em cada passo do loop ReAct. A seta de 'sumarização' mostra que a janela de contexto pode ser comprimida para memória de sessão.

### 🤖 Agent LLM

- Agent LLM ReAct loop (ai)

### ⚡ Layer 1 — Context Window (RAM)

- Context Window ~200k tokens max ephemeral, costly (storage)

### 🗂️ Layer 2 — Session Memory (Cache)

- Session Store Redis / DynamoDB TTL = session lifetime (storage)
- Summarizer LLM compression (ai)

### 🗄️ Layer 3 — Long-Term Memory (DB)

- Vector Store OpenSearch / pgvector semantic retrieval (data)
- Episodic Store structured facts user preferences (data)
- TTL Policy stale-data eviction (security)

### Fluxos

- agent_core -> ctx: lê/escreve (síncrono)
- ctx -> summarizer: comprime quando > threshold
- summarizer -> session: persiste resumo
- agent_core -> session: recupera histórico
- agent_core -> vector_store: busca semântica
- agent_core -> episodic: lê fatos / preferências
- ttl_policy -> vector_store: evict stale
- ttl_policy -> episodic: evict stale

## Multi-Agente: quando ajuda de verdade e quando só adiciona complexidade

A pergunta mais importante sobre multi-agente não é 'qual topologia usar' — é 'eu realmente preciso de multi-agente?' A resposta honesta é: na maioria dos casos, não. Um agente único bem projetado com as ferramentas certas resolve 80% dos problemas que as pessoas tentam resolver com arquiteturas multi-agente complexas.

Multi-agente faz sentido em três cenários reais: (1) **paralelismo genuíno** — sub-tarefas independentes que podem rodar simultaneamente (ex: analisar 10 documentos em paralelo); (2) **especialização de domínio** — um sub-agente com prompt system e ferramentas otimizados para um domínio específico (ex: agente de compliance vs. agente de análise financeira); (3) **isolamento de contexto** — você não quer que o contexto de uma sub-tarefa contamine o raciocínio de outra.

As quatro topologias principais são: **Supervisor/Orquestrador** (um agente central delega para sub-agentes e consolida resultados — como um tech lead distribuindo tarefas); **Hierárquico** (supervisor de supervisores — para problemas muito grandes); **Swarm/Peers** (agentes sem hierarquia que se comunicam por mensagens — mais resiliente, mais difícil de debugar); e **Roteamento por Especialista** (um router LLM classifica a tarefa e envia para o agente especializado correto — análogo a um API Gateway com roteamento semântico).

O critério de decisão que uso em produção: se você não consegue explicar em uma frase *por que* cada agente existe separado, você provavelmente não precisa de multi-agente.

## Diagrama 3 — Topologia Supervisor → Sub-Agentes Especialistas

O orquestrador recebe a tarefa do usuário, decompõe em sub-tarefas, delega para agentes especializados (com seus próprios tools e memória), e consolida os resultados. Guardrails operam em cada fronteira. Human-in-the-loop é um checkpoint antes da ação de alto risco.

### 👤 User / Client

- User request (user)

### 🛡️ Entry Guardrail

- Entry Guardrail injection / scope check (security)

### 🧠 Orchestrator Agent

- Supervisor LLM task decomposition + result consolidation (ai)
- Task Router which sub-agent? (ai)

### 🔬 Specialist Sub-Agents

- Compliance Agent regulatory tools narrow context (ai)
- Finance Agent data / calc tools narrow context (ai)
- Document Agent Agentic RAG vector store (ai)

### 🧑‍💼 Human-in-the-Loop

- Human Checkpoint approve / reject high-risk action (user)

### 🛡️ Exit Guardrail

- Exit Guardrail output validation data leak check (security)

### Fluxos

- u2 -> g_entry: tarefa bruta
- g_entry -> orch: input validado
- orch -> router: decompõe
- router -> sa_compliance: delega (paralelo)
- router -> sa_finance: delega (paralelo)
- router -> sa_docs: delega (paralelo)
- sa_compliance -> orch: resultado parcial
- sa_finance -> orch: resultado parcial
- sa_docs -> orch: resultado parcial
- orch -> hitl: checkpoint (ação de risco)
- hitl -> orch: aprovado / rejeitado
- orch -> g_exit: resposta consolidada
- g_exit -> u2: resposta final

## Guardrails, Segurança e Human-in-the-Loop: arquitetura, não afterthought

O erro mais comum que vejo em times que estão chegando em agentes de IA é tratar segurança como uma camada que se adiciona depois. Não funciona assim. Guardrails precisam ser projetados como parte do fluxo desde o início, porque eles afetam latência, custo e o design das ferramentas.

**Prompt injection** é o SQL injection dos agentes: dados externos (um e-mail, um documento, uma resposta de API) podem conter instruções que sequestram o comportamento do agente. A defesa é em camadas: (1) separar claramente dados de instruções no prompt (use delimitadores explícitos); (2) validar no guardrail de entrada se o conteúdo de dados contém padrões de instrução; (3) aplicar o **princípio do menor privilégio** nas ferramentas — um agente que só precisa ler documentos não deve ter ferramenta de escrita em banco de dados.

**Tool sprawl** é o anti-pattern de dar ao agente 30 ferramentas 'porque pode precisar'. O LLM precisa escolher a ferramenta certa entre todas as disponíveis — quanto mais ferramentas, maior a probabilidade de escolha errada e maior o tamanho do prompt de sistema. Regra prática: se um agente tem mais de 15 ferramentas, considere dividir em sub-agentes especializados.

**Human-in-the-loop** não é um sinal de fraqueza da arquitetura — é um requisito de negócio em qualquer sistema que executa ações irreversíveis (transferências financeiras, envio de e-mails em massa, deleção de dados). O padrão correto é modelar checkpoints explícitos no fluxo Plan-and-Execute: o plano é gerado, um humano aprova, a execução começa. Isso também é o que o Amazon Bedrock Agents suporta nativamente com 'human approval steps'.

## Anti-Patterns Clássicos de Agentes — Sintoma, Causa e Remédio
| Critério | Anti-Pattern | Sintoma | Causa raiz | Remédio |
| --- | --- | --- | --- | --- |
| Multi-agente prematuro | Latência alta, debugging impossível | Complexidade antes de necessidade real | Comece single-agent; adicione agentes só com justificativa clara | — |
| Tool Sprawl | Agente escolhe ferramenta errada, erros aleatórios | Mais de 15-20 ferramentas por agente | Dividir em sub-agentes especializados com ferramentas mínimas | — |
| Memória sem TTL | Custo crescente, alucinações de fatos antigos | Nenhuma política de expiração no vector store | TTL por tipo de dado; re-indexar fatos que mudam | — |
| Loop infinito | Timeout, custo explodindo, nenhuma resposta | Sem orçamento de passos (step budget) | Definir max_iterations; fallback explícito para 'não sei' | — |
| Contexto poluído | Respostas inconsistentes, custo alto | Histórico completo sempre no prompt | Sumarização + memória de sessão; injetar só o relevante | — |

## Por onde começar — Checklist mental para o arquiteto

- ✅ Comece com o padrão mais simples que resolve o problema: um agente ReAct com 3-5 ferramentas resolve a maioria dos casos.
- ✅ Defina o orçamento de passos (max_iterations) antes de ir para produção — sem isso, você tem loop infinito garantido.
- ✅ Modele as camadas de memória explicitamente: o que vai na janela de contexto, o que vai na sessão, o que vai no vector store — e qual é o TTL de cada um.
- ✅ Guardrails de entrada e saída são obrigatórios em produção — mesmo que sejam simples no início. Adicione prompt injection detection desde o dia 1.
- ✅ Antes de adicionar um segundo agente, escreva em uma frase por que ele existe separado. Se não conseguir, não adicione.
- ✅ Identifique as ações irreversíveis do seu sistema e adicione human-in-the-loop checkpoints para cada uma delas.

> **Perspectiva do Arquiteto — Para quem está fazendo essa transição:** Se você vem de sistemas distribuídos, a maior armadilha ao projetar agentes é o instinto de adicionar complexidade para resolver problemas de confiabilidade. Em microsserviços, quando algo falha, você adiciona retry, circuit breaker, saga. Em agentes, a resposta quase sempre é: simplifique o loop, reduza as ferramentas, melhore o prompt. Multi-agente é poderoso, mas é o equivalente a microsserviços — você paga o custo de coordenação em latência, tokens e complexidade operacional. Eu só adiciono um segundo agente quando consigo medir o benefício concreto: redução de latência por paralelismo, ou melhoria mensurável de qualidade por especialização. O que me convenceu a levar guardrails a sério não foi teoria — foi ver um agente em staging ser sequestrado por um prompt injection escondido no corpo de um e-mail que ele estava processando. A Parte 3 desta série vai mostrar como o Bedrock AgentCore trata esses problemas com infraestrutura gerenciada, mas os princípios desta aula valem para qualquer stack.

## Veredicto — O que leva para casa

O catálogo de padrões desta aula não é uma lista de opções equivalentes — é uma escada de complexidade. ReAct é o degrau 1: resolve a maioria dos problemas, é auditável e barato de operar. Reflexion e Plan-and-Execute são degraus 2 e 3: adicionam capacidade de autocorreção e aprovação humana, mas com custo de tokens e latência. Multi-agente é o degrau 4: só suba quando os degraus anteriores falharem por razões mensuráveis. Memória e guardrails não são degraus — são fundações que precisam estar presentes desde o degrau 1. A Parte 3 desta série fecha o ciclo mostrando como o Amazon Bedrock AgentCore implementa esses padrões em infraestrutura gerenciada, com suporte nativo a memória, guardrails e human-in-the-loop.

## Referências

- [Anthropic — Building effective agents](https://www.anthropic.com/engineering/building-effective-agents)
- [AWS — Multi-agent orchestration on Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-multi-agent-collaboration.html)
- [Yao et al. — ReAct: Synergizing Reasoning and Acting in Language Models (arXiv 2210.03629)](https://arxiv.org/abs/2210.03629)
- [Shinn et al. — Reflexion: Language Agents with Verbal Reinforcement Learning (arXiv 2303.11366)](https://arxiv.org/abs/2303.11366)
- [Gregor Hohpe — The Architecture Elevator (book)](https://architectureelevator.com/)
- [AWS — Amazon Bedrock Agents documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/agents.html)

## Fontes do caso

- [Anthropic — Building effective agents](https://www.anthropic.com/engineering/building-effective-agents)
- [AWS — Multi-agent orchestration on Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-multi-agent-collaboration.html)
- [Yao et al. — ReAct](https://arxiv.org/abs/2210.03629)
- [Shinn et al. — Reflexion](https://arxiv.org/abs/2303.11366)
