# Financial Compliance AI

> <!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT -->

- Skill: `frank-luongt/financial-compliance-ai` (Agent Skill)
- Install (CLI): `npx skillmds@latest add frank-luongt/financial-compliance-ai`
- Raw SKILL.md: https://api.skillmd.com/api/skills/frank-luongt/financial-compliance-ai/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: frank-luongt (https://skillmd.com/u/frank-luongt)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/frank-luongt/financial-compliance-ai

---

<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT -->
---
name: financial-compliance-ai
description: Financial compliance AI patterns for KYC/AML, Basel III, Solvency II, and regulatory reporting. Use when building AI agents that assist with anti-money laundering, know-your-customer, sanctions screening, fraud detection, or regulatory compliance workflows.
tags: [compliance, kyc, aml, fraud, regulatory, basel, solvency]
---

# Financial Compliance AI

Build AI agents that assist with KYC/AML, sanctions screening, fraud detection, and regulatory compliance (Basel III, Solvency II, IFRS 17) while maintaining full auditability.

## When to Use

- Building AI-assisted KYC/AML screening and investigation workflows
- Implementing sanctions list screening with entity resolution
- Automating Suspicious Activity Report (SAR) narrative generation
- Creating fraud detection agents with explainable decisioning
- Assisting with regulatory reporting (Basel III, Solvency II, IFRS 17)

## Compliance Domain Map

| Domain | Regulations | AI Use Cases |
|---|---|---|
| **KYC** | CDD, EDD, UBO identification | Document verification, risk scoring, entity resolution |
| **AML** | BSA, 4AMLD/5AMLD/6AMLD, FATF | Transaction monitoring, SAR generation, network analysis |
| **Sanctions** | OFAC SDN, EU sanctions, UN | Name screening, fuzzy matching, PEP identification |
| **Fraud** | PSD2 SCA, Reg E | Real-time scoring, anomaly detection, case summarization |
| **Regulatory** | Basel III/IV, Solvency II, IFRS 17 | Data aggregation, report generation, gap analysis |

## Patterns

### 1. KYC Document Verification Agent

```python
import anthropic
import base64

def verify_kyc_document(document_image_b64: str, document_type: str) -> dict:
    """Extract and verify KYC document data using vision AI.

    Args:
        document_image_b64: Base64-encoded document image
        document_type: Type of document (passport, drivers_license, national_id)
    """
    client = anthropic.Anthropic()

    response = client.messages.create(
        model="claude-sonnet-4-5-20250929",
        max_tokens=1024,
        messages=[{
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {"type": "base64", "media_type": "image/jpeg", "data": document_image_b64},
                },
                {
                    "type": "text",
                    "text": f"""Extract structured data from this {document_type}. Return JSON with:
- full_name, date_of_birth, document_number, expiry_date, issuing_country
- is_expired: boolean
- confidence: high/medium/low for each field
Do NOT return any data you cannot clearly read from the document.""",
                },
            ],
        }],
    )

    # IMPORTANT: AI extraction must be reviewed by compliance officer
    # before being used for KYC decisions
    return {"extraction": response.content[0].text, "requires_human_review": True}
```

### 2. Sanctions Screening with Fuzzy Matching

```python
from rapidfuzz import fuzz, process

class SanctionsScreener:
    def __init__(self, sanctions_lists: list[dict]):
        """Initialize with loaded sanctions entries.

        Each entry: {"name": "...", "aliases": [...], "list": "OFAC_SDN", "id": "..."}
        """
        self.entries = sanctions_lists
        self.all_names = []
        self.name_to_entry = {}
        for entry in sanctions_lists:
            names = [entry["name"]] + entry.get("aliases", [])
            for name in names:
                self.all_names.append(name)
                self.name_to_entry[name] = entry

    def screen(self, query_name: str, threshold: int = 85) -> list[dict]:
        """Screen a name against sanctions lists.

        Args:
            query_name: Name to screen
            threshold: Minimum fuzzy match score (0-100)
        """
        matches = process.extract(
            query_name,
            self.all_names,
            scorer=fuzz.token_sort_ratio,
            score_cutoff=threshold,
            limit=10,
        )
        results = []
        for matched_name, score, _ in matches:
            entry = self.name_to_entry[matched_name]
            results.append({
                "matched_name": matched_name,
                "score": score,
                "sanctions_list": entry["list"],
                "entry_id": entry["id"],
                "canonical_name": entry["name"],
            })
        return results

def screen_customer(customer_name: str) -> str:
    """Screen a customer name against OFAC and EU sanctions lists.

    Args:
        customer_name: Full name to screen
    """
    screener = SanctionsScreener(load_sanctions_lists())
    hits = screener.screen(customer_name, threshold=85)
    if not hits:
        return f"No sanctions hits for '{customer_name}'. Screening passed."
    hit_summary = "\n".join(
        f"- {h['canonical_name']} ({h['sanctions_list']}, score: {h['score']}%)"
        for h in hits
    )
    return f"ALERT: {len(hits)} potential sanctions hit(s) for '{customer_name}':\n{hit_summary}\nRequires compliance officer review."
```

### 3. SAR Narrative Generation

