AI Architecture
Você projetará um SaaS multi-tenant de análise de documentos com API, gateway, PostgreSQL/pgvector, Redis e workers. O caso central é upload assíncrono com busca síncrona após indexação. A entrega inclui ADR, diagrama e testes de fronteira, permitindo defender custo, segurança, consistência e operação.
Use os artefatos das semanas 40–45 e Node para o exemplo local. Não é necessário criar uma conta cloud para esta etapa. Antes de ler a resolução, desenhe seu próprio fluxo e marque onde o estado é persistido, onde a identidade é validada e onde um retry pode repetir um efeito. Depois compare o desenho com as falhas propostas no laboratório.
JavaScriptAPIsAgentesIA & MLInfraestruturaAo terminar esta aula
- Arquitetura conecta contratos e fronteiras de confiança.
- Consistência e recuperação precisam de estados explícitos.
- Multi-tenancy atravessa dados, cache, quotas e observabilidade.
Antes de continuar: Leitura: AI Architecture
Descrever requisitos e escolher sync ou async
FundamentosEscreva três histórias: consultar política curta, indexar cem documentos e gerar análise com ferramenta de escrita. Defina para cada uma tempo de espera aceitável, resultado durável e regra de recuperação. Escolha sync para consulta curta e async para lote se isso atender aos requisitos; justifique qualquer alternativa. Um stream de tokens pode acompanhar a análise, mas precisa de job e resultado final quando recuperação for necessária. Anote que 202 só vem após aceitação durável. Não escolha serviços antes de definir esses contratos, pois os mesmos nomes podem implementar comportamentos incompatíveis.
Executar os testes de identidade e repetição
AvaliaçãoRode architecture.cjs e confirme pending, negação para t2 e succeeded com index.size um. Remova a verificação de tenant do status em uma cópia do teste e observe o acesso indevido, restaurando o controle em seguida. Adicione uma segunda identidade com mesmo docId e confirme chaves e entradas separadas. Altere a política para denied entre submit e work e decida explicitamente se o worker revalida. Para uma revogação sensível, o trabalho não deve continuar apenas porque foi aceito antes. Registre a política efetiva e o resultado da decisão.
const assert=require('node:assert/strict');
const policies=new Map([['t1',{version:'p1',allowed:true}]]);
const jobs=new Map(),index=new Map();
function submit(session,docId){
const policy=policies.get(session.tenant);
if(!policy?.allowed)throw new Error('denied');
const key=JSON.stringify([session.tenant,docId]);
if(!jobs.has(key))jobs.set(key,{tenant:session.tenant,docId,state:'pending',policy:policy.version});
return key;
}
function status(session,key){
const job=jobs.get(key);
if(!job || job.tenant!==session.tenant)throw new Error('denied');
return job.state;
}
function work(key){
const job=jobs.get(key);if(job.state==='succeeded')return;
index.set(key,{tenant:job.tenant,docId:job.docId});job.state='succeeded';
}
const session={tenant:'t1'},key=submit(session,'d1');
assert.equal(status(session,key),'pending');
assert.throws(()=>status({tenant:'t2'},key),/denied/);
work(key);work(key);
assert.equal(index.size,1);assert.equal(status(session,key),'succeeded');
console.log({key,state:status(session,key),policy:jobs.get(key).policy});Desenhar o diagrama com planos e fronteiras
FundamentosColoque usuário autenticado, API, gateway, workers, banco, fila e provedor no data plane. Coloque administração de tenants, políticas e quotas no control plane. Desenhe setas rotuladas com dados e protocolos, inclusive publicação de política versionada. Marque fronteiras externas e identidades de serviço. Identifique que worker não recebe poder administrativo e que provedor não recebe documentos fora de seu escopo. Acrescente onde o outbox liga commit do documento à intenção de indexação. Um diagrama sem fluxo de erro e recuperação não explica como o sistema sobrevive a falhas.
Escrever a ADR com alternativas e consequências
FundamentosCompare banco compartilhado com tenant obrigatório e banco por tenant usando critérios de isolamento, operação, custo e migração. Escolha uma opção para o cenário e registre o que a faria mudar. Decida TTL de cache público, proibição de cache compartilhado de dados privados e limites de jobs por tenant. Declare consistência eventual para o índice e verificação atual para autorização. Inclua uma consequência negativa real de cada escolha, como maior esforço de operar bancos separados ou risco de controles esquecidos em banco compartilhado. Uma ADR defensável não promete benefício sem custo.
↗ Architect Multitenant Solutions on Azure↗ Cache-Aside Pattern
Diagnosticar falhas e apresentar a arquitetura
InfraestruturaSimule commit sem publicação, mensagem duplicada, cache antigo e gateway indisponível. Para cada falha, aponte o componente que detecta, o estado preservado e o caminho de recuperação. Use outbox para a janela commit/publicação e idempotência para duplicatas. Mostre que quotas evitam um tenant monopolizar workers e que logs preservam isolamento. Entregue um walkthrough de uma consulta e de um upload, com versões e decisões observáveis. Termine com critérios de revisão e incertezas que exigem medição, como capacidade de fila e recall da busca; não invente benchmarks para defender o desenho.
Exercício aplicado
O upload foi salvo, a publicação em Redis falhou e a busca ainda não encontra o documento. Além disso, outro tenant conhece o jobId. Proponha um desenho que trate as duas falhas.
- Registre estado pending_index junto com a intenção de publicação.
- Use outbox e publicador com deduplicação.
- Exponha status consistente com o estágio real.
- Autorize consulta do job pela identidade.
Abrir resolução comentada
A transação grava documento e outbox, permitindo reenvio posterior sem perder a intenção. O worker usa chave idempotente e atualiza a projeção. Enquanto isso, o produto informa indexação pendente, sem afirmar disponibilidade na busca.
Conhecer jobId não concede acesso. A API verifica tenant no estado do job, e o mesmo isolamento precisa valer para índice, cache e logs. O control plane publica políticas, mas não deve ser editável pela execução do agente.
const assert=require('node:assert/strict');
const policies=new Map([['t1',{version:'p1',allowed:true}]]);
const jobs=new Map(),index=new Map();
function submit(session,docId){
const policy=policies.get(session.tenant);
if(!policy?.allowed)throw new Error('denied');
const key=JSON.stringify([session.tenant,docId]);
if(!jobs.has(key))jobs.set(key,{tenant:session.tenant,docId,state:'pending',policy:policy.version});
return key;
}
function status(session,key){
const job=jobs.get(key);
if(!job || job.tenant!==session.tenant)throw new Error('denied');
return job.state;
}
function work(key){
const job=jobs.get(key);if(job.state==='succeeded')return;
index.set(key,{tenant:job.tenant,docId:job.docId});job.state='succeeded';
}
const session={tenant:'t1'},key=submit(session,'d1');
assert.equal(status(session,key),'pending');
assert.throws(()=>status({tenant:'t2'},key),/denied/);
work(key);work(key);
assert.equal(index.size,1);assert.equal(status(session,key),'succeeded');
console.log({key,state:status(session,key),policy:jobs.get(key).policy});Como conferir seu resultado
- ADR apresenta alternativas e uma consequência negativa.
- Diagrama distingue política administrativa e dados do usuário.
- Job e cache não podem ser acessados por outra identidade.
- Commit/publicação e redelivery possuem recuperação definida.
Aplique em um problema novo
Primeiro resolva sem consultar a resposta. Explique suas decisões e guarde a evidência. A conclusão de leitura é independente desta autoavaliação.
Confira seus pré-requisitos
- Modelar sync/async e consistência eventual.
- Aplicar isolamento do tenant.
Upload M3 foi salvo, Redis indisponível impede publish; outbox persistido marca pendente. Worker recebe M3 duas vezes; tenant B tenta consultar job de A. Busca ainda não indexou.
Conferir raciocínio e critérios de domínio
Outbox pendente permite reenviar M3 quando Redis voltar, sem perder intenção; a gravação do upload sozinha não ofereceria essa recuperação.
Estado ainda é aceito/indexando, não pronto. Dois replays da mesma intenção devem manter um registro de indexação versionado e efeito único.
B é recusado antes de receber status privado, mesmo conhecendo o id. Consistência eventual exige estado/prazo de acompanhamento, não promessa de busca imediata.
Evidências para autoavaliação ou revisão por pares
- Outbox e intenção: Outbox pendente permite reenviar M3 quando Redis voltar, sem perder intenção; a gravação do upload sozinha não ofereceria essa recuperação.
- Estado da indexação: Estado ainda é aceito/indexando, não pronto. Dois replays da mesma intenção devem manter um registro de indexação versionado e efeito único.
- Consulta autorizada: B é recusado antes de receber status privado, mesmo conhecendo o id. Consistência eventual exige estado/prazo de acompanhamento, não promessa de busca imediata.
Um erro frequente
Consistência eventual permite espera sem contrato.
Consistência eventual precisa de estados, prazo e observabilidade.
Teste sua compreensão
Responda com suas palavras antes de abrir o comentário. Saber explicar uma decisão é parte do domínio.
1. Streaming HTTP substitui uma fila durável?
Não.
Exibir progresso não garante aceitação ou recuperação de trabalho.
2. Consistência eventual serve para toda autorização?
Não automaticamente.
Revogação pode exigir consulta atual à fonte de identidade.
3. O que faz uma ADR ser útil?
Critérios, alternativas, consequências e condições de revisão.
Uma lista de tecnologias não mostra por que a decisão atende ao cenário.
Seu progresso fica salvo neste navegador. Concluir a leitura não substitui demonstrar o domínio nos exercícios.
Referências e aprofundamento
Documentação oficial e trabalhos originais. As referências registram o escopo e as limitações para você conferir o que sustentam.
- Asynchronous Request-Reply Pattern
Microsoft • consulta: 2026-10-06
FundamentosSeparar aceite de requisição, processamento longo e consulta de status.
Limites: Persistir status e tratar timeout/cancelamento; assíncrono não elimina falhas.
- Event-Driven Architecture Style
Microsoft • consulta: 2026-10-06
InfraestruturaProducers/consumers, pub/sub, streaming, desacoplamento, idempotência, consistência eventual e recuperação.
Limites: A complexidade pode não se justificar para request-response simples; ordenação e duplicação exigem desenho explícito.
- Redis streaming
Redis • consulta: 2026-10-06
RedisAPIsStreams, logs append-only, consumer groups, acknowledgments e distribuição entre workers.
Limites: Entrega at-least-once requer tratamento de duplicações; Redis Streams e uma fila de jobs têm semânticas diferentes.
- Cache-Aside Pattern
Microsoft • consulta: 2026-10-06
FundamentosCarregamento sob demanda, invalidação e expiração de cache.
Limites: Cache pode ficar desatualizado; não garante consistência entre origem e cópia.
- Retry pattern
Microsoft • consulta: 2026-10-06
FundamentosRetries de falhas transitórias, política de atrasos, logging e impacto em transações.
Limites: Retries de operações não idempotentes e camadas aninhadas podem duplicar efeitos e ampliar carga.
- Tasks
Celery • consulta: 2026-10-06
FundamentosTasks, workers, execução assíncrona, idempotência, acknowledgment, retries e limites de tempo.
Limites: Retry e redelivery podem repetir efeitos; desenhar tarefa idempotente e testar interrupções.
- Router - Load Balancing
LiteLLM • consulta: 2026-10-06
FundamentosBalanceamento, estratégias por uso/latência/custo, retries, cooldowns e fallbacks entre deployments.
Limites: Routing operacional não garante qualidade sem evals por classe de tarefa; fallback pode mudar comportamento e recursos.
- Budgets, Rate Limits
LiteLLM • consulta: 2026-10-06
FundamentosOrçamentos e limites de requisições/tokens por usuário, chave e equipe.
Limites: Configuração e persistência importam; não citar valores de preço como permanentes.
- Considerations for Multitenant Control Planes
Microsoft • consulta: 2026-10-06
FundamentosResponsabilidades do control plane, tenant lifecycle, configuração, recursos e separação dos data planes.
Limites: Não existe template único; proteger o plano de controle e evitar sobreposição de responsabilidades.
- Architect Multitenant Solutions on Azure
Microsoft • consulta: 2026-10-06
FundamentosArquitetura SaaS multi-tenant, organização de recursos, dados, identidade, messaging e operação.
Limites: Guia amplo de decisões; escolher e justificar isolamento e custos para o caso concreto.
- LLM06:2025 Excessive Agency
OWASP • consulta: 2026-10-06
FundamentosMinimização de ferramentas, funcionalidade, permissões, contexto do usuário, autorização e aprovação de ações de alto impacto.
Limites: Autorizações devem ser impostas no sistema de destino; uma recusa textual ou decisão do LLM não é controle de acesso.