RAG 캐시, 그냥 질문을 키로 쓰면 되는 거 아닌가

← 전체 목차 · 이전: 단일 라운드 RAG는 완벽한데 다중턴만 가면 무너진다 · 다음: 분산된 문서 증거를 어떻게 조립하는가

"사용자 질문을 캐시 키로 저장하고, 같은 질문이 오면 과거 답을 그대로 돌려준다." 이 답은 절반만 맞다. 그것은 정확 매칭(KV) 캐시이지 시맨틱 캐시가 아니다. 트래픽이 많고 의미는 같은데 표현이 다른 질문의 비중이 큰 실서비스에서는, 표현만 바뀌어도 적중하지 못하는 정확 매칭이 거의 무력하다. 그렇다고 적중률을 올리려고 유사도 기준을 느슨히 풀면 곧바로 **오적중(그릇된 매칭)**이라는 새로운 구덩이에 빠진다.

정확 매칭 캐시와 시맨틱 캐시는 같은 "캐시"라는 이름을 쓸 뿐 완전히 다른 기술 축이다.

정확 매칭 캐시시맨틱 캐시
판단 기준문자열 동일임베딩 유사도
실패 모드누락(Miss) — 성능만 손해오적중(그릇된 매칭) — 오답을 그대로 출력
리스크 등급낮음높음

왜 위험한가 — 오적중은 침묵하지 않는다

정확 매칭이 실패하면 그냥 다시 계산할 뿐이다. 시맨틱 캐시가 실패하면 "의미는 비슷하지만 정답은 다른" 질문에 과거의 엉뚱한 답을 확신에 찬 어조로 돌려준다. 그리고 이 오답은 캐시에 남아 있는 한 같은 시간대에 들어오는 모든 유사 질문에 반복 적용된다 — 사고 규모가 QPS에 비례해 커지는 이유다.

캐시 오염 사고의 전형적 시간선
──────────────────────────────
① 오염된 응답이 캐시에 쓰인다      (임계값이 관대해 오적중 발생)
② 유사 질문이 동일 캐시를 반복 적중  (사고가 확산)
③ 사용자/모니터링이 이상을 발견
④ 관련 캐시를 일괄 실효(invalidate)
⑤ 사후 복기 — 임계값·트리거 조건을 재정의

이 5단계를 서술하지 못하면 "방안은 압니다"이지 "다뤄 봤습니다"가 아니다.

1층: 유사도 임계값은 상수가 아니라 업무 허용오차의 함수다

가장 흔한 실패는 **전사에 하나의 임계값(예: 0.9)**을 박아 넣는 것이다. 합규/가격/의료처럼 오답 허용오차가 거의 0인 업무와, 사내 잡담형 문의처럼 오답의 대가가 작은 업무를 같은 기준으로 캐시하면, 리스크가 가장 민감한 업무 쪽으로 위험이 그대로 전가된다.

업무 등급예시캐시 정책
엄금 캐시실시간 가격, 합규 문답, 개인화 답변캐시 대상에서 원천 제외
고정확 필수고객 응대, 제품 문의시맨틱 캐시 + 답변 일치성 검증 동반
저민감사내 일반 안내느슨한 TTL 캐시로 시작, 점진 강화

2층: 짧은 TTL은 최종 방어이지 근본 관리가 아니다

"만료 시간을 짧게 잡아 둔다"는 후보 답이 시험에서 가장 먼저 탈락하는 이유는, TTL이 오답의 생존 시간만 줄일 뿐 오답 자체를 없애지 못하기 때문이다. 진짜 관리는 두 축이다 — 지식베이스 갱신과 연동된 능동 실효(주동), 그리고 TTL 만료(수동, 최종 방어용).

캐시 일관성 = 능동 실효 + 수동 TTL
  능동: 지식베이스 갱신 이벤트 → 관련 캐시 일괄 실효 태스크 트리거
  수동: TTL 과기 — 능동 갱신이 누락된 경우의 마지막 방어선

지식베이스가 갱신됐는데 캐시가 여전히 구 응답을 서빙하는
그 구간이 "캐시 불일치 시간 창"이며, 이것도 측정 대상이다.

3층: 캐시 입도 — 정답을 통째로 캐시할 것인가, 조각을 캐시할 것인가

캐시 입도적중률저장/조립 비용
문답쌍 전체 캐시낮음(질문이 조금만 달라도 미스)낮음
검색 결과(조각) 레벨 캐시높음조립·정렬 비용 발생

입도 선택은 적중 수익과 저장 비용을 분리하는 설계 결정이지 기본값이 아니다 — 어느 쪽이 맞는지는 질문 재현율과 지식베이스 갱신 빈도를 보고 정한다.

캐시 방안 3단 판정

판정조건처치
가용내부 저민감 문의, 짧은 TTL을 최종 방어로우선 적용 후 점진 강화
수익은 있으나 고위험적중 수익 있음, 그러나 창구 오염 리스크 존재일치성 검증 보강 필수
불가무검증, 고동시성에서 오답이 대량 확산상용 서비스 배치 금지

상용 배치 문 앞의 철칙

실효 메커니즘도 없고 일치성 검증도 없는 시맨틱 캐시는 그대로 배포 금지.

