벡터 검색하기
벡터 검색하기 (Querying vectors)
QueryVectors API 작업으로 유사도 검색(similarity query)을 실행할 수 있어요. 검색 시 쿼리 벡터, 반환할 관련 결과 수(가장 가까운 상위 K 이웃, top K nearest neighbors), 인덱스 ARN을 지정해요. 또한 검색에 메타데이터 필터를 사용해 필터와 일치하는 벡터만 검색할 수 있어요. 필터링 불가능한(non-filterable) 메타데이터 필드로 필터를 요청하면 요청이 400 Bad Request 오류를 반환해요. 메타데이터 필터링에 대한 자세한 내용은 메타데이터 필터링을 참고하세요.
응답에서는 기본적으로 벡터 키가 반환돼요. 선택적으로 응답에 거리(distance)와 메타데이터를 포함시킬 수 있어요. topK가 페이지 크기를 넘으면 결과가 여러 페이지에 걸쳐 반환돼요. 응답에는 다음 페이지를 가져오는 데 쓰는 nextToken이 포함돼요. 같은 queryVector, topK, filter 파라미터로 QueryVectors 요청을 계속 보내고, 각 응답의 nextToken을 전달하다가 nextToken이 더 이상 없을 때까지 반복해요. 또는 AWS SDK에 내장된 페이지네이터(paginator)를 사용하면 nextToken을 수동으로 처리하지 않고도 모든 페이지를 자동으로 순회할 수 있어요. 페이지네이션 토큰은 쿼리 실행 후 몇 분 동안 유효해요. 토큰이 만료되면 원래 쿼리를 다시 실행해 새 세션을 시작하세요. 페이지를 가져오는 사이에 벡터 인덱스에 대한 쓰기 작업은 그 쿼리 세션에 반영되지 않아요. topK와 페이지 크기의 구체적인 제한은 제한 사항을 참고하세요.
쿼리 벡터를 생성할 때는 벡터 인덱스에 저장된 초기 벡터를 만드는 데 쓴 것과 같은 벡터 임베딩 모델을 사용해야 해요. 예를 들어 Amazon Bedrock의 Amazon Titan Text Embeddings V2 모델로 문서의 벡터 임베딩을 만들었다면, 같은 임베딩 모델로 질문을 쿼리 벡터로 변환해야 해요. 또한 Amazon Bedrock Knowledge Bases는 완전 관리형 엔드투엔드 RAG 워크플로를 제공해요. Amazon Bedrock이 S3 데이터 소스에서 데이터를 자동으로 가져와 콘텐츠를 텍스트 블록으로 변환하고, 임베딩을 생성한 뒤 벡터 인덱스에 저장해 줘요. 그런 다음 지식 기반을 검색하고 소스 데이터에서 검색된 청크를 바탕으로 응답을 생성할 수 있어요. 콘솔에서 Amazon Bedrock 지식 기반으로 벡터를 검색하는 방법에 대한 자세한 내용은 (선택) S3 Vectors와 Amazon Bedrock Knowledge Bases 통합을 참고하세요.
오픈소스 도구인 Amazon S3 Vectors Embed CLI를 쓰면 명령줄에서 의미 검색을 더 간단하게 할 수 있어요. 이 도구는 Amazon Bedrock 파운데이션 모델로 벡터 임베딩을 만드는 작업과 S3 벡터 인덱스에 대한 의미 검색 실행을 모두 처리해 검색 과정을 간소화해 줘요. 이 도구로 벡터 데이터를 검색하는 방법에 대한 자세한 내용은 s3vectors-embed-cli로 벡터 임베딩 만들기 및 의미 검색 수행하기를 참고하세요.
S3 Vectors는 Amazon S3의 탄력적 처리량(elastic throughput)을 활용해 수십억 개의 벡터를 효율적으로 검색하므로 콜드 쿼리(cold query)에 대해 1초 미만의 응답 시간을 제공해요. 덕분에 쿼리가 드문 워크로드에 매우 비용 효율적이에요. 웜 쿼리(warm query)의 경우 S3 Vectors는 응답 시간을 100ms까지 낮출 수 있어 반복적이거나 빈번한 쿼리 패턴을 가진 워크로드에 유리해요. 쿼리 결과가 여러 페이지에 걸쳐 반환될 때 후속 페이지는 즉시 접근할 수 있어요.
벡터 임베딩에 대한 유사도 검색을 수행할 때 평균 재현율(recall) 성능에 영향을 줄 수 있는 요인은 여러 가지가 있어요. 벡터 임베딩 모델, 벡터 데이터셋의 크기(벡터 수와 차원 수), 쿼리 분포 등이 그것이에요. S3 Vectors는 대부분의 데이터셋에 대해 평균 재현율 90% 이상을 제공해요. 평균 재현율은 쿼리 결과의 품질을 측정해요. 평균 재현율 90%는 쿼리 벡터에 상대적으로 벡터 인덱스에 저장된 실제 가장 가까운 벡터(ground truth)의 90%가 응답에 포함된다는 뜻이에요. 다만 실제 성능은 특정 사용 사례에 따라 달라질 수 있으므로, 대표적인 데이터와 쿼리로 직접 테스트해 S3 Vectors가 여러분의 재현율 요구사항을 충족하는지 확인하는 걸 권장해요.
출처: 문서
본문
Python SDK (Boto3)
# Query a vector index with an embedding from Amazon Titan Text Embeddings V2.
import boto3
import json
# Create Bedrock Runtime and S3 Vectors clients in the AWS Region of your choice.
bedrock = boto3.client("bedrock-runtime", region_name="us-west-2")
s3vectors = boto3.client("s3vectors", region_name="us-west-2")
# Query text to convert to an embedding.
input_text = "adventures in space"
# Generate the vector embedding.
response = bedrock.invoke_model(
modelId="amazon.titan-embed-text-v2:0",
body=json.dumps({"inputText": input_text})
)
# Extract embedding from response.
model_response = json.loads(response["body"].read())
embedding = model_response["embedding"]
# Query vector index.
response = s3vectors.query_vectors(
vectorBucketName="media-embeddings",
indexName="movies",
queryVector={"float32": embedding},
topK=3,
returnDistance=True,
returnMetadata=True
)
print(json.dumps(response["vectors"], indent=2))
# Query vector index with a metadata filter.
response = s3vectors.query_vectors(
vectorBucketName="media-embeddings",
indexName="movies",
queryVector={"float32": embedding},
topK=3,
filter={"genre": "scifi"},
returnDistance=True,
returnMetadata=True
)
print(json.dumps(response["vectors"], indent=2))
# Paginated query with manual nextToken handling.
query_params = dict(
vectorBucketName="media-embeddings",
indexName="movies",
queryVector={"float32": embedding},
topK=500,
returnDistance=True,
returnMetadata=True,
)
response = s3vectors.query_vectors(**query_params)
for vector in response["vectors"]:
print(vector)
while response.get("nextToken") is not None:
response = s3vectors.query_vectors(**query_params, nextToken=response["nextToken"])
for vector in response["vectors"]:
print(vector)
# Use the built-in paginator to automatically iterate through all pages.
paginator = s3vectors.get_paginator("query_vectors")
for page in paginator.paginate(
vectorBucketName="media-embeddings",
indexName="movies",
queryVector={"float32": embedding},
topK=500,
returnDistance=True,
returnMetadata=True,
):
for vector in page["vectors"]:
print(vector)