mozak.tech Arquitetura de IA Corporativa 71%

Parte 6 — Cibersegurança Defensiva e Governança Sistêmica

6.1 — Triagem de Input e Fallback Routing: Firewall Semântico e Degradação Controlada na Entrada do Harness

Objetivo da Aula

Explicar por que o input de um sistema de IA é uma superfície não confiável por padrão, no mesmo sentido que uma requisição HTTP é

Desenhar uma camada de triagem semântica que classifica risco antes de qualquer chamada ao modelo principal

Diferenciar triagem de moderação de conteúdo — triagem decide roteamento, não apenas aprova ou reprova

Projetar arquitetura de degradação controlada: para onde vai um input que falha nos critérios de segurança sem simplesmente travar o sistema

Instrumentar a decisão de triagem para que ela seja auditável, não uma caixa-preta dentro de outra caixa-preta

Por que isso importa

Até aqui, este livro tratou o harness como a camada que governa o que o modelo pode fazer — permissões (1.3), ferramentas (1.5), custo (Parte 5). Este capítulo trata de uma pergunta anterior a todas essas: o que entra no harness, para começo de conversa, merece ser processado pelo seu modelo mais capaz, com acesso às suas ferramentas mais privilegiadas?

Um erro comum de arquitetos que vêm da engenharia de prompt é tratar segurança de input como um problema de system prompt — "instrua o modelo a recusar pedidos perigosos". Isso é exatamente o mesmo erro estrutural do capítulo 1.1: colocar uma responsabilidade determinística dentro de um componente probabilístico. Um modelo pode ser convencido, via engenharia de prompt adversarial, a ignorar sua própria instrução de recusa. Uma camada de triagem que roda antes do modelo principal, como um processo separado com sua própria lógica, não pode ser "convencida" pelo texto do usuário — ela nunca vê o restante da conversa como um interlocutor, vê como um classificador vê um vetor de features.

Impacto direto no seu trabalho: todo sistema de IA exposto a input externo — de clientes, de parceiros, de qualquer usuário que não seja seu próprio time de engenharia — precisa responder a uma pergunta de arquitetura antes de qualquer feature: "o que acontece quando alguém manda algo que o sistema não deveria processar do jeito que processa o caso normal?" Se a resposta hoje é "o modelo principal recebe, e a gente confia no system prompt", você tem uma superfície de ataque do tamanho do seu modelo mais caro e mais privilegiado. Este capítulo mostra como reduzir essa superfície com uma camada dedicada.

Conceitos Fundamentais

O input não é confiável por padrão

Em engenharia de software tradicional, ninguém discute se dados vindos de fora do sistema — parâmetros de URL, corpo de requisição, upload de arquivo — precisam de validação antes de tocar lógica de negócio. É óbvio, é ensinado no primeiro ano, e existe uma camada inteira (validação de schema, sanitização, WAF) dedicada a isso antes que a requisição chegue ao código de aplicação.

Em sistemas de IA agentic, essa mesma disciplina frequentemente desaparece — porque o "parâmetro de entrada" agora é linguagem natural, e linguagem natural parece maleável demais para "validar" com uma regra fixa. Essa aparência é enganosa. Você não precisa validar sintaxe (o modelo lida bem com isso); precisa classificar intenção e risco antes de decidir qual caminho do sistema aquele input percorre. Três desenhos de fluxo ilustram a diferença entre não tratar, e tratar, o input como uma superfície não confiável:

Web tradicional

  • Requisição.
  • Validação de schema (determinístico).
  • WAF (determinístico).
  • Lógica de negócio.
  • Resposta.

Sistema de IA sem triagem

  • Input do usuário.
  • Modelo principal, com todas as ferramentas (probabilístico, decide tudo sozinho).
  • Ação.

Sistema de IA com triagem

  • Input do usuário.
  • Classificador de risco (determinístico/leve).
  • Roteamento (harness).
  • Modelo apropriado (privilégio proporcional ao risco).
  • Ação.

A diferença central: no terceiro desenho, o componente que decide "isso é seguro processar normalmente?" não é o mesmo componente que processaria a tarefa em si. São dois modelos (ou um modelo e um classificador clássico) com responsabilidades diferentes, exatamente como harness e motor de inferência são componentes diferentes desde o capítulo 1.1.

Anatomia de uma camada de triagem

