Qdrant 데이터 탐색

Qdrant 데이터 탐색 (Explore the Data)

검색(search) 개념을 익힌 뒤에는 다른 방식으로도 데이터를 탐색할 수 있어요. Qdrant는 유사한 벡터를 찾거나, 반대로 가장 비유사한 벡터를 찾는 등 여러 API 스택을 제공해요. 이 페이지는 추천(Recommendation)·디스커버리(Discovery)·거리 행렬(Distance Matrix) API를 설명해요.

출처: Qdrant — Concepts: Explore

본문

추천 API (Recommendation API)

일반 검색 외에도 Qdrant는 여러 positive·negative 예시를 바탕으로 검색할 수 있게 해줘요. API 이름은 recommend이며, 예시로 포인트 ID를 쓸 수 있어 이미 인코딩된 객체를 활용할 수 있어요. v1.6부터는 원시 벡터도 입력으로 사용할 수 있어 포인트로 업로드하지 않고 즉석에서 벡터를 만들 수 있어요.

추천 API는 Query API의 Recommend Query로 노출돼요.

다른 컬렉션에서 벡터 조회 (Lookup Vectors From Another Collection)

POST /collections/{collection_name}/points/query
{
  "query": {
    "recommend": {
      "positive": [100, 231],
      "negative": [718]
    }
  },
  "limit": 10,
  "lookup_from": {
    "collection": "{external_collection_name}",
    "vector": "{external_vector_name}"
  }
}

전략 (Strategy)

  • Average vector 전략: positive 예시의 평균 벡터를 만들어 그 주변에서 검색해요.
  • Best score 전략: 이 전략은 정확도에 영향을 줄 수 있어요. 개선하려면 ef 검색 파라미터를 기본 16보다 높여 사용해요. 예: "params": { "ef": 64 }. 사용하려면 추천 요청에 "strategy": "best_score"를 설정해요.
  • Sum scores 전략: 이 전략은 UKP Lab, hessian.ai, cohere.ai의 논문에서 후속 검색에 관련성 피드백을 통합하는 데 사용됐어요.

여러 벡터 (Multiple Vectors)

배치 추천 API (Batch Recommendation API, v0.10.0+)

배치 검색 API와 사용법·장점이 유사하며, 추천 요청을 배치 처리할 수 있게 해줘요.

POST /collections/{collection_name}/points/query/batch
{
  "searches": [
    {
      "query": {
        "recommend": {
          "positive": [100, 231],
          "negative": [718]
        }
      },
      "filter": {
        "must": [
          {
            "key": "city",
            "match": {
              "value": "London"
            }
          }
        ]
      },
      "limit": 10
    }
  ]
}

디스커버리 API (Discovery API, v1.7+)

디스커버리 API는 Query API의 Discover Query로 노출돼요. 컨텍스트를 제공하는 인터페이스는 추천 API와 유사해요(ids 또는 원시 벡터).

  • Discovery search: 컨텍스트(positive-negative 벡터 쌍)와 target을 사용해, target에 더 유사하면서도 컨텍스트에 의해 제약된 포인트를 반환해요.
  • Context search: 컨텍스트 쌍만 사용해서 loss가 최소화되는 최적의 구역에 있는 포인트를 얻어요.

컨텍스트 쌍에서 positive·negative 예시를 배치하는 방식은 전적으로 여러분의 몫이에요. 모델과 데이터에 따라 다양한 순열 기법을 시도할 수 있어요. 검색 속도는 쿼리에 제공하는 예시 수에 선형적으로 비례해요.

디스커버리 검색 (Discovery Search)

이 검색 유형은 멀티모달·벡터 제약 검색을 결합할 때 특히 잘 동작해요. Qdrant는 페이로드에 기반해 검색을 제약하는 필터를 광범위하게 지원하지만, 디스커버리 검색을 쓰면 검색이 수행되는 벡터 공간 자체도 제약할 수 있어요.

