Inicio / Trilha 2 / Modulo 2.1
MODULO 2.1

🏗️ Arquitetura da Plataforma de Agentes

Neste modulo voce vai entender como organizar uma plataforma de agentes de IA desde o primeiro arquivo. Da estrutura de pastas ao fluxo de execucao, cada decisao arquitetural tomada aqui define se o projeto vai escalar ou colapsar.

6
Topicos
45
Minutos
Basico
Nivel
Teoria+Pratica
Tipo
1

🏛️ Arquitetura de Plataformas de Agentes

A arquitetura de uma plataforma de agentes nao e um diagrama bonito num slide. E a decisao que define quantos agentes o sistema suporta, como eles se comunicam, e se a plataforma sobrevive quando voce precisa trocar de provedor de IA as 3h da manha porque a API caiu.

Conceito Principal

Uma plataforma de agentes profissional se organiza em camadas com responsabilidades claras. A camada de entrada (app/) recebe requests de diferentes canais: Telegram, API REST, webhooks. A camada de decisao (agents/) contem a logica de cada agente e sua capacidade de raciocinio. A camada de ferramentas (tools/) oferece acoes atomicas que os agentes podem chamar. A camada de instrucoes (prompts/) armazena system prompts versionados e templates. A camada de habilidades (skills/) compoe multiplas tools em capacidades complexas. E a camada de estado (memory/) persiste tudo que precisa sobreviver entre execucoes.

O modelo event-driven e a cola entre essas camadas. Em vez de chamadas diretas e acopladas, cada componente emite e escuta eventos. Quando um usuario envia uma mensagem, o sistema emite um evento "message.received". O roteador escuta esse evento, classifica a intencao e emite "agent.selected". O agente processa e emite "response.ready". Esse desacoplamento permite adicionar novos agentes, trocar provedores ou adicionar logging sem mexer no codigo existente.

Dados e Pesquisa

Plataformas event-driven como Kafka processam mais de 10 milhoes de mensagens por segundo em producao. A arquitetura A-tier (application tier) usada por Netflix, Uber e Stripe segue o mesmo principio: separar a camada de aplicacao da camada de dados e da camada de apresentacao. Em plataformas multi-tenant, o isolamento entre clientes nao e opcional. Um bug no agente de um cliente nao pode derrubar ou contaminar o agente de outro.

Dica Pratica

Comece com a estrutura mais simples que funcione, mas com os limites de responsabilidade ja definidos. Um arquivo router.ts que sabe para qual agente enviar, um arquivo por agente em agents/, e um arquivo por tool em tools/. Voce nao precisa de Kafka no dia um, mas precisa que cada peca saiba exatamente o que ela faz e o que ela nao faz.

Fazer

Separar responsabilidades desde o primeiro commit. Cada camada em seu diretorio, cada agente em seu arquivo, cada tool com uma unica funcao. Documentar as fronteiras entre camadas.

Evitar

Colocar tudo num unico arquivo "bot.js" de 3000 linhas. Misturar logica de roteamento com logica de agente. Fazer um agente chamar outro diretamente sem passar pelo orquestrador.

2

📂 Estrutura de Pastas Profissional

A estrutura de pastas nao e estetica. E a primeira decisao de arquitetura. Ela define como o time navega o codigo, como novas features sao adicionadas e como o sistema cresce sem perder coerencia.

Conceito Principal

A estrutura de referencia para uma plataforma de agentes segue o principio de separacao por dominio funcional, nao por tipo de arquivo. Em vez de ter uma pasta "controllers/", outra "models/" e outra "services/" (que nao dizem nada sobre o que o sistema faz), voce organiza por responsabilidade:

projeto/
├── app/              # Entrada: servidor, rotas, middleware
│   ├── server.ts
│   ├── router.ts
│   └── middleware/
├── agents/           # Logica de cada agente
│   ├── claude.ts
│   ├── ollama.ts
│   └── openrouter.ts
├── prompts/          # System prompts e templates
│   ├── global.md
│   └── agents/
├── skills/           # Capacidades compostas
│   ├── gmail.ts
│   └── calendar.ts
├── tools/            # Acoes atomicas
│   ├── web-search.ts
│   ├── file-read.ts
│   └── db-query.ts
├── memory/           # Persistencia de estado
│   ├── store.ts
│   └── migrations/
├── config/           # Configuracao centralizada
│   ├── env.ts
│   └── providers.ts
├── .env
├── .env.example
└── .gitignore

Dados e Pesquisa

