Guía de API de supresión de PII (2026): comparativa de AWS, Google Cloud, Azure y Presidio para aplicaciones con LLM
Una API de supresión de PII recibe texto, detecta datos personales como nombres, correos electrónicos, números de teléfono, números de tarjeta e identificadores oficiales, y devuelve la ubicación de esos datos o una copia del texto con ellos enmascarados, sustituidos o tokenizados. Para los equipos de producto de IA, su función principal es eliminar o seudonimizar los datos personales antes de que los prompts, documentos y registros lleguen a un LLM de terceros. Las cuatro opciones que evalúa la mayoría de los equipos son Amazon Comprehend DetectPiiEntities, Google Cloud Sensitive Data Protection (antes Cloud DLP), la detección de PII de Azure Language y Microsoft Presidio, de código abierto.
Esta guía compara sus endpoints, autenticación, idiomas admitidos, unidades de facturación y formato de salida, con ejemplos ejecutables que usan datos sintéticos. También presenta resultados reales de detección de una prueba local con Presidio, incluidos los datos que no detectó y los falsos positivos que conviene prever. Todos los detalles de los proveedores se contrastaron con la documentación oficial el 27 de octubre de 2026.
Flatkey no ofrece una API integrada de supresión de PII. Los patrones que se describen a continuación se ejecutan en tu propio servicio antes de enviar una solicitud a través de cualquier pasarela de modelos, incluida Flatkey. Para abordar este mismo problema desde el punto de vista de las políticas, consulta nuestra guía de políticas de supresión de datos para API de IA.
Supresión, enmascaramiento, detección de entidades y tokenización: ¿en qué se diferencian?
| Técnica | Qué devuelve | ¿Es reversible? | Uso habitual |
|---|---|---|---|
| Detección de entidades | Tipo de entidad, puntuación de confianza y posiciones de los caracteres | No aplica (el texto no cambia) | Decidir qué hacer con cada entidad; auditar qué datos circulan |
| Supresión | Texto con la PII eliminada o sustituida por una etiqueta como [PERSON_1] |
No | Prompts para LLM externos, registros, analítica |
| Enmascaramiento | Texto con caracteres ocultos, como ***********1111 |
No | Pantallas de soporte que necesitan mostrar valores parciales |
| Tokenización / seudonimización | Texto con la PII sustituida por un token consistente o un valor cifrado | Sí, con la clave o la tabla de correspondencias | Flujos de trabajo con LLM que deben reinsertar los valores reales en la respuesta |
| Supresión por campos | Campos conocidos (como email en JSON) eliminados o sustituidos según el esquema |
Depende | Cargas de datos estructuradas en las que sabes qué campos contienen PII |
Para los datos estructurados, las reglas por campos son más rápidas y fiables que cualquier modelo. Usa las API de detección de PII para texto libre: mensajes de chat, tickets de soporte, transcripciones y documentos.
Comparativa de API de supresión de PII (octubre de 2026)
| Amazon Comprehend | Google Sensitive Data Protection | Azure Language PII | Microsoft Presidio | |
|---|---|---|---|---|
| Tipo | API gestionada | API gestionada | API gestionada (también en contenedores) | Código abierto, alojado en tu infraestructura |
| Llamada principal | DetectPiiEntities |
projects.content.deidentify |
analyze-text con PiiEntityRecognition |
AnalyzerEngine + AnonymizerEngine |
| Devuelve directamente el texto con la PII suprimida | No, devuelve posiciones (úsalas para suprimir los datos) | Sí | Sí (redactedText) |
Sí |
| Tokenización reversible | No | Sí (transformaciones criptográficas) | No | Sí (operadores encrypt / decrypt) |
| Idiomas admitidos para PII | Inglés y español | Numerosos infoTypes, algunos específicos de cada país | Varios idiomas, según la documentación | Depende del modelo de PLN que cargues |
| Límite de entrada / unidad | 100 KB por solicitud; se factura por cada 100 caracteres, con un mínimo de 3 unidades | Se factura por GiB; mínimo de 1 KB por solicitud | Se factura por registro de texto | Tus recursos de cómputo |
| Cuota gratuita | 50K unidades (5M caracteres) por API al mes durante 12 meses | Primer 1 GiB al mes para inspección | 5,000 registros de texto al mes (nivel gratuito) | Software gratuito |
| Los datos salen de tu red | Sí (AWS) | Sí (Google Cloud) | Sí, salvo que ejecutes el contenedor | No |
Fuentes: documentación de PII de Amazon Comprehend, precios de Comprehend, documentación de desidentificación de Google, precios de Sensitive Data Protection, descripción de Azure PII, precios de Azure Language y documentación de Presidio, todas consultadas el 27 de octubre de 2026.
¿Cuánto cuesta?
- Amazon Comprehend: en el ejemplo de AWS para Detect PII, 10,000 comentarios de clientes de 550 caracteres cada uno equivalen a 6 unidades por solicitud; por tanto, 60,000 unidades a $0.0001 por unidad cuestan $6 (precios de Comprehend, ejemplo 7). Las solicitudes cortas se facturan con un mínimo de 3 unidades (300 caracteres), por lo que agrupar mensajes pequeños ahorra dinero.
- Google Sensitive Data Protection: la inspección de contenido es gratuita para el primer 1 GiB al mes; después cuesta $3.00 por GiB y baja a $2.00 por GiB con volúmenes mayores. La transformación tiene un precio publicado de $2.00 por GiB, que después baja a $1.00. Se factura un mínimo de 1 KB por solicitud.
- Azure Language: la detección de PII se factura por registro de texto, con 5,000 registros de texto gratuitos al mes en el nivel gratuito. Los niveles de pago se detallan en la página de precios de Azure para tu región.
- Presidio: no hay coste de licencia; pagas los recursos de cómputo que ejecutan el analizador y el modelo de PLN.
Amazon Comprehend: DetectPiiEntities
Comprehend detecta PII en textos en inglés o español. DetectPiiEntities devuelve el Type, Score, BeginOffset y EndOffset de cada entidad; la entrada máxima es de 100 KB de texto UTF-8 (referencia de la API). No devuelve el texto con la PII suprimida, así que debes sustituir los fragmentos por tu cuenta.
import boto3
comprehend = boto3.client("comprehend", region_name="us-east-1")
text = "Hi, I'm Dana Whitfield. Email dana.whitfield@example.com or call 212-555-0187."
resp = comprehend.detect_pii_entities(Text=text, LanguageCode="en")
# Replace from the end so earlier offsets stay valid
redacted = text
for e in sorted(resp["Entities"], key=lambda e: e["BeginOffset"], reverse=True):
if e["Score"] >= 0.5:
redacted = redacted[:e["BeginOffset"]] + f"[{e['Type']}]" + redacted[e["EndOffset"]:]
print(redacted)
La autenticación utiliza credenciales estándar de AWS (rol de IAM, SSO o claves de acceso) con permiso para comprehend:DetectPiiEntities.
Google Cloud Sensitive Data Protection: content.deidentify
La API de Google inspecciona y transforma en una sola llamada. Eliges los infoTypes (como EMAIL_ADDRESS y PHONE_NUMBER) y una transformación: replaceWithInfoTypeConfig, redactConfig, characterMaskConfig o seudonimización criptográfica (documentación de desidentificación).
curl -X POST \
"https://dlp.googleapis.com/v2/projects/$PROJECT_ID/content:deidentify" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"item": {"value": "Email dana.whitfield@example.com or call 212-555-0187."},
"inspectConfig": {
"infoTypes": [{"name": "EMAIL_ADDRESS"}, {"name": "PHONE_NUMBER"}, {"name": "PERSON_NAME"}]
},
"deidentifyConfig": {
"infoTypeTransformations": {
"transformations": [{"primitiveTransformation": {"replaceWithInfoTypeConfig": {}}}]
}
}
}'
El campo item.value de la respuesta contiene texto como Email [EMAIL_ADDRESS] or call [PHONE_NUMBER]. Google recomienda indicar solo los infoTypes que necesites, porque buscar el conjunto predeterminado añade latencia.
Azure Language: reconocimiento de entidades PII
El endpoint analyze-text de Azure devuelve tanto las entidades como un campo redactedText. El parámetro redactionPolicies controla la salida; por ejemplo, entityMask para etiquetas o characterMask para asteriscos (referencia REST).
curl -X POST "$AZURE_LANGUAGE_ENDPOINT/language/:analyze-text?api-version=2026-05-01" \
-H "Ocp-Apim-Subscription-Key: $AZURE_LANGUAGE_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "PiiEntityRecognition",
"parameters": {"redactionPolicies": [{"policyKind": "entityMask"}]},
"analysisInput": {"documents": [
{"id": "1", "language": "en", "text": "My name is John Doe My phone number is 424 878 9192"}
]}
}'
La respuesta de ejemplo documentada por Microsoft devuelve "redactedText": "My name is [PERSON_1] My phone number is [PHONENUMBER_1]", además de la categoría, la posición, la longitud y la puntuación de confianza de cada entidad. Azure también admite la detección de PII en conversaciones y documentos, y ofrece contenedores para ejecutar el modelo en tu propio entorno.
Versión para Node.js
const res = await fetch(
`${process.env.AZURE_LANGUAGE_ENDPOINT}/language/:analyze-text?api-version=2026-05-01`,
{
method: "POST",
headers: {
"Ocp-Apim-Subscription-Key": process.env.AZURE_LANGUAGE_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
kind: "PiiEntityRecognition",
parameters: { redactionPolicies: [{ policyKind: "entityMask" }] },
analysisInput: {
documents: [{ id: "1", language: "en", text: "Call Dana at 212-555-0187." }],
},
}),
}
);
const data = await res.json();
console.log(data.results.documents[0].redactedText);
Microsoft Presidio: supresión de PII de código abierto
Presidio se ejecuta íntegramente en tu propia infraestructura. El analizador combina reconocimiento de entidades con nombre mediante PLN, expresiones regulares, sumas de comprobación y palabras de contexto; el anonimizador aplica operadores como replace, mask, redact, hash y encrypt. Su documentación indica expresamente que la detección automatizada no puede garantizar que encuentre todos los datos sensibles, por lo que debes prever medidas de protección adicionales.
Instalamos Presidio (analizador 2.2.365 con el modelo en_core_web_lg de spaCy) y lo ejecutamos sobre esta frase sintética:
Hola, soy Dana Whitfield. Escribe a dana.whitfield@example.com o llama al 212-555-0187. Tarjeta 4111 1111 1111 1111, SSN 078-05-1120. El pedido #A-77231 se envía a 42 Elm Street.
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import OperatorConfig
text = ("Hi, I'm Dana Whitfield. Email dana.whitfield@example.com or call 212-555-0187. "
"Card 4111 1111 1111 1111, SSN 078-05-1120. Order #A-77231 ships to 42 Elm Street.")
results = AnalyzerEngine().analyze(text=text, language="en")
for r in sorted(results, key=lambda r: r.start):
print(r.entity_type, repr(text[r.start:r.end]), round(r.score, 2))
out = AnonymizerEngine().anonymize(
text=text,
analyzer_results=results,
operators={
"DEFAULT": OperatorConfig("replace", {"new_value": "<REDACTED>"}),
"PERSON": OperatorConfig("replace", {"new_value": "<PERSON>"}),
"EMAIL_ADDRESS": OperatorConfig("replace", {"new_value": "<EMAIL>"}),
"CREDIT_CARD": OperatorConfig("mask", {"masking_char": "*", "chars_to_mask": 15, "from_end": False}),
},
)
print(out.text)
Qué detectó y qué pasó por alto
| Texto | Detectado como | Puntuación | Evaluación |
|---|---|---|---|
| Dana Whitfield | PERSON | 0.85 | Correcto |
| dana.whitfield@example.com | EMAIL_ADDRESS | 1.0 | Correcto |
| example.com (dentro del correo electrónico) | URL | 0.5 | Falso positivo, se solapa con el correo electrónico |
| 212-555-0187 | PHONE_NUMBER | 0.4 | Correcto, pero con baja confianza |
| 4111 1111 1111 1111 | CREDIT_CARD | 1.0 | Correcto (suma de comprobación validada) |
| 078-05-1120 | PHONE_NUMBER | 0.4 | Tipo incorrecto: es un conocido SSN de ejemplo no válido, por lo que el reconocedor de SSN lo rechazó |
| Elm Street | LOCATION | 0.85 | Parcialmente correcto; el número de la dirección, "42", permaneció en el texto |
| A-77231 (ID del pedido) | No detectado | No aplica | No se detectó: los identificadores de negocio necesitan reglas personalizadas |
Tres lecciones de esta pequeña prueba:
- Los umbrales obligan a equilibrar omisiones y ruido. Al repetir la prueba con
score_threshold=0.5, el número de teléfono (puntuación 0.4) quedó excluido y permaneció sin suprimir. Ajusta los umbrales por tipo de entidad, no de forma global. - Tus propios identificadores necesitan reconocedores personalizados. Al añadir un
PatternRecognizerpara\bA-\d{5}\bcon una puntuación de 0.6, se detectó el ID del pedido. Un valor con formato de SSN realista (536-90-4399) se detectó comoUS_SSNcon una puntuación de 0.85. - La tokenización reversible funciona. El uso del operador
encryptcon una clave de 128 bits y deDeanonymizeEnginecondecryptrestauró exactamente el texto original.
Un flujo de supresión de PII para aplicaciones con LLM
El patrón habitual en los productos de IA consiste en suprimir la PII, llamar al modelo y después restaurar lo que el usuario necesita ver:
- Primero, reglas por campos. Elimina o sustituye los campos de PII conocidos de las cargas de datos estructuradas según el esquema.
- Detecta la PII en el texto libre. Ejecuta una API de PII o Presidio sobre mensajes, tickets y documentos.
- Seudonimiza de forma consistente. Sustituye cada entidad por un marcador estable (
<PERSON_1>) y guarda la correspondencia en tu servicio, nunca en el prompt. - Llama al LLM con el texto con la PII suprimida.
- Restaura los marcadores en la salida del modelo solo donde el usuario tenga permiso para ver los valores reales.
- Registra la versión con la PII suprimida y los recuentos de entidades, no el original.
import os, re
from openai import OpenAI
from presidio_analyzer import AnalyzerEngine
analyzer = AnalyzerEngine()
client = OpenAI(api_key=os.environ["FLATKEY_API_KEY"], base_url="https://router.flatkey.ai/v1")
def non_overlapping(results, min_score=0.35):
kept = []
# prefer higher scores, then longer spans; drop anything overlapping a kept span
for r in sorted(results, key=lambda r: (-r.score, -(r.end - r.start))):
if r.score >= min_score and all(r.end <= k.start or r.start >= k.end for k in kept):
kept.append(r)
return sorted(kept, key=lambda r: r.start, reverse=True)
def pseudonymize(text):
mapping, counters = {}, {}
for r in non_overlapping(analyzer.analyze(text=text, language="en")):
counters[r.entity_type] = counters.get(r.entity_type, 0) + 1
token = f"<{r.entity_type}_{counters[r.entity_type]}>"
mapping[token] = text[r.start:r.end]
text = text[:r.start] + token + text[r.end:]
return text, mapping
ticket = "Customer Dana Whitfield (dana.whitfield@example.com) says order A-77231 never arrived."
safe, mapping = pseudonymize(ticket)
reply = client.chat.completions.create(
model="claude-haiku-5-5",
messages=[{"role": "user", "content": f"Draft a short apology email for this ticket:\n{safe}"}],
).choices[0].message.content
for token, value in mapping.items(): # restore only on your side
reply = reply.replace(token, value)
print(reply)
El paso non_overlapping es importante: sin él, la URL detectada dentro de la dirección de correo electrónico corrompe la sustitución. Al incluirlo, nuestro ticket de prueba quedó así: Customer <PERSON_1> (<EMAIL_ADDRESS_1>) says order A-77231 never arrived. El ID del pedido sigue pasando sin cambios, por lo que el reconocedor personalizado de la sección anterior debe incluirse en producción. El propio anonimizador de Presidio resuelve los solapamientos automáticamente.
Gestión de fallos y pruebas
| Riesgo | Mitigación |
|---|---|
| Tiempo de espera agotado o error 5xx de la API de PII | Bloquea el envío ante un fallo: no envíes al LLM el texto sin la PII suprimida; ponlo en cola y reintenta |
| Detecciones de baja confianza | Umbrales por entidad; revisión semanal de muestras |
| Idioma no admitido | Detecta primero el idioma; AWS Comprehend PII solo admite inglés y español |
| Identificadores de negocio (ID de pedidos, números de cuenta) | Reconocedores personalizados con expresiones regulares o reglas por campos |
| Falsos positivos que alteran el significado | Listas de permitidos para nombres de productos y direcciones públicas |
| PII en la salida del modelo | Ejecuta la detección sobre las respuestas antes de registrarlas o mostrarlas a otros usuarios |
| Registros que contienen los originales | Registra solo el texto con la PII suprimida y los recuentos de entidades |
Crea un conjunto de pruebas etiquetado con mensajes sintéticos que se parezcan a tu tráfico real e incluyan nombres de muchas culturas, formatos internacionales de teléfono y tus propios formatos de ID. Mide la exhaustividad de la detección por tipo de entidad antes del lanzamiento y después de cada cambio en las reglas.
Cómo elegir una API de supresión de PII
- Ya usas AWS y el texto está en inglés o español: Amazon Comprehend es sencillo y económico para volúmenes pequeños.
- Necesitas tokenización reversible como servicio gestionado o muchos identificadores específicos de cada país: Google Sensitive Data Protection.
- Necesitas recibir directamente el texto con la PII suprimida, detectar PII en conversaciones o documentos, o usar contenedores en tus instalaciones: Azure Language PII.
- Los datos no pueden salir de tu red o necesitas controlar por completo las reglas: Presidio, con reconocedores personalizados y tu propia evaluación.
Muchos equipos los combinan: Presidio o reglas por campos en la ruta de procesamiento más frecuente y una API gestionada para analizar documentos por lotes.
Cómo encaja con Flatkey
Flatkey es una pasarela de modelos: una sola clave y un endpoint compatible con OpenAI para muchos LLM. No detecta ni suprime la PII por ti, así que ejecuta la supresión en tu aplicación antes de que las solicitudes salgan de tu servicio, como en el flujo anterior. La documentación de Flatkey para empresas describe la retención cero del contenido de las solicitudes, lo que reduce la exposición, pero no sustituye la supresión de datos. Lecturas relacionadas: política de supresión de datos para API de IA, gestión segura de claves de API, seguimiento de costes de LLM y el catálogo de modelos de Flatkey.
Preguntas frecuentes
¿Qué es una API de supresión de PII?
Es una API que detecta datos personales en texto, como nombres, correos electrónicos, números de teléfono y números de identificación, y devuelve la ubicación de esos datos o una versión del texto con ellos eliminados, enmascarados o sustituidos.
¿Cuál es la mejor API de supresión de PII?
Depende de tu entorno tecnológico y de tus datos. Amazon Comprehend encaja con textos en inglés y español en AWS; Google Sensitive Data Protection destaca en tokenización reversible y variedad de infoTypes; Azure devuelve directamente el texto con la PII suprimida y se ejecuta en contenedores; y Presidio es la mejor opción cuando los datos deben permanecer en tu red.
¿Hay alguna API gratuita de supresión de PII?
Presidio es software gratuito de código abierto. Los servicios gestionados tienen cuotas gratuitas: AWS Comprehend incluye 50K unidades (5M caracteres) por API al mes durante 12 meses, el primer 1 GiB de inspección mensual de Google es gratuito y el nivel gratuito de Azure incluye 5,000 registros de texto al mes.
¿Debo suprimir la PII antes de enviar prompts a ChatGPT, Claude u otras API de LLM?
Sí, cuando el modelo no necesite los valores reales. Seudonimiza los nombres, los datos de contacto y los identificadores, envía marcadores al modelo y restaura los valores en tu propio servicio si el usuario los necesita.
¿Se puede revertir la supresión de PII?
La supresión simple y el enmascaramiento no se pueden revertir. La tokenización o la seudonimización basada en cifrado sí pueden revertirse con la clave o la tabla de correspondencias, que debes guardar de forma segura y separada de los datos con la PII suprimida.
¿Qué precisión tienen las API de detección de PII?
Ninguna es perfecta. En nuestra prueba con Presidio, un número de teléfono obtuvo solo 0.4 y un ID de pedido pasó inadvertido hasta que añadimos una regla personalizada. Mide la exhaustividad de la detección con tus propios datos sintéticos y bloquea el envío cuando falle el detector.
¿Flatkey suprime la PII?
No. Flatkey dirige las solicitudes a los modelos; la supresión debe realizarse en tu aplicación antes de enviar la solicitud.


