O Microsoft Presidio é um dos melhores conjuntos de ferramentas de código aberto para deteção de dados pessoais que existem. Lemos o seu código, aprendemos com ele e, mesmo assim, escolhemos não o integrar. Eis o argumento honesto para o porquê.
Em versão curta: o Presidio encontra dados pessoais dentro de um bloco de texto. O promptShield faz algo mais estreito e mais concreto — pega num PDF no portátil de alguém, sem ligação à Internet, e permite ao utilizador clicar num nome na página e vê-lo ser tapado de preto. Ambas as tarefas envolvem «encontrar dados pessoais», por isso parecem o mesmo trabalho. Não são. E as diferenças entre elas são exatamente as partes onde teríamos passado todo o nosso tempo a lutar com o Presidio para fazer algo para que ele nunca foi construído.
Portanto, não se trata de reinventar a roda só pelo gosto de o fazer. Precisávamos genuinamente de outra roda. Eis porquê.
O que entregamos não é um fluxo de texto
O Presidio raciocina em texto simples: você dá-lhe uma cadeia de caracteres e ele devolve uma lista de posições — «os caracteres 40 a 51 são um nome». É perfeito se está a analisar mensagens de chat ou uma coluna de base de dados, onde o texto é só texto. É o ponto de partida errado para nós, porque o nosso utilizador não está a olhar para uma cadeia de caracteres. Está a olhar para uma página.
Uma página de PDF não é uma linha de texto — é uma disposição. As palavras ocupam caixas em coordenadas precisas. Um único nome pode estar partido em duas linhas, repartido por duas colunas, ou até rodado. E o utilizador não oculta «os caracteres 40 a 51» — tapa de preto um retângulo na página que tem à frente. Para nós, encontrar o nome e saber onde ele se situa na página não são, portanto, dois passos distintos que se pudessem colar. São o mesmo passo.
Eis o que isto dá na prática. Quando o nosso pipeline encontra «Pierre Dubois» quebrado entre o fim de uma linha e o início da seguinte, tem de transformar esse único nome em dois retângulos e tapar ambos de preto. Quando encontra um nome na página 1, lembra-se dele e tapa-o automaticamente na página 4, para que o revisor não tenha de assinalar a mesma pessoa onze vezes à mão. O Presidio não tem noção nenhuma de tudo isto — só conhece posições numa cadeia de caracteres. Para o fazer funcionar, teríamos de o envolver em tanto código dedicado à página e à disposição que o Presidio teria tratado da pequena parte fácil, e o nosso próprio código de tudo o que é realmente difícil.
Não corremos um modelo. Corremos cinco camadas que votam.
No Presidio, cada detetor trabalha por sua conta e você limita-se a juntar tudo o que encontram. É flexível, mas tem um senão: se algum detetor for de gatilho fácil, todos os seus falsos alarmes acabam nos seus resultados. A sua precisão é puxada para baixo, até ao nível do seu detetor mais ruidoso.
Adotámos uma abordagem diferente: os nossos detetores têm de concordar entre si. Cinco deles percorrem a mesma página:
- Regex — padrões estruturados de alta precisão (segurança social, IBAN, e-mail, telefone, identificadores de empresa), com uma janela de contexto para que um simples número de 9 dígitos não seja um número de segurança social a menos que as palavras à volta o digam.
- Entidades spaCy — modelos estatísticos por idioma, um para cada uma das 7 línguas.
- GLiNER — reconhecimento de entidades zero-shot para os tipos que os modelos treinados deixam escapar.
- Entidades por transformador — reconhecimento apoiado em transformador onde os modelos mais pequenos pecam por baixa revocação.
- LLM — opcional, GGUF local ou uma API remota, para as decisões de contexto da cauda longa.
Em vez de simplesmente juntar o que encontram, pomo-los a votar. Se dois detetores assinalam a mesma coisa, confiamos mais nela; se três concordam, mais ainda. Algo que só um detetor nervoso detetou tem de ultrapassar uma fasquia muito mais alta antes de o mostrarmos ao utilizador. Esta lógica de votação — como ponderamos a concordância, fundimos deteções sobrepostas e transportamos resultados entre páginas — é o produto. É de onde vem, na verdade, a nossa precisão. O Presidio dá-lhe os detetores, mas deixa-lhe deliberadamente a si a decisão sobre como os reconciliar. E escrever essa decisão é escrever a maior parte de um motor — por isso escrevemos a coisa toda.
Tem de correr com o cabo de rede desligado
O promptShield é uma aplicação de secretária offline. A promessa toda é que os seus documentos nunca saem do seu dispositivo — nenhuma ida e volta à cloud, nenhuma chave de API, nenhum «prometemos que não o registamos». É uma restrição forte, e redesenha a questão da dependência.
O Presidio também pode correr localmente — mas não é assim que a maioria das pessoas o usa, na verdade. Para dele tirar boa precisão, o caminho habitual é ligá-lo aos serviços linguísticos na cloud da Microsoft ou da Amazon. São exatamente as chamadas à cloud que prometemos nunca fazer. Resta a opção totalmente local do Presidio, que assenta em modelos mais pequenos e mais leves — e essa é justamente a configuração que medimos no nosso benchmark, a que inunda os documentos financeiros de falsos positivos.
E vai mais fundo do que a precisão. Temos de empacotar cada modelo de IA dentro do instalador da aplicação e fazê-lo correr no dispositivo do utilizador. Cada modelo tem de ser empacotado, fixado a uma versão, verificado contra adulteração, carregado em memória e — a parte de que ninguém o avisa — limpamente descarregado de novo. No Windows, se um utilizador remover um pacote de idioma enquanto qualquer parte desse modelo está ainda retida em memória, o Windows recusa-se pura e simplesmente a apagar os ficheiros. Por isso mantemos uma lista cuidadosamente atualizada de todos os sítios onde um modelo possa ainda estar carregado, ao longo dos cinco detetores, e libertamo-los todos antes de apagar fosse o que fosse. Esse tipo de arrumação só funciona se controlarmos exatamente como e quando cada modelo é carregado. Um motor de terceiros que carrega os seus próprios modelos, ao seu próprio ritmo, tropeçaria constantemente nisto.
A filtragem de ruído é o verdadeiro fosso — e é nosso
No nosso confronto direto, o Presidio por defeito emitiu 666 deteções num corpus de 14 documentos; nós emitimos 252 nos mesmos documentos. A diferença é quase inteiramente ruído que filtramos e que uma instalação por defeito deixa passar: menções a países em cláusulas jurisdicionais («regido pelas leis de França»), URLs em rodapés, títulos de cargo confundidos com nomes, substantivos genéricos de departamento etiquetados como organizações, a mesma pessoa fragmentada em três deteções sobrepostas.
Cada um desses filtros funciona nas sete línguas, está calibrado contra contratos e demonstrações financeiras reais, e corre dentro do passo de votação — onde pode ponderar tanto o grau de confiança dos detetores como o sítio em que o texto realmente se situa na página. Podia reconstruir tudo isto como módulos acoplados ao Presidio. Mas a essa altura o Presidio limita-se a correr os detetores, enquanto tudo o que torna o nosso resultado limpo — a filtragem, a votação, a consciência da página — continua a ser código que tivemos de escrever nós próprios. Estaríamos a carregar uma pesada dependência sobretudo para desligar grandes partes dela.
Aquilo a que abdicámos
Esta opção não foi gratuita, e fingir o contrário seria desonesto.
- Não recebemos de graça a amplitude de reconhecedores do Presidio. A sua comunidade entrega reconhecedores para tipos de entidades e línguas que não construímos. Cada um que queremos, escrevemo-lo e testamo-lo nós próprios.
- Carregamos a nossa própria manutenção. Quando uma biblioteca de transformadores introduz uma alteração disruptiva, é problema nosso absorvê-la — não há um projeto a montante a quem abrir um ticket e esperar. Engolimos algumas dessas.
- Não nos podemos apoiar no nome do Presidio. «Construído sobre o Microsoft Presidio» é um atalho de credibilidade numa conversa de aquisição. Trocámo-lo por «eis o nosso benchmark reproduzível», que dá mais trabalho e empresta menos a uma marca.
Quando deve antes recorrer ao Presidio
Se o seu problema se parece com algum destes, o Presidio é muito provavelmente a escolha certa e construir o seu próprio seria um desperdício:
- Está a analisar fluxos de texto — registos de chat, colunas de base de dados, cargas úteis de API — e não documentos delimitados e dispostos numa página.
- Quer controlo ao nível de biblioteca dentro de um sistema DLP em Python maior, e aceita assumir o ajuste da precisão.
- Pode usar um motor de entidades na cloud (Azure, AWS) e quer uma única abstração de PII por cima de vários fornecedores.
- Precisa mais de amplitude de tipos de entidades e línguas do que de uma experiência de revisão impecável numa classe de documentos fixa.
O Presidio é a melhor ferramenta para uma fatia grande e variada do mundo da deteção de dados pessoais. Não estamos nessa fatia.
A verdadeira regra de decisão
Eis o teste que aplicámos, e o que recomendaríamos a quem quer que pese «adotar a biblioteca» contra «construir o motor»:
Se a dependência fizesse a parte fácil e você escrevesse a parte difícil por cima dela, não está a adotar uma biblioteca — está a adotar uma restrição.
Para nós, as partes difíceis — saber onde o texto se situa na página, ter cinco detetores a votar, gerir modelos de IA offline, filtrar ruído em sete línguas — constituem a maior parte do produto, e estão todas estreitamente entrelaçadas. O Presidio teria ficado lá no fundo a correr os detetores, enquanto cada decisão que realmente importava acontecia no nosso próprio código. Por isso escrevemos também essa camada de baixo — e acabámos com um motor onde compreendemos cada peça, o entregamos inteiramente offline, e o calibramos contra o tipo exato de documentos que os nossos utilizadores realmente ocultam.
O Presidio inspirou-nos. Apenas tínhamos outro documento para ocultar.