Pilha empresarial do agente
Propósito
Seção intitulada “Propósito”Este documento mapeia a lacuna entre a atual implementação de referência da demonstração e o que uma implantação de produção exigiria. Ele serve a operadores que planejam adaptar a demonstração em uma implantação real, e a leitores que avaliam a consciência de produção da implementação de referência.
A arquitetura é apresentada em cinco camadas (Computação/Hospedagem, Armazenamento/Dados, IA/ML, Observabilidade, Segurança/Conformidade) usando diagramas Mermaid para clareza visual.
Isto cobre o agente conversacional de adesão à medicação conforme implantado no Google Cloud Run, o pipeline de CI/avaliação e uma arquitetura de referência de produção genérica. A demonstração roda em um host específico (Cloud Run); a referência de produção não prescreve um fornecedor de nuvem específico: ela identifica o que uma implantação real precisaria, não qual fornecedor usar.
1. Diagrama de Contexto do Sistema
Seção intitulada “1. Diagrama de Contexto do Sistema”A visão de mais alto nível: quem usa o sistema, de quais sistemas externos ele depende e quais dados fluem entre eles.
graph TB
Patient[Patient / Caregiver<br/>Chat + Voice UI]
Operator[Operator / Reviewer<br/>Demo Key Mgmt + HITL Review]
Agent[Medication Adherence Agent<br/>FastAPI + LangGraph]
LLM[LLM Providers<br/>OpenAI + Anthropic<br/>Groq judge fallback]
TTS[ElevenLabs<br/>TTS + STT]
KB[Knowledge Base<br/>Chroma Embedded<br/>38 Synthetic KB Cards]
Obs[Observability<br/>OTel / Langfuse / Phoenix]
Supabase[(Supabase<br/>Demo Operational Data)]
Patient -->|Chat / Voice Input| Agent
Operator -->|Key Mgmt + Review| Agent
Agent -->|Generate + Judge| LLM
Agent -->|TTS / STT| TTS
Agent -->|Retrieve + Cite| KB
Agent -->|Spans + Metrics| Obs
Agent -->|Keys + Sessions + Interactions| Supabase
Agent -->|Response| Patient
Limites-chave:
- O agente é o único limite de confiança. Toda entrada do usuário entra através do FastAPI e passa pelo pipeline de salvaguardas antes de alcançar qualquer sistema externo.
- Os provedores de LLM, o ElevenLabs e os sinks de observabilidade são dependências externas. O agente degrada graciosamente quando qualquer um deles está indisponível.
- O Supabase armazena dados operacionais (chaves da demo, interações, sugestões de melhoria), mas o agente continua servindo turnos se ele estiver fora do ar.
2. Diagramas de Contêiner
Seção intitulada “2. Diagramas de Contêiner”Três contextos de implantação: a demonstração ao vivo, o pipeline de CI/avaliação e uma referência de produção.
2.1 Contêiner da demonstração (atual)
Seção intitulada “2.1 Contêiner da demonstração (atual)”graph TB
subgraph CloudRun["Google Cloud Run<br/>Single Instance (max-instances 1)<br/>us-central1 / scale-to-zero"]
FastAPI[FastAPI<br/>Single Uvicorn Worker]
Graph[LangGraph StateGraph<br/>6 Nodes + Optional HITL]
MemorySaver[MemorySaver<br/>In-Memory Checkpointer]
Chroma[Chroma Embedded<br/>DuckDB + Parquet<br/>38 Synthetic Cards]
Resilience[Resilience Layer<br/>Rate Limiter + Fallback + Cache]
OTel[OTel Exporter]
end
subgraph External["External Services"]
OpenAI[OpenAI<br/>gpt-4o-mini<br/>Primary Completions]
Anthropic[Anthropic<br/>claude-haiku-4-5<br/>Fallback + Eval Judge]
Langfuse[Langfuse Cloud Hobby<br/>50K obs/month]
Supabase[(Supabase Free Tier<br/>500 MB Postgres)]
ElevenLabs[ElevenLabs<br/>TTS + STT<br/>Entitlement-gated]
end
FastAPI --> Graph
Graph --> MemorySaver
Graph --> Chroma
Graph --> Resilience
Resilience --> OpenAI
Resilience --> Anthropic
FastAPI --> OTel
OTel --> Langfuse
FastAPI --> Supabase
FastAPI --> ElevenLabs
Custo: perto de $0/mês em escala de demonstração. A hospedagem (a franquia sempre gratuita do Cloud Run sob uma única instância com escala a zero), a observabilidade (Langfuse Cloud Hobby, 50K obs/mês) e os dados operacionais (Supabase camada gratuita) permanecem dentro de camadas gratuitas em tráfego de demonstração (50-150 revisores, 5-10 turnos cada). Os completamentos de LLM rodam em provedores pagos (OpenAI primário, Anthropic de fallback), medidos pelo registro de custos “como se pago” e limitados por um disjuntor de orçamento diário, de modo que o gasto da demo é limitado. A primeira requisição após a instância escalar a zero paga um arranque a frio do contêiner. A mesma imagem também roda a custo genuinamente $0 no Hugging Face Spaces como alvo secundário.
2.2 Contêiner de CI/avaliação
Seção intitulada “2.2 Contêiner de CI/avaliação”graph TB
subgraph GitHub["GitHub Actions<br/>ubuntu-latest"]
Build[Docker Build<br/>Same Dockerfile]
Pytest[pytest Runner<br/>Deterministic Core<br/>Coverage Gate]
end
subgraph Eval["Eval Pipeline"]
Deterministic[Deterministic Scorers<br/>Citation + Refusal<br/>Escalation + Recall]
Judge[LLM-as-Judge<br/>Anthropic claude-haiku-4-5<br/>Groundedness + Faithfulness]
DeepEval[DeepEval<br/>Hallucination Metric]
Promptfoo[Promptfoo Nightly<br/>OWASP LLM Top 10 subset]
end
subgraph TestInfra["Test Infrastructure"]
StubLLM[StubLLMClient<br/>Deterministic, Key-Free]
Phoenix[Phoenix Self-Hosted<br/>Docker Compose Profile]
GoldenCorpus[Golden Corpus<br/>315 Cases / 3 Locales<br/>JSONL Format]
end
Build --> Pytest
Pytest --> StubLLM
Pytest --> Deterministic
Pytest --> Judge
Pytest --> DeepEval
Pytest --> Phoenix
Pytest --> GoldenCorpus
Promptfoo --> GoldenCorpus
Garantia de determinismo: O gate de CI passa sem chave por meio de um cliente LLM stub determinístico. Os scorers apoiados em juiz só são ativados quando uma chave do provedor juiz (Anthropic) está definida. A mesma imagem Docker que passa no CI é a imagem que é entregue ao Cloud Run.
2.3 Contêiner de referência de produção
Seção intitulada “2.3 Contêiner de referência de produção”graph TB
subgraph Cloud["Cloud Hosting<br/>e.g., AWS / GCP / Azure"]
LB[Load Balancer<br/>TLS Termination]
FastAPIProd[FastAPI<br/>Multiple Workers<br/>Behind Reverse Proxy]
GraphProd[LangGraph StateGraph<br/>Same 6 Nodes]
PostgresSaver[AsyncPostgresSaver<br/>Durable Checkpointer]
ManagedVector[Managed Vector Store<br/>e.g., Qdrant Cloud / Pinecone]
ResilienceProd[Resilience Layer<br/>Redis-backed Rate Limiting<br/>Circuit Breakers]
end
subgraph LLMProd["LLM Providers"]
LLMPrimary[Primary LLM<br/>SLA-backed API]
LLMFallback[Fallback LLM<br/>Different Vendor]
LLMJudge[Judge Model<br/>Dedicated Instance]
end
subgraph SecurityProd["Security + Compliance"]
WAF[Web Application Firewall]
SIEM[SIEM Integration<br/>Audit Log Export]
SecretsMgr[Secrets Manager<br/>Vault / Cloud Secret Manager]
KMS[Key Management Service]
end
LB --> WAF
WAF --> FastAPIProd
FastAPIProd --> GraphProd
GraphProd --> PostgresSaver
GraphProd --> ManagedVector
FastAPIProd --> ResilienceProd
ResilienceProd --> LLMPrimary
ResilienceProd --> LLMFallback
FastAPIProd --> SIEM
FastAPIProd --> SecretsMgr
FastAPIProd --> KMS
Lacuna de produção: A demonstração roda em uma única instância com escala a zero e estado em memória. A produção precisa de escalonamento horizontal atrás de um balanceador de carga, persistência durável, segredos gerenciados, WAF, SIEM e provedores de LLM com SLA. A arquitetura é a mesma (StateGraph de seis nós do LangGraph) — apenas as camadas de infraestrutura mudam.
3. Diagrama de Componentes: internos do grafo do agente
Seção intitulada “3. Diagrama de Componentes: internos do grafo do agente”O StateGraph de seis nós do LangGraph com o sétimo nó HITL opcional.
graph LR
Intake[intake<br/>Mark turn start<br/>Seed trace_id<br/>PII redaction]
GuardPre[guardrail_pre<br/>Scope classification<br/>Escalation detection<br/>Out-of-domain routing]
Retrieve[retrieve_context<br/>RAG from Chroma<br/>Citation matching]
Generate[generate_response<br/>LLM generation<br/>Citation enforcement]
GuardPost[guardrail_post<br/>Output safety check<br/>Refusal verification]
Closing[closing<br/>Duration calculation<br/>OTel span close]
Review[review_response<br/>HITL pause<br/>Optional 7th node]
Intake --> GuardPre
GuardPre -->|in-scope| Retrieve
GuardPre -->|out-of-domain| Generate
GuardPre -->|escalation| Closing
Retrieve --> Generate
Generate --> GuardPost
GuardPost -->|safe| Closing
GuardPost -->|flagged| Review
Review -->|approved| Closing
Review -->|rejected| Generate
Fluxo de dados:
- intake — marca o início do turno, semeia o trace ID, aplica a redação de PII.
- guardrail_pre — executa o classificador de escopo. Mensagens dentro de escopo seguem para a recuperação RAG. Mensagens fora de domínio contornam a recuperação e recebem um fallback gracioso. Mensagens que disparam escalonamento curto-circuitam para o closing com um encaminhamento.
- retrieve_context — consulta o Chroma embedded por cartões de KB relevantes. Se nenhum cartão corresponder, o agente recusa em vez de alucinar.
- generate_response — chama o provedor de LLM configurado com o contexto recuperado e um prompt que impõe citação.
- guardrail_post — verifica que a resposta gerada não contém dosagem, diagnóstico ou outro conteúdo fora de escopo. Respostas sinalizadas são roteadas para a revisão HITL.
- closing — calcula a duração do turno, fecha o span OTel e retorna a resposta.
- review_response (opcional) — uma interrupção do LangGraph para revisão human-in-the-loop de turnos sinalizados. Desabilitado por padrão no modo de avaliação.
4. Comparação em cinco camadas: demonstração vs produção
Seção intitulada “4. Comparação em cinco camadas: demonstração vs produção”| Camada | Demonstração (atual) | Referência de produção |
|---|---|---|
| Computação/Hospedagem | Google Cloud Run; única instância de contêiner (--max-instances 1); região us-central1; escala a zero quando ocioso; implantação sem chaves disparada por tag a partir da mesma imagem da CI | Hospedagem em nuvem (qualquer fornecedor); múltiplas instâncias atrás de balanceador de carga; auto-escalonamento; implantações sem tempo de inatividade; uptime com SLA |
| Armazenamento/Dados | Chroma embedded (DuckDB+Parquet) para RAG; MemorySaver em memória para o estado da conversa; Supabase camada gratuita (500 MB) para dados operacionais da demo | Armazenamento vetorial gerenciado (Qdrant Cloud / Pinecone) para RAG; AsyncPostgresSaver para estado durável da conversa; Postgres gerenciado (RDS / Cloud SQL) com backups para dados operacionais; criptografia de dados em repouso |
| IA/ML | OpenAI gpt-4o-mini (primário) com Anthropic claude-haiku-4-5 (fallback) para os completamentos; juiz de avaliação Anthropic claude-haiku-4-5 (Groq como fallback do juiz); embeddings gerenciados da Voyage voyage-3.5 (primário) com um fallback local embutido BAAI/bge-small-en-v1.5; cliente LLM stub determinístico para CI; cartões de KB sintéticos | API de LLM com SLA e throughput dedicado; uma instância de juiz dedicada; serviço de embedding gerenciado; base de conhecimento expandida com revisão clínica; avaliação contínua com detecção de drift |
| Observabilidade | Spans OTel com convenções OpenInference; Langfuse Cloud Hobby (50K obs/mês); Phoenix auto-hospedado em Docker para execuções de avaliação; Arize AX como painel secundário; exportação OTLP | Pilha OTel completa com collector, amostragem e políticas de retenção; backend de observabilidade dedicado (Datadog / Grafana / Honeycomb); alertas sobre latência, taxa de erro e anomalias de custo; exportação de log de auditoria para SIEM |
| Segurança/Conformidade | Sem segredos no repositório (gitleaks no CI); lockfile fixado; Dependabot habilitado; sem PHI / sem EHR real; enquadramento de General Wellness da FDA; redação de PII na entrada e na saída; borda Cloudflare (Turnstile, origin-lock) | WAF / proteção contra DDoS; segredos gerenciados (Vault / Cloud Secret Manager); BAA com todos os provedores de LLM; conformidade com a HIPAA Security Rule; SOC 2 Type II; testes de penetração; plano de resposta a incidentes |
Cronograma de produção (qualitativo)
Seção intitulada “Cronograma de produção (qualitativo)”A comparação em cinco camadas nomeia o que muda entre a demonstração e uma implantação de produção; esta faixa esboça quando, como fases qualitativas em vez de datas comprometidas. Cada fase é condicionada à anterior, e o código do agente (o grafo de seis nós e suas salvaguardas) atravessa as quatro sem alteração: o trabalho está nas camadas de infraestrutura e governança.
graph LR
A[Demo today<br/>Cloud Run single instance<br/>synthetic data, near $0] --> B[Hardening<br/>durable state + shared store<br/>managed vector store]
B --> C[Pilot<br/>clinical KB review<br/>BAA + compliance controls]
C --> D[Production<br/>multi-instance autoscale<br/>SLA + alerting + SIEM]
A demonstração já entrega a parte difícil determinante -o comportamento do agente medido e controlado por gates-, então o cronograma é dominado pelo trabalho de infraestrutura e conformidade, não por reconstruir o agente.
Custo em volume (ilustrativo)
Seção intitulada “Custo em volume (ilustrativo)”A demo roda perto de $0 / mês: hospedagem scale-to-zero, observabilidade e
dados operacionais em camadas gratuitas, e completions de LLM medidos pelo
livro de custos as-if-paid sob um disjuntor diário rígido. O custo de produção
não é esse número escalado linearmente: ele tem duas partes que escalam de
formas diferentes.
- O custo variável é a inferência do LLM: tokens por turno vezes a taxa do provedor. Escala aproximadamente linear com o tráfego e é a linha dominante em volume. O livro as-if-paid já mede isso por turno, então uma cotação real parte de uma base medida em vez de um palpite.
- O custo fixo é o piso de infraestrutura: uma instância quente, um vector store gerenciado, um Postgres gerenciado e um backend de observabilidade com retenção. Ele aparece como um degrau ao sair das camadas gratuitas e permanece bastante plano ao longo de uma ampla faixa de tráfego.
A forma, como faixas ilustrativas de ordem de grandeza -os números reais dependem do contrato do provedor, do modelo, do tamanho da recuperação e do uso de voz:
| Turnos mensais | O que domina | Forma do custo |
|---|---|---|
| Demo (centenas) | camadas gratuitas + LLM medido | perto de $0, limitado pelo disjuntor diário |
| Milhares baixos | tokens de LLM por turno | gasto variável pequeno; infra ainda quase-grátis |
| Dezenas de milhares | tokens de LLM + instância quente + stores gerenciados | aparece um piso de infra fixo; domina o custo variável de LLM |
| Centenas de milhares+ | throughput de LLM + retenção | território de contrato com o provedor: negocie throughput e taxas |
Duas alavancas movem a linha variável sem tocar o agente: um modelo de geração menor ou mais barato, e uma recuperação que mantenha o prompt enxuto (menos tokens por turno). Ambas são configuração, não uma reconstrução.
5. Detalhes das camadas
Seção intitulada “5. Detalhes das camadas”5.1 Computação/Hospedagem
Seção intitulada “5.1 Computação/Hospedagem”Estado atual. A demonstração roda no Google Cloud Run como uma única instância de contêiner (--max-instances 1, região us-central1), escalando a zero quando ociosa. As implantações são sem chaves (Workload Identity Federation) e condicionadas a uma matriz de CI verde para a tag de release; o mesmo Dockerfile compila no CI, no desenvolvimento local e no Cloud Run. O teto de instância única é deliberado: o limitador de taxa, o cache de respostas e o checkpointer de HITL são em processo.
Lacuna de produção. Uma implantação de produção precisa de múltiplas instâncias atrás de um balanceador de carga, auto-escalonamento para lidar com picos de tráfego, implantações sem tempo de inatividade e uptime com SLA (tipicamente 99,9% ou mais). Os arranques a frio devem ser eliminados com uma contagem mínima de instâncias quentes. O próprio código do agente é portável — FastAPI com uvicorn funciona atrás de qualquer proxy reverso — mas a camada de infraestrutura precisa de investimento significativo.
Caminho de migração. A mesma imagem Docker pode implantar em qualquer host com capacidade Docker; o Hugging Face Spaces está documentado como alvo secundário (veja deploy). Escalar para fora no Cloud Run significa elevar o teto de instâncias, adicionar uma instância mínima quente e mover o limitador de taxa, o cache e o checkpointer em processo para um armazenamento compartilhado (Redis, Postgres) para que se comportem de forma consistente entre instâncias.
5.2 Armazenamento/Dados
Seção intitulada “5.2 Armazenamento/Dados”Estado atual. A recuperação RAG usa o Chroma embedded (DuckDB+Parquet), que é sem rede e roda inteiramente dentro da memória da instância. O estado da conversa usa o MemorySaver em memória por padrão; ele é perdido no reinício da instância. Os dados operacionais da demo (chaves, sessões, interações) são armazenados no Supabase camada gratuita (500 MB de Postgres gerenciado). A base de conhecimento contém cartões de KB sintéticos em formato JSONL.
Lacuna de produção. Uma implantação de produção precisa de estado durável da conversa (AsyncPostgresSaver via uma string de conexão do Postgres). A recuperação RAG deveria usar um armazenamento vetorial gerenciado (Qdrant Cloud, Pinecone ou pgvector no Postgres operacional) para persistência, suporte a corpus maior e desempenho de consulta em escala. Os dados operacionais precisam de um Postgres gerenciado com backups automatizados, recuperação a um ponto no tempo e criptografia em repouso.
Caminho de migração. O agente já provisiona uma fábrica de checkpointer durável do Postgres via uma string de conexão. Trocar do Chroma embedded por um armazenamento vetorial gerenciado exige atualizar a configuração do recuperador, mas não o próprio grafo do agente. O formato JSONL versionado já é compatível com o carregamento em massa em qualquer armazenamento vetorial.
5.3 IA/ML
Seção intitulada “5.3 IA/ML”Estado atual. Os completamentos de LLM rodam uma cascata de dois provedores: OpenAI gpt-4o-mini como primário, com fallback em Anthropic claude-haiku-4-5 diante de uma falha transitória do upstream. O juiz de avaliação é Anthropic claude-haiku-4-5, com Groq llama-3.3-70b-versatile como nível de fallback do juiz. Os embeddings usam por padrão o embedder gerenciado da Voyage quando há uma chave da Voyage presente e recaem no BAAI/bge-small-en-v1.5 localmente (sem chamada de API). O arcabouço de avaliação é um núcleo de pytest feito à mão mais DeepEval (métrica de Alucinação), um LLM-como-juiz da Anthropic e Promptfoo (red-team), executado contra casos golden sintéticos em três locales (en, es-419, pt-BR). A base de conhecimento cobre vários domínios de adesão à medicação com 38 cartões sintéticos.
Lacuna de produção. As APIs dos provedores têm limites de taxa e infraestrutura compartilhada. Uma implantação de produção precisa de provedores de LLM com SLA, com throughput e latência garantidos. O juiz de avaliação deveria rodar em uma instância dedicada para consistência. A base de conhecimento precisaria de revisão clínica e expansão para além dos dados sintéticos. A avaliação contínua com detecção de drift é essencial para a segurança em produção.
Caminho de migração. O Protocol de cliente torna a troca de provedor uma mudança de configuração. Adicionar um novo provedor exige implementar o Protocol (no máximo um punhado de métodos) e definir a cascata de geração por configuração. O arcabouço de avaliação já avalia contra limiares configuráveis e é controlado por CI.
5.4 Observabilidade
Seção intitulada “5.4 Observabilidade”Estado atual. Spans OpenTelemetry com convenções semânticas OpenInference envolvem cada nó, chamada de LLM, recuperação e decisão de salvaguarda. Sinks: Langfuse Cloud Hobby para a demonstração ao vivo (50K observações/mês, retenção de 30 dias), Phoenix auto-hospedado via Docker Compose para execuções de avaliação, e Arize AX como painel secundário. Nenhum alerta está configurado.
Lacuna de produção. Uma implantação de produção precisa de uma pilha OTel completa: collector com amostragem configurável, um backend dedicado com retenção longa (90+ dias), alertas sobre percentis de latência, taxas de erro e anomalias de custo, e exportação de log de auditoria para SIEM para conformidade. Os spans atuais já carregam os atributos certos; a lacuna está na infraestrutura de backend, não na instrumentação.
Caminho de migração. A instrumentação OTel é neutra em relação ao fornecedor. Trocar de backend é uma mudança de configuração do exportador OTLP. Os atributos de span existentes (interaction.*, llm.*, retrieval.*) são compatíveis com qualquer backend compatível com OTel.
5.5 Segurança/Conformidade
Seção intitulada “5.5 Segurança/Conformidade”Estado atual. Sem segredos no repositório (imposto pelo gitleaks no CI). As dependências são fixadas via o lockfile com monitoramento do Dependabot. Sem PHI, sem dados reais de EHR, sem informação identificável de paciente (dados 100% sintéticos). O agente opera sob o enquadramento de General Wellness / CDS de 2026 da FDA (veja postura regulatória). A redação de PII é aplicada tanto na entrada quanto na saída. Uma borda Cloudflare (verificação de bots com Turnstile, origin-lock) protege o serviço. O fingerprinting das chaves da demo usa uma impressão sha256 pseudonimizada (reidentificável), não anonimização.
Lacuna de produção. Uma implantação de produção que manipule dados reais de pacientes precisaria de: Web Application Firewall e proteção contra DDoS, segredos gerenciados (Vault, Cloud Secret Manager), Business Associate Agreements com todos os provedores de LLM, conformidade com a HIPAA Security Rule (avaliação de risco, notificação de violação, acesso mínimo necessário), certificação SOC 2 Type II, testes de penetração regulares e um plano de resposta a incidentes. A postura regulatória mudaria de General Wellness para um arcabouço de conformidade completo.
Caminho de migração. A arquitetura de salvaguardas é projetada para produção: classificação de escopo determinística, modelos de recusa auditáveis e escalonamento baseado em regras são todos padrões de nível de produção. A lacuna de segurança está principalmente na infraestrutura (WAF, gestão de segredos, criptografia) e no processo (avaliações de risco, cronogramas de auditoria), não no código da aplicação.
Referências cruzadas
Seção intitulada “Referências cruzadas”| Tópico | ADR |
|---|---|
| Arcabouço de orquestração (StateGraph de seis nós) | ADR-0001 |
| Abstração de fornecedor de LLM (Protocol + adaptadores) | ADR-0002 |
| Arcabouço de avaliação (pytest + DeepEval + juiz Anthropic + Promptfoo) | ADR-0003 |
| Pilha RAG (Chroma embedded) | ADR-0004 |
| Salvaguardas (escopo + recusa + escalonamento) | ADR-0005 |
| Observabilidade (OTel + OpenInference) | ADR-0006 |
| Implantação (Google Cloud Run) | ADR-0007 |
| Camada de dados (Supabase camada gratuita) | ADR-0010 |
| Extensão de voz (ElevenLabs TTS/STT) | ADR-0013 |
| Arquitetura de streaming (eventos SSE) | ADR-0009 |