Como Construir um Produto de IA Multiagente Autocorretivo com LangGraph e AWS
Uma arquitetura baseada em agentes especializados que geram, avaliam e melhoram respostas automaticamente, com persistência, segurança, observabilidade e execução em produção na AWS.

A maior parte das aplicações de Inteligência Artificial Generativa começa de forma simples: o usuário envia uma solicitação, um modelo de linguagem processa o prompt e uma resposta é devolvida.
Usuário → Aplicação → LLM → Resposta
Esse modelo funciona bem para experimentação, assistentes simples e alguns casos de uso internos.
O problema aparece quando queremos transformar essa ideia em produto.
Um produto precisa fazer mais do que gerar respostas. Ele precisa controlar qualidade, manter histórico, lidar com falhas, proteger dados, controlar custos, monitorar execuções, autenticar usuários e registrar o que aconteceu durante o processamento.
É nesse contexto que entra a arquitetura deste artigo.
A proposta é construir um Produto de IA Multiagente Autocorretivo, no qual diferentes agentes assumem responsabilidades específicas dentro de um workflow coordenado pelo LangGraph.
O fluxo principal será:
Gerar → Avaliar → Corrigir → Avaliar novamente → Aprovar
Em vez de confiar integralmente na primeira resposta produzida por um LLM, introduzimos um processo de qualidade dentro da própria aplicação.
O produto que estamos construindo
Nosso produto permite que um usuário envie um tema, uma solicitação ou um conteúdo e receba como resultado uma resposta que passou por um processo automático de geração, avaliação e correção.
A primeira versão terá três agentes principais:
Agente Escritor → Agente Revisor → Agente de Correção
Cada agente possui uma responsabilidade específica.
O Agente Escritor produz a primeira versão do conteúdo.
O Agente Revisor avalia o resultado utilizando critérios de qualidade.
O Agente de Correção utiliza o feedback recebido para melhorar a resposta.
Depois da correção, o conteúdo retorna ao Revisor para uma nova avaliação.
Esse processo continua até que a resposta seja aprovada ou que o número máximo de revisões seja atingido.
O produto também pode apresentar ao usuário:
- resposta final;
- score de qualidade;
- critérios avaliados;
- quantidade de revisões;
- feedback dos agentes;
- tempo de execução;
- modelo utilizado;
- consumo de tokens;
- custo estimado;
- histórico da execução;
- status de aprovação.
A experiência deixa de ser simplesmente:
Prompt → Resposta
e passa a ser:
Solicitação → Geração → Avaliação → Correção → Validação → Resultado
O usuário deixa de interagir apenas com um modelo e passa a utilizar um sistema de IA com processo de qualidade incorporado.
Arquitetura de alto nível
A arquitetura proposta para o produto utiliza os seguintes componentes:
| Camada | Tecnologia |
|---|---|
| Frontend | React / Next.js |
| Backend | FastAPI |
| Orquestração | LangGraph |
| Inferência | Amazon Bedrock |
| Autenticação | Amazon Cognito |
| Persistência | PostgreSQL / Amazon RDS |
| Estado do workflow | LangGraph Checkpointer |
| Segurança | IAM, Secrets Manager e Bedrock Guardrails |
| Observabilidade | Amazon CloudWatch |
| Containerização | Docker |
| Registry | Amazon ECR |
| Deploy | AWS App Runner |
| Infraestrutura | Terraform |
| CI/CD | GitHub Actions |
O fluxo principal da aplicação será:
Usuário → React / Next.js → Amazon Cognito → FastAPI → LangGraph → Agentes → LLM Provider → Amazon Bedrock
Ao redor desse fluxo teremos persistência, segurança, governança, observabilidade e mecanismos de entrega contínua.
Por que utilizar múltiplos agentes?
Uma aplicação tradicional baseada em LLM normalmente concentra várias responsabilidades dentro do mesmo prompt.
Podemos solicitar ao modelo que:
- escreva um conteúdo;
- seja técnico;
- seja claro;
- valide a própria resposta;
- verifique se existem exemplos;
- corrija problemas;
- mantenha determinado tamanho;
- confirme se todos os requisitos foram atendidos.
É possível trabalhar dessa forma.
O problema é que estamos concentrando geração, avaliação e correção dentro da mesma etapa.
Do ponto de vista de engenharia, podemos separar essas responsabilidades.
Produzir → Avaliar → Corrigir
Esse é o mesmo princípio de separação de responsabilidades utilizado em software tradicional.
Cada agente passa a possuir uma função específica e previsível.
Agente Escritor
O primeiro agente é responsável pela geração inicial do conteúdo.
Ele recebe:
Tema + Contexto + Requisitos → Rascunho inicial
Por exemplo:
"Explique arquitetura hexagonal para um desenvolvedor intermediário e apresente um exemplo prático.
Podemos definir algumas responsabilidades para esse agente:
- produzir conteúdo técnico;
- explicar de forma objetiva;
- utilizar exemplos;
- manter foco no assunto;
- respeitar limites de tamanho;
- seguir o formato solicitado;
- evitar informações desnecessárias.
O resultado produzido pelo agente é armazenado no estado do workflow.
class WorkflowState(TypedDict):
topic: str
draft: str
feedback: str
decision: str
score: float
revision_count: int
O Agente Escritor não precisa decidir se sua própria resposta está boa.
Essa responsabilidade pertence ao próximo agente.
Agente Revisor
O Agente Revisor funciona como um Quality Gate.
Seu objetivo é avaliar o conteúdo produzido pelo Agente Escritor.
Uma implementação simples poderia retornar:
{
"decision": "PASS"
}
ou:
{
"decision": "REVISE"
}
Para um produto profissional, podemos ir além.
O Revisor pode produzir uma avaliação estruturada:
{
"decision": "REVISE",
"score": 0.74,
"criteria": {
"clarity": 0.91,
"relevance": 0.89,
"completeness": 0.68,
"technical_quality": 0.72
},
"issues": [
"O exemplo está pouco detalhado.",
"A explicação sobre inversão de dependência está incompleta."
],
"suggestions": [
"Adicionar um exemplo com Ports and Adapters.",
"Explicar melhor a direção das dependências."
]
}
Agora o produto possui algo muito mais interessante do que uma simples opinião do modelo.
Temos uma avaliação estruturada, que pode ser armazenada, analisada e utilizada pelo próprio workflow.
O Revisor como mecanismo de qualidade
Podemos estabelecer regras objetivas para aprovação.
Por exemplo:
Score geral ≥ 0,85
Também podemos criar critérios adicionais:
- clareza ≥ 0,80;
- relevância ≥ 0,90;
- qualidade técnica ≥ 0,80;
- completude ≥ 0,80.
A aplicação passa a combinar dois mecanismos:
Avaliação do LLM + Regras determinísticas
Exemplo:
approved = (
score >= 0.85
and clarity >= 0.80
and relevance >= 0.90
and technical_quality >= 0.80
)
Essa combinação é importante.
Não estamos simplesmente perguntando ao modelo se ele considera a resposta boa.
Estamos utilizando Inteligência Artificial dentro de um mecanismo controlado pela aplicação.
Agente de Correção
Quando o Agente Revisor identifica problemas, entramos no processo de correção.
O Agente de Correção recebe:
Tema original + Resposta atual + Problemas encontrados + Sugestões do Revisor
Por exemplo:
"Problema identificado: a explicação sobre portas e adaptadores não ficou suficientemente clara.
"Sugestão: adicionar um exemplo mostrando uma interface de repositório e uma implementação PostgreSQL.
O agente utiliza essas informações para produzir uma nova versão.
Draft v1 → Reviewer → Feedback → Reviser → Draft v2
Depois disso, a nova versão retorna ao Agente Revisor.
O loop de autocorreção
Essa é a parte central da arquitetura.
O workflow possui um ciclo.
Writer → Reviewer → Reviser → Reviewer
Se o conteúdo for aprovado:
Writer → Reviewer → PASS → Resultado Final
Se o conteúdo precisar de melhorias:
Writer → Reviewer → REVISE → Reviser → Reviewer
Caso ainda existam problemas:
Reviewer → Reviser → Reviewer → Reviser → Reviewer
Esse padrão pode ser resumido como:
Generate → Evaluate → Improve → Evaluate
Ou, conceitualmente:
Actor → Critic → Refiner
Esse ciclo transforma uma simples geração em um processo de melhoria controlada.
Por que LangGraph?
Pipelines tradicionais costumam ser lineares.
A → B → C → D
Nosso workflow não é linear.
O Agente Revisor precisa decidir dinamicamente qual será o próximo passo.
Quando a resposta é aprovada:
Reviewer → PASS → Resultado Final
Quando existe necessidade de correção:
Reviewer → REVISE → Reviser → Reviewer
Temos:
- estado compartilhado;
- decisões condicionais;
- ciclos;
- checkpoints;
- múltiplos agentes;
- condições de encerramento;
- possibilidade de retomada.
LangGraph assume o papel de orquestrador do workflow.
Ele não é responsável por gerar o conteúdo.
Sua responsabilidade é controlar a execução dos agentes e determinar como o estado evolui durante o processo.
Estado compartilhado entre os agentes
Todos os agentes trabalham sobre um estado compartilhado.
Podemos representar esse estado da seguinte maneira:
class WorkflowState(TypedDict):
topic: str
draft: str
feedback: str
decision: str
score: float
revision_count: int
Durante uma execução podemos ter:
{
"topic": "Arquitetura Hexagonal",
"draft": "Arquitetura hexagonal é...",
"feedback": "Detalhar Ports and Adapters.",
"decision": "REVISE",
"score": 0.76,
"revision_count": 1
}
Cada agente modifica apenas aquilo que pertence à sua responsabilidade.
O fluxo passa a trabalhar sobre uma representação explícita do estado da execução.
Controlando o número de revisões
Um produto autocorretivo precisa possuir limites.
Caso contrário, podemos gerar um ciclo indefinido:
Reviewer → Reviser → Reviewer → Reviser → Reviewer → ...
Isso representa:
Mais chamadas ao LLM → Mais tokens → Mais custo → Maior latência
Por isso podemos estabelecer:
MAX_REVISIONS = 3
A lógica pode seguir a seguinte regra:
Reviewer → PASS → Resultado Final
ou:
Reviewer → REVISE → Verificar limite → Reviser
Caso o limite tenha sido atingido:
Reviewer → Limite máximo atingido → Finalizar execução
Existe uma diferença importante.
Chegar ao limite máximo de revisões não significa que a resposta foi aprovada.
A API deve deixar isso explícito.
{
"status": "MAX_REVISIONS_REACHED",
"approved": false,
"score": 0.81,
"revision_count": 3
}
Essa transparência é importante para um produto profissional.
Persistência do workflow
Durante uma prova de conceito podemos guardar o estado apenas em memória.
Em produção, isso não é suficiente.
Imagine uma execução em andamento:
Writer → Reviewer → Reviser
Nesse momento o container é reiniciado.
Sem persistência, a execução é perdida.
Precisamos conseguir recuperar o workflow.
LangGraph Checkpointer
A solução passa pela utilização de checkpoints.
LangGraph → Checkpointer → PostgreSQL
Na AWS podemos utilizar:
LangGraph → Checkpointer → Amazon RDS PostgreSQL
Depois de cada etapa, o estado pode ser persistido.
Writer → Checkpoint → Reviewer → Checkpoint → Reviser → Checkpoint
Cada execução recebe um identificador.
thread_id
Exemplo:
a32887cb-36a1-4272
Isso permite reconstruir o estado de uma execução e continuar o processamento após falhas.
Também abre espaço para funcionalidades como:
- pause e resume;
- human-in-the-loop;
- recuperação após falhas;
- replay;
- auditoria;
- debugging;
- histórico de execução.
Checkpoint não é banco de negócio
Existe uma separação importante.
O Checkpointer deve armazenar o estado operacional do workflow.
O banco da aplicação deve armazenar os dados do produto.
São responsabilidades diferentes.
Podemos criar tabelas como:
users
projects
executions
execution_steps
evaluations
model_usage
prompt_versions
Uma tabela de execuções poderia possuir:
executions
id
user_id
thread_id
topic
status
approved
final_answer
final_score
revision_count
model
input_tokens
output_tokens
estimated_cost
created_at
finished_at
Agora conseguimos construir dashboards, histórico, auditoria, relatórios e métricas de produto.
Histórico de execução como funcionalidade
Uma das funcionalidades mais interessantes do produto é permitir que o usuário visualize como a resposta foi construída.
O fluxo pode ser apresentado como:
Execução iniciada → Writer → Reviewer → Reviser → Reviewer → Resultado aprovado
Podemos apresentar informações como:
Writer
- duração: 1,82 s;
- versão do prompt;
- modelo utilizado;
- quantidade de tokens;
- rascunho produzido.
Reviewer
- duração: 1,21 s;
- score: 0,74;
- clareza: 0,91;
- relevância: 0,88;
- completude: 0,67;
- decisão:
REVISE.
Reviser
- duração: 2,02 s;
- versão corrigida;
- feedback utilizado.
Nova avaliação
- score: 0,92;
- decisão:
PASS.
Resultado
- aprovado;
- duas avaliações realizadas;
- uma correção executada.
Isso é muito diferente de uma interface que simplesmente apresenta uma resposta.
Estamos expondo o comportamento do sistema.
Frontend do produto
Para o MVP podemos utilizar React ou Next.js.
O frontend pode conter:
- autenticação;
- dashboard;
- criação de nova execução;
- acompanhamento do workflow;
- resultado final;
- histórico;
- métricas;
- detalhes de cada revisão;
- perfil;
- configurações.
O fluxo de navegação será:
Usuário → Login → Dashboard → Nova Execução → Acompanhamento → Resultado → Histórico
A tela de execução pode apresentar cada etapa em tempo real:
Escritor concluído → Revisor executando → Correção necessária → Corretor concluído → Nova avaliação → Aprovado
Essa visualização aumenta a transparência e melhora a percepção de valor do produto.
FastAPI como camada de aplicação
O backend pode ser desenvolvido utilizando FastAPI.
Evitaria concentrar toda a lógica em poucos arquivos.
Uma estrutura possível seria:
apps/
└── api/
└── app/
├── main.py
├── api/
│ └── v1/
│ └── routes/
│ ├── executions.py
│ ├── health.py
│ └── users.py
├── agents/
│ ├── writer.py
│ ├── reviewer.py
│ └── reviser.py
├── graphs/
│ └── self_correcting.py
├── providers/
│ └── bedrock.py
├── repositories/
│ └── execution_repository.py
├── services/
│ └── execution_service.py
├── schemas/
└── core/
├── config.py
├── logging.py
└── security.py
A separação lógica será:
HTTP → Routes → Services → Workflow → Agents → Providers → Infraestrutura
Isso melhora:
- manutenção;
- testes;
- organização;
- desacoplamento;
- evolução do produto.
API orientada ao produto
Em vez de trabalhar apenas com um endpoint como:
POST /run
podemos tratar a execução como um recurso real da aplicação.
Criar uma execução
POST /api/v1/executions
Payload:
{
"topic": "Explique arquitetura orientada a eventos",
"max_revisions": 3
}
Resposta:
{
"execution_id": "exec_001",
"status": "running"
}
Consultar uma execução
GET /api/v1/executions/exec_001
Resposta:
{
"id": "exec_001",
"status": "approved",
"approved": true,
"score": 0.91,
"revision_count": 2,
"final_answer": "..."
}
Consultar as etapas
GET /api/v1/executions/exec_001/steps
O histórico pode ser retornado como:
Writer → Reviewer → Reviser → Reviewer → Final
Essa abordagem aproxima a API da estrutura real do produto.
Amazon Bedrock como camada de inferência
Para o MVP utilizaremos Amazon Bedrock.
O fluxo será:
LangGraph → LLM Provider → Amazon Bedrock → Foundation Model
Existe uma decisão arquitetural importante.
Os agentes não deveriam depender diretamente da AWS.
Evitaria criar:
Writer → boto3
Reviewer → boto3
Reviser → boto3
Criaria uma abstração.
class LLMProvider(Protocol):
async def generate(
self,
messages: list,
model: str,
):
...
Depois implementamos:
LLMProvider → BedrockProvider
Os agentes conhecem apenas o contrato LLMProvider.
Isso permite trocar o provedor futuramente.
LangGraph → LLM Provider → Amazon Bedrock
ou:
LangGraph → LLM Provider → OpenAI
ou:
LangGraph → LLM Provider → Azure OpenAI
ou:
LangGraph → LLM Provider → Google
ou:
LangGraph → LLM Provider → Modelo local
A lógica principal dos agentes permanece praticamente intacta.
Estratégia de modelos
Não precisamos utilizar o mesmo modelo para todos os agentes.
Podemos ter:
Writer → Modelo A
Reviewer → Modelo B
Reviser → Modelo A
O Writer pode privilegiar:
- qualidade de geração;
- velocidade;
- custo;
- capacidade de seguir instruções.
O Reviewer pode privilegiar:
- reasoning;
- consistência;
- structured output;
- capacidade de avaliação.
O Reviser pode utilizar um modelo equilibrado entre qualidade e custo.
Essa estratégia permite otimizar o workflow completo.
A métrica que realmente importa
Em aplicações com LLM costuma-se observar o custo por token.
Mas isso pode ser insuficiente.
Imagine dois cenários.
Modelo A
- menor custo por chamada;
- aprovação na primeira revisão: 65%.
Modelo B
- custo um pouco maior por chamada;
- aprovação na primeira revisão: 92%.
O Modelo B pode produzir menos ciclos de revisão.
Portanto, mesmo sendo mais caro individualmente, pode ser mais barato no workflow completo.
A métrica mais interessante passa a ser:
Custo por execução aprovada
e não apenas:
Custo por chamada ao modelo
Isso aproxima métricas técnicas das métricas de produto.
Autenticação com Amazon Cognito
Como estamos construindo um produto, usuários precisam existir.
O fluxo será:
Usuário → Frontend → Amazon Cognito → JWT → FastAPI
O backend valida o token e identifica o usuário responsável pela execução.
A partir disso podemos associar:
Usuário → Projetos → Execuções → Histórico
Essa arquitetura também prepara o produto para futuramente suportar:
- organizações;
- workspaces;
- tenants;
- roles;
- permissions;
- diferentes planos de uso.
Segurança AWS
Um produto em produção não deve armazenar credenciais AWS permanentes dentro da aplicação.
Devemos evitar:
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
dentro do container.
A aplicação deve receber permissões através de IAM Roles.
FastAPI → IAM Role → Amazon Bedrock
Isso reduz o risco associado ao gerenciamento de credenciais.
AWS Secrets Manager
Segredos da aplicação podem ser armazenados no AWS Secrets Manager.
Por exemplo:
- credenciais do banco;
- tokens de APIs externas;
- segredos de integrações;
- configurações sensíveis.
O fluxo será:
Aplicação → IAM Role → Secrets Manager → Segredo
Mantemos configuração sensível separada do código.
Bedrock Guardrails
Existe outra camada importante de controle.
O Reviewer avalia principalmente qualidade.
Os Guardrails tratam segurança, políticas e restrições.
São responsabilidades diferentes.
Podemos pensar no fluxo:
Entrada → Guardrail → Writer → Reviewer → Reviser → Guardrail → Resposta
Assim criamos duas camadas distintas:
Quality Control + Safety Control
O Agente Revisor verifica se a resposta atende aos critérios definidos pelo produto.
Os Guardrails ajudam a controlar o que pode entrar e sair do sistema.
Observabilidade do produto
Aplicações de IA precisam de observabilidade além da tradicional.
Não basta saber se a API está funcionando.
Também precisamos saber:
- qual agente está mais lento;
- qual modelo consome mais tokens;
- quantas revisões são feitas em média;
- quantas respostas passam na primeira tentativa;
- quanto custa cada execução;
- qual é a taxa de aprovação;
- quais prompts produzem melhores resultados;
- quais modelos apresentam melhor relação entre qualidade e custo.
Podemos dividir as métricas em três grupos.
Aplicação
- requests;
- latency;
- errors;
- HTTP status;
- CPU;
- memória.
Workflow
workflow_duration;writer_duration;reviewer_duration;reviser_duration;revision_count;approval_rate;failure_rate.
Inteligência Artificial
- modelo;
- tokens de entrada;
- tokens de saída;
- latência do LLM;
- custo estimado;
- score de avaliação;
- taxa de aprovação.
Essas métricas podem ser centralizadas no Amazon CloudWatch.
Observabilidade também ajuda o produto a evoluir
Depois de algumas semanas podemos descobrir:
Taxa de aprovação na primeira tentativa → 78%
Média de revisões → 1,42
Custo médio por execução aprovada → US$ 0,018
Agora temos dados para decidir:
- trocar o modelo;
- alterar prompts;
- mudar o score mínimo;
- reduzir o número de revisões;
- utilizar outro modelo no Reviewer;
- mudar critérios de aprovação.
As decisões deixam de ser subjetivas.
Versionamento de prompts
Prompts fazem parte do comportamento do produto.
Por isso, deveriam ser versionados.
Evitaria ter prompts espalhados diretamente pelo código.
Podemos manter:
prompts/
├── writer/
│ ├── v1.md
│ └── v2.md
├── reviewer/
│ ├── v1.md
│ └── v2.md
└── reviser/
├── v1.md
└── v2.md
Cada execução pode armazenar:
writer_prompt_version
reviewer_prompt_version
reviser_prompt_version
Assim conseguimos responder:
"Qual versão do prompt foi utilizada para gerar esse resultado?
Isso melhora rastreabilidade, auditoria e análise de regressões.
Testes tradicionais não são suficientes
O produto precisará de diferentes níveis de testes.
Para software:
- Unit Tests;
- Integration Tests;
- API Tests;
- Contract Tests.
Para Inteligência Artificial:
- Evaluations;
- datasets de teste;
- comparação entre modelos;
- comparação entre prompts;
- avaliação de regressões.
Podemos criar datasets contendo casos esperados.
{
"topic": "Explique REST",
"requirements": [
"explicar recursos",
"mencionar HTTP",
"explicar stateless",
"incluir exemplo"
]
}
Depois podemos testar diferentes combinações.
Prompt A + Modelo A
Prompt A + Modelo B
Prompt B + Modelo A
A partir disso conseguimos comparar resultados.
Evals como parte do desenvolvimento
Imagine que uma determinada versão do Reviewer apresente:
Reviewer Prompt v1 → Score médio 0,81
Depois de uma alteração:
Reviewer Prompt v2 → Score médio 0,89
Agora conseguimos medir se uma mudança realmente melhorou o comportamento do produto.
Isso é muito melhor do que simplesmente afirmar que uma nova versão parece melhor.
Containerização
A aplicação será containerizada.
Código → Docker → Imagem
Depois:
Imagem Docker → Amazon ECR
Isso cria um artefato de deploy padronizado e reproduzível.
AWS App Runner para o MVP
Não precisamos começar o produto utilizando a infraestrutura mais complexa disponível.
É possível utilizar EKS ou ECS com Fargate.
Para este MVP, podemos reduzir a complexidade operacional utilizando AWS App Runner.
O fluxo será:
GitHub → GitHub Actions → Docker → Amazon ECR → AWS App Runner → FastAPI
A ideia é manter o primeiro ambiente de produção simples.
Conforme o produto crescer, podemos evoluir para:
Amazon ECR → ECS → Fargate → ALB → Auto Scaling
sem precisar redesenhar completamente a aplicação.
Arquitetura profissional não significa começar com a infraestrutura mais complexa possível.
Significa construir uma solução capaz de evoluir.
Infrastructure as Code
Toda infraestrutura deve ser reproduzível.
Podemos utilizar Terraform.
infra/
└── terraform/
├── modules/
│ ├── app_runner/
│ ├── cognito/
│ ├── database/
│ ├── ecr/
│ └── observability/
└── environments/
├── dev/
├── staging/
└── prod/
A partir disso conseguimos manter ambientes separados:
DEV → STAGING → PRODUCTION
Cada ambiente pode utilizar configurações específicas, mas compartilhar os mesmos módulos de infraestrutura.
CI/CD
O pipeline de entrega pode seguir:
Developer → Pull Request → GitHub Actions → Validações → Merge → Docker Build → Amazon ECR → AWS App Runner → Production
As validações podem incluir:
- Ruff;
- Type Check;
- Pytest;
- Security Scan;
- AI Evals;
- Docker Build.
Com o tempo podemos evoluir para:
- Canary Deployment;
- Blue/Green Deployment;
- Automatic Rollback.
Arquitetura completa do produto
A arquitetura final do MVP pode ser resumida pelo fluxo principal:
Usuário → React / Next.js → Amazon Cognito → JWT → FastAPI → LangGraph → Agentes → LLM Provider → Amazon Bedrock
O workflow multiagente funciona como:
Agente Escritor → Agente Revisor → Agente de Correção → Agente Revisor → Resultado Final
A persistência do workflow funciona como:
LangGraph → Checkpointer → Amazon RDS PostgreSQL
Os dados de negócio seguem:
FastAPI → Repository → Amazon RDS PostgreSQL
A segurança segue:
Usuário → Cognito → JWT → FastAPI → IAM Role → Amazon Bedrock
Os segredos seguem:
Aplicação → IAM Role → AWS Secrets Manager
A observabilidade segue:
FastAPI + LangGraph + Bedrock → Métricas e Logs → Amazon CloudWatch
O pipeline de entrega segue:
GitHub → GitHub Actions → Docker → Amazon ECR → AWS App Runner
A infraestrutura segue:
Terraform → AWS
Fluxo completo de uma execução
Imagine que o usuário envie:
"Explique Event-Driven Architecture e apresente um exemplo utilizando AWS.
O fluxo começa:
Usuário → Frontend → FastAPI
O backend cria dois identificadores principais:
execution_id
thread_id
Depois:
FastAPI → LangGraph → Writer
O Writer gera:
Draft v1
O estado é persistido:
Writer → Checkpointer → PostgreSQL
Depois:
LangGraph → Reviewer
O resultado pode ser:
{
"score": 0.73,
"decision": "REVISE"
}
O feedback pode indicar:
"A explicação está clara, mas o exemplo utilizando EventBridge e SQS precisa ser mais detalhado.
Então:
Reviewer → Reviser
O Reviser produz:
Draft v2
A nova versão retorna para avaliação:
Reviser → Reviewer
O Reviewer pode retornar:
{
"score": 0.91,
"decision": "PASS"
}
A aplicação salva:
- resposta final;
- score;
- quantidade de revisões;
- tokens utilizados;
- modelos utilizados;
- custo estimado;
- tempo total;
- histórico de etapas.
Depois:
LangGraph → FastAPI → Frontend → Usuário
O produto pode atender diferentes cenários
Embora o exemplo inicial seja geração de conteúdo, a arquitetura é genérica.
Desenvolvimento de software
Developer Agent → Code Reviewer → Code Fixer → Code Reviewer → Resultado
SQL
SQL Generator → SQL Reviewer → SQL Optimizer → Validator → Resultado
Data Engineering
Pipeline Generator → Data Quality Reviewer → Optimizer → Validation Agent → Resultado
Documentação empresarial
Document Generator → Compliance Reviewer → Document Reviser → Approval
Arquitetura de software
Solution Architect → Architecture Reviewer → Security Reviewer → Architecture Reviser → Final Architecture
O produto pode futuramente oferecer diferentes workflows para diferentes necessidades.
Evolução do produto: Fact Checker
Existe uma limitação importante no modelo inicial.
Um Reviewer baseado em LLM não é garantia absoluta de factualidade.
Uma evolução natural seria adicionar um novo agente.
Writer → Reviewer → Fact Checker → Reviser → Quality Gate
O Fact Checker poderia consultar:
- RAG;
- Web Search;
- APIs;
- bancos de dados;
- bases corporativas;
- documentos internos.
Agora passamos a combinar:
Generation + Reflection + Grounding
Evolução para Agentic RAG
O próximo estágio pode adicionar recuperação de conhecimento diretamente ao workflow.
O fluxo pode evoluir para:
Usuário → Orquestrador → Retriever → Contexto → Writer → Reviewer → Fact Checker → Reviser → Quality Gate → Resultado
Nesse cenário, o sistema passa a consultar fontes externas antes de produzir ou validar determinadas respostas.
Isso nos leva para uma arquitetura de Agentic RAG.
Tool Calling
Outra evolução importante é permitir que os agentes utilizem ferramentas.
O fluxo passa a ser:
Agente → Decisão → Ferramenta → Resultado → Agente
As ferramentas podem incluir:
- APIs;
- bancos de dados;
- mecanismos de busca;
- sistemas corporativos;
- calculadoras;
- serviços AWS;
- ferramentas internas.
Isso aumenta significativamente a capacidade do produto.
Human-in-the-loop
Nem toda decisão precisa ser automática.
Podemos estabelecer regras como:
Score ≥ 0,90 → Aprovação automática
Score entre 0,75 e 0,89 → Revisão humana
Score < 0,75 → Nova revisão por IA
Esse padrão é especialmente importante em contextos como:
- financeiro;
- jurídico;
- compliance;
- documentação regulatória;
- relatórios empresariais;
- processos críticos.
Nesse cenário, a persistência do workflow torna-se ainda mais importante.
O fluxo pode ser:
Reviewer → Human Review → Aprovar ou Solicitar Correção → Reviser
Multiagente não significa autonomia total
Existe uma distinção importante.
Nossos agentes possuem responsabilidades específicas.
Writer → Gerar
Reviewer → Avaliar
Reviser → Corrigir
Eles não precisam ter autonomia ilimitada para serem úteis.
Em aplicações empresariais, previsibilidade pode ser mais importante do que autonomia.
A inteligência da solução está na combinação:
Agentes especializados + Workflow + Estado + Regras + Persistência + Segurança + Observabilidade
Essa combinação é o que transforma modelos em componentes de um sistema de software.
Produto de IA é software
Talvez esse seja o ponto mais importante de toda a arquitetura.
É comum olhar para aplicações de Inteligência Artificial e pensar que o LLM é o produto.
Não é.
O modelo é uma dependência do sistema.
O produto completo é formado por:
- frontend;
- backend;
- workflow;
- modelos;
- estado;
- dados;
- autenticação;
- segurança;
- observabilidade;
- infraestrutura;
- CI/CD;
- regras de negócio;
- avaliações.
O LLM ocupa apenas uma parte dessa arquitetura.
A aplicação completa funciona como:
Software + Workflow + IA + Dados + Regras + Segurança + Observabilidade + Infraestrutura
Da primeira versão à plataforma
O MVP pode começar com:
Writer → Reviewer → Reviser
Depois podemos evoluir progressivamente:
Self-Correction → Tool Calling → Fact Checking → RAG → Agentic RAG → Human-in-the-loop → Multi-Agent Platform
Ao longo dessa evolução, o produto deixa de ser apenas um gerador autocorretivo e começa a se transformar em uma plataforma de execução de workflows inteligentes.
Conclusão
Construir três agentes capazes de participar do mesmo fluxo é relativamente simples.
Transformar isso em produto exige engenharia.
Precisamos pensar em:
- arquitetura;
- separação de responsabilidades;
- persistência;
- controle de qualidade;
- recuperação de falhas;
- segurança;
- identidade;
- observabilidade;
- custos;
- versionamento;
- testes;
- avaliações;
- infraestrutura;
- deploy.
O padrão de autocorreção é interessante justamente porque introduz algo essencial em aplicações de IA:
o resultado deixa de ser simplesmente aceito porque veio de um LLM.
Ele passa por um processo.
Gerar → Avaliar → Corrigir → Validar → Entregar
LangGraph permite transformar esse processo em um workflow explícito.
Amazon Bedrock fornece a camada de inferência.
FastAPI fornece a camada de aplicação.
PostgreSQL mantém estado e dados.
Amazon Cognito controla identidade.
Amazon CloudWatch permite observar o comportamento do produto.
Docker, Amazon ECR, AWS App Runner e Terraform permitem colocar a solução em produção de forma reproduzível.
O resultado não é apenas uma aplicação que chama Inteligência Artificial.
É um produto de software orientado por IA, no qual modelos são componentes dentro de uma arquitetura maior, controlada, mensurável e preparada para evoluir.
"Não se trata apenas de escolher qual modelo utilizar, mas de definir qual arquitetura será construída ao redor dele.


