RAG 문서 최신화·삭제 설계: 원본을 지워도 답변에 남는 문제 막기
RAG 서비스에서 원본 문서의 변경과 삭제를 청크, 벡터 색인, 캐시, 평가 자료까지 전파하고 고아 문서와 오래된 답변을 시험하는 운영 방법을 정리했습니다.
핵심 요약
- 원본 저장소에서 파일을 지워도 벡터 색인과 답변 캐시에 청크가 남으면 검색 결과에 다시 나타날 수 있습니다.
- 문서마다 원본 ID, 버전, 해시, 수집 시각과 삭제 표식을 남겨야 변경·삭제 전파를 감사할 수 있습니다.
- 최신성 목표와 삭제 목표를 분리하고 원본·색인·캐시를 실제 검색으로 확인하는 tombstone 시험이 필요합니다.
사내 위키에서 오래된 가격표를 삭제했는데 챗봇은 다음 날에도 예전 금액을 답할 수 있습니다. 원본 파일은 사라졌지만 잘게 나눈 청크가 벡터 색인에 남았거나, 이전 답변이 캐시에서 재사용됐기 때문입니다.
RAG 파이프라인은 복사본을 많이 만듭니다. 원본, 파싱 결과, 청크, 임베딩, 검색 색인, 답변 캐시와 평가 자료가 서로 다른 저장소에 놓이죠. “문서를 삭제했다”는 말은 어느 계층에서 무엇이 사라졌는지 명시하지 않으면 검증할 수 없습니다.
데이터 수명주기 지도를 먼저 만든다
문서 하나가 답변이 되기까지 거치는 저장 위치를 그립니다.
원본 저장소
-> 수집 큐
-> 파싱·정제 결과
-> 청크와 메타데이터
-> 임베딩·검색 색인
-> 검색 결과 캐시
-> 최종 답변 캐시
-> 평가·디버그 표본
각 화살표에는 복사 주기, 실패 재시도, 소유자와 삭제 이벤트 전달 방식을 적습니다. 관리형 벡터 저장소만 보는 것으로는 답변 캐시와 분석용 내보내기를 놓치기 쉽습니다.
NIST 생성형 AI 프로필은 데이터 출처와 수정 이력을 문서화하고, 정정과 삭제 절차를 추적하도록 권고합니다. 모델 품질만이 아니라 데이터 계보와 사후 조치를 운영 대상으로 보는 접근입니다. NIST AI 600-1
문서 ID와 청크 ID를 분리한다
파일명이나 URL만 키로 쓰면 문서가 이동하거나 같은 이름으로 교체될 때 이전 청크와 구분하기 어렵습니다. 문서 계층과 청크 계층에 다음 메타데이터를 둡니다.
| 필드 | 역할 |
|---|---|
source_system | 위키, 드라이브, 객체 저장소 같은 원본 위치 |
source_document_id | 경로가 바뀌어도 유지되는 원본 고유 ID |
source_version | 원본 시스템의 수정 버전 또는 ETag |
content_hash | 같은 내용의 중복 수집과 변경 확인 |
chunk_id | 문서 버전 안의 청크 식별자 |
ingested_at | 해당 버전을 색인한 시각 |
valid_from, valid_to | 검색에서 유효한 업무 기간 |
deleted_at | 삭제 이벤트를 받은 시각 |
pipeline_version | 파서·청킹·임베딩 구성 버전 |
source_document_id + source_version + chunk_id 조합이면 새 버전을 넣은 뒤 예전 버전을 닫을 수 있습니다. 해시는 변경 탐지를 돕지만 문서의 업무상 정체성을 대신하지는 않습니다.
개인정보가 들어간 원본 ID를 그대로 로그와 색인에 복제하지 마세요. 내부 가명 키를 쓰고 원본 매핑은 더 좁은 권한의 저장소에서 관리합니다.
변경은 덮어쓰기보다 새 버전과 폐기로 처리한다
문서를 제자리에서 덮어쓰면 색인 작업 중 새 청크와 옛 청크가 섞일 수 있습니다. 안전한 변경 순서는 다음과 같습니다.
- 원본의 새 버전과 해시를 읽습니다.
- 별도 작업 ID로 파싱, 청킹과 임베딩을 완료합니다.
- 문서 단위 검증을 통과한 새 청크를 검색 가능 상태로 전환합니다.
- 이전 버전의
valid_to를 닫고 검색 필터에서 제외합니다. - 문서 ID와 연관된 검색·답변 캐시를 무효화합니다.
- 일정 유예 뒤 이전 청크와 임베딩을 물리적으로 정리합니다.
중간 실패 때는 새 버전을 노출하지 않거나 이전 버전을 유지해야 합니다. 청크 30개 중 18개만 갱신된 상태를 정상으로 표시하면 하나의 답변에 서로 다른 규정 버전이 섞일 수 있다.
삭제는 이벤트 하나가 아니라 상태 전이다
삭제 요청을 받자마자 원본을 물리적으로 지우면 색인에서 어떤 청크를 제거해야 하는지 찾지 못할 수 있습니다. 먼저 tombstone, 즉 삭제 표식을 남기고 검색에서 차단합니다.
{
"event_type": "document.deleted",
"source_system": "policy-wiki",
"source_document_id": "doc_7f19",
"source_version": "42",
"deleted_at": "2026-08-23T03:15:00Z",
"reason_class": "source_deleted",
"event_id": "evt_01J..."
}
삭제 소비자는 같은 이벤트를 여러 번 받아도 결과가 같아야 합니다. event_id와 문서 상태를 확인해 색인 삭제, 캐시 무효화와 감사 기록이 중복 실행돼도 망가지지 않게 만듭니다.
권장 삭제 순서
- 삭제 표식을 영속 저장하고 새 검색에서 즉시 제외합니다.
- 진행 중인 수집·재색인 작업을 취소하거나 삭제 상태를 다시 확인하게 합니다.
- 모든 청크와 임베딩을 문서 ID로 삭제합니다.
- 검색 결과와 최종 답변 캐시를 무효화합니다.
- 평가·디버그 표본과 내보내기에서 적용 대상을 찾습니다.
- 원본과 백업은 각 보존 정책에 맞춰 삭제합니다.
- 실제 검색 시험이 통과하면 완료 시각과 남은 예외를 기록합니다.
Azure AI Search의 Blob 인덱서 문서는 변경 탐지는 지원하지만 삭제 탐지는 자동이 아니라고 설명합니다. 네이티브 soft delete를 쓰려면 첫 인덱서 실행부터 정책을 구성하고, 원본이 물리적으로 사라지기 전에 검색 문서를 먼저 삭제해야 고아 문서를 피할 수 있습니다. Azure AI Search 변경·삭제 감지
이 제약은 Azure만의 체크리스트로 끝나지 않습니다. 어떤 관리형 파이프라인이든 “원본 삭제가 색인 삭제를 자동 보장하는가”를 제품 문서와 실제 시험으로 확인해야 한다.
최신성 목표와 삭제 목표를 분리한다
새 사내 공지가 10분 늦게 검색되는 문제와 삭제한 개인정보가 10분 더 노출되는 문제는 영향이 다릅니다. 하나의 “동기화 주기”로 관리하지 않습니다.
| 지표 | 계산 예시 | 운영 질문 |
|---|---|---|
| 수집 지연 | 검색 가능 시각 - 원본 수정 시각 | 새 문서가 언제 답변에 반영되는가 |
| 버전 일치율 | 최신 원본 버전과 같은 색인 문서 비율 | 색인이 어느 정도 뒤처졌는가 |
| 삭제 차단 지연 | 검색 제외 시각 - 삭제 접수 시각 | 사용자가 더 이상 찾지 못하는 시점은 언제인가 |
| 물리 삭제 지연 | 모든 저장소 삭제 시각 - 삭제 접수 시각 | 복사본이 실제로 정리되는 시점은 언제인가 |
| 고아 청크 수 | 존재하지 않는 원본 ID를 참조하는 청크 수 | 삭제 전파가 빠진 자료가 있는가 |
업무 영향에 따라 목표를 정합니다. 긴급 안전 공지와 일반 회의록의 최신성 목표가 같을 필요는 없습니다. 삭제도 검색 차단과 백업 만료를 구분해 사용자에게 약속할 범위를 명확히 해야 합니다.
캐시는 문서 단위 의존성을 알아야 한다
질문 문자열만 키로 답변을 캐시하면 문서가 바뀌어도 예전 답이 남습니다. 최소한 검색에 사용한 문서 ID와 버전을 캐시 메타데이터에 기록하세요.
answer_cache_key = hash(
normalized_question,
access_scope,
retrieval_policy_version,
source_version_set,
model_config_version
)
모든 문서 버전을 키에 넣기 어렵다면 문서 집합이나 테넌트별 knowledge_epoch를 올려 관련 캐시를 한꺼번에 무효화할 수 있습니다. 비용은 늘지만 삭제 위험이 큰 업무에서는 단순 TTL만 믿는 것보다 예측 가능하다.
권한도 캐시 키에 포함해야 합니다. 한 사용자가 볼 수 있는 문서로 만든 답변이 권한이 낮은 사용자에게 재사용되면 검색 필터가 올바르게 작동해도 정보가 샐 수 있습니다.
관리형 벡터 저장소의 삭제 의미를 따로 확인한다
OpenAI API 데이터 제어 문서는 vector store와 file 객체가 삭제할 때까지 유지되는 유형임을 설명합니다. 삭제 API가 있다는 사실과 모든 관련 데이터가 즉시 물리 삭제된다는 주장은 같지 않습니다. 사용 제품의 현재 보존 조건과 계약을 확인해야 합니다. OpenAI API 데이터 제어
OpenAI Vector Stores API는 벡터 저장소의 파일 삭제와 검색 작업을 제공합니다. 애플리케이션은 공급자 객체 ID를 내부 source_document_id와 연결해 두어야 삭제 요청 때 대상을 찾을 수 있습니다. OpenAI Vector Stores API
Vertex AI RAG Engine도 코퍼스에서 파일을 삭제하는 API와 샘플을 제공합니다. 서비스마다 삭제 단위와 비동기 작업 상태가 다르므로 호출 성공만 보지 말고 완료 상태와 실제 검색 결과를 확인합니다. Vertex AI RAG 파일 삭제 샘플
tombstone 시험으로 삭제 완료를 증명한다
삭제 파이프라인의 단위 테스트만으로는 인덱서 설정과 캐시를 검증하기 어렵습니다. 운영과 같은 환경에 고유 문구가 든 시험 문서를 넣습니다.
TOMBSTONE-7F19-ONLY처럼 다른 문서에 없는 문자열을 포함합니다.- 수집 뒤 키워드 검색과 의미 검색에서 문서가 나오는지 확인합니다.
- 해당 문서를 근거로 답변이 생성되는지 기록합니다.
- 원본 시스템에서 정상 삭제 절차를 실행합니다.
- 목표 시간 뒤 키워드·의미 검색과 답변 캐시를 다시 시험합니다.
- 청크 수, 벡터 저장소, 로그 표본과 삭제 감사 이벤트를 확인합니다.
시험 문서는 실제 개인정보를 넣지 않습니다. 삭제 완료 기준은 API의 200 응답이 아니라 고유 문구가 허용된 모든 검색 경로에서 사라지고, 남은 보존 예외가 문서화된 상태다.
오래된 문서를 찾는 주간 점검
- 원본에 없는
source_document_id를 색인에서 역조회합니다. - 원본 최신 버전과 색인의
source_version차이를 집계합니다. deleted_at이 있는데 검색 가능한 청크를 찾습니다.- 파이프라인 실패 큐와 재시도 한도를 확인합니다.
- 캐시 항목이 참조하는 문서 버전의 존재 여부를 검사합니다.
- 접근 권한이 바뀐 문서의 재색인·캐시 무효화를 표본 시험합니다.
RAG 정확성 평가는 최신성 문제를 별도로 분류해야 합니다. 답변 자체는 문법적으로 맞아도 폐기된 문서를 근거로 삼으면 운영 실패다. 검색·인용 평가의 기본 구조는 RAG 품질 평가 가이드와 연결할 수 있습니다.
첫 개선은 벡터 DB 교체가 아닙니다. 문서 고유 ID와 버전을 모든 청크에 넣고, 삭제 표식 하나가 색인과 캐시에서 실제로 사라지는지 끝까지 추적하세요. 그 경로가 증명되면 최신성 목표와 대규모 재색인 전략을 붙일 수 있습니다.