Estudos de produtividade em grandes codebases mostram que desenvolvedores gastam 60% do tempo lendo e navegando codigo, nao escrevendo. Uma estrutura previsivel reduz esse tempo drasticamente. O padrao de monorepo usado por Google, Meta e Microsoft mantem todo o codigo num unico repositorio com fronteiras internas claras. Feature folders (agrupar por funcionalidade em vez de por tipo) e o padrao recomendado por Angular, Next.js e a maioria dos frameworks modernos.

Dica Pratica

Use barrel exports (index.ts em cada pasta) para controlar o que cada modulo expoe. Se agents/index.ts exporta apenas createAgent() e listAgents(), o resto do sistema nao precisa saber dos detalhes internos de cada agente. Isso permite refatorar a implementacao interna sem quebrar nada de fora.

Fazer

Criar a estrutura completa antes de escrever a primeira linha de logica. Adicionar README curto em cada pasta explicando sua responsabilidade. Usar nomes descritivos: agents/claude.ts, nao agents/a1.ts.

Evitar

Criar pastas "utils/", "helpers/" ou "misc/" que viram lixeira. Ter mais de 10 arquivos numa unica pasta sem subpastas. Nomear arquivos com abreviacoes que so voce entende.

3

🔑 Configuracao de APIs e Variaveis

Uma plataforma de agentes conversa com o mundo externo o tempo todo. Cada conversa precisa de credenciais, endpoints e configuracoes que mudam entre ambientes. Gerenciar isso de forma profissional e a diferenca entre dormir tranquilo e acordar com uma fatura de $50.000 porque sua chave vazou.

Conceito Principal

O padrao profissional de configuracao usa tres camadas. A primeira e o arquivo .env na raiz do projeto, que contem as variaveis de ambiente locais e nunca entra no git. A segunda e o arquivo .env.example, que contem as mesmas variaveis mas com valores placeholder, servindo de documentacao viva. A terceira e um modulo config/ que carrega, valida e exporta as configuracoes de forma tipada:

// config/env.ts
import { config } from 'dotenv';
config();

export const env = {
  // Provedores de IA
  OPENAI_API_KEY: requireEnv('OPENAI_API_KEY'),
  ANTHROPIC_API_KEY: requireEnv('ANTHROPIC_API_KEY'),
  GOOGLE_API_KEY: getEnv('GOOGLE_API_KEY', ''),

  // Telegram
  TELEGRAM_TOKEN: requireEnv('TELEGRAM_TOKEN'),
  ALLOWED_CHAT_ID: requireEnv('ALLOWED_CHAT_ID'),

  // Server
  PORT: getEnv('PORT', '3000'),
  NODE_ENV: getEnv('NODE_ENV', 'development'),
};

function requireEnv(key: string): string {
  const value = process.env[key];
  if (!value) throw new Error(`Missing: ${key}`);
  return value;
}

function getEnv(key: string, fallback: string): string {
  return process.env[key] || fallback;
}

Dados e Pesquisa

GitHub reporta que mais de 2 milhoes de secrets sao detectados em repositorios publicos por ano. A rotacao de chaves (trocar a chave periodicamente e invalidar a anterior) e pratica padrao em empresas serias. Para producao, servicos como AWS Secrets Manager, Google Secret Manager ou Vault substituem o .env por um armazenamento criptografado e auditavel. A provider abstraction (uma camada que abstrai qual provedor de IA esta sendo usado) permite trocar entre OpenAI, Anthropic e Google mudando apenas uma variavel de ambiente.

Dica Pratica

Sempre valide todas as variaveis obrigatorias na inicializacao do sistema. Se OPENAI_API_KEY nao esta definida, o sistema deve falhar imediatamente com mensagem clara, nao 20 minutos depois quando alguem tenta usar o agente. Adicione ao .gitignore: .env, *.pem, credentials.json, e qualquer arquivo que tenha "secret" ou "key" no nome.

Fazer

Criar .env.example com todos os campos documentados. Validar variaveis no startup. Usar nomes descritivos: OPENAI_API_KEY, nao KEY1. Ter fallbacks sensiveis para variaveis opcionais.

Evitar

Hardcodar chaves no codigo. Commitar .env no repositorio. Usar a mesma chave de API em desenvolvimento e producao. Ignorar limites de rate limiting dos provedores.

4

🧠 Contexto Global vs por Agente

Em uma plataforma com multiplos agentes, nem todo agente precisa saber tudo. Um agente de pesquisa nao precisa das regras de formatacao de email. Um agente de comunicacao nao precisa dos detalhes tecnicos de deploy. A hierarquia de contexto define o que cada agente sabe e o que e compartilhado entre todos.

