Compliance Monitoring Systems
The GDPR Fine That Could Have Been Caught
On January 21, 2019, the French data protection authority CNIL issued a 50 million euro fine against Google LLC. The violation: Google's privacy disclosures lacked transparency, and users did not genuinely consent to personalized advertising because consent was not freely given. The evidence CNIL relied upon was largely in plain text - privacy policies, consent flows, cookie banners.
A compliance monitoring system that had been reading Google's customer-facing communications and cross-referencing them against GDPR Articles 5, 6, and 13 would have flagged the consent architecture as problematic months before the complaint was filed. Not as a legal conclusion, but as a risk signal: "Article 13(1)(c) requires disclosure of purposes for processing. Detected 14 advertising-related purposes in internal documentation not disclosed in user-facing privacy notice. Risk level: HIGH."
This is what modern compliance AI does. Not legal interpretation, but systematic gap detection between what regulations require and what an organization's actual communications, processes, and policies say. The gap between what the law requires in plain text and what an organization actually documents is often measurable. NLP systems are better at reading everything than humans are.
The scale of the compliance monitoring problem is enormous. A large bank operating across the EU, UK, and US faces requirements from GDPR, MiFID II, AML directives, CCPA, the Bank Secrecy Act, FINRA rules, and dozens of other regulatory frameworks - simultaneously, with requirements that sometimes conflict. Regulatory updates arrive continuously: the EU publishes thousands of pages of regulatory guidance per year. No team of compliance officers can read everything.
The consequence of missing a regulatory requirement is not just a fine - it can be criminal liability, license revocation, reputational damage that far exceeds the fine. Deutsche Bank paid 1.9 billion in 2012. These are not cases where the violations were invisible - they were cases where the monitoring systems were insufficient to surface the patterns from the transaction data and communications.
AI compliance monitoring does not prevent people from breaking the law. It does prevent compliance failures from going undetected. The difference is whether a compliance officer sees a risk signal in week 1 or week 52 of a violation pattern.
Why This Exists
Traditional compliance programs run on three mechanisms: manual policy review, periodic audits, and human monitoring of flagged transactions. All three are point-in-time. A manual policy review happens once a year. An audit covers a sample. Human monitoring of communications covers a fraction of the total volume.
The problem is that compliance risk is continuous and high-volume. A bank processes millions of transactions per day. A financial services firm sends millions of customer communications per year. A healthcare company generates thousands of patient data access events per hour. Reviewing a sample and hoping the violations are in the sample is not a compliance program - it is a liability waiting to materialize.
The regulatory environment has also become more complex. GDPR came into force in 2018, CCPA in 2020, China's PIPL in 2021. Every major jurisdiction now has data protection regulations with materially different requirements. A global company that was GDPR-compliant in 2019 may not be PIPL-compliant in 2021 without specific changes. Tracking these changes and their implications for internal policies requires reading hundreds of regulatory documents and mapping their requirements to internal procedures - continuously.
AI compliance monitoring compresses the timeline from violation to detection, increases coverage from sample-based to near-comprehensive, and provides structured, auditable evidence when regulators come calling.
Historical Context
The first generation of compliance monitoring systems were rule-based: flag transactions above a threshold, flag communications containing specific keywords, alert on deviations from standard operating procedures. These systems generated enormous numbers of false positives - suspicious activity reports that turned out to be legitimate, communications flagged for containing the word "loan" in an innocent context. Compliance teams spent most of their time clearing false positives.
The Bank Secrecy Act was enacted in 1970, requiring US financial institutions to maintain records of certain transactions and file suspicious activity reports. For 40 years, the monitoring was almost entirely rule-based. A 10,000 triggers a structuring flag. The rules were known to everyone, including the people trying to evade them.
Machine learning for financial crime detection began gaining traction in the early 2010s, driven by the realization that rules-based systems generated too many false positives and missed behavioral patterns that no single rule captured. Graph-based ML for transaction networks (detecting money laundering rings), sequence models for behavior analysis, and NLP for communication monitoring began to replace purely rule-based systems.
GDPR enforcement starting in 2018 created a new category of text-based compliance monitoring. Proving GDPR compliance requires analyzing what organizations say about their data processing practices (privacy policies, consent forms, DPA agreements) and what they actually do (data flows, retention schedules, access logs). NLP for gap analysis between documentation and practice became a compliance requirement, not just a nice-to-have.
Core Concepts
Multi-Level Compliance Architecture
Compliance monitoring operates at three levels, and the NLP challenges differ at each:
Document level: Does our privacy policy comply with GDPR Article 13 requirements? This is a compliance classification task - given a document and a regulatory requirement, classify whether the document satisfies the requirement. The model needs to understand both the regulatory text and the organizational document well enough to assess compliance.
Communication level: Does this email exchange between a financial advisor and a client comply with MiFID II suitability requirements? This is per-message or per-conversation classification. Volume is high (millions of communications), so models must be fast and precise to avoid alert fatigue.
Process level: Does the overall data processing flow comply with GDPR's data minimization principle? This requires connecting data flow documentation, system architecture documents, and the regulatory requirement - a multi-document reasoning task.
Named Entity Recognition for Regulated Entities
In compliance monitoring, knowing which entities are involved in a transaction or communication is critical for routing to the right compliance rules.
For AML compliance, regulated entities include:
- Politically Exposed Persons (PEPs) - politicians, their families, close associates
- Sanctioned entities - OFAC SDN list, EU sanctions list, UN sanctions list
- High-risk jurisdictions - countries on FATF watchlists
- Correspondent banks and beneficial owners
Custom NER for compliance identifies these entities from unstructured text - client communications, transaction memos, KYC documentation. The NER must handle fuzzy matching (name variations, transliterations) and be updated continuously as sanctions lists change.
The technical challenge: sanctions list matching is not simple string matching. "Mikhail Ivanov" and "Michael Ivanov" may be the same person. "Huawei Technologies" and "HWAT" (a common abbreviation used internally) may be the same entity. Fuzzy entity matching with confidence scoring is necessary.
Text Classification for Policy Violations
Given a customer communication (email, chat message, call transcript), classify whether it contains a policy violation. This is a multi-label classification problem because a single message can violate multiple policies simultaneously.
For financial services, violation categories include:
- Unauthorized advice (giving investment advice without appropriate authorization)
- Front-running indicators (discussing pending large orders before execution)
- Confidential information disclosure
- Market manipulation language ("we can move the price")
- Inappropriate promises ("guaranteed returns")
The class imbalance problem is severe. In a bank's communication archive, genuine policy violations are rare - perhaps 0.01% of messages. Training a classifier on highly imbalanced data produces models that predict "compliant" for everything and achieve 99.99% accuracy while catching zero violations.
Mitigation strategies:
- Oversample violation examples using synthetic data generation
- Use anomaly detection as a pre-filter before classification
- Weight the violation class more heavily in the loss function
- Frame as a ranking problem rather than binary classification
Regulatory Change Detection
Regulations change. New articles are added, existing requirements are amended, guidance notes modify interpretation. A compliance monitoring system that reads 2019 GDPR guidance may be out of date by 2024 after years of regulatory updates, enforcement decisions, and EDPB opinions.
Regulatory change detection is an NLP pipeline:
- Subscribe to official regulatory publication feeds (EUR-Lex for EU, Federal Register for US, FCA handbook changes for UK)
- When a new document is published, embed it alongside existing regulatory text
- Compute semantic similarity between new and existing content
- Flag sections where requirements have materially changed (low similarity to prior version)
- Generate a diff summary: "GDPR Recital 32 interpretation updated - new guidance on cookie consent granularity"
- Route changes to affected compliance policies for review
Code Examples
GDPR Compliance Classifier for Customer Communications
"""
GDPR compliance monitoring system for customer communications.
Classifies communications for GDPR-relevant events and policy violations.
"""
from transformers import (
AutoTokenizer,
AutoModelForSequenceClassification,
pipeline,
TrainingArguments,
Trainer,
)
from datasets import Dataset
import torch
import numpy as np
from typing import List, Dict, Optional, Tuple
from dataclasses import dataclass
import json
import re
from datetime import datetime
# --- 1. GDPR Event Categories ---
GDPR_EVENT_TYPES = {
"data_subject_request": (
"Communication contains a data subject access, rectification, "
"erasure, or portability request"
),
"consent_withdrawal": (
"Individual is withdrawing previously given consent to process personal data"
),
"data_breach_indicator": (
"Communication suggests a personal data breach may have occurred"
),
"third_party_transfer": (
"Data being transferred or disclosed to a third party not in the privacy notice"
),
"sensitive_data_processing": (
"Health, biometric, political, religious, or other special category data "
"is being processed"
),
"retention_violation": (
"Data is being retained beyond the stated retention period"
),
"unauthorized_processing": (
"Personal data being processed for a purpose not disclosed to the data subject"
),
}
@dataclass
class ComplianceAlert:
"""A compliance alert generated from a communication."""
message_id: str
timestamp: datetime
event_type: str
confidence: float
severity: str # HIGH, MEDIUM, LOW
text_excerpt: str
regulation_reference: str
recommended_action: str
class GDPRComplianceClassifier:
"""
Multi-label classifier for GDPR-relevant events in customer communications.
Designed for high-recall, high-precision operation in production.
"""
def __init__(self, model_name: str = "distilbert-base-uncased"):
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModelForSequenceClassification.from_pretrained(
model_name,
num_labels=len(GDPR_EVENT_TYPES),
problem_type="multi_label_classification",
)
self.label_names = list(GDPR_EVENT_TYPES.keys())
self.thresholds = {label: 0.5 for label in self.label_names}
def set_thresholds(self, thresholds: Dict[str, float]) -> None:
"""Set per-class thresholds for precision/recall tradeoff."""
self.thresholds.update(thresholds)
def predict(self, texts: List[str]) -> List[List[Dict]]:
"""
Classify a batch of communications for GDPR events.
Returns list of detected events per message.
"""
encodings = self.tokenizer(
texts,
padding=True,
truncation=True,
max_length=512,
return_tensors="pt",
)
self.model.eval()
with torch.no_grad():
outputs = self.model(**encodings)
probabilities = torch.sigmoid(outputs.logits).cpu().numpy()
results = []
for prob_vector in probabilities:
detected = []
for i, (label, prob) in enumerate(zip(self.label_names, prob_vector)):
if prob >= self.thresholds[label]:
detected.append({
"event_type": label,
"confidence": float(prob),
"description": GDPR_EVENT_TYPES[label],
})
results.append(detected)
return results
def generate_alert(
self,
message_id: str,
text: str,
event: Dict,
) -> ComplianceAlert:
"""Generate a structured compliance alert from a detected event."""
severity_map = {
"data_breach_indicator": "HIGH",
"unauthorized_processing": "HIGH",
"third_party_transfer": "HIGH",
"data_subject_request": "MEDIUM",
"consent_withdrawal": "MEDIUM",
"sensitive_data_processing": "HIGH",
"retention_violation": "MEDIUM",
}
regulation_map = {
"data_subject_request": "GDPR Art. 15-22 (Data Subject Rights)",
"consent_withdrawal": "GDPR Art. 7(3) (Withdrawal of Consent)",
"data_breach_indicator": "GDPR Art. 33-34 (Breach Notification)",
"third_party_transfer": "GDPR Art. 28-29 (Processor Requirements)",
"sensitive_data_processing": "GDPR Art. 9 (Special Categories)",
"retention_violation": "GDPR Art. 5(1)(e) (Storage Limitation)",
"unauthorized_processing": "GDPR Art. 6 (Lawfulness of Processing)",
}
action_map = {
"data_subject_request": (
"Route to DPO within 24 hours. Respond within 30 days per Art. 12."
),
"consent_withdrawal": (
"Cease processing immediately. Update consent records. "
"Confirm withdrawal to data subject."
),
"data_breach_indicator": (
"URGENT: Escalate to DPO immediately. "
"72-hour supervisory authority notification window starts now."
),
"third_party_transfer": (
"Verify DPA in place with third party. "
"Check if data subject was notified per Art. 13."
),
"sensitive_data_processing": (
"Verify explicit consent or Art. 9(2) exception. "
"Check DPIA was conducted."
),
"retention_violation": (
"Review retention schedule. Delete or anonymize if past retention period."
),
"unauthorized_processing": (
"Stop processing. Review lawful basis. "
"Notify data subject if basis does not exist."
),
}
excerpt = text[:300] + "..." if len(text) > 300 else text
return ComplianceAlert(
message_id=message_id,
timestamp=datetime.utcnow(),
event_type=event["event_type"],
confidence=event["confidence"],
severity=severity_map.get(event["event_type"], "MEDIUM"),
text_excerpt=excerpt,
regulation_reference=regulation_map.get(event["event_type"], "GDPR"),
recommended_action=action_map.get(event["event_type"], "Review and escalate."),
)
# --- 2. PII and Regulated Entity Detection ---
class PIIDetector:
"""
Detect and classify PII in text using NER + regex patterns.
Supports GDPR-relevant PII categories.
"""
PII_PATTERNS = {
"email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
"phone_uk": r"\b(?:\+44|0044|0)\s?(?:\d\s?){9,10}\b",
"phone_us": r"\b(?:\+1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b",
"national_id_uk": r"\b[A-Z]{2}\d{6}[A-D]\b", # UK NI number
"iban": r"\b[A-Z]{2}\d{2}[A-Z0-9]{4}\d{7}([A-Z0-9]?){0,16}\b",
"ip_address": r"\b(?:\d{1,3}\.){3}\d{1,3}\b",
"date_of_birth": r"\b(?:dob|date of birth|born on)[:\s]+\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b",
}
SPECIAL_CATEGORIES = {
# GDPR Art. 9 special categories - higher sensitivity
"health_keywords": [
"diagnosis", "medical condition", "medication", "treatment",
"health record", "prescription", "disability", "chronic",
],
"biometric_keywords": [
"fingerprint", "facial recognition", "iris scan", "retina scan",
"voice recognition", "biometric",
],
"political_keywords": [
"political party", "trade union", "political opinion",
"political affiliation",
],
}
def __init__(self):
# Use spaCy or a transformer-based NER model for person/org names
try:
import spacy
self.nlp = spacy.load("en_core_web_sm")
self.use_spacy = True
except (ImportError, OSError):
self.use_spacy = False
def detect_pii(self, text: str) -> Dict:
"""
Detect PII instances in text.
Returns structured PII inventory with categories.
"""
findings = {
"standard_pii": [],
"special_category_pii": [],
"named_entities": [],
"overall_risk": "LOW",
}
# Pattern-based detection
for pii_type, pattern in self.PII_PATTERNS.items():
matches = re.findall(pattern, text, re.IGNORECASE)
if matches:
findings["standard_pii"].append({
"type": pii_type,
"count": len(matches),
"examples": matches[:3],
})
# Special category detection
text_lower = text.lower()
for category, keywords in self.SPECIAL_CATEGORIES.items():
found_keywords = [kw for kw in keywords if kw in text_lower]
if found_keywords:
findings["special_category_pii"].append({
"category": category,
"keywords_found": found_keywords,
})
# NER-based detection for names and organizations
if self.use_spacy:
doc = self.nlp(text[:5000]) # Limit for performance
for ent in doc.ents:
if ent.label_ in ("PERSON", "ORG", "GPE"):
findings["named_entities"].append({
"text": ent.text,
"label": ent.label_,
})
# Assign overall risk
if findings["special_category_pii"]:
findings["overall_risk"] = "HIGH"
elif findings["standard_pii"] or len(findings["named_entities"]) > 3:
findings["overall_risk"] = "MEDIUM"
return findings
# --- 3. Regulatory Change Detection ---
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity as sklearn_cosine
import numpy as np
class RegulatoryChangeDetector:
"""
Detects material changes in regulatory text between versions.
Generates structured change summaries for compliance review.
"""
def __init__(self):
self.encoder = SentenceTransformer("sentence-transformers/all-mpnet-base-v2")
def detect_changes(
self,
old_regulation_text: str,
new_regulation_text: str,
section_name: str,
similarity_threshold: float = 0.85,
) -> Dict:
"""
Compare two versions of regulatory text and identify material changes.
"""
# Split into paragraphs
old_sections = [s.strip() for s in old_regulation_text.split("\n\n") if len(s.strip()) > 50]
new_sections = [s.strip() for s in new_regulation_text.split("\n\n") if len(s.strip()) > 50]
if not old_sections or not new_sections:
return {"error": "Insufficient text for comparison"}
old_embeddings = self.encoder.encode(old_sections, normalize_embeddings=True)
new_embeddings = self.encoder.encode(new_sections, normalize_embeddings=True)
sim_matrix = sklearn_cosine(new_embeddings, old_embeddings)
changes = []
new_additions = []
for i, new_sec in enumerate(new_sections):
best_match_score = sim_matrix[i].max()
best_match_idx = sim_matrix[i].argmax()
if best_match_score < 0.5:
# New section - no equivalent in old text
new_additions.append({
"new_text": new_sec[:300],
"type": "addition",
})
elif best_match_score < similarity_threshold:
# Modified section
changes.append({
"new_text": new_sec[:300],
"old_text": old_sections[best_match_idx][:300],
"similarity": float(best_match_score),
"type": "modification",
"change_significance": (
"MAJOR" if best_match_score < 0.6
else "MODERATE" if best_match_score < 0.75
else "MINOR"
),
})
return {
"section": section_name,
"total_sections_analyzed": len(new_sections),
"modifications": changes,
"additions": new_additions,
"deletions_count": max(0, len(old_sections) - len(new_sections)),
"material_change": bool(changes or new_additions),
}
# --- 4. Alert Prioritization ---
class AlertPrioritizer:
"""
Reduces alert fatigue by scoring and prioritizing compliance alerts.
Uses rule-based scoring + ML reranking.
"""
SEVERITY_WEIGHTS = {"HIGH": 3, "MEDIUM": 2, "LOW": 1}
REGULATION_URGENCY = {
"GDPR Art. 33-34": 10, # 72-hour breach notification
"GDPR Art. 15-22": 5, # 30-day response deadline
"AML SAR": 8, # 60-day filing window
"MiFID II": 6,
}
def score_alert(self, alert: ComplianceAlert) -> float:
"""
Compute priority score for a compliance alert.
Higher score = higher priority.
"""
base_score = self.SEVERITY_WEIGHTS.get(alert.severity, 1)
confidence_factor = alert.confidence # 0.0 to 1.0
# Regulation urgency factor
urgency_factor = 1.0
for regulation, urgency in self.REGULATION_URGENCY.items():
if regulation in alert.regulation_reference:
urgency_factor = urgency / 10
break
return base_score * confidence_factor * (1 + urgency_factor)
def prioritize(self, alerts: List[ComplianceAlert]) -> List[ComplianceAlert]:
"""Sort alerts by priority score descending."""
return sorted(alerts, key=lambda a: self.score_alert(a), reverse=True)
Mermaid Diagrams
Compliance Monitoring Pipeline Architecture
Multi-Jurisdiction Compliance Mapping
Alert Triage Flow
Production Engineering Notes
Explainability Requirements
Regulatory compliance monitoring AI must be explainable - not as a nice feature, but as a legal requirement in some jurisdictions. GDPR Article 22 regulates "solely automated decision-making" with "legal or similarly significant effects." If your compliance system automatically triggers a regulatory report, freezes an account, or initiates a disciplinary process based on AI output, you may need to provide the data subject with an explanation.
Even where GDPR Art. 22 does not directly apply, regulators expect compliance programs to be explainable. When the FCA or SEC asks why a suspicious activity report was filed, "the model said so" is not acceptable. Implement attention-based explanations or LIME/SHAP explanations for every compliance alert:
from transformers import pipeline
import shap
# For transformer-based classifiers, use SHAP with TextClassificationExplainer
explainer = shap.Explainer(compliance_model)
shap_values = explainer([text])
# Extract top contributing tokens for the alert
Handling Conflicting Regulations
A common production challenge: GDPR requires you to delete customer data on request (right to erasure), while AML regulations require you to retain transaction records for 5-10 years. A customer requesting erasure of their data creates a genuine regulatory conflict.
Build a conflict resolution layer:
- Classify each data record by the retention requirements from all applicable regulations
- When a conflicting request arrives, surface the conflict with references to both regulations
- Route to legal counsel with automated context (which regulation requires retention, for how long, what penalties attach to non-compliance on each side)
- Never auto-resolve regulatory conflicts - always human-in-the-loop for conflicting requirements
False Positive Management
Alert fatigue is the death of compliance programs. If compliance officers receive 1,000 alerts per day and 995 are false positives, they will start ignoring alerts. The right false positive rate depends on the regulatory stakes, but as a starting point target:
- Data breach indicators: 80% precision (missing a breach is catastrophic)
- Data subject requests: 95% precision (falsely escalating routine emails wastes resources)
- AML suspicious activity: 70% precision (overreporting to regulators has costs but underreporting has criminal liability)
Track false positive rate weekly per event type. Continuously retrain classifiers as new false positive examples are identified and labeled by compliance officers. The human review queue is a continuous source of labeled training data.
Audit Trail Architecture
Every compliance alert, every model prediction, and every human decision must be logged with enough detail to reconstruct the decision chain. This is not optional - regulators expect to see it.
Log structure for each alert:
- Unique alert ID
- Message ID (for the original communication)
- Model name and version
- Confidence score and raw probability vector
- Feature importances or SHAP values
- Regulatory references triggered
- Human reviewer ID and decision (if reviewed)
- Timestamp of each step
- Any override or escalation actions
Store this in an append-only audit log (write once, read many). Use cryptographic hashing to ensure the log cannot be tampered with.
Common Mistakes
:::danger Auto-acting on compliance alerts without human review Automating enforcement actions based solely on AI output is dangerous for three reasons: false positives harm legitimate customers, automated decisions under GDPR may require human review, and automated regulatory reports (SAR filings) can create legal liability if filed on inaccurate grounds. Always require human-in-the-loop before any enforcement action. The AI triages and prioritizes; humans decide and act. :::
:::danger Training on historical alerts without correcting for past biases If your compliance program historically under-monitored certain communication channels or customer segments, your "violation" training labels will reflect that bias. A model trained on historical labeled data will learn to flag what was flagged before, not what actually violates policy. Audit your training data for coverage gaps before using it as ground truth. :::
:::warning Jurisdiction scope creep Building a system that monitors for GDPR compliance and then claiming it also handles CCPA and PIPL compliance without specific jurisdiction-aware models is a dangerous shortcut. Each regulation has different requirements, different definitions of personal data, different consent standards. Build jurisdiction-specific classifiers and be explicit about scope. :::
:::warning Ignoring the 72-hour clock for GDPR breach notification GDPR Article 33 requires notification to the supervisory authority within 72 hours of becoming aware of a data breach. "Becoming aware" starts when your compliance system generates a high-confidence breach indicator alert - not when a human reviews and confirms it. Build 72-hour countdown tracking from the moment a breach indicator alert is generated and escalate to DPO immediately. :::
Interview Q&A
Q: How would you handle the class imbalance problem in a compliance communication classifier where genuine violations are 0.01% of messages?
Three-pronged approach: (1) At the data level - use SMOTE or LLM-based augmentation to generate synthetic violation examples, expanding the minority class. For compliance, LLMs can generate plausible examples of policy-violating communications that legal counsel confirms. (2) At the training level - use weighted cross-entropy loss with the weight inversely proportional to class frequency. For a 10,000:1 imbalance, assign weight 10,000 to the violation class. Also consider using focal loss, which down-weights easy negatives and focuses learning on hard cases. (3) At the inference level - tune the decision threshold based on the desired precision-recall tradeoff from a calibration set. For high-stakes violations, accept lower precision (more false positives) to ensure high recall (catch all real violations).
Q: What explainability approach is most appropriate for a GDPR compliance classifier, and why?
For transformer-based classifiers, SHAP with the Partition explainer is the most production-ready option. It attributes model predictions to individual tokens, showing which words or phrases drove the classification. For compliance, the explanation should be: "This message was flagged as a data subject access request because of the phrases 'access my data' and 'personal information you hold about me.'" This explanation is auditable, understandable to compliance officers, and defensible to regulators. Attention visualization (from BERT's attention heads) is an alternative but is less theoretically grounded - high attention does not directly correspond to feature importance. For simpler models (logistic regression, tree-based), feature importance is straightforward and preferred when accuracy allows.
Q: How do you build a regulatory change detection system that works across different regulatory frameworks?
Three components: (1) Ingestion - subscribe to RSS feeds, APIs, or web scrapers for regulatory publications. EUR-Lex for EU, Federal Register for US, FCA Handbook for UK. Normalize all documents to plain text with metadata (regulation name, article number, effective date). (2) Semantic change detection - embed all regulation sections with a sentence transformer, store embeddings with version history. When a new version is published, compute section-to-section similarity between versions. Sections with cosine similarity below 0.85 are flagged as materially changed. (3) Impact mapping - link regulation sections to internal policies using a compliance taxonomy. When a section changes, automatically identify which internal policies need review. The hardest part is step 3 - building the taxonomy that maps external regulatory text to internal policy documents requires legal expertise and ongoing maintenance.
Q: A compliance officer complains that your system generates 500 alerts per day and they can only review 50. How do you address this?
This is the alert fatigue problem. Fix it in four steps: (1) Measure - track the false positive rate per alert type by having officers label reviewed alerts. Find which alert types generate the most false positives. (2) Tune thresholds - increase the confidence threshold for high-FP alert types until precision meets a target level. (3) Prioritization - implement multi-factor alert scoring (severity, confidence, regulatory urgency, recency) so the top 50 alerts represent the highest actual risk. (4) Automated pre-filtering - deploy a fast, high-recall pre-filter that eliminates obvious negatives before the main classifier runs, reducing load. The goal is not to reduce alert volume at the cost of recall - it is to ensure the human's finite review time is spent on the alerts with highest risk.
Q: How would you design a multi-jurisdiction compliance system for a company operating under GDPR, CCPA, and PIPL simultaneously?
Architecture with three layers: (1) Jurisdiction detection - classify each piece of data (communication, transaction, record) by which jurisdictions' laws apply based on the data subject's location, the processing location, and the company's legal entities involved. (2) Jurisdiction-specific monitoring - run separate classifiers per jurisdiction, each trained on that jurisdiction's violation patterns and tuned to that regulation's requirements. Do not share classifiers across jurisdictions - GDPR's "legitimate interest" basis does not exist in PIPL. (3) Conflict resolution layer - when multiple jurisdictions apply and their requirements conflict (GDPR erasure vs. AML retention), surface the conflict with both regulation references and route to legal for resolution. Never auto-resolve cross-jurisdictional conflicts.