Uma camada de triagem semântica típica não é um único classificador binário ("seguro" / "não seguro"). É um pipeline curto de checagens especializadas, cada uma barata em latência e custo, que juntas produzem um score de risco. O input bruto passa sequencialmente por três estágios antes de sair como um score de risco:

  • Estágio 1 — Intenção: classificador de intenção avalia se o pedido é operacional, informativo, ou tenta alterar o comportamento do sistema.
  • Estágio 2 — Padrões de risco: detector de padrões conhecidos, combinando heurísticas e embeddings, compara o input contra uma biblioteca de ataques anteriores.
  • Estágio 3 — Perfil de risco: contexto do solicitante — RBAC do usuário, histórico recente, raio de impacto das ferramentas disponíveis para essa sessão.

Saída do pipeline: score_de_risco (0.0 – 1.0) + categoria + justificativa.

Cada estágio é deliberadamente mais barato que uma chamada completa ao modelo principal — classificadores pequenos, embeddings com busca por similaridade contra uma biblioteca de exemplos maliciosos conhecidos (o mesmo tipo de infraestrutura de retrieval da Parte 2, reaproveitada aqui para segurança em vez de grounding de conhecimento), regras determinísticas simples. O objetivo não é ser tão inteligente quanto o modelo principal — é ser rápido e barato o suficiente para rodar em todo input, sem exceção, sem virar gargalo.

Fundamento: Triagem não é moderação de conteúdo

Moderação de conteúdo pergunta "este texto viola uma política de uso aceitável?" e normalmente resulta numa decisão binária: aprova ou bloqueia. Triagem de input, no sentido arquitetural deste capítulo, pergunta algo mais amplo: "com que nível de confiança e privilégio este input deveria ser processado?" A saída não é um booleano — é uma decisão de roteamento entre múltiplos caminhos possíveis. Um input pode ser perfeitamente aceitável em termos de conteúdo e, ainda assim, ser roteado para um caminho mais contido porque o contexto (usuário novo, sessão anômala, combinação de ferramentas sensíveis solicitadas em sequência) eleva o risco sistêmico da interação.

Fallback routing: para onde vai o que não passa direto

A parte que costuma faltar em implementações ingênuas de triagem é o que acontece depois de um score de risco elevado. A resposta errada mais comum é binária: "bloqueia ou libera". Isso produz dois problemas simétricos — libera demais (a triagem vira teatro) ou bloqueia demais (usuários legítimos são recusados e abandonam o produto). A arquitetura de degradação controlada resolve isso com mais de dois destinos possíveis:

Score de riscoDestinoPrivilégio concedido
0.00 – 0.20Modelo principal, caminho normalTotal (conforme RBAC)
0.20 – 0.50Modelo principal, contexto reduzido (sem ferramentas de escrita/exec)Ferramentas de leitura apenas
0.50 – 0.75Modelo contido (menor, sandboxed, sem acesso a ferramentas externas)Nenhuma ferramenta; apenas resposta textual
0.75 – 0.90Fila de revisão humana (HITL)Zero até aprovação
0.90 – 1.00Bloqueio automático + log de segurançaZero, sem exceção

Note a semelhança estrutural com o roteamento de modelos por custo da Parte 5 (5.3) — lá, o critério de roteamento era complexidade cognitiva da tarefa; aqui, é risco. Nos dois casos, o princípio arquitetural é o mesmo: nem toda requisição merece o recurso mais caro/privilegiado do sistema. A diferença é que, em FinOps, rotear errado custa dinheiro; em triagem de segurança, rotear errado custa uma ação indevida.

Degradação controlada é o nome dado a esse desenho porque o sistema nunca simplesmente "cai" diante de um input suspeito — ele reduz privilégio de forma gradual e previsível, preservando alguma utilidade (mesmo que limitada) sempre que o risco permitir. Um modelo contido que só responde texto, sem ferramentas, ainda é útil para um usuário legítimo que por algum motivo disparou um score intermediário (uma pergunta ambígua, um padrão de uso incomum). Isso evita o efeito colateral mais caro de segurança mal desenhada: recusar em massa casos de uso legítimos porque a única alternativa ao "sim total" era o "não total".

Aprofundamento Técnico

Onde a triagem vive na topologia do harness

A camada de triagem precisa ficar estritamente antes da montagem de contexto (capítulo 1.2) e da resolução de ferramentas (capítulo 1.5) — não em paralelo, não depois. Se a triagem roda depois que o modelo principal já recebeu ferramentas privilegiadas no contexto, o desenho já falhou: o modelo teve a chance de agir antes de qualquer classificação de risco terminar.

