목차
먼저 확인할 전제
이 글은 문서와 검색어를 같은 임베딩 모델로 변환하고, 벡터 데이터베이스에 저장한 뒤 유사도 검색을 수행하는 환경을 가정합니다. 데이터베이스 종류나 라이브러리에 따라 설정 이름은 다를 수 있지만, 결과가 엉뚱할 때 확인할 순서는 대부분 비슷합니다.
거리 함수와 임베딩 모델 점검
거리 함수는 벡터 사이의 가까움을 계산하는 기준입니다. 코사인 유사도는 방향의 관계를, 내적은 벡터의 방향과 크기 관계를 함께 반영하며, 유클리드 거리는 두 벡터 사이의 좌표상 거리를 계산합니다. 두 벡터를 모두 L2 정규화했다면 코사인 유사도와 내적은 같은 값이 되어 검색 순위도 동일해집니다. 반대로 정규화하지 않은 벡터에 내적을 사용하면 길이가 긴 벡터가 과도하게 높은 점수를 받을 수 있으므로, 유클리드 거리와 혼동하지 않도록 기준별 점수의 의미와 방향을 구분해야 합니다.
문서 저장과 검색에 서로 다른 임베딩 모델을 사용해도 문제가 생깁니다. 차원이 같아도 벡터 공간의 의미가 다르므로 검색어와 문서의 점수를 정상적으로 비교하기 어렵습니다. 모델을 바꿨다면 기존 벡터를 부분 수정하지 말고, 같은 모델로 전체 문서를 다시 임베딩했는지 확인하는 것이 핵심입니다.
ANN 인덱스와 검색 정확도
ANN 인덱스는 전체 벡터를 모두 비교하지 않고 가까운 후보를 빠르게 찾는 방식입니다. 속도를 얻는 대신 후보 탐색 범위를 줄이면 실제 최상위 문서를 놓칠 수 있습니다. 원본 벡터를 직접 비교한 결과와 ANN 결과의 순서가 크게 다르다면, 인덱스의 탐색 파라미터나 검색 정확도 설정을 높인 결과와 비교하면 원인을 좁힐 수 있습니다.
잘못된 결과가 특정 데이터 규모에서만 나타난다면 인덱스 설정을 의심할 수 있습니다. 먼저 작은 데이터셋에서 전체 비교와 ANN 검색을 같은 Top-k로 실행하고, 차이가 줄어드는지 확인합니다. 정확도를 높였을 때 결과가 개선되지만 응답 시간이 늘어난다면, 속도와 정확도 사이에서 어느 쪽을 우선할지 정하는 것이 핵심입니다.
청크 크기와 오버랩
청크가 너무 크면 한 문서에 여러 주제가 섞여 검색어와 직접 관련 없는 내용이 함께 반환됩니다. 반대로 너무 작으면 제목, 조건, 예외처럼 의미를 완성하는 정보가 서로 다른 청크로 분리됩니다. 이때 검색 결과에는 관련 단어가 포함되어도 실제 답변에 필요한 맥락이 빠질 수 있습니다.
청크 오버랩은 경계에서 문장이 끊기는 문제를 줄이지만, 지나치게 크면 거의 같은 내용이 반복 저장됩니다. 검색 결과가 비슷한 청크로 채워지거나 문서의 앞뒤 조건이 자주 끊긴다면 문장이나 문단 경계를 우선하는 편이 좋습니다. 오버랩 크기에도 고정된 정답값이 있는 것은 아니므로, 테스트 질문을 기준으로 검색 결과를 비교하면서 조정하는 방식이 안전합니다.
Top-k와 점수 임계값
Top-k를 크게 잡으면 관련 문서가 포함될 가능성은 높아지지만, 낮은 품질의 문서도 함께 전달됩니다. 반대로 Top-k가 작으면 필요한 문서가 상위 결과에 포함되지 않을 수 있습니다. 검색 결과 개수만 고정하기보다 점수와 원문을 함께 확인해 실제로 유효한 결과의 범위를 정하는 방식이 적절합니다.
점수 임계값은 일정 수준보다 낮은 결과를 제외하는 장치입니다. 다만 거리 함수마다 점수의 의미와 방향이 다르므로 코사인 점수의 기준을 유클리드 거리에도 그대로 적용하면 모든 결과가 사라지거나 엉뚱한 결과만 남을 수 있습니다. 검색어와 정답 문서가 포함된 테스트 질문을 준비한 뒤, 점수 분포를 기준으로 임계값을 조정하는 방식이 안전합니다.
결론
벡터 검색 오류는 모델, 거리 함수, 인덱스, 청크, Top-k를 따로 보지 말고 같은 테스트셋으로 순서대로 비교해야 원인을 빠르게 좁힐 수 있습니다.