sar-narrative-gen
AI-powered SAR narrative generator for AML compliance teams — turns flagged transaction data into FinCEN-ready Suspicious Activity Report draft narratives using Claude.
Why this exists
Writing SAR narratives is one of the most time-consuming tasks in a BSA/AML program. A compliance analyst reviewing 800+ alerts a week spends a significant portion of their time translating transaction data into structured prose — describing the who, what, when, where, and why of each suspicious pattern, in language that meets FinCEN guidance.
This toolkit automates the first draft. Feed it flagged transactions and subject information; get back a structured SAR narrative that follows FinCEN best practices. Analysts review and refine rather than write from scratch.
How it works
The generator takes flagged transaction data, subject information, and a detected typology (structuring, layering, smurfing, rapid fund movement, dormant account) and constructs a structured prompt grounded in FinCEN SAR narrative guidance. It calls the Anthropic Claude API and returns a formatted narrative draft with metadata — transaction count, total flagged amount, date range, and generation timestamp.
The system prompt encodes FinCEN narrative requirements: objective language, no conclusory statements, specific transaction references, typology identification, and the standard who/what/when/where/why structure.
Quick start
pip install sar-narrative-gen
Set your Anthropic API key:
export ANTHROPIC_API_KEY=your_key_here
Generate a SAR narrative:
from sar import generate_sar_narrative
transactions = [
{"date": "2024-03-01", "amount": 9400.00, "type": "cash_deposit",
"from_account": "CASH", "to_account": "CHK-004821"},
{"date": "2024-03-04", "amount": 9200.00, "type": "cash_deposit",
"from_account": "CASH", "to_account": "CHK-004821"},
{"date": "2024-03-07", "amount": 8900.00, "type": "cash_deposit",
"from_account": "CASH", "to_account": "CHK-004821"},
]
subject = {
"name": "Meridian Auto Parts LLC",
"account_number": "CHK-004821",
"customer_since": "2021-06-15",
"business_type": "Auto parts retailer",
}
result = generate_sar_narrative(
transactions=transactions,
subject_info=subject,
typology="structuring",
filing_institution="First National Community Bank",
additional_context="Subject's reported annual revenue is $180,000.",
)
print(result["narrative"])
print(f"Total flagged: ${result['total_amount']:,.2f}")
print(f"Transactions: {result['transaction_count']}")
Supported typologies
| Typology | Description | Reference |
|---|---|---|
structuring |
Breaking up transactions below CTR threshold | 31 U.S.C. 5324 |
layering |
Moving funds through multiple accounts to obscure origin | FATF Typologies 2006 |
smurfing |
Multiple individuals conducting sub-threshold transactions | FinCEN FIN-2014-A005 |
rapid_movement |
Funds moving through accounts within 24–48 hours | FATF Guidance 2012 |
dormant_account |
Sudden high-volume activity in previously inactive account | FinCEN FIN-2022-A001 |
Batch processing
Generate narratives for multiple cases at once:
from sar import batch_generate, get_all_demo_cases
cases = get_all_demo_cases() # includes structuring, layering, dormant account
results = batch_generate(cases)
for r in results:
print(f"\n--- {r['case_id']} ---")
print(r["narrative"])
Demo cases
The package ships with three synthetic SAR cases for testing and demos:
from sar.synthetic import (
generate_structuring_case,
generate_layering_case,
generate_dormant_account_case,
)
case = generate_structuring_case()
print(case["transactions"])
All synthetic data — no real individuals, accounts, or institutions.
Works great with aml-analytics
sar-narrative-gen is designed to work alongside aml-analytics. Detect suspicious patterns with aml-analytics, then feed the flagged output directly into this generator:
from aml.graph import build_network, detect_structuring
from aml.synthetic import generate_transactions
from sar import generate_sar_narrative
# Detect with aml-analytics
txns = generate_transactions(n=1000)
G = build_network(txns)
flagged = detect_structuring(G, threshold=9000)
# Draft the SAR
result = generate_sar_narrative(
transactions=flagged,
subject_info={"name": "Subject LLC", "account_number": "CHK-001"},
typology="structuring",
)
print(result["narrative"])
Disclaimer
This toolkit is for educational and research purposes only. Generated narratives are AI-drafted first drafts and must be reviewed, verified, and approved by a qualified BSA/AML compliance officer before filing. It does not constitute legal or compliance advice. All demo data is entirely synthetic.
Citation
@software{sar_narrative_gen,
author = {Bhavesh Awalkar},
title = {sar-narrative-gen: AI-powered SAR narrative generator for AML compliance},
year = {2024},
url = {https://github.com/Bhavesh0205/sar-narrative-gen},
license = {MIT}
}
License
MIT — see LICENSE for details.
Metadata
Release files for sar-narrative-gen 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| sar_narrative_gen-0.1.0.tar.gz | 12.2 kB | Without provenance | Details for sar_narrative_gen-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| sar_narrative_gen-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for sar_narrative_gen-0.1.0-py3-none-any.whl |
Total release size: 21.9 kB
Release files / sar_narrative_gen-0.1.0.tar.gz
| Download URL | sar_narrative_gen-0.1.0.tar.gz |
|---|---|
| Size | 12.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b483719796fa34abb7c78767e1f1d46542fbf8b62d82dea6537ee495a10d0a4
|
|
BLAKE2b-256 checksum How to use checksums |
6439873a5240b823f4b9ae1a68b783b0721738361c273f67c1d0c7e53a734e21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.8.2
|
Release files / sar_narrative_gen-0.1.0-py3-none-any.whl
| Download URL | sar_narrative_gen-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5821b0804c97c19d366b70c634d36c62d43fa3c45982e3e158876c45e7807512
|
|
BLAKE2b-256 checksum How to use checksums |
d150ab1715cbed4ab270093d9c31e8e0f949be3d369ab1d21f7cbbae80ce9de6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.8.2
|
Security for sar-narrative-gen 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.