function processar_requisicao(input_usuario, sessao):
    # ---- TRIAGEM: primeiro ponto de controle, antes de tudo ----
    resultado_triagem = classificar_risco(input_usuario, sessao)  # 6.1

    destino = resolver_destino(resultado_triagem.score)
    if destino == BLOQUEIO:
        registrar_evento_seguranca(resultado_triagem)             # 6.3
        return recusar(motivo=resultado_triagem.categoria)

    if destino == FILA_HUMANA:
        return enfileirar_para_revisao(input_usuario, resultado_triagem)

    # ---- A PARTIR DAQUI, fluxo normal do harness (Parte 1) ----
    ferramentas_permitidas = resolver_ferramentas(sessao, destino)  # 1.5, ajustado pelo destino
    contexto = montar_contexto(sessao, input_usuario)                # 1.2
    modelo = selecionar_modelo(destino)                              # contido ou principal

    resposta = chamar_llm(modelo, contexto, ferramentas_permitidas)
    return resposta

Repare que resolver_ferramentas — já conhecida do capítulo 1.1 — agora recebe um parâmetro adicional, destino, vindo da triagem. RBAC (1.3) responde "o que este usuário pode fazer em geral"; triagem responde "o que esta interação específica deveria poder fazer agora, dado o risco observado". As duas camadas compõem, não competem.

O trade-off de latência

Toda camada de triagem adiciona latência ao caminho crítico, e isso precisa ser medido, não assumido. Um pipeline de três estágios como o descrito acima, bem implementado com classificadores leves, tipicamente adiciona entre 30 e 150 milissegundos ao tempo total de resposta — comparado a uma chamada de modelo principal que frequentemente leva 1 a 5 segundos. Em proporção, o custo de latência é pequeno; em termos absolutos, ainda é um orçamento que precisa ser gerenciado.

Orçamento de latência (exemplo ilustrativo):

EtapaTempo
Estágio 1 (classificador de intenção, modelo pequeno)~20ms
Estágio 2 (busca por similaridade em biblioteca de ataques)~15ms
Estágio 3 (regras de RBAC + contexto de sessão)~5ms
Total triagem~40ms
Chamada ao modelo principal (caso aprovado)~2000ms
Overhead relativo da triagem~2%

O erro de dimensionamento mais comum é usar o próprio modelo principal (ou um modelo quase tão grande) como classificador de triagem, "porque já está ali". Isso duplica a latência e o custo por requisição sem necessariamente melhorar a qualidade da decisão — classificadores especializados e pequenos, treinados ou calibrados para a tarefa estreita de scoring de risco, tendem a superar modelos generalistas grandes nessa tarefa específica, pelo mesmo motivo que um roteador de modelos (5.3) prefere o menor modelo suficiente para cada tarefa.

Falsos positivos e o custo de errar em cada direção

Toda camada de classificação binária ou multi-classe opera com uma curva de compromisso entre dois tipos de erro:

Input maliciosoInput legítimo
Classificado como "risco alto"Verdadeiro Positivo (correto: bloqueou)Falso Positivo (custo: recusou usuário legítimo)
Classificado como "risco baixo"Falso Negativo (custo: deixou passar um ataque)Verdadeiro Negativo (correto: liberou)

Threshold de score baixo (ex.: bloquear tudo acima de 0.3) minimiza falsos negativos mas maximiza falsos positivos — muitos usuários legítimos recusados. Threshold alto (ex.: bloquear só acima de 0.9) faz o oposto. Não existe threshold "correto" universal: a escolha depende do raio de impacto das ferramentas disponíveis atrás daquele caminho. Um sistema onde o pior caso de um falso negativo é "o modelo escreveu um texto inadequado" tolera threshold mais alto (mais permissivo) do que um sistema onde o pior caso é "o agente executou uma transação financeira ou apagou um registro de produção". O capítulo 6.2 aprofunda esse cálculo de raio de impacto quando o assunto é exploit estrutural, não apenas input malicioso isolado.

Auditabilidade da própria decisão de triagem

Uma camada de triagem que decide silenciosamente, sem deixar rastro do porquê, transfere o problema de auditoria do capítulo 1.1 (o modelo como "autobiografia não confiável") para um novo componente igualmente opaco. Cada decisão de roteamento precisa gravar, no mínimo: o score calculado, qual estágio do pipeline mais contribuiu para o score, a versão do classificador usado (classificadores são retreinados e evoluem, exatamente como modelos), e o destino escolhido. Esse registro é o que torna possível, mais adiante, responder à pergunta que fecha a Parte 6: "por que o sistema tomou esta decisão, e conseguimos provar isso depois?" — tema central do capítulo 6.3.