이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • vector search는 어떤 검색 문제에 강한가?
  • metadata filter는 왜 권한과 최신성에 중요하게 연결되는가?
  • vector DB 검색 결과를 서버에서 다시 검증해야 하는 이유는 무엇인가?

개요

Vector Search는 query와 문서의 embedding vector 사이 유사도를 계산해 의미적으로 가까운 결과를 찾는다. 사용자가 정확한 단어를 쓰지 않아도 비슷한 의미의 문서를 찾을 수 있다는 장점이 있다.

그러나 운영 검색은 유사도만으로 끝나지 않는다. tenant, 권한, 삭제 상태, 문서 유형, 최신성 같은 metadata filter가 필요하다.

핵심 원리

검색 요청은 보통 다음 조건을 함께 가진다.

  • query vector와의 유사도
  • tenant id
  • user role
  • document type
  • deleted flag
  • updated_at
  • language

vector DB는 유사도 검색과 metadata filter를 함께 지원하는 경우가 많다. 하지만 metadata가 실제 서비스 권한 모델과 동기화되어야 안전하다.

코드로 이해하기

metadata filter를 만들 때 사용자 입력만 믿지 않는다. 인증된 context에서 tenant와 role을 가져온다.

def build_search_filter(auth_context) -> dict:
    return {
        "tenant_id": auth_context.tenant_id,
        "allowed_roles": {"$contains": auth_context.role},
        "deleted": False,
    }

검색 후에도 source id로 서버 DB에서 접근 가능 여부를 한 번 더 확인할 수 있다.

def filter_authorized_results(results, permission_service, user):
    return [
        result for result in results
        if permission_service.can_read(user, result.source_id)
    ]

Keyword Search와의 조합

Vector search는 의미 유사도에 강하고, keyword search는 정확한 문자열과 식별자에 강하다.

예를 들어 다음은 keyword가 더 유리할 수 있다.

  • 주문 번호
  • 에러 코드
  • 클래스명
  • API endpoint
  • 날짜
  • 법 조항 번호

실무에서는 hybrid search를 검토한다.

장애 상황과 대응

증상:

  • 권한 없는 문서가 검색된다.
  • 오래된 문서가 계속 상위에 나온다.
  • 특정 키워드 검색이 안 된다.
  • 검색 결과는 맞는데 답변이 틀리다.

대응:

  • metadata filter와 DB 권한 모델을 비교한다.
  • source updated_at을 ranking에 반영한다.
  • keyword search와 hybrid search를 검토한다.
  • retrieval eval과 answer eval을 분리한다.

인프라 협업 포인트

metadata filter는 index 성능에 영향을 준다. 인프라팀과 filter cardinality, index configuration, query latency, tenant 분리 전략을 논의한다.

개인 프로젝트 최소 기준

  • source id와 deleted flag를 metadata로 둔다.
  • public/private 문서를 구분한다.
  • top-k를 제한한다.
  • 검색 결과 source를 답변에 표시한다.

기업 운영 수준 기준

  • tenant와 role filter를 강제한다.
  • 서버 DB 권한과 vector metadata를 동기화한다.
  • 권한 변경 이벤트를 index에 반영한다.
  • filter 성능과 query latency를 모니터링한다.

실전 팁

  • vector score를 절대 점수처럼 보지 않는다.
  • source freshness를 ranking에 섞을 수 있다.
  • code, ID, 숫자 검색은 keyword search를 함께 고려한다.
  • 검색 결과가 없을 때 모델이 추측하지 않게 한다.

위험 신호!

  • metadata filter 없이 모든 문서를 검색한다.
  • tenant id를 사용자가 보낸 값으로만 필터링한다.
  • 권한 없는 chunk를 prompt에 넣고 모델에게 무시하라고 한다.
  • vector score만 보고 최신성을 무시한다.

확인 질문

확인 질문

  • metadata filter가 권한에 중요한 이유는 무엇인가?
    • 검색 단계에서 tenant와 role에 맞지 않는 문서를 제외해야 유출 위험을 줄일 수 있기 때문이다.
  • vector search가 keyword search를 완전히 대체하지 않는 이유는 무엇인가?
    • 정확한 식별자, 에러 코드, 숫자, 날짜는 keyword 검색이 더 안정적일 수 있기 때문이다.

Spring AI 적용 연결

참고 문서