Conceito Principal

O sistema de contexto funciona como uma hierarquia de heranca. No topo esta o contexto global: identidade da plataforma, regras de seguranca, formato de resposta padrao, e restricoes que valem para todos os agentes. Esse contexto normalmente fica em um arquivo como CLAUDE.md ou system-prompt.md na raiz do projeto.

No segundo nivel esta o contexto por agente: dominio de atuacao, tom de voz especifico, ferramentas disponiveis e restricoes locais. Cada agente tem seu arquivo de configuracao (agents/research.yaml, agents/comms.yaml) que define essas instrucoes especificas.

No terceiro nivel esta o contexto por sessao: historico da conversa atual, preferencias do usuario detectadas durante a interacao, e estado temporario. Esse contexto existe apenas durante a execucao e nao persiste entre sessoes (a menos que explicitamente salvo em memory/).

// Hierarquia de contexto
const context = {
  global: loadFile('prompts/global.md'),     // Regras da plataforma
  agent:  loadFile('prompts/agents/research.md'), // Instrucoes especificas
  session: getSessionHistory(chatId),         // Historico da conversa
  user:   getUserPreferences(userId),         // Preferencias do usuario
};

// O system prompt final e a composicao das camadas
const systemPrompt = [
  context.global,
  context.agent,
  context.user,
].join('\n\n');

Dados e Pesquisa

A janela de contexto dos modelos atuais varia de 8K a 200K tokens. Cada token de contexto adicional custa dinheiro e tempo de processamento. Pesquisas mostram que modelos perdem qualidade com contexto excessivo (fenomeno "lost in the middle" documentado por pesquisadores de Stanford). Plataformas de agentes bem projetadas mantendo o contexto enxuto e relevante geram respostas melhores e mais baratas do que as que despejam toda informacao disponivel no prompt.

Dica Pratica

A regra de ouro: se uma instrucao vale para todos os agentes, coloque no global. Se vale so para um agente, coloque no arquivo daquele agente. Se vale so para aquela sessao, monte dinamicamente. Nunca repita a mesma instrucao em multiplos arquivos de agente. Centralize, depois especialize.

Fazer

Criar um prompt global com regras de seguranca e identidade. Criar prompts por agente com dominio e ferramentas. Compor o contexto final em runtime concatenando as camadas relevantes.

Evitar

Dar o contexto inteiro da plataforma para todos os agentes. Copiar e colar instrucoes entre arquivos de agentes diferentes. Deixar o historico de sessao crescer indefinidamente sem compactacao.

5

⚡ Fluxo Padrao de Execucao

Todo request que entra na plataforma precisa seguir um caminho previsivel. Da mensagem do usuario ate a resposta final, cada etapa tem um papel claro. Sem isso, bugs aparecem em lugares inesperados e diagnosticar problemas vira adivinhacao.

Conceito Principal

O pipeline padrao de execucao tem quatro fases:

1. Entrada: O sistema recebe a mensagem (Telegram, API, webhook), valida o formato, autentica o usuario, e registra o inicio do request com um ID unico para rastreabilidade.

2. Decisao: O roteador analisa a mensagem e decide qual agente deve processar. Isso pode ser baseado em comandos explicitos (/claude, /ollama), classificacao por IA, ou regras fixas. O contexto relevante e montado nesta fase.

3. Execucao: O agente selecionado recebe a mensagem e o contexto, processa usando o provedor de IA correspondente, pode chamar tools durante o processo, e gera uma resposta. Se o provedor falha, o sistema tenta um fallback.

4. Saida: A resposta e formatada para o canal de origem, metricas sao registradas (tokens usados, tempo de resposta, custo), o historico e atualizado, e a resposta e enviada ao usuario.

// Fluxo simplificado
async function handleMessage(msg) {
  const requestId = generateId();
  log.info({ requestId, user: msg.from }, 'request.start');

  try {
    // 1. Entrada: validar e autenticar
    validateMessage(msg);
    authenticate(msg.from.id);

    // 2. Decisao: rotear para agente
    const agent = router.selectAgent(msg.text);
    const context = await buildContext(msg, agent);

    // 3. Execucao: processar com fallback
    const response = await executeWithFallback(
      () => agent.process(msg.text, context),
      () => fallbackAgent.process(msg.text, context)
    );

    // 4. Saida: formatar, registrar, enviar
    await trackUsage(requestId, response.usage);
    await saveHistory(msg.chat.id, msg.text, response.text);
    await sendResponse(msg.chat.id, response.text);

    log.info({ requestId, tokens: response.usage }, 'request.done');
  } catch (error) {
    log.error({ requestId, error }, 'request.failed');
    await sendResponse(msg.chat.id, 'Erro no processamento.');
  }
}

