Nesta página
Propriedade de arquitetura
O COADF P-1 enuncia o mínimo: um componente probabilístico devolve um valor junto com uma confiança e o método pelo qual o valor foi obtido, nunca um valor nu, e nunca chega diretamente a uma saída. Este padrão trata da segunda metade, que é a metade que as implementações perdem. A resposta de um modelo pode entrar no sistema. O que ela não pode é se tornar, por caminho algum, aquilo que o sistema trata como estabelecido.
Três coisas precisam valer ao mesmo tempo:
- A saída tem um tipo próprio. Uma proposta e um registro com autoridade são tipos diferentes, tabelas diferentes ou mensagens diferentes. Um código que tem um deles em mãos não consegue passá-lo onde se espera o outro sem uma etapa explícita que alguém possa revisar.
- A fronteira valida em tempo de execução. O contrato é verificado quando a resposta chega, no processo que a recebe, diga o remetente o que disser ter verificado.
- A procedência viaja com o valor. O método, o modelo e sua revisão, a revisão do prompt e a localização na fonte permanecem ligados ao valor em cada etapa, serialização incluída. Sem eles, o P-4 não consegue reconstruir e o P-5 não consegue declarar.
O P-1 também faz o componente informar uma confiança. Como a confiança é expressa, atribuída e usada pertence ao P-2, que o COADF publica apenas como princípio. Este Companion não a descreve, e nada abaixo depende dela.
Por que importa
A saída de um modelo vem de um processo que não pode ser reproduzido a partir de suas entradas como a saída de um parser pode: amostragem, atualizações do modelo e mudanças de prompt, tudo isso a desloca. Isso é aceitável para uma proposta e inaceitável para um fato. O risco não é um modelo às vezes errar; tudo às vezes erra. O risco é perder a capacidade de dizer quais valores vieram de onde, porque todo controle posterior depende disso. Um gate só detém o que consegue ver, uma declaração só nomeia o que está marcado, e uma pessoa revisora só confere o que ainda aponta para sua fonte.
A perda raramente é uma decisão. Ela acontece numa linha de código comum: uma entidade do ORM preenchida a partir do JSON do modelo porque os nomes dos campos por acaso coincidiam, um modelo de resposta que descarta a procedência porque ninguém a acrescentou, uma importação em lote que contorna o formulário onde a validação morava. O padrão existe para tornar impossível escrever essa linha sem perceber.
Estratégias de implementação válidas
O isolamento é arquitetural, não necessariamente físico
Microsserviços não são necessários. A propriedade vale quando nenhum caminho de código permite ao lado probabilístico produzir um objeto com autoridade, e um único processo consegue mantê-la tão bem quanto uma rede. A topologia se escolhe por razões próprias (escalar separadamente uma carga de inferência, isolar a biblioteca cliente de um fornecedor, fazer deploy de forma independente), e depois a fronteira se constrói na forma escolhida. As quatro figuras abaixo mantêm a mesma propriedade em quatro formas.
Arquitetura de exemplo · Não normativa
Monólito modular
- Fluxo de dados neste exemplo
- Opcional: pode estar indisponível
Descrição textual. Dentro de um processo: um cliente do modelo, marcado como probabilístico, passa sua resposta bruta a um módulo de fronteira, que passa uma Proposal ao núcleo de domínio. Um adaptador de classificação, também dentro do processo, pode passar um enriquecimento ao núcleo de domínio, e consulta um serviço de classificação externo, fora do processo. O núcleo de domínio grava entradas na trilha de auditoria, um banco de dados separado. O único caminho do cliente do modelo até o núcleo de domínio passa pela fronteira.
Arquitetura de exemplo · Não normativa
Orientada a serviços
- Fluxo de dados neste exemplo
- Opcional: pode estar indisponível
Descrição textual. Um serviço de inferência contém um cliente do modelo, marcado como probabilístico, e uma fronteira que valida o que ele envia. Ele envia por HTTP, sob um contrato JSON, a um serviço de domínio, cuja própria fronteira valida o que recebe e passa uma Proposal ao núcleo de domínio. O serviço de domínio também contém um adaptador de classificação, que consulta um serviço externo e pode passar um enriquecimento ao núcleo de domínio, e a trilha de auditoria, na qual o núcleo de domínio grava entradas. O serviço de inferência não tem nenhuma conexão com a trilha de auditoria.
Arquitetura de exemplo · Não normativa
Orientada a eventos
- Fluxo de dados neste exemplo
Descrição textual. Um worker de inferência contém um cliente do modelo, marcado como probabilístico, e uma fronteira. Ele publica uma mensagem em um tópico de propostas. O corpo da mensagem carrega o trace_id de auditoria; seus cabeçalhos carregam o contexto de execução como um traceparent W3C. Um consumidor de domínio lê o tópico, valida cada mensagem no recebimento e passa uma Proposal ao núcleo de domínio, que grava entradas na trilha de auditoria.
Arquitetura de exemplo · Não normativa
Deploy cloud-native
- Fluxo de dados neste exemplo
Descrição textual. No namespace de inferência, um pod de inferência executa o cliente do modelo e sua fronteira. Ele pode enviar ao endpoint do modelo, no namespace de serviço de modelos, e à recepção de propostas, no namespace de registros, somente pela porta de API desta. A recepção de propostas valida o que recebe e passa uma Proposal ao núcleo de domínio, que grava na trilha de auditoria e no banco de dados de registros. Uma nota afirma que o namespace de inferência não tem rota nem credencial para esse banco de dados.
Os mesmos quatro elementos em toda topologia
- Tipos distintos. O lado probabilístico consegue construir uma proposta e nada mais. O registro com autoridade é construído apenas pelo código de domínio, a partir de uma proposta somada a algo que o lado probabilístico não consegue produzir.
- Validação em tempo de execução em todo lado receptor. Um esquema estrito: campos não declarados rejeitados, nenhuma coerção de tipo, vocabulários fechados para valores categóricos, comprimentos limitados. Numa topologia distribuída cada receptor valida, inclusive o lado do domínio quando o remetente é um serviço próprio: “validamos antes de enviar” é uma afirmação sobre outra unidade implantável, possivelmente uma versão mais antiga dela.
- Procedência no contrato. Declarada, obrigatória e preservada por todo mapeador e serializador no caminho de saída.
- Uma etapa explícita de promoção. A única rota de uma proposta até um registro com autoridade é uma função, um endpoint ou um comando que exige o que o lado probabilístico não consegue fornecer. Para valores derivados por um modelo de linguagem, o fence público F-03 do COADF exige verificação humana antes que cheguem a uma saída publicada. A própria promoção fica registrada na trilha de auditoria.
Validação determinística em torno de uma saída estocástica
Verificações que leem apenas o valor (sua forma, seu vocabulário, sua unidade, os intervalos que o próprio domínio define) rodam antes que qualquer pessoa olhe para ele. Elas não tornam um valor verdadeiro. Elas tornam impossível um valor impossível, e fazem isso sempre do mesmo jeito, algo em que a pessoa revisora do valor pode se apoiar.
Opções de aplicação, da mais fraca à mais forte
| Mecanismo | Detém | Não detém |
|---|---|---|
| Separação de tipos | Promoção acidental em código que passa na verificação de tipos | Casts, tipagem dinâmica, reflexão |
| Validação de esquema em tempo de execução | Respostas malformadas ou que afirmam mais do que deveriam | Um valor bem formado e errado |
| Teste de arquitetura sobre importações | O módulo probabilístico importar código que escreve registros | Importações feitas por nome em tempo de execução; caminhos de dados que não são importações |
| Permissões de banco de dados por componente | Um componente escrever no armazenamento com autoridade | Componentes que compartilham credenciais |
| Deploy separado e política de rede | Um componente com deploy separado sequer alcançar o armazenamento | Qualquer coisa dentro de um mesmo processo; clusters cujo plugin de rede não aplica a política |
A maioria dos sistemas quer as três primeiras sempre, e as duas últimas quando o componente probabilístico tem deploy próprio. O perfil Python e FastAPI implementa as três primeiras; o perfil Cloud-native acrescenta as duas últimas.
Modos de falha
Saída do modelo escrita direto no armazenamento com autoridade
A resposta é convertida na entidade que o resto do sistema lê como fato, porque os campos coincidiam. Nenhuma linha isolada está errada. A fronteira simplesmente não existe.
Propostas indistinguíveis de dados verificados
Uma tabela, um tipo e uma flag que diz qual é qual. A flag assume por padrão o valor conveniente, ou o próprio JSON do modelo consegue defini-la.
Procedência perdida no caminho de saída
Um mapeador, um modelo de resposta ou uma exportação omite o método e a fonte. Frameworks que filtram a saída por um esquema declarado fazem isso sem ruído algum: o FastAPI filtra uma resposta pelo seu modelo de resposta, e o serializador do Fastify deixa de fora as propriedades que um esquema de resposta não lista, a menos que o esquema permita propriedades adicionais.
Validação apenas na interface do usuário
O formulário valida. A importação em lote, o script de administração e o segundo cliente, não.
Sistemas a jusante não distinguem inferido de verificado
O formato de exportação não tem campo para o método, então o sistema seguinte recebe um valor e nada mais, e todo controle que ele tem fica cego para a diferença.
A resposta bruta tratada como confiável sem validação em tempo de execução
Um cast em TypeScript, um dicionário em Python, um mapeador leniente em Java: o contrato existe nos tipos do código e em nenhum lugar do seu comportamento. As anotações de tipo do TypeScript são apagadas em tempo de compilação, e suas tipagens padrão declaram o resultado de
JSON.parsecomoany.A coerção esconde o erro do modelo
Uma análise permissiva transforma
"12"em12e"true"emTrue. O número parece certo e nunca foi um número. O modo estrito do Pydantic recusa essa coerção; a configuração padrão do validador do Fastify ativa a coerção de tipos. É preciso saber qual dos dois está rodando.Reparo silencioso
A resposta falha na validação, então a chamada é repetida até que uma resposta passe, e só a última é guardada. As falhas eram evidência sobre o modelo, e se perderam.
Validação contornada por desempenho
Uma otimização que constrói objetos sem validação vira o caminho mais fácil e, depois, o desvio. O
model_constructdo Pydantic cria um modelo sem validá-lo, exatamente como documentado.
Verificação
Teste unitário
Passa quando: Cada resposta malformada é rejeitada: um campo não declarado, um tipo coercível, uma procedência ausente, um atributo que ninguém pediu.
Prova de dentes: Apagar uma restrição numa cópia descartável (por exemplo, a regra que rejeita campos não declarados): o teste correspondente precisa falhar.
Teste de arquitetura
Passa quando: O módulo probabilístico não tem caminho de importação até o código que escreve registros com autoridade.
Prova de dentes: Acrescentar a importação proibida numa cópia descartável: o contrato falha e o build para.
Teste de contrato
Passa quando: Produtor e consumidor concordam sobre o esquema da proposta, com os campos de procedência obrigatórios.
Prova de dentes: Remover um campo de procedência do esquema do produtor: o teste de contrato do consumidor falha.
Teste de integração
Passa quando: Quando o componente probabilístico tem deploy próprio, suas credenciais não conseguem escrever no armazenamento com autoridade.
Prova de dentes: Tentar a escrita com essas credenciais: o banco de dados a recusa.
Teste de ponta a ponta
Passa quando: Uma saída cujo atributo veio de uma proposta que ninguém verificou não pode ser publicada.
Prova de dentes: Plantar uma proposta não verificada e pedir a publicação: recusada, e a recusa está na trilha de auditoria.
Realizações alternativas
- Interfaces só de sugestão. A saída do modelo é mostrada a uma pessoa como sugestão e nunca armazenada como valor. Simples e forte; abre mão da rastreabilidade do que foi sugerido, a menos que as sugestões também sejam registradas.
- Um contrato compartilhado e neutro em relação à linguagem (JSON Schema, Protocol Buffers) em vez de modelos nativos da linguagem. Melhor entre linguagens; desloca a questão do rigor para o esquema, onde propriedades adicionais e formatos precisam ser decididos explicitamente.
- Modos de saída estruturada das APIs de modelos. Reduzem respostas malformadas no produtor. Não dispensam o consumidor de validar, porque o consumidor não consegue verificar como o produtor foi configurado.
- Armazenamento separado para propostas e registros, duas tabelas ou dois armazenamentos em vez de uma tabela com um status. Mais pesado, e torna a separação visível em toda consulta que alguém escrever.
Limitações
- A fronteira controla para onde a saída do modelo pode ir. Ela não torna a saída do modelo correta, e um valor bem formado e errado passa em todas as verificações deste padrão.
- A separação de tipos detém acidentes, não intenção. Quem desenvolve com acesso de escrita ao domínio consegue construir à mão um objeto com autoridade; a revisão de código e a trilha de auditoria são o que torna isso visível.
- Este padrão não diz quando uma proposta precisa de uma pessoa, nem como a confiança é expressa. Isso pertence ao P-2 e ao P-3, que o COADF publica apenas como princípios.
- A validação só é tão boa quanto o contrato. Um esquema permissivo, validado com rigor, continua permissivo.
Fontes
- FastAPI: Response model: return type and data filtering · documentação oficial · FastAPI 0.141 · Verificado em 2026-09-11
- Fastify: fast-json-stringify: additionalProperties · repositório do projeto · Verificado em 2026-09-11
- TypeScript: The Basics: erased types · documentação oficial · Verificado em 2026-09-11
- TypeScript: lib.es5.d.ts: JSON.parse · repositório do projeto · Verificado em 2026-09-11
- Pydantic: Strict mode · documentação oficial · Pydantic 2.13 · Verificado em 2026-09-11
- Fastify: Validation and serialization · documentação oficial · Fastify 5.12 · Verificado em 2026-09-11
- Pydantic: Models: creating models without validation · documentação oficial · Pydantic 2.13 · Verificado em 2026-09-11
