#RAG#로컬 LLM#프라이버시#자동화#Ollama

로컬 LLM 게이팅 — RAG 보안의 진짜 리스크는 나가는 개인정보다

👁 0 조회
로컬 LLM 게이팅 — RAG 보안의 진짜 리스크는 나가는 개인정보다 핵심 개념을 담은 커버 이미지
로컬 LLM 게이팅 — RAG 보안의 진짜 리스크는 나가는 개인정보다 핵심 개념을 담은 커버 이미지

지난 4월, 내부 문서 검색 RAG 시스템을 배포하기 직전에 클라우드 API 로그를 점검하다가 식은땀이 났습니다. 프롬프트에 고객 전화번호와 이메일 주소가 그대로 실려 외부 서버로 올라가고 있었거든요. RAG 보안을 검색 정확도와 환각 방지 중심으로만 생각했는데, 실무에서 진짜 무서운 건 프롬프트에 실려 외부로 나가는 개인정보예요. Ollama로 띄운 로컬 모델을 앞단 스크리너로 두면 이 리스크를 크게 줄일 수 있습니다.

클라우드 LLM에 고객 정보가 그대로 올라가던 순간

제가 구축한 RAG 시스템은 내부 고객 문의 이력을 검색해서 답변하는 구조였어요. 벡터 DB에서 관련 문서를 가져오고, 그 내용을 클라우드 LLM 프롬프트에 넣어 답변을 생성했죠. 문제는 검색된 문서 안에 고객명·연락처·이메일 주소 같은 원본 텍스트가 그대로 포함된다는 거였습니다. GDPR이나 개인정보보호법 관점에서 보면, 이건 명백한 외부 전송이에요.

초기 테스트 2주 동안 약 340건의 프롬프트 중 87건에서 이메일 주소가, 52건에서 전화번호가 감지됐어요. 정규표현식으로 간단히 잡을 수 있는 패턴인데도 RAG 파이프라인 설계 단계에서 전혀 고려하지 않았던 겁니다. Ollama 공식 저장소 문서를 보니 Mistral 7B 같은 소형 모델도 CPU 추론이 가능했고, 16GB 램 환경에서 충분히 돌아갔습니다. 민감정보 감지만 하는 단순 태스크라면 로컬 모델로도 충분하겠다는 확신이 들었어요.

로컬 게이팅을 실제로 구성하고 본 것들

로컬 게이팅을 실제로 구성하고 본 것들
로컬 게이팅을 실제로 구성하고 본 것들

제가 도입한 구조는 간단합니다. RAG 파이프라인에서 벡터 검색 결과를 받으면, 먼저 Ollama로 띄운 Mistral 7B 모델에 보내요. 이 로컬 모델은 "이 텍스트에서 개인정보를 찾아 마스킹하라"는 시스템 프롬프트만 받습니다. 출력은 [EMAIL], [PHONE] 같은 플레이스홀더로 대체된 텍스트죠. 그 결과를 클라우드 LLM에 보내고, 최종 답변을 받은 뒤 플레이스홀더를 원본 값으로 복원해요.

Ollama 기준으로 Mistral 7B 모델 파일은 4.1GB고, CPU 추론 속도는 제 환경(AMD Ryzen 7 5800H, 32GB RAM)에서 초당 약 12토큰이었어요. 민감정보 스크리닝은 입력 200~300토큰, 출력 250토큰 정도라 응답이 20초 안에 나왔습니다. 클라우드 API 호출 전 단계라 전체 응답 시간에 미치는 영향은 생각보다 적었고요.

정규표현식과 로컬 모델을 조합한 덕분에 리콜도 높았어요. 이메일·전화번호·주민번호 같은 고정 패턴은 정규식으로 먼저 잡고, "계약 금액 3,500만원", "프로젝트 코드네임 오리온" 같은 문맥상 민감한 정보는 로컬 모델이 감지했습니다. 도입 후 3주간 클라우드 API 로그를 매일 샘플링했는데, 개인정보 노출 건수는 제로였어요.