핵심 통찰

  1. 정확 매칭과 시맨틱 캐시는 실패 모드가 정반대다 — 전자의 실패는 누락(성능 손해)이고 후자의 실패는 오적중(정답 오염)이다. "캐시를 붙였다"는 한 문장으로 두 기술을 뭉뚱그리면, 리스크 모델이 전혀 다른 두 시스템을 같은 잣대로 설계하게 된다.
  2. 유사도 임계값은 값이 아니라 업무 허용오차의 함수다 — 0.9라는 숫자 자체는 아무 의미가 없다. 같은 임계값을 전사에 하드코딩하는 것은 가장 민감한 업무의 위험 허용치를 가장 둔감한 업무에까지 강요하는 것과 같다.
  3. 짧은 TTL은 근본 관리 방안이 아니라 최종 방어다 — 오답의 존속 시간을 줄일 뿐 오답의 발생을 막지 못한다. 진짜 치리는 지식베이스 갱신과 캐시 실효를 같은 이벤트 스트림에 묶는 능동 연동이다.
  4. 캐시 불일치는 "없다"가 아니라 "시간 창의 길이"로 관리해야 한다 — 완벽한 일관성을 주장하는 대신, 지식베이스 갱신부터 캐시 실효까지 걸리는 시간을 측정 가능한 값으로 만들고 그 창을 줄이는 것이 목표다.
  5. 고동시성은 오적중을 "개별 사례"에서 "대량 확산"으로 바꾸는 배수기다 — 한 번 오염된 캐시가 피크 시간대에 수천·수만 번 읽히면 사고 규모는 QPS에 정비례한다. 이것이 캐시 오염이 일반 버그보다 위험한 구조적 이유다.
  6. 캐시 입도는 적중 수익과 저장/조립 비용을 맞바꾸는 설계 선택이다 — 문답쌍 전체 캐시는 싸지만 적중률이 낮고, 조각 레벨 캐시는 적중률이 높지만 조립 비용이 든다. 기본값이 아니라 데이터를 보고 결정할 항목이다.
  7. 사고를 시간선으로 복기할 수 있는가가 "읽었다"와 "다뤄 봤다"를 가른다 — 오염 작성 → 확산 → 발견 → 일괄 실효 → 복기의 다섯 단계를 구체적으로 서술할 수 있어야 실제 운영 경험이 있다는 신호다.
  8. 캐시는 성능 최적화 컴포넌트가 아니라 정확성 구성요소로 다뤄야 한다 — 실효 메커니즘과 일치성 검증이 없는 시맨틱 캐시를 "속도를 위한 부가기능"으로 취급하는 순간, 그것은 곧 정답 오염 경로가 된다.

엔지니어링 실전 Tips

  • 업무 등급별로 캐시 대상 자체를 분리할 것: 실시간 가격·합규 문답처럼 오답 허용오차가 0에 가까운 질의는 애초에 캐시 대상에서 제외하는 것이 임계값 튜닝보다 안전하다.
  • 적중률과 오적중률을 항상 짝으로 볼 것: 적중률은 올릴수록 좋아 보이는 단방향 지표라 임계값을 계속 풀게 만든다. 오적중률이라는 대구 지표 없이 적중률만 보고하면 리스크가 숨는다.
  • 주동 예열 + 피동 적중을 함께 쓸 것: 순수 피동 적중은 피크 시간대 콜드스타트에서 한꺼번에 관통당하고, 순수 주동 예열은 롱테일 질문을 못 덮는다. 핫 이슈는 예열, 나머지는 피동 적중으로 역할을 나눌 것.
  • 실효 태스크는 배치로 처리 가능해야 한다: 지식베이스 갱신은 대량 이벤트다. 실효가 키 단위로만 가능하면 대버전 갱신 한 번에 불일치 시간 창이 크게 벌어진다.
  • 고정확 모듈은 별도 링크로 뺄 것: 고객 응대·제품 문의·합규 문답은 독립된 준입 기준과 강제 일치성 검증을 갖고, 내부 저민감 문의와 정책을 공유하지 않는다.
  • 캐시 오염 사고 대응은 사전에 템플릿화할 것: "오염 작성 → 확산 범위 → 발견 경로 → 일괄 실효 → 복기 조치"를 고정 포맷으로 만들어 두면 치리 자산이자 사고 대응 매뉴얼이 된다.
  • 캐시 키에 지식베이스 버전을 포함시킬 것: 질문이 같아도 지식베이스가 갱신되면 다른 캐시 항목이어야 한다. 버전을 키에 넣지 않으면 갱신 후에도 옛 답이 계속 나온다.
  • 더 파고들 방향: 캐시 적중 후 경량 재검증(질문-답 매칭도를 소형 모델로 2차 확인해 "한 번 왕복"을 "한 번 왕복 + 경량 검증"으로 바꾸기), 캐시 불일치 시간 창의 SLO화(지식베이스 갱신 후 N분 내 전량 실효 같은 약속치로 전환), 멀티테넌트 환경에서의 캐시 격리(동일 질문이 테넌트별로 다른 지식베이스에 걸리면 교차 테넌트 적중 자체가 오염이 된다).