8.11 Vector DB 검색의 본질적 비결정성 타파 환경 구축
RAG(Retrieval-Augmented Generation) 시스템을 테스트할 때 직면하는 가장 교활한 형태의 비결정성(Nondeterminism)은 언어 모델(LLM) 자체가 아니라, 그 앞 단에 위치한 벡터 데이터베이스(Vector Database)의 검색 엔진에서 기인한다.
완벽하게 동일한 생성 프롬프트(Generation Prompt)와 하이퍼파라미터(Temperature=0)를 설정했음에도 불구하고, 어제는 ’통과(Pass)’했던 오라클 기반 회귀 테스트가 오늘은 ’실패(Fail)’로 무너질 수 있다. 이는 인덱스가 미세하게 재구성되었거나 유사도 검색 알고리즘의 근사 근접 이웃(Approximate Nearest Neighbor, ANN) 연산이 매번 미세하게 다른 문서를 상위 랭킹(Top-K)으로 끌어올렸기 때문이다. RAG 시스템을 위한 진정한 결정론적 평가 파이프라인을 온전히 통제하기 위해서는 Vector DB 레이어를 하드코딩된 상태로 고정(Freezing)하거나 분리하는 전략이 필수적이다.
1. 재현 가능한 벤치마크를 위한 ANN 검색의 통제
대다수의 상용 Vector DB(Pinecone, Milvus, Qdrant 등)는 방대한 데이터의 빠른 검색 속도를 위해 HNSW(Hierarchical Navigable Small World)와 같은 근사 검색(Approximate Search) 알고리즘을 기본으로 사용한다. 이름에서 알 수 있듯 ANN은 ’절대적인 최적의 결과’가 아니라 ’충분히 좋은 결과’를 타협하여 반환하므로, 아주 미세한 벡터 거리 차이를 가진 엣지 케이스 데이터에서는 호출할 때마다 검색 순위가 뒤바뀔 수 있다.
- 테스트 환경 전용 완전 탐색(Exact KNN) 모드 전환: 자동화된 오라클 테스트 슈트(Test Suite)가 실행되는 환경(CI 파이프라인 등)에서는 검색 속도라는 이점을 포기하더라도, 모든 벡터를 1:1로 거리 계산하는 브루트 포스(Brute-force) 방식의 완전 탐색 매치(Exact K-Nearest Neighbors) 지시어로 검색 쿼리를 강제(Override)해야 한다. 수학적으로 완전히 동일한 검색 결과 보장만이 테스트의 재현성을 담보할 수 있다.
- 검색 결과의 정렬 기준(Tie-Breaking) 명시: 유사도 점수(Cosine Similarity)가 완전히 소수점 끝자리까지 동일한 여러 문서가 있을 때, DB의 내부 상태표(Hash Table)에 따라 순서가 달라질 수 있다. 이를 방지하기 위해 검색 쿼리에 반드시 ’유사도가 같을 경우 문서의 고유 ID(ex:
doc_id) 오름차순으로 정렬하라’는 명시적인 2차 정렬 조건(Secondary Index Sorting)을 추가하여 순위 변동의 변수를 원천 차단하라.
2. 문서 삽입 및 인덱스 업데이트 스냅샷(Snapshot) 격리
실제 프로덕션 환경의 Vector DB는 매 분, 매 초마다 새로운 문서가 추가(Upsert)되거나 삭제되는 살아 움직이는 유기체와 같다. 이러한 라이브 데이터베이스를 타겟으로 회귀 검증을 돌리는 것은 움직이는 과녁에 화살을 쏘는 것과 같은 무의미한 행위다.
- 정적 데이터베이스 컨테이너화(Containerization): 회귀 테스트만을 위한 완벽히 조립된 미니 Vector DB 이미지를 도커(Docker) 컨테이너 형태로 구워두어라(Pre-bake). 테스트가 시작될 때 이 고정된 이미지의 인스턴스를 띄워 항상 수학적으로 동일한 데이터 스키마와 인덱스 트리(Index Tree) 구조를 확보하고, 테스트가 끝나면 폐기(Tear down)하는 환경 격리(Environment Isolation) 패턴을 구현해야 한다.
- Mocking을 통한 검색 레이어 완전 우회: 생성 노드(Generation Node)의 순수한 추론 능력이나 오라클의 프롬프트 자체를 디버깅할 목적이라면 아예 Vector DB 호출부 자체를 모킹(Mocking) 처리하라. 특정한 테스트 쿼리 ID가 주어지면 사전에 하드코딩 정의해 둔 JSON 배열(Top-K 문서 리스트)을 반환하는 가짜 검색 클라이언트를 주입(Dependency Injection)함으로써, 데이터베이스의 상태 변동이라는 불확실성을 시스템 외부로 완전히 도려낼 수 있다.
3. 리랭커(Reranker) 모델의 시드 및 정밀도 제어
최신 RAG 파이프라인에서 벡터 검색의 한계를 보완하기 위해 Cross-Encoder 기반의 리랭커 모델을 검색 후처리(Post-processing) 단계에 배치하는 형태가 스탠다드로 자리 잡았다. 하지만 리랭커 모델 역시 본질적으로 신경망이므로 비결정적 요소가 개입할 수 있다.
- 소형 리랭커 모델을 사용할 경우 부동 소수점(Floating-point) 연산 최적화 방식이나 하드웨어 아키텍처(CPU vs GPU) 차이로 인해 스코어 값이 미세하게 달라질 수 있다. 오라클 테스트 베드 내에서는 연산 정밀도(Precision)를
FP32로 고정하고, 연산의 재현성을 해치는 텐서플로우나 파이토치의 비결정적 알고리즘(예:torch.use_deterministic_algorithms(True)) 사용 옵션을 명시적으로 켜두어 순위 산정 로직 자체를 콘크리트처럼 굳혀야 한다.