로컬 모델 게이팅이 부담스럽다는 반론에 답하기

로컬 모델 게이팅이 부담스럽다는 반론에 답하기
로컬 모델 게이팅이 부담스럽다는 반론에 답하기

첫 번째 반론은 인프라 비용과 운영 부담입니다. "로컬 모델 띄우려면 GPU 서버 새로 사야 하는 거 아니냐"는 질문을 많이 받아요. 제 경험상 그렇지 않습니다. Ollama는 CPU 추론을 지원하고, 민감정보 마스킹만 하는 단순 태스크는 7B 모델로도 충분해요. 제가 쓴 AWS EC2 t3.xlarge 인스턴스는 월 120달러 정도였는데, 클라우드 LLM 토큰 비용 절감분이 월 200달러를 넘었습니다. 민감정보가 포함된 긴 프롬프트를 보내지 않으니 토큰 소비가 줄어든 거죠.

두 번째는 오탐 리스크입니다. 로컬 모델이 민감정보를 못 걸러내면 오히려 더 위험하다는 우려죠. 맞는 말이에요. 하지만 정규식과 모델을 이중으로 쓰면 리콜을 높일 수 있습니다. Mistral AI 공식 문서를 보면 7B 모델도 분류 태스크에선 90% 이상 정확도를 보여요. 제 경우엔 이메일·전화번호 패턴은 정규식이 100% 잡았고, 문맥상 민감한 정보는 로컬 모델이 보완했습니다. 로컬 게이팅 후 클라우드 API 로그를 주기적으로 샘플링해서 모니터링하면 누락 리스크도 관리할 수 있어요.

세 번째는 검색 품질 저하입니다. 마스킹된 정보로 RAG 정확도가 떨어지지 않겠냐는 거예요. 실제론 거의 영향이 없었습니다. 플레이스홀더는 [EMAIL], [PHONE] 같은 명확한 태그로 대체하고, 클라우드 LLM이 답변을 생성한 뒤 원본 값으로 복원했어요. 검색된 문서의 의미는 그대로 유지되니까, 답변 품질은 동일했습니다.

로컬 게이팅을 직접 시도해보세요

팀원들도 이 구조를 도입한 뒤 고객 정보 유출 우려가 줄었다는 피드백을 줬어요. 특히 GDPR 컴플라이언스 담당자가 "외부 전송 리스크를 기술로 해결했다"며 긍정적으로 평가했죠. Ollama와 Mistral 7B로 간단한 민감정보 필터링 프로토타입을 만들어보세요. 기존 RAG 파이프라인 앞에 끼워 넣는 구조라 기존 코드를 크게 바꿀 필요도 없습니다. 환각 방지보다 민감정보 보호가 먼저라는 걸, 실무에서 배웠습니다.

자주 묻는 질문

Q. 기존 RAG 파이프라인에 어떤 순서로 붙이나요? A. 벡터 검색 → 로컬 모델 마스킹 → 클라우드 LLM 호출 → 복원 순서예요. 코드 변경은 벡터 검색 결과를 클라우드로 바로 보내던 부분에 로컬 모델 호출 한 줄만 추가하면 됩니다.

Q. 로컬 모델 크기는 얼마부터 쓸 만한가요? A. 제 경험상 7B 모델이면 충분해요. 민감정보 패턴 감지는 단순 분류 태스크라 파라미터 수보다 정규식 조합이 더 중요했습니다. 3B 모델도 테스트해볼 만해요.

Q. 마스킹 이력을 감사 로그로 남기려면 어떻게 하나요? A. 로컬 모델 출력을 클라우드 LLM에 보내기 전에 로그 파일에 기록하세요. 원본과 마스킹 결과를 쌍으로 저장하면, 나중에 누락이나 오탐을 검토할 수 있습니다.

이 글이 도움이 됐다면 공유해 주세요
X 공유

관련 글