RAG를 위한 시맨틱 캐시 구현기: 캐싱을 하지 말아야 할 때를 아는 것이 어려웠다
요약
본 글은 RAG 애플리케이션의 효율성을 높이기 위해 'Weir'라는 오픈 소스 게이트웨이를 소개합니다. Weir는 시맨틱 캐싱, 모델 라우팅, 비용 회계를 결합하여 중복 요청에 대한 답변을 재사용하고 최적의 LLM을 선택함으로써 운영 비용과 지연 시간을 관리하는 방법을 제시합니다.
핵심 포인트
- Weir는 RAG 앞에 위치하여 캐시 적중 여부와 필요한 모델 티어를 결정합니다.
- 단순 임베딩 유사도 대신 엔티티 가드를 사용하여 잘못된 답변 위험을 최소화했습니다.
- 반복 요청이 많은 워크로드에서 비용 절감 효과가 매우 크며, 지연 시간 감소에 큰 도움이 됩니다.
RAG 애플리케이션이 질문에 답변할 때마다 문서를 검색하고 LLM 호출을 해야 할 수 있습니다.
하지만 누군가 본질적으로 같은 질문을 다시 한다면 어떻게 될까요?
우리는 이전 답변을 재사용할 수 있습니다. 문제는 두 질문이 답을 공유하기에 충분히 유사한지, 아니면 단지 보기에만 비슷한지를 아는 것입니다.
이것은 제가 오픈 소스이며 비용 인식이 가능한 Retrieval-Augmented Generation (RAG) 게이트웨이인 Weir를 구축하면서 탐구했던 문제입니다.
GitHub: https://github.com/yatinannam/weir
Weir란 무엇인가?
Weir는 기존 RAG 서비스 앞에 위치합니다. 요청이 캐시된 답변을 안전하게 사용할 수 있는지, 아니면 검색 및 생성이 필요한지 결정하며, 생성이 필요할 때는 모델 티어를 선택합니다.
이는 세 가지 주요 아이디어를 결합합니다:
- 시맨틱 캐싱 (Semantic caching): 충분히 유사한 질문에 대해 답변을 재사용합니다.
- 모델 라우팅 (Model routing): 적절한 질문에는 더 저렴한 모델을, 필요할 때는 더 큰 모델을 사용합니다.
- 비용 회계 (Cost accounting): 실제 요청 비용, 반사실적 비용(counterfactual cost), 지연 시간(latency)을 추적하여 절감액을 측정할 수 있게 합니다.
또한 요청 로깅, 모니터링, 평가 도구, 그리고 Docker 기반 데모를 포함합니다.
시맨틱 캐싱의 놀라운 문제점
사용자가 다음과 같이 질문했다고 가정해 봅시다:
"ICU 방문 시간은 언제인가요?"
나중에 다른 사용자가 이렇게 질문했습니다:
"일반 병동 방문 시간은 언제인가요?"
두 질문은 구조적으로 유사합니다. 임베딩 기반 캐시는 이들에게 높은 유사도 점수를 부여할 수 있습니다.
하지만 두 번째 사용자에게 ICU 답변을 제공하는 것은 잘못될 것입니다.
이것이 Weir가 임베딩 유사도와 함께 엔티티 가드(entity guard)를 사용하는 이유입니다. 잠재적인 캐시 적중(cache hit)을 받아들이기 전에 숫자, 부정어(negation), 그리고 중요한 도메인 용어 같은 구별되는 정보를 확인합니다.
목표는 가능한 한 공격적으로 캐싱하는 것이 아닙니다. 잘못된 답변을 조용히 반환하면서 불필요한 작업을 줄이는 것입니다.
평가 방법
저는 네 가지 구성을 비교했습니다:
- 캐싱을 사용하지 않고 항상 더 큰 모델을 사용하는 기준선(Baseline)
- 시맨틱 캐싱만 적용
- 모델 라우팅만 적용
- 캐싱과 라우팅을 결합한 전체 Weir (Full Weir)
평가에는 패러프레이즈, 유사 질문, 답변 불가능 질문 등을 포함하는 40개의 문서와 158개의 평가 질문으로 구성된 가상의 병원 FAQ를 사용했습니다.
1. 콜드-패스(Cold-pass) 평가
158개의 질문 각각이 한 번씩 주어졌습니다.
Full Weir는 요청당 측정 비용을 $0.0988에서 $0.0786으로 줄여, 20% 감소를 달성했습니다. 평가 심사 점수와 핵심 사실(key-fact) 점수는 기준선과 비교하여 변동이 없었습니다.
트레이드오프가 중요합니다: 이 워크로드에서는 중앙값 지연 시간(median latency)이 767ms에서 876ms로 증가했습니다. 비용 절감이 모든 워크로드가 더 빨라진다는 것을 자동으로 의미하지는 않습니다.
2. 반복 중심의 재현(Repeat-heavy replay)
요청 중 73.7%가 반복인 300개 요청의 재현 테스트도 진행했습니다.
| 지표 | 기준선 (Baseline) | Full Weir |
|---|---|---|
| 캐시 적중률 (Cache hit rate) | 0% | 93.0% |
| ... |
이 워크로드에서 측정된 비용 절감은 약 94%였고, 중앙값 지연 시간은 약 50배 낮았습니다.
주의할 점은 이것들이 합성적이고 반복 중심의 벤치마크 결과일 뿐이며, 실제 운영(production) 워크로드에서의 동등한 절약 효과를 입증하는 것은 아니라는 것입니다.
잘못된 캐시 적중률에 대해서는 어떨까요?
선택된 유사성 임계값(similarity threshold)에서 임베딩 유사도만으로는 평가 세트 내 일부 위험한 유사 질문 일치(look-alike matches)를 허용했습니다. 엔티티 가드(entity guard)를 추가하자 해당 테스트 세트에서 잘못 수락되는 캐시 적중률이 0으로 줄었습니다.
이는 고무적이지만, 안전을 보장하는 것은 아닙니다. 작은 합성 데이터셋으로는 모든 가능한 모호성이나 도메인별 구분을 다룰 수 없습니다.
부하 상태에서는 어땠나요?
저는 또한 프로바이더 장애 및 데이터베이스 지연을 포함하여 시스템을 부하 상태에서 테스트했습니다.
이 테스트를 통해 실제 과부하 모드(overload mode)가 드러났습니다: CPU 압력 하에서 캐시 조회(cache lookups)가 시간 초과되기 시작하자, 더 많은 요청이 캐시를 우회하여 검색 및 생성 단계에 도달했고, 이는 추가적인 부하를 유발했습니다.
저는 부하 테스트를 무조건적인 용량 주장으로 제시하기보다는 그 한계를 문서화했습니다.
직접 사용해보기
Weir는 단일 명령어로 데모 런처를 제공합니다:
uv run demo.py
Docker Desktop과 uv가 필요합니다. Groq API 키는 선택 사항입니다. 키가 없어도 데모는 스텁 모델을 사용하므로, 캐시, 검색(retrieval), 가드(guard), 라우팅 구성 요소는 실제 상태를 유지하면서 생성 과정만 시뮬레이션됩니다.
저장소에는 구현체, 평가 보고서, 아키텍처, 한계점 및 테스트 실행 지침이 포함되어 있습니다.
피드백을 받고 싶은 부분
저는 특히 RAG 애플리케이션이나 LLM 인프라를 구축하는 분들의 피드백에 관심이 많습니다:
- 시맨틱 캐시 평가에 어떤 실패 사례들을 추가할 수 있을까요?
- 도메인 전반에 걸쳐 엔티티 가드를 어떻게 더 견고하게 만들 수 있을까요?
- 이러한 절감액이 프로덕션 환경에서도 유효한지 테스트하기 위해 어떤 실제 워크로드를 사용해 볼 수 있을까요?
기술적인 비판, 벤치마크 제안, 그리고 기여를 환영합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기