Dados e Pesquisa

O padrao de middleware (usado por Express, Koa, Fastify) e a forma mais testada de implementar pipelines de processamento. Cada middleware adiciona uma responsabilidade (auth, logging, rate limiting) sem que os outros precisem saber. O circuit breaker pattern (popularizado pelo livro "Release It!" de Michael Nygard) impede que falhas em cascata derrubem o sistema inteiro: se um provedor de IA falha 5 vezes seguidas, o circuito "abre" e redireciona para o fallback automaticamente.

Dica Pratica

Implemente retry com exponential backoff: espere 1s na primeira falha, 2s na segunda, 4s na terceira, e desista apos 3 tentativas. Para producao, adicione um timeout global (60 segundos e um bom padrao) para garantir que requests travados nao acumulem e derrubem o servidor. Sempre registre o tempo total de cada request para identificar gargalos.

Fazer

Definir o pipeline antes de implementar features. Ter error handling em cada etapa. Registrar metricas de tempo e tokens. Ter fallback para pelo menos o provedor principal.

Evitar

Tratar erro com catch vazio que engole a excecao. Nao ter timeout em chamadas de API externas. Deixar o sistema travar silenciosamente quando o provedor nao responde.

6

🛠️ Exercicio: Criar Estrutura Base

Hora de sair da teoria. Neste exercicio voce vai criar o repositorio, montar a estrutura de pastas, configurar as variaveis de ambiente e construir o esqueleto do primeiro agente. Ao final, voce tera a base funcional que vai receber tudo das proximas trilhas.

Conceito Principal

O exercicio cobre 5 passos concretos:

Passo 1 - Inicializar o repositorio: git init, npm init, instalar dependencias base (dotenv, typescript).

Passo 2 - Criar a estrutura de pastas: Criar todos os diretorios (app/, agents/, prompts/, skills/, tools/, memory/, config/) com seus index files.

Passo 3 - Configurar .env: Criar .env com as chaves de pelo menos um provedor, .env.example como documentacao, e .gitignore para proteger os secrets.

Passo 4 - Modulo de configuracao: Criar config/env.ts que carrega, valida e exporta as variaveis de ambiente de forma tipada.

Passo 5 - Esqueleto do primeiro agente: Criar agents/simple.ts com a interface basica: recebe mensagem, chama provedor de IA, retorna resposta. Testar com um script simples.

# Passo 1: Inicializar
mkdir meu-saas-agentes && cd meu-saas-agentes
git init
npm init -y
npm install dotenv typescript @types/node
npx tsc --init

# Passo 2: Criar estrutura
mkdir -p app agents prompts/agents skills tools memory config
touch app/server.ts app/router.ts
touch agents/simple.ts agents/index.ts
touch prompts/global.md
touch tools/index.ts skills/index.ts
touch memory/store.ts
touch config/env.ts

# Passo 3: Configurar
echo "OPENAI_API_KEY=sk-sua-chave" > .env
echo "OPENAI_API_KEY=sk-xxx" > .env.example
echo -e ".env\nnode_modules/\ndist/" > .gitignore

# Passo 4: Primeiro commit
git add .
git commit -m "feat: scaffold inicial da plataforma"

Dica Pratica

Nao pule nenhum passo. A tentacao e ir direto para o codigo do agente e "ver funcionando". Mas se a estrutura nao estiver certa agora, voce vai pagar o preco nas proximas trilhas quando precisar adicionar autenticacao, dashboard, multiplos agentes e deploy. Invista 15 minutos na base e economize horas de refactoring depois.

Entregavel

Repositorio git com a estrutura completa de pastas, .env configurado, .gitignore protegendo secrets, modulo de configuracao validando variaveis, e um agente simples que recebe texto e retorna resposta de um provedor de IA. Tudo rodando com um npm start.

Resumo Final

✓ Entendeu a arquitetura event-driven com camadas funcionais separadas.

✓ Montou a estrutura de pastas profissional com separacao por dominio.

✓ Configurou APIs e variaveis de ambiente com seguranca e validacao.

✓ Aprendeu a hierarquia de contexto: global, por agente e por sessao.

✓ Entendeu o pipeline padrao: entrada, decisao, execucao, saida.

✓ Criou a estrutura base do projeto com agente funcional.