Registros de Decisão de Arquitetura
Esta seção reúne os Registros de Decisão de Arquitetura (ADRs) da
implementação de referência ai-agent-eval-harness-healthtech. Cada ADR
captura uma decisão arquiteturalmente significativa que é difícil ou
cara de reverter e explica por que ela foi tomada.
Convenções
Seção intitulada “Convenções”- Formato: MADR 4.0.0. Copie a estrutura de um ADR existente para qualquer nova decisão; não invente estruturas ad-hoc.
- Status:
Proposed->Accepted. Cada registro declara uma decisão no tempo presente; as alternativas que foram ponderadas e deixadas de lado são mantidas na seção “Opções consideradas” do próprio registro. - Nomenclatura de arquivos:
ADR-NNNN-kebab-title, sequência de quatro dígitos preenchida com zeros à esquerda, título em kebab minúsculo. - Escopo de um ADR: uma decisão por arquivo.
- Tom: inglês técnico, sem texto de marketing, sem emojis, sem travessões. Toda afirmação sobre framework / fornecedor / versão cita uma fonte primária (notas de versão, documentação oficial, registro da FDA, etc.).
| ID | Título | Status | Resumo em uma linha |
|---|---|---|---|
| ADR-0001 | Framework de orquestração | Accepted | LangGraph 1.x em vez de CrewAI, Microsoft Agent Framework, Claude Agent SDK, Pydantic AI, AutoGen. Grafo de seis nós com um nó HITL review_response opcional via interrupt() e uma fábrica de checkpointer MemorySaver / AsyncPostgresSaver. |
| ADR-0002 | Abstração de fornecedor de LLM | Accepted | Um Protocol LLMClient fino sobre adaptadores LangChain mais um caminho Groq direto via um cliente REST compatível com OpenAI, alternado por uma variável de ambiente LLM_PROVIDER. |
| ADR-0003 | Harness de avaliação | Accepted | Núcleo artesanal em pytest mais DeepEval e Promptfoo, com um LLM-como-juiz Anthropic Claude Haiku para as dimensões pontuadas por rubrica e Phoenix para inspeção opcional de traces. |
| ADR-0004 | Stack de RAG | Accepted | Armazenamento vetorial primário Chroma embarcado; Voyage voyage-3.5 como embedder primário com um fallback dev/eval BAAI/bge-small-en-v1.5 no extra embeddings-local (fora da imagem de produção) usando recuperação assimétrica consciente de instruções; Qdrant Cloud documentado como a alternativa de banco de dados vetorial gerenciado. |
| ADR-0005 | Guardrails e postura regulatória | Accepted | Classificador de escopo, templates de recusa e um roteador de escalonamento determinístico de alto recall como módulos de primeira classe; contrato de design = linha de orientação FDA 2026 General Wellness / CDS Software. |
| ADR-0006 | Stack de observabilidade | Accepted | Formato de transmissão OpenTelemetry + OpenInference; Langfuse Cloud para a demo ao vivo, Phoenix auto-hospedado para execuções de avaliação, Pydantic Logfire documentado como alternativa. |
| ADR-0007 | Alvo de implantação | Accepted | Google Cloud Run (imagem de contêiner, instância única) como alvo de produção. Camada de resiliência de implantação: rate limiter por sessão, fallback de provedor OpenAI -> Anthropic, cache de resposta com TTL curto. |
| ADR-0008 | Licença de código | Accepted | O código tem licença Apache 2.0. |
| ADR-0009 | Streaming do grafo de execução do agente para a UI | Accepted | O Agent Execution Graph transmite eventos por nó para a SPA via server-sent events, com adesão opcional por negociação de conteúdo via cabeçalho Accept; o contrato JSON /chat permanece inalterado. |
| ADR-0010 | Camada de dados (Supabase para dados operacionais da demo) | Accepted | Postgres gerenciado do Supabase para chaves da demo, interações, sugestões de melhoria, solicitações de chaves da demo, consentimentos de chaves da demo, sessões da demo, uso de turnos da demo, orçamento global da demo e verificações de e-mail da demo. O RAG continua sendo Chroma (ADR-0004). |
| ADR-0011 | Detecção de fora de domínio em texto livre | Accepted | O classificador de escopo determinístico (regex + palavra-chave) ganha detecção de fora de domínio ciente do tópico: admite turnos dentro de domínio, recusa fora de escopo de alta confiança, e dá à entrada benigna fora de tópico um empurrão gentil em vez de uma recusa dura. Sem chamada de LLM (um classificador baseado em LLM foi descartado por custo). |
| ADR-0012 | Estratégia de expansão do corpus | Accepted | Estratégia de acréscimo ao existente: novos domínios adicionados sobre o corpus base em vez de substituí-lo. Novos cartões de KB e turnos de avaliação ampliam a cobertura pelos domínios de adesão a medicamentos; paridade de localidade mantida entre en / es-419 / pt-BR. |
| ADR-0013 | Extensão de voz (ElevenLabs TTS + STT) | Accepted | ElevenLabs eleven_multilingual_v2 para TTS sob demanda com mapeamento de voz por localidade e ElevenLabs Scribe para STT, entregue como uma superfície com consentimento prévio e limitada por direitos em vez de um controle universal. |
| ADR-0014 | Fallback em cascata de provedor de LLM | Accepted | Cascata tipada de erros transitórios OpenAI -> Anthropic. Um 4xx que não seja 429 não é repetido (preservação de cota). O provedor que respondeu é etiquetado em metadata para atribuição honesta de custo. |
| ADR-0015 | Armazenamento da Camada de Melhoria Contínua | Accepted | Logs de interação e sugestões de melhoria são projetados para coalocar no mesmo projeto Postgres gerenciado (ADR-0010), com PII redigida na entrada, curados pelo operador e nunca aplicados automaticamente. |
| ADR-0016 | Camada de resiliência de implantação no nível gratuito | Accepted | Rate limiter de janela deslizante em processo (IP consciente de proxy) + cache de resposta com TTL, ambos limitados e residentes em memória. Sem Redis, sem serviço externo. Design de worker único; escalonamento multi-worker exige estado externo. |
| ADR-0017 | Voz desligada por padrão - política de segurança | Accepted | A voz vem desligada por padrão e é condicionada por consentimento explícito registrado no servidor antes de qualquer turno de áudio; o estado do consentimento é do lado do servidor, não apenas do cliente. Paridade de localidade entre en / es-419 / pt-BR. |
| ADR-0018 | Invariante de dados exclusivamente sintéticos + lista de exclusão | Accepted | Corpus de avaliação 100% sintético a partir de fontes de domínio público (MedlinePlus, DailyMed, WHO EML, rótulos da FDA). Lista de exclusão explícita: MIMIC, ChatDoctor, MedDialog, n2c2/i2b2. Ônus da prova no PR para qualquer novo conjunto de dados (licença + procedência + compatibilidade). |
| ADR-0019 | Resposta estruturada do agente (esquema Pydantic + modo JSON do LLM) | Accepted | O agente emite uma resposta estruturada validada por Pydantic via modo JSON do LLM em vez de prosa livre, de modo que os avaliadores de recusa / escalonamento leiam campos explícitos em vez de inferir intenção a partir do texto. |
| ADR-0020 | Recuperação de documento pai (chunking de subcartão, citação em nível de cartão) | Accepted | Os cartões de KB são divididos em passagens de subcartão para embedding/recuperação e, em seguida, deduplicados de volta para o cartão pai para citação, melhorando o recall enquanto mantém as citações em nível de cartão. |
| ADR-0021 | Streaming de tokens (stream customizado do LangGraph + cliente de streaming) | Accepted | Deltas de LLM por token são transmitidos para a SPA pela superfície SSE existente (ADR-0009), de modo que a mensagem do assistente seja renderizada enquanto é gerada, em vez de após um buffer de resposta completa. |
| ADR-0022 | Recuperação híbrida (BM25 + densa + RRF + rerank com cross-encoder) | Accepted | A recuperação somente densa é substituída por um pipeline de três estágios condicionado por flag - geradores léxico (BM25) + denso em paralelo, fusão por reciprocal-rank e, em seguida, rerank com cross-encoder - degradando graciosamente para o caminho denso anterior. |
| ADR-0023 | Medição de recall de recuperação (recall@k / hit@k / nDCG@k) | Accepted | A qualidade da recuperação é medida diretamente com recall@k / hit@k / nDCG@k contra cartões relevantes rotulados, desacoplando a pontuação de recuperação de métricas acopladas à geração, como cobertura de citação. |
| ADR-0024 | Enriquecimento de citação no lado do servidor | Accepted | O modelo Citation ganha source_url, source_license e retrieved_score opcionais, enriquecidos no lado do servidor no nó de encerramento, de modo que o popover de citação da SPA renderize sem um segundo ida e volta à KB. |
| ADR-0025 | Provedor de reranking gerenciado e determinismo de avaliação | Accepted | O reranking é transferido para um reranker gerenciado fora da caixa resolvido por turno (gerenciado quando há uma chave da Voyage, senão local), degradando para apenas-fusão em qualquer queda; o portão de avaliação offline permanece sem store, determinístico e gratuito. |
| ADR-0026 | Trava de design da calibração do juiz | Accepted | O portão de concordância humano-vs-juiz congela seu enquadramento, bins, limiar e corpus antes de rotular qualquer caso, mede um kappa de Cohen com ponderação linear por dimensão (portão agrupado, diagnósticos por locale) e só permite reequilibrar o corpus - nunca ajustar o limiar - ante um paradoxo de kappa. |
| ADR-0027 | Reequilíbrio do corpus de calibração | Accepted | O corpus de calibração é composto para discriminar - ponderado ao limítrofe, paralelo entre locales e diverso em defeitos - após um painel especialista constatar que um corpus saturado nos polos rende um kappa quase circular e não informativo; aplica a única alavanca aberta da trava de design com cada constante de integridade congelada. |
| ADR-0028 | Correção do construto de fidelidade | Accepted | A fidelidade é re-especificada como um construto de somente contradição - desvinculado da fundamentação, que fica com as adições não apoiadas - e recalibrada por um painel às cegas com as constantes congeladas intactas, para que humano e juiz meçam a mesma coisa. |
| ADR-0029 | Pontuador de fidelidade por rubrica | Accepted | O pontuador de fidelidade de produção é substituído por um pontuador por rubrica do juiz que lê o cartão citado completo e pontua a contradição ou violação de suas regras de comportamento explícitas, para que os dois lados da calibração meçam o mesmo construto; o juiz não muda. |
| ADR-0030 | Portão de calibração consultivo por padrão | Accepted | O portão de calibração cabeado é entregue consultivo por padrão - um caminho de corpus não definido pula em verde (registrado), a aplicação é uma adesão explícita do operador que dispara e passa como está provado - para que uma dimensão honestamente no limite nunca se torne um CI permanentemente vermelho, com o limiar e os bins congelados nunca como alavanca. |
| ADR-0031 | Calibração com portão de escalonamento e autolesão | Accepted | Escalonamento e autolesão se somam ao portão humano-vs-juiz como bloqueadores duros do lançamento - um portão de revalidação que falha ante uma concordância de segurança ausente, obsoleta para a cadeia ativa, de uma única classe ou abaixo do limiar - enquanto as dimensões de qualidade conservam o pulo consultivo; nenhuma constante congelada se move e o juiz fica intacto. |
| ADR-0032 | Correção do construto da rubrica de autolesão | Accepted | A rubrica de autolesão é re-especificada com portão de presença - primeiro pergunta se o turno carrega um sinal de autolesão (interpretado amplamente) e não confere crédito em um turno benigno nem em uma emergência que não é de autolesão - refletindo a âncora-ausente de escalonamento e revalidada sobre um conjunto reservado, com os rótulos humanos e as constantes congeladas sem alteração. |
| ADR-0033 | Portão da faixa de lançamento restrito às dimensões exigidas | Accepted | Na faixa de aplicação do lançamento o portão falha em duro só sobre as dimensões de segurança exigidas; as dimensões não de segurança ficam consultivas-e-reportadas ali, e o portão geral não muda - para que o veredito de lançamento gire sobre o sinal de segurança, sem mover nenhum limiar nem enfraquecer nenhum controle de segurança. |
| ADR-0034 | Piso de escalonamento cego à negação, ratificado | Accepted | O piso de emergência determinístico e sempre ativo é intencionalmente cego à negação - um sinal de alarme negado ou hipotético mesmo assim escala (recall acima de precisão) - e qualquer mudança nele deve re-passar um portão de paridade de recall e uma prova de piso sem juiz, para que um caso nunca possa ser descartado em silêncio. |
| ADR-0035 | Inversão fail-safe do juiz de escalonamento | Accepted | O juiz semântico de escalonamento é a única barreira que falha em direção ao escalonamento - cada tempo limite, erro, fora-do-esquema ou desfecho malformado escala - rodando atrás do piso determinístico (combinado por conjunção, sem nunca estreitá-lo) com um prior enviesado ao recall, um tempo limite duro limitado sem retentativas em linha, e a calibração empírica diferida. |
| ADR-0036 | Política limitada de redação de nomes | Accepted | O redator determinístico de PII cobre só identificadores estruturados (e-mail, telefone, IDs nacionais incluídos RUT/CPF/DNI, cartão, MRN, data de nascimento, endereço, com dígito verificador) e exclui intencionalmente os nomes de pessoas por taxa de falsos positivos e por dados somente sintéticos; uma passagem ativa de nomes condicionada por configuração é a melhoria nomeada e diferida para uma implantação com dados reais. |
Referências
Seção intitulada “Referências” Parte do portfólio de Waldemar Szemat · szemat.pro
GitHub · LinkedIn