원시 PII 전송 없이 LLM 컨텍스트 인식 벤치마킹
Source: Dev.to
TL;DR: 나는 원시 식별자가 프롬프트에 절대 들어가지 않을 때 LLM이 관계와 맥락을 여전히 이해할 수 있는지를 측정했다. 결과는 – 단순한 삭제는 잘 작동하지 않지만, 약간의 조정을 하면 전체 컨텍스트에 거의 근접한다!
나는 세 가지 접근 방식을 비교했다
- Full Context (baseline) → 전체 컨텍스트 (베이스라인)
- Standard Redaction (everything becomes
) → **표준 삭제** (모든 것이로 변환) - Semantic Masking (my own simple package built on top of spaCy that generates context‑aware placeholders with IDs to keep relations, e.g.
{Person_A}) → 시맨틱 마스킹 (내가 spaCy 위에 만든 간단한 패키지로, 관계를 유지하기 위해 ID가 포함된 컨텍스트 인식 플레이스홀더를 생성, 예:{Person_A})
결과는 놀라웠다: 관계 추론을 위한 스트레스 테스트에서 표준 삭제는 27 % 정확도로 급락했다. 시맨틱 마스킹은 91 % 정확도를 달성했으며, 직접 식별자를 로컬에 유지하면서 거의 완벽하게 마스크되지 않은 베이스라인과 일치했다!
Scope note: This is not anonymisation. The goal is narrower but practical: keep direct identifiers (names, emails, IDs) local, while giving the model enough structure to reason intelligently.
범위 주석: 이것은 익명화가 아니다. 목표는 더 좁지만 실용적이다: 직접 식별자(이름, 이메일, ID)를 로컬에 유지하면서 모델에게 충분한 구조를 제공해 지능적으로 추론할 수 있게 하는 것이다.
모든 소스 코드는 끝에 링크되어 있다.
왜 이것이 중요한가 (단순 RAG를 넘어)
사람들은 AI 인터페이스 사용을 좋아하지만, LLM은 범용 엔진일 뿐, 보안 금고가 아니라는 점을 종종 잊습니다. 챗봇, 에이전트, 혹은 RAG 파이프라인을 구축하든, 원시 데이터를 그대로 전달하는 것은 다음과 같은 위험을 내포합니다:
- 프롬프트 로깅 및 추적
- 벡터‑DB 저장(원시 PII 임베딩)
- 디버깅 스크린샷
- 외부 제공자에 대한 “폴백” 호출
EU에 거주하는 개발자로서, 나는 마스크‑우선 접근법을 탐구하고 싶었습니다: 데이터를 로컬에서 변환하고, 마스크된 텍스트로 프롬프트를 수행하며, (선택적으로) 응답을 로컬에서 다시 복원하는 방식입니다.
문제: 컨텍스트 붕괴
표준 마스킹(삭제)의 문제는 도구가 나쁘기 때문이 아니라, 모델이 누가 무엇을 하는지 이해하는 데 필요한 정보를 파괴한다는 점이다.
“Anna & Emma” 시나리오
원본 텍스트: “Anna calls Emma.”
표준 마스킹 → calls .
- 문제: 모델은 누가 누구에게 전화를 걸었는지 구분할 방법이 전혀 없다. 추론이 붕괴된다.
시맨틱 마스킹 → {Person_A} calls {Person_B}.
- 이점: 모델은 A와 B가 서로 다른 사람임을 알고 관계를 보존한다. 답변이 돌아오면 (
{Person_A} initiated the call), 실제 이름을 로컬에서 다시 교체할 수 있다.
나는 측정하고 싶었다: 마스킹으로 인해 정확히 얼마나 많은 추론이 손실되는지, 그리고 시맨틱을 추가함으로써 이를 해결할 수 있는지.
벤치마크
이 가설을 테스트하기 위해 두 가지 실험을 수행했습니다.
| # | 벤치마크 | 설명 |
|---|---|---|
| 1 | “Who is Who” 스트레스 테스트 (N = 11) | 다양한 PII 제거 도구를 사용하여 LLM의 컨텍스트 인식을 테스트하도록 설계된 작은 합성 데이터셋입니다. 하나의 이야기에서 여러 사람이 상호작용하고 관계 추론(예: “누가 매니저인가?”)을 포함합니다. |
| 2 | RAG QA 벤치마크 | 검색 파이프라인 시뮬레이션: 1. 개인 문서를 가져옵니다. 2. 마스킹합니다. 3. 마스킹된 텍스트 만을 기반으로 LLM에 질문합니다. |
설정
- 모델:
gpt‑4o‑mini(temperature = 0) - 평가자: 별도의 평가 프롬프트에서 LLM 판사로 사용된
gpt‑4o‑mini(temperature = 0) - 측정항목: 관계 추출 질문에 대한 정확도
참고: Small‑N 벤치마크는 실패 모드를 드러내기 위한 것이며, 통계적 완벽성을 주장하는 것이 아닙니다. 논리를 위한 “바이브 체크”입니다.
접근 방식 비교
-
Full Context (Baseline) – 원시 텍스트 (높은 개인 정보 위험, 완전한 컨텍스트).
-
Standard Redaction – 엔터티를 일반 태그(“)로 교체.
-
Semantic Masking – 내 접근 방식으로, 세 가지를 다르게 수행합니다:
- Consistency: “Anna”는
{Person_hxg3}가 되며; 이후 모든 등장에서는 동일한 플레이스홀더를 사용합니다. - Entity Linking: “Anna Smith”와 “Anna”가 동일한 엔터티로 감지되어 동일한 플레이스홀더를 받습니다.
- Semantic Hints: 날짜는 단순히 “가 아니라
{Date_October_2000}이며, 정확한 날짜를 공개하지 않으면서도 타임라인 정보를 보존합니다.
- Consistency: “Anna”는
결과
벤치마크 1 – 코어퍼런스 스트레스 테스트 (N = 11)
| 전략 | 정확도 | 이유 |
|---|---|---|
| 전체 컨텍스트 | 90.9 % (10/11) | 기본값 (모델 환각으로 인한 한 번의 오류). |
| 표준 삭제 | 27.3 % (3/11) | 완전 붕괴 – 모두 “였기 때문에 모델이 무작위로 추측했습니다. |
| 시맨틱 마스킹 | 90.9 % (10/11) | 컨텍스트 복원 – 성능이 원시 데이터와 일치합니다. |
벤치마크 2 – RAG QA
| 전략 | 컨텍스트 유지 |
|---|---|
| 원본 (기본값) | 100 % |
| 표준 삭제 | ≈ 10 % |
| 시맨틱 마스킹 | 92–100 % |
핵심: 추론에 실제 이름이 필요하지 않습니다. 구조만 있으면 됩니다.
내가 배운 것
- Structure > Content: 대부분의 AI 작업에서 모델은 누구인지는 신경 쓰지 않고 관계 그래프 (예: Person A → boss of → Person B)에 신경을 씁니다.
- Entity Linking is Critical: 단순한 찾기‑바꾸기는 “Anna”와 “Anna Smith”를 구분하지 못합니다. 이들을 동일한 ID에 연결하는 로직이 필요하며, 그렇지 않으면 모델은 두 사람을 별개의 인물로 인식합니다.
- Privacy Enablement: 이는 (HR, 상세 고객 지원, 법무 등) 이전에 “데이터를 보낼 수 없으니 LLM을 사용할 수 없다”고 생각했던 사용 사례를 열어줍니다.
재현성 vs. 프라이버시
- In Production: Use ephemeral IDs (random per session). “Anna”는 오늘은
{Person_X}이고 내일은{Person_Y}이며, 세션 간 프로파일링을 방지합니다. - For Benchmarking: 실행을 비교 가능하게 만들기 위해 고정 시드를 사용했습니다.
리소스 및 코드
이것을 재현하거나 내 시맨틱 마스킹 접근 방식을 직접 스트레스 테스트하고 싶다면, 다음 라이브러리를 확인하세요:
# Clone the repo
git clone https://github.com/Privalyse/privalyse-research.git
cd privalyse-research
# Install dependencies
pip install -r requirements.txt
# Run the coreference stress test
python benchmarks/coreference_stress_test.py
# Run the RAG QA benchmark
python benchmarks/rag_qa.py
코어퍼런스 벤치마크 (context_research/01_coreference_benchmark.py)
# (your coreference benchmark code here)
RAG QA 벤치마크 (context_research/02_rag_qa_benchmark.py)
# (your RAG QA benchmark code here)
시맨틱 마스킹 라이브러리
pip install privalyse-mask
Limitations / Threat Model
To be fully transparent:
- ✅ Direct Identifiers are gone: Names, emails, phone numbers are masked locally.
- ❌ Re‑identification is possible: If the context (except PII) is unique enough (e.g., “The CEO of Apple in 2010”), the model might infer a real person.
- ❌ No Differential Privacy: This is a utility‑first approach, not a mathematical guarantee.
This approach is about minimizing data exposure while maximizing model intelligence, not about achieving perfect anonymity.
토론
프라이버시‑보호 AI에 대해 작업하고 계신 분들의 의견을 듣고 싶습니다:
- 마스킹 중에 entity linking을 처리하는 다른 도구가 있나요?
- “privacy‑preserving reasoning”을 위한 표준 데이터셋을 알고 계신가요?
- 그런 종류의 컨텍스트 인식을 위한 일반적인 벤치마크가 있나요? (긴 컨텍스트에 대한 것만 찾았습니다)
댓글로 이야기해 주세요! 👇