한국형 개인정보 필터

# 한국형 개인정보 필터 API **Korean Privacy Filter** — 한국어 텍스트에서 개인정보(PII)를 정확하게 탐지·마스킹하는 AI 모델이에요. 개인정보보호법 §24-2 고유식별정보 9 종을 포함한 17 카테고리를 다뤄요. - **모델 ID**: `pii` - **라이브 버전**: `pii-2026.05` - **정확도**: 자체 2,000건 분류까지 일치 정확도 99.99% + 외부 평가 묶음 14,195건 분류까지 일치 정확도 99.99% (동음이의어 함정 3,682건 + 공인 본명 1,222건 모두 오탐 0건) ## 핵심 기능 - 주민등록번호·전화번호·이메일·주소·계좌번호 등 개인정보 자동 탐지 - 문맥 기반 PII 인식 (단순 패턴이 아닌 의미 이해 기반) - 실시간 마스킹 / 치환 / 삭제 처리 - API 기반 입력·출력 양방향 필터링 - 로그·감사 추적 지원 (compliance 대응) ## 특징 - 한국어 특화 (이름 + 맥락 기반 식별 강점) - 정규식 + 한국어 특화 작은 AI 모델 결합 구조로 높은 정확도 - 개인정보보호법 등 국내 규제 대응 최적화 - 빠른 응답 시간으로 실시간 서비스 적용 가능 - 다양한 포맷 (텍스트·문서·채팅) 대응 ## 1. 빠른 호출 ```bash curl -X POST https://api.corepin.ai/v1/pii/redact \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "안녕하세요, 김민수입니다. 010-1234-5678로 연락주세요. 주민번호 900101-1234567.", "output_mode": "redacted" }' ``` 응답: ```json { "text": "안녕하세요, 김민수입니다. 010-1234-5678로 연락주세요. 주민번호 900101-1234567.", "detected_spans": [ {"label": "private_person", "start": 7, "end": 10, "text": "김민수", "placeholder": "<PRIVATE_PERSON>"}, {"label": "private_phone", "start": 16, "end": 29, "text": "010-1234-5678", "placeholder": "<PRIVATE_PHONE>"}, {"label": "kr_rrn", "start": 41, "end": 55, "text": "900101-1234567", "placeholder": "<KR_RRN>"} ], "span_count": 3, "by_label": {"private_person": 1, "private_phone": 1, "kr_rrn": 1}, "redacted_text": "안녕하세요, <PRIVATE_PERSON>입니다. <PRIVATE_PHONE>로 연락주세요. 주민번호 <KR_RRN>.", "meta": { "model_id": "pii", "model_version": "pii-2026.05", "processing_time_ms": 38.7, "request_id": "4c74bd30c53e497ca8a71f05aead6012", "quota_remaining": 99998 } } ``` ## 2. 엔드포인트 | Method | Path | 인증 | 설명 | |---|---|:-:|---| | GET | `/v1/pii/version` | – | 모델 버전·릴리스 노트 | | GET | `/v1/pii/categories` | – | 17 카테고리 카탈로그 (한글 설명 포함) | | POST | `/v1/pii/detect` | ✓ | 탐지 only — spans 배열 반환 | | POST | `/v1/pii/redact` | ✓ | 탐지 + 마스킹된 텍스트 | | POST | `/v1/pii/batch` | ✓ | 1 - 100 텍스트 일괄 처리 | | GET | `/v1/pii/history` | ✓ | 본문 미저장 검출 이력 (라벨 카운트만) | | GET | `/v1/pii/audit` | ✓ | 본문 저장 감사 로그 (audit 모드 활성화 후의 요청만) | 레거시 alias `/v1/{detect,redact,batch}` 도 그대로 작동해요. 새 통합은 `/v1/pii/*` 사용을 권해요. ### 2.1 POST `/v1/pii/detect` **Request**: ```json { "text": "탐지할 텍스트 (1 ~ 32,768자)", "categories": ["kr_rrn", "private_phone"], "return_text": true, "apply_policy": false } ``` `categories` (선택) — 화이트리스트. 지정하지 않으면 17개 모두 탐지. `return_text` (기본 true) — false 면 응답에서 `text` 필드 생략. `apply_policy` (기본 false) — true 시 조직·테넌트의 PII 카테고리 토글 정책을 적용해서 차단(keep=false)된 카테고리의 spans만 응답에서 제외해요. 응답 `meta.policy_applied=true` 와 `meta.filtered_out` (제외된 span 수) 가 함께 와요. 정책 우선순위는 [tenants 문서 §3](/docs/tenants#3-정책-resolve-순서-호출-시점) 참조. ### 2.2 POST `/v1/pii/redact` `/v1/pii/detect` 의 모든 필드 (`apply_policy` 포함) + ```json { "output_mode": "redacted", "placeholder_template": "[{label}]" } ``` `output_mode`: - `redacted` — `placeholder_template` 적용 (기본 `<KR_RRN>` 등) - `partial_mask` — span 마지막 4자 외 `*` (예: `**********4567`) - `typed` — 마스킹 없이 spans만 반환 `placeholder_template` 변수: `{label}`, `{start}`, `{end}`, `{original}`. positional `{0}` 사용 시 422. ### 2.3 POST `/v1/pii/batch` ```json { "texts": ["...", "...", "..."], "categories": [...], "output_mode": "redacted", "placeholder_template": null, "return_text": true, "apply_policy": false } ``` 각 항목당 quota 1 unit 차감. `apply_policy=true` 시 배치 전체에 동일 정책 적용 (호출당 1회 정책 resolve, 항목별 fan-out). 배치 N 개는 RPM·월 한도 모두 N 건으로 차감돼요. ### 2.4 GET `/v1/pii/history` 본문 미저장 검출 이력. 본문이나 span text는 절대 포함되지 않아요 — 라벨 카운트와 길이만 반환해요. ```bash curl "https://api.corepin.ai/v1/pii/history?limit=50" \ -H "Authorization: Bearer $COREPIN_API_KEY" ``` 응답 필드: `ts`, `request_id`, `text_length`, `summary.by_label`, `summary.span_count`. `from_ts` / `to_ts` (unix epoch sec) · `limit` (1 - 500) · `offset` 으로 페이지네이션. ### 2.5 GET `/v1/pii/audit` 본문 저장 감사 로그. **대시보드 → 설정** 에서 PII 감사 모드를 `metadata` 또는 `full` 로 켠 이후의 요청만 적재돼요. `level=full` 인 경우에만 `input_text` 가 채워지고, `metadata` 모드는 길이·라벨만 저장돼요. ```bash curl "https://api.corepin.ai/v1/pii/audit?limit=50" \ -H "Authorization: Bearer $COREPIN_API_KEY" ``` 쿼리 파라미터: `from_ts`, `to_ts` (unix epoch sec) · `blocked_only` (true/false) · `limit` (1 - 500, 기본 50) · `offset`. 응답 필드: ```ts { items: [ { ts: number, // unix epoch sec request_id: string, key_id: string, input_text: string | null, // level='full' 일 때만 본문 output: object, // 모델 응답 그대로 blocked: boolean, level: "metadata" | "full", input_length: number, } ], count: number, total: number, limit: number, offset: number, model_id: "pii", note: string } ``` ## 3. 17 카테고리 | 라벨 | 한글명 | 개인정보보호법 고유식별 | |---|---|:-:| | `private_person` | 이름 | | | `private_address` | 주소 | | | `private_email` | 이메일 | | | `private_phone` | 전화번호 | | | `private_url` | URL | | | `private_date` | 날짜 (생년월일 등) | | | `account_number` | 계좌·카드번호 | | | `secret` | API 키·토큰·비밀번호 | | | `kr_rrn` | 주민등록번호 | ✓ | | `kr_foreigner_id` | 외국인등록번호 | ✓ | | `kr_passport` | 여권번호 | ✓ | | `kr_driver_license` | 운전면허번호 | ✓ | | `kr_biz_no` | 사업자등록번호 | | | `kr_corp_no` | 법인등록번호 | | | `kr_health_insurance` | 건강보험증번호 | ✓ | | `kr_vehicle_plate` | 차량번호 | | | `private_ip` | IP 주소 | | 각 카테고리의 한글 설명은 `GET /v1/pii/categories` 에서 받아볼 수 있어요. ## 4. 응답 스키마 ```ts { text: string | null, detected_spans: { label: string, // 17 카테고리 중 하나 start: number, // Python str index (UTF-16 unit 아님) end: number, // exclusive text: string, // 원문 substring placeholder: string // 권장 마스킹 토큰 }[], span_count: number, by_label: { [label: string]: number }, redacted_text: string | null, meta: { model_id: "pii", model_version: "pii-2026.05", processing_time_ms: number, request_id: string, quota_remaining: number | null, policy_applied: boolean, // apply_policy=true 호출 시 true filtered_out: number // 정책에 의해 제외된 span 수 (apply_policy=true 일 때만 ≥0) } } ``` ## 5. 개인정보 처리 안내 - 본 서비스는 입력 텍스트와 탐지 spans의 텍스트를 저장하지 않아요. 메트릭·로그·검출 이력에는 길이·라벨 카운트만 남아요. - `pipa_sensitive: true` 카테고리(주민·외국인·여권·운전면허·건강보험증)는 개인정보보호법 §24-2 고유식별정보예요. 마스킹 후에도 별도 처리·암호화 의무가 발생할 수 있어요. - 본 API는 **탐지기**예요. `redacted_text` 는 참고용이며 재식별 가능성이 있어요. ## 6. 변경 이력 - **pii-2026.05** (2026-04-25 학습, 2026-05 출시) — 외부 일반화 완성. 한국 개인정보 마스킹 공개 평가 셋 통합 (총 22.3만 문장, 5 회차에 걸친 학습). 자체 분류 일치 정확도 99.99% 그대로 + 외부 14,195 평가 묶음 분류 일치 정확도 99.99%. 동음이의어 함정 3,682건·공인 본명 1,222건 오탐 0건. - **v8-20260425** — 한국 공개 학습 비중 확대 (V7 잔여 케이스 보완). - **v7-20260425** — 한국 개인정보 마스킹 공개 평가 셋 1차 통합. 외부 14,195 평가 묶음에서 78.6 → 99.2 도약. - **v6-20260423** — 자체 시험지 정확도 마무리. 17 카테고리, 분류 일치 정확도 99.99% (2,000건 자체 평가 묶음). ## 6.5 단가 - 무료: 60회/분 · 1,000회/월 · 카드 등록 불필요 - 유료: **₩15/호출** (배치 호출은 텍스트 개수만큼 차감) - 연간 대량 계약 할인 가능 — <support@corepin.ai> - 전체 요금 비교는 [`/pricing`](/pricing) 또는 [`/docs/billing`](/docs/billing) ## 7. SDK / 코드 예제 ### Python ```python from kpf_client import KPFClient client = KPFClient(api_key="sk_live_…") result = client.redact("홍길동 010-1234-5678") print(result.redacted_text) # "<PRIVATE_PERSON> <PRIVATE_PHONE>" ``` ### JavaScript / TypeScript ```ts const r = await fetch(`${BASE}/v1/pii/redact`, { method: "POST", headers: { "Authorization": `Bearer ${process.env.COREPIN_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ text, output_mode: "redacted" }), }); if (!r.ok) throw new Error((await r.json()).error.message); const { redacted_text, detected_spans } = await r.json(); ``` ### Go ```go body, _ := json.Marshal(map[string]any{"text": text, "output_mode": "redacted"}) req, _ := http.NewRequest("POST", base+"/v1/pii/redact", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+os.Getenv("COREPIN_API_KEY")) req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) ```