```python
import anthropic

def generate_sar_narrative(alert_data: dict, transaction_data: list[dict], customer_data: dict) -> str:
    """Generate a Suspicious Activity Report narrative draft.

    Args:
        alert_data: AML alert details (rule triggered, score, etc.)
        transaction_data: Related transactions
        customer_data: Customer profile (redacted PII)
    """
    client = anthropic.Anthropic()

    response = client.messages.create(
        model="claude-sonnet-4-5-20250929",
        max_tokens=2048,
        system="""You are a BSA/AML compliance analyst assistant. Generate SAR narrative drafts
following FinCEN guidelines. Include: subject description, suspicious activity description,
transaction patterns, and why activity is suspicious. Use factual, objective language only.
Flag any gaps in evidence. This is a DRAFT requiring human review.""",
        messages=[{
            "role": "user",
            "content": f"""Generate a SAR narrative draft for this alert:

Alert: {alert_data}
Transactions: {transaction_data}
Customer Profile: {customer_data}

Follow FinCEN SAR narrative best practices.""",
        }],
    )

    return response.content[0].text
```

### 4. Transaction Monitoring Rules

```python
from dataclasses import dataclass
from datetime import datetime, timedelta

@dataclass
class TransactionAlert:
    rule_id: str
    severity: str  # high, medium, low
    description: str
    transactions: list[dict]
    customer_id: str

def check_structuring(transactions: list[dict], threshold: float = 10000.0, window_days: int = 3) -> TransactionAlert | None:
    """Detect potential structuring (transactions just below reporting threshold).

    Args:
        transactions: List of customer transactions
        threshold: CTR reporting threshold (default $10,000)
        window_days: Lookback window in days
    """
    cutoff = datetime.now() - timedelta(days=window_days)
    recent_cash = [
        t for t in transactions
        if t["type"] == "cash_deposit"
        and datetime.fromisoformat(t["date"]) >= cutoff
        and threshold * 0.5 <= t["amount"] < threshold
    ]
    if len(recent_cash) >= 3:
        total = sum(t["amount"] for t in recent_cash)
        return TransactionAlert(
            rule_id="AML-001",
            severity="high",
            description=f"Potential structuring: {len(recent_cash)} cash deposits totaling ${total:,.2f} in {window_days} days, each below ${threshold:,.0f} threshold",
            transactions=recent_cash,
            customer_id=recent_cash[0].get("customer_id", ""),
        )
    return None
```

### 5. Regulatory Reporting Helper

```python
def generate_regulatory_summary(report_type: str, data: dict) -> str:
    """Generate a regulatory report summary for review.

    Args:
        report_type: Type of report (basel_iii_capital, solvency_ii_scr, ifrs17_liability)
        data: Pre-computed regulatory data
    """
    import anthropic

    prompts = {
        "basel_iii_capital": "Summarize this Basel III capital adequacy data. Highlight CET1, Tier 1, and Total Capital ratios vs minimums (4.5%, 6%, 8%). Flag any breaches.",
        "solvency_ii_scr": "Summarize this Solvency II SCR calculation. Highlight solvency ratio, own funds, and SCR. Flag if ratio is below 100% or approaching warning threshold (120%).",
        "ifrs17_liability": "Summarize this IFRS 17 insurance contract liability. Highlight BEL, risk adjustment, and CSM. Flag material changes vs prior period.",
    }

    client = anthropic.Anthropic()
    response = client.messages.create(
        model="claude-sonnet-4-5-20250929",
        max_tokens=1024,
        system="You are a regulatory reporting analyst. Provide factual, precise summaries. Always flag items requiring attention. This is a draft for human review.",
        messages=[{"role": "user", "content": f"{prompts.get(report_type, 'Summarize this regulatory data.')}\n\nData: {data}"}],
    )
    return response.content[0].text
```

## Critical Compliance Requirements

- **Human-in-the-loop**: AI MUST NOT make final compliance decisions -- always route to compliance officers
- **Audit trail**: Log all AI inputs, outputs, and decisions with timestamps for regulatory examination
- **Data residency**: Ensure customer PII stays within required jurisdictions (no cross-border LLM calls without approval)
- **Model explainability**: Regulators require explanation of AI decisions -- use models with reasoning capabilities
- **PII handling**: Mask/redact PII before sending to external LLMs; use on-premise models for sensitive data

## Anti-Patterns

- Using AI to auto-file SARs without human review -- regulatory violation
- Sending unmasked SSN/DOB/account numbers to cloud LLMs -- data breach risk
- Training on customer data without privacy review -- GDPR/CCPA violation
- Hard-coding sanctions lists instead of using live feeds -- lists change daily
- Relying solely on AI for sanctions screening -- regulators require documented methodology

## References

- [FinCEN SAR Filing](https://www.fincen.gov/resources/filing-information)
- [FATF Recommendations](https://www.fatf-gafi.org/en/recommendations.html)
- [Basel III Framework](https://www.bis.org/bcbs/basel3.htm)
- [Solvency II Directive](https://www.eiopa.europa.eu/browse/solvency-2_en)
- [IFRS 17 Insurance Contracts](https://www.ifrs.org/issued-standards/list-of-standards/ifrs-17-insurance-contracts/)

<!-- Source: .faos/custom/skills/security/financial-compliance-ai/SKILL.md -->