sigmoid 함수로 점수를 0과 1 사이로 정규화하고, rank의 합으로 negative 예시보다 positive 예시에 가까운 벡터에 페널티를 줘요. 즉 개별 rank의 합이 포인트가 몇 개의 positive 구역에 있는지를 결정하고, 유사도 계층 구조가 두 번째로 고려돼요.

POST /collections/{collection_name}/points/query
{
  "query": {
    "discover": {
      "target": [0.2, 0.1, 0.9, 0.7],
      "context": [
        {
          "positive": 100,
          "negative": 718
        },
        {
          "positive": 200,
          "negative": 300
        }
      ]
    }
  },
  "limit": 10
}

참고 사항:

  • 예시로 ids를 제공하면 결과에서 제외돼요.
  • 점수는 사용하는 메트릭과 무관하게 항상 내림차순이에요(클수록 좋음).
  • 공간이 컨텍스트로 강하게 제약되므로 기본 설정에서는 정확도가 떨어지는 게 정상이에요. 완화하려면 ef를 기본 16에서 64 이상으로 높이면 훨씬 좋아져요. 예: "params": { "ef": 128 }.

컨텍스트 검색 (Context Search)

target이 없으면 근접 그래프(HNSW)를 사용할 때 정직한 정수별 함수가 검색에 큰 도움을 주지 못해요. 그래서 컨텍스트 검색은 모델 훈련에 주로 쓰이는 triplet-loss 개념에서 파생된 함수를 써요. 이 함수는 검색을 negative 예시가 적은 구역으로 이끌도록 적응됐어요.

점수 함수를 loss 함수로 직접 연관지을 수 있는데, 0.0이 포인트가 가질 수 있는 최대 점수이며 positive 구역에만 있다는 뜻이에요. 포인트가 negative 예시에 가까워지면 그 loss는 positive·negative 유사도의 차이가 돼요.

$$\text{context score} = \sum \min(s(v^+_i) - s(v^-_i), 0.0)$$

여기서 $v^+_i$와 $v^-_i$는 각 쌍의 positive·negative 예시이고, $s(v)$는 유사도 함수예요. 이런 검색의 결과는 한 포인트 주변에 모이기보다는 negative 예시에 가깝지 않은 어떤 포인트든 될 수 있어요. 즉 제약된 다양성 있는 결과를 만들어요.

컨텍스트 검색 참고 사항:

  • 예시로 ids를 제공하면 결과에서 제외돼요.
  • 점수는 항상 내림차순이에요(클수록 좋음).
  • 가능한 최고 점수는 0.0이며, 많은 포인트가 이 점수를 받는 게 정상이에요.

거리 행렬 (Distance Matrix)

엔진은 컬렉션에서 100개의 랜덤 포인트를 선택하고, 선택된 각 포인트에 대해 샘플 안에서 가장 가까운 상위 10개 포인트의 거리를 계산해요. 총 1000개의 점수가 생성되고, 효율적인 처리를 위해 희소 행렬로 표현돼요.

쌍별 형식 (Pairwise Format)

거리 행렬을 포인트 ids 쌍과 각각의 점수 목록으로 반환해요.

POST /collections/{collection_name}/points/search/matrix/pairs
{
    "sample": 10,
    "limit": 2,
    "filter": {
        "must": {
            "key": "color",
            "match": { "value": "red" }
        }
    }
}

오프셋 형식 (Offset Format)

거리 행렬을 네 개의 배열로 반환해요.

  • offsets_rowoffsets_col: 행렬에서 0이 아닌 거리 값의 위치
  • scores: 거리 값
  • ids: 거리 값에 대응하는 포인트 id
POST /collections/{collection_name}/points/search/matrix/offsets
{
    "sample": 10,
    "limit": 2,
    "filter": {
        "must": {
            "key": "color",
            "match": { "value": "red" }
        }
    }
}

더 알아보기