RAG 시스템을 구축할 때 가장 흔하게 겪는 문제 중 하나가 검색된 문서가 질문과 전혀 상관없는 내용일 때 발생하거든요. 질문과 무관한 정보가 프롬프트에 포함되면 LLM이 혼란을 느껴 엉뚱한 대답을 하거나 환각 현상을 일으킬 확률이 높아지기 때문이에요. 단순히 유사도 점수가 높은 상위 5개를 무조건 가져오는 방식은 데이터가 방대해질수록 노이즈를 제대로 걸러내지 못하는 한계가 있더라고요. 특히 검색 결과가 많아질수록 모델이 핵심적인 정보에 집중하지 못하고 부차적인 정보에 휘둘려 답변의 품질이 떨어지는 경우가 빈번하게 발생해요.
이러한 문제를 해결하기 위해 벡터 데이터베이스에서 검색 결과를 가져올 때 특정 임계값을 설정하는 과정이 필요해요. 실무에서는 주로 Cosine Similarity를 활용하는데, 이 수치는 -1에서 1 사이의 범위를 가집니다. 보통 0.7이나 0.8 이상의 결과만 유효한 정보로 판단하고, 이 기준을 넘지 못하는 데이터는 프롬프트 구성 단계에서 아예 제외하는 방식을 사용해요. 단순히 상위 5개를 가져오는 Top-K 방식과 달리 임계값 방식은 검색된 결과의 양이 가변적일 수 있지만, 훨씬 정교하게 노이즈를 제거할 수 있다는 장점이 있어요. 이를 통해 불필요한 토큰 소모를 줄이고 LLM이 가장 관련성이 높은 정보에만 집중할 수 있는 환경을 만들어주거든요.
results = vector_db.query(query_vector, top_k=10)
# 임계값을 설정하여 노이즈를 제거
threshold = 0.8
filtered_results = [res for res in results if res.score >= threshold]
# 필터링된 결과만 프롬프트에 포함
context = " ".join([res.text for res in filtered_results])
# LLM 호출
response = llm.generate(prompt + context)
임계값 설정 시 고려해야 할 중요한 포인트는 사용 중인 임베딩 모델의 특성을 정확히 파악하는 것이에요. 예를 들어 OpenAI의 text-embedding-3-small 모델과 다른 오픈소스 기반 임베딩 모델들은 유사도 점수가 분포되는 범위가 다를 수 있거든요. 모델에 따라 0.8이 매우 높은 유사도일 수도 있고, 0.9를 넘어야 유의미한 정보로 판단할 수도 있기 때문이에요. 또한 거리 기반의 Euclidean Distance를 사용하는 경우에는 유사도와 반대 개념으로 수치가 낮을수록 의미적으로 가깝다고 판단하기 때문에 로직을 다르게 구성해야 해요. 따라서 서비스의 목적과 사용 중인 임베딩 모델의 성능을 고려하여 다양한 데이터셋으로 테스트를 반복하며 최적의 임계값 수치를 찾아내는 과정이 반드시 필요하다고 생각해요.
'develop > AI' 카테고리의 다른 글
| LLM 응답의 일관성을 위한 Pydantic 기반 구조화 출력 (Instructor) (0) | 2026.09.12 |
|---|---|
| OpenAI Responses API 기반 추론 모델 활용 (GPT-5 시리즈) (0) | 2026.09.04 |
| Metadata 필터링을 통한 RAG 검색 범위 제한 (0) | 2026.08.30 |
| OpenAI API 속도 제한 대응을 위한 지수 백오프(Exponential Backoff) 구현 (0) | 2026.08.18 |
| PyTorch 2.x 및 torch.compile 기반의 성능 최적화 (0) | 2026.08.10 |