은행 업무의 구조 · 리스크와 규제 · 실습
AML 룰 엔진 만들기
목표
의심 거래 탐지 규칙 다섯 개를 SQL 과 파이썬으로 구현해 고객별 경보 점수를 내고, 가장 점수가 높은 고객의 의심거래보고 초안을 사실만으로 작성합니다.
왜 중요한가
자금세탁방지(AML)는 은행 IT 가 가장 자주 만나는 규제 업무입니다. 법은 은행에 두 가지 보고 의무를 지웁니다. 하루에 일정 금액 이상의 현금이 오가면 그 자체로 보고하는 고액현금거래보고(CTR), 그리고 금액과 무관하게 자금세탁이 의심되면 보고하는 의심거래보고(STR)입니다. CTR 은 기계적이고, STR 은 판단입니다. 그 판단을 돕는 것이 룰 엔진입니다.
룰 엔진은 화려한 모델이 아닙니다. "하루 현금 합계가 기준을 넘는가", "기준 바로 아래 금액으로 여러 번 쪼갰는가", "고위험 국가와 거래했는가", "고객 확인이 오래됐는가", "오래 쉬던 계좌가 갑자기 큰돈을 움직이는가" 같은 규칙의 묶음입니다. 규칙 하나는 오탐이 많지만, 한 사람에게 여러 규칙이 겹치면 신호가 됩니다. 그래서 규칙마다 가중치를 두고 합산합니다.
이 일에는 두 가지 제약이 따라옵니다. 보고서에는 사실만 적습니다 — 거래 번호, 금액, 날짜, 걸린 규칙. "수상하다" 는 결론이 아니라 근거입니다. 그리고 보고했다는 사실을 고객에게 알리지 않습니다. 이것은 법이 정한 비밀유지 의무이고, 시스템은 그 사실이 채널 화면이나 고객 알림으로 새지 않게 설계돼야 합니다.
이 실습의 규칙 (기준일 2026-08-31)
- R1 고액현금: 같은 고객이 같은 날 같은 방향(입금
CASH_DEP또는 출금CASH_WDR)으로 움직인 현금 합계가 10,000,000원 이상. 가중치 1. - R2 분할 의심: 한 고객의 현금 거래 중 8,000,000원 이상 10,000,000원 미만인 건이 3건 이상. 가중치 3.
- R3 고위험국:
cp_country가high_risk_country표에 있는 이체. 가중치 2. - R4 고객확인 경과:
risk_grade가HIGH이거나pep가 1 인데kyc_date로부터 365일 이상 지남. 가중치 1. - R5 휴면 후 활동: 8월 첫 거래일이
last_activity로부터 180일 이상 지났고, 그 첫 거래 금액이 5,000,000원 이상. 가중치 2. - 점수 = 걸린 규칙의 가중치 합. 규칙 이름은
R1+R3처럼 번호순으로+로 잇습니다.
단계
1. 오른쪽 예시의 생성기를 /root/bank/make_aml.py 로 저장하고 python3 make_aml.py 로 실행하세요. aml.db 에 고객 20명, 거래 108건, 고위험국 3개가 들어갑니다.
2. R1 결과를 /root/bank/ctr.csv 에 cust_id,biz_date,direction,cash_total 머리글로 적으세요. direction 은 DEP 또는 WDR 입니다.
3. R2 결과를 /root/bank/structuring.csv 에 cust_id,txn_count,cash_total,first_date,last_date 머리글로 적으세요.
4. R3 결과를 /root/bank/highrisk.csv 에 txn_id,cust_id,type,cp_country,amount 머리글로 적으세요.
5. R4 결과를 /root/bank/kyc_due.csv 에 cust_id,risk_grade,pep,kyc_date,days_since 머리글로, R5 결과를 /root/bank/dormant.csv 에 cust_id,last_activity,first_txn_date,dormant_days,amount 머리글로 적으세요.
6. 규칙에 하나라도 걸린 고객을 /root/bank/alerts.csv 에 cust_id,rules,score 머리글로, 점수 내림차순(같으면 cust_id 오름차순)으로 적으세요.
7. 점수가 가장 높은 고객의 보고 초안을 /root/bank/str_<cust_id>.json 에 쓰세요. 키는 cust_id, rules(목록), score, txn_ids(그 고객이 규칙에 걸린 거래 번호 목록), total_amount(그 거래들의 금액 합), narrative(100자 이상, 사실만), prepared_by(사람 이름이 아니라 역할), customer_notified(반드시 false) 입니다.
8. /root/bank/aml_report.md 에 ## 탐지 규칙과 결과, ## 보고 대상, ## 오탐과 한계, ## 비밀유지와 개인정보 네 절로 보고서를 쓰세요.
참고
substr(ts, 1, 10)으로 날짜만 떼면 일 단위 집계가 됩니다.julianday('2026-08-31') - julianday(kyc_date)가 경과 일수입니다.- 규칙마다 SQL 한 개면 충분합니다. 6단계는 다섯 결과를 합치는 일이라 파이썬이 편합니다.
- 흔한 실수 1: R1 에서 입금과 출금을 합쳐 세는 것. 방향별로 따로 셉니다.
- 흔한 실수 2: R5 의 첫 거래를 8월 전체 최대 금액으로 잡는 것. 8월의 첫 거래입니다.
- 흔한 실수 3: 보고서에 고객 실명이나 계좌번호를 적는 것.
name_masked조차 필요 없습니다 — 고객 번호로 충분합니다.
단계 8개
- 고객·거래 데이터 만들기
- R1 고액현금 — 하루 합계로 세기
- R2 분할 의심 — 기준 바로 아래를 세기
- R3 고위험국 — 목록과 대조하기
- R4·R5 — 고객확인 경과와 휴면 후 활동
- 규칙을 합쳐 경보 점수 내기
- 의심거래보고 초안을 사실만으로 쓰기
- AML 점검 보고서 쓰기