개인정보 마스킹
SensitiveInfoMask는 SDK가 소유하는 deterministic 개인정보 detector와
마스킹 전략입니다. Registry rule ID·이름·pattern을 개인정보 종류로 추측하지
않으므로 Registry 없이 단독으로 쓸 수 있고, Registry regex가 놓친 값도
설정한 kind에 해당하면 마스킹합니다.
Registry 없이 사용
섹션 제목: “Registry 없이 사용”GuardrailConfig에서 id를 생략하고 sensitive_info만 선언합니다.
이 경로는 Registry 조회와 prompt judge LLM 호출을 하지 않습니다.
from llamon_agent import GuardrailConfig, SensitiveInfoMaskfrom llamon_agent.agent import Agent
AGENT = Agent( model="qwen3", provider="ollama", output_guardrail=GuardrailConfig( mask_replacement="[REDACTED]", sensitive_info=[ SensitiveInfoMask( kind="kr_rrn", strategy="front7_v1", ), SensitiveInfoMask( kind="email", strategy="domain_v1", ), ], ),)id와 sensitive_info를 모두 생략한 빈 GuardrailConfig는 거부됩니다.
Registry 없는 설정에는 의미가 없는 regex_action, prompt_action,
judge_llm도 설정 오류로 처리됩니다. SensitiveInfoMask 자체가 항상
마스킹 정책이므로 별도의 action="mask"는 없습니다.
Registry 정책과 함께 사용
섹션 제목: “Registry 정책과 함께 사용”기존 Registry 가드레일에 SDK 개인정보 안전망을 추가할 수 있습니다.
GuardrailConfig( id="output-guardrail", regex_action="mask", prompt_action="block", mask_replacement="[REDACTED]", sensitive_info=[ SensitiveInfoMask( kind="kr_rrn", strategy="front7_v1", ), ],)처리 우선순위는 다음과 같습니다.
- Registry가
block으로 판정하면 전체 응답을 차단합니다. - SDK
sensitive_info가 탐지한 값에는 kind별 strategy를 적용합니다. - 겹치지 않는 Registry regex match는 기존
mask_replacement로 치환합니다.
따라서 Registry regex가 주민등록번호를 탐지하지 못해도 SDK detector가
탐지하면 9001011234567은 900101-1******로 나갑니다. Registry regex도
같은 값을 mask로 탐지했다면 SDK의 더 구체적인 strategy가 우선합니다.
반대로 해당 Registry rule이 block이면 마스킹 결과를 반환하지 않습니다.
id가 있는 설정에서 Registry 조회·판정이 실패하면 SDK 마스킹만 하고
통과시키지 않고 기존 정책대로 fail-closed 처리합니다.
kind별 strategy
섹션 제목: “kind별 strategy”strategy를 생략하면 모든 kind에서 가장 보수적인 full_v1을 사용합니다.
full_v1의 결과 토큰은 GuardrailConfig.mask_replacement입니다. 부분
마스킹 전략은 출력 형태가 이름에서 드러나며, 같은 버전 이름의 의미는
SDK 업데이트에서 바꾸지 않습니다.
kind | strategy | 입력 예시 | 출력 예시 |
|---|---|---|---|
kr_rrn | full_v1 | 900101-1234567 | [REDACTED] |
kr_rrn | front6_v1 | 9001011234567 | 900101-******* |
kr_rrn | front7_v1 | 9001011234567 | 900101-1****** |
kr_foreigner_id | full_v1 | 900101-5123456 | [REDACTED] |
kr_foreigner_id | front6_v1 | 9001015123456 | 900101-******* |
kr_foreigner_id | front7_v1 | 9001015123456 | 900101-5****** |
email | full_v1 | user@example.com | [REDACTED] |
email | domain_v1 | user@example.com | ***@example.com |
email | local_first_v1 | user@example.com | u***@example.com |
kr_phone | full_v1 | 010-1234-5678 | [REDACTED] |
kr_phone | middle_v1 | 01012345678 | 010-****-5678 |
payment_card | full_v1 | 1234-5678-9012-3456 | [REDACTED] |
payment_card | last4_v1 | 1234567890123456 | ****-****-****-3456 |
kind에 없는 strategy를 조합하거나 같은 kind를 두 번 선언하면
GuardrailConfig 생성 시점에 오류가 납니다. 예를 들어
SensitiveInfoMask(kind="email", strategy="front7_v1")은 실행까지
미뤄지지 않습니다.
부분 마스킹은 일부 정보를 의도적으로 공개합니다. 업무상 표시 필요가
확실하지 않으면 기본 full_v1을 유지하세요.
TextPart와 DataPart
섹션 제목: “TextPart와 DataPart”기본 inspect_parts={"text", "data", "file"}에서는 다음 위치에 같은
strategy가 적용됩니다.
- 사용자 표시 text와 artifact text
- DataPart의 중첩 dict·list 안 모든 문자열 값
- artifact/task metadata 문자열
- FilePart의 이름·URI·MIME 등 metadata
숫자·boolean·null과 JSON의 키 및 전체 구조는 유지합니다. FilePart의
bytes_b64 본문은 검사하거나 바꾸지 않습니다. inspect_parts를 좁히면
제외한 채널은 탐지도 마스킹도 하지 않습니다.
탐지는 되었지만 난독화·인코딩 때문에 원문 위치에 동일한 변환을 안전하게 적용할 수 없거나, 마스킹 후 detector가 다시 매치하면 응답을 내보내지 않고 fail-closed 차단합니다.
제공 범위
섹션 제목: “제공 범위”현재 built-in은 형식 기반으로 일관되게 탐지할 수 있는 주민등록번호,
외국인등록번호, 이메일, 한국 전화번호, 16자리 결제카드번호를 제공합니다.
이름·주소처럼 문맥에 따라 달라지는 정보는 deterministic detector가
안정적으로 span을 확정할 수 없으므로 포함하지 않습니다. 이런 의미 기반
정책은 Registry prompt의 block을 사용하세요.