벡터 데이터베이스에서 자동 검색

벡터 데이터베이스에서 자동 검색 (Auto-Retrieval from a Vector Database)

이 가이드에서는 LlamaIndex에서 자동 검색(Auto-Retrieval) 을 수행하는 방법을 배워볼게요. 자연어 쿼리를 주면 LLM이 벡터 DB에 전달할 메타데이터 필터와 검색어를 함께 추론해서, 더 정확하고 표현력 있는 검색이 가능해진답니다. Elasticsearch 예제로 진행하지만 원리는 다른 벡터 DB에도 그대로 적용돼요.

출처: 문서

본문

이 가이드에서는 LlamaIndex에서 자동 검색(auto-retrieval) 을 수행하는 방법을 보여줍니다.

많은 인기 벡터 DB는 의미적 검색(semantic search)을 위한 쿼리 문자열 외에도 메타데이터 필터 세트를 지원합니다. 자연어 쿼리가 주어지면 먼저 LLM을 사용해 메타데이터 필터 세트와 벡터 DB에 전달할 올바른 쿼리 문자열을 추론합니다(둘 중 하나는 비어 있을 수도 있습니다). 이 전체 쿼리 번들을 벡터 DB에 대해 실행합니다.

이를 통해 top-k 의미적 검색보다 더 역동적이고 표현력 있는 형태의 검색이 가능해집니다. 주어진 쿼리에 대한 관련 컨텍스트가 메타데이터 태그 필터링만 필요할 수도 있고, 필터링된 집합 안에서 필터링과 의미적 검색을 결합해야 할 수도 있으며, 단순한 의미적 검색만으로 충분할 수도 있습니다.

Elasticsearch 예제를 보여드리지만, 자동 검색은 다른 많은 벡터 DB(예: Pinecone, Weaviate 등)에서도 구현되어 있습니다.

설정 (Setup)

먼저 import를 정의합니다.

콜랩 노트북에서 열고 있다면 LlamaIndex 설치가 필요할 거예요 🦙.

%pip install llama-index-vector-stores-elasticsearch
!pip install llama-index
import logging
import sys


logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
# set up OpenAI
import os
import getpass


os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
import openai


openai.api_key = os.environ["OPENAI_API_KEY"]

샘플 데이터 정의하기 (Defining Some Sample Data)

텍스트 청크를 포함한 샘플 노드 몇 개를 벡터 데이터베이스에 삽입합니다. 각 TextNode 는 텍스트뿐만 아니라 category, country 같은 메타데이터도 포함한다는 점에 주목하세요. 이 메타데이터 필드들은 내부 벡터 DB에서 그에 상응하는 표현으로 변환/저장됩니다.

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.elasticsearch import ElasticsearchStore
from llama_index.core.schema import TextNode


nodes = [
    TextNode(
        text=(
            "A bunch of scientists bring back dinosaurs and mayhem breaks"
            " loose"
        ),
        metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"},
    ),
    TextNode(
        text=(
            "Leo DiCaprio gets lost in a dream within a dream within a dream"
            " within a ..."
        ),
        metadata={
            "year": 2010,
            "director": "Christopher Nolan",
            "rating": 8.2,
        },
    ),
    TextNode(
        text=(
            "A psychologist / detective gets lost in a series of dreams within"
            " dreams within dreams and Inception reused the idea"
        ),
        metadata={"year": 2006, "director": "Satoshi Kon", "rating": 8.6},
    ),
    TextNode(
        text=(
            "A bunch of normal-sized women are supremely wholesome and some"
            " men pine after them"
        ),
        metadata={"year": 2019, "director": "Greta Gerwig", "rating": 8.3},
    ),
    TextNode(
        text="Toys come alive and have a blast doing so",
        metadata={"year": 1995, "genre": "animated"},
    ),
]

Elasticsearch 벡터 저장소로 벡터 인덱스 구축하기

여기서는 데이터를 벡터 저장소에 로드합니다. 위에서 언급했듯이 각 노드의 텍스트와 메타데이터 모두 Elasticsearch에서의 상응하는 표현으로 변환됩니다. 이제 이 데이터에 대해 의미적 검색과 메타데이터 필터링을 모두 실행할 수 있습니다.

vector_store = ElasticsearchStore(
    index_name="auto_retriever_movies", es_url="http://localhost:9200"
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex(nodes, storage_context=storage_context)

VectorIndexAutoRetriever 정의하기

핵심 모듈인 VectorIndexAutoRetriever 를 정의합니다. 이 모듈은 벡터 저장소 컬렉션과 지원하는 메타데이터 필터에 대한 구조화된 설명을 포함하는 VectorStoreInfo 를 입력받습니다. 이 정보는 자동 검색 프롬프트에서 사용되어 LLM이 메타데이터 필터를 추론하게 됩니다.

from llama_index.core.retrievers import VectorIndexAutoRetriever
from llama_index.core.vector_stores import MetadataInfo, VectorStoreInfo



vector_store_info = VectorStoreInfo(
    content_info="Brief summary of a movie",
    metadata_info=[
        MetadataInfo(
            name="genre",
            description="The genre of the movie",
            type="string or list[string]",
        ),
        MetadataInfo(
            name="year",
            description="The year the movie was released",
            type="integer",
        ),
        MetadataInfo(
            name="director",
            description="The name of the movie director",
            type="string",
        ),
        MetadataInfo(
            name="rating",
            description="A 1-10 rating for the movie",
            type="float",
        ),
    ],
)
retriever = VectorIndexAutoRetriever(
    index, vector_store_info=vector_store_info
)

샘플 데이터로 실행하기 (Running over some sample data)

샘플 데이터를 대상으로 실행해 봅니다. 메타데이터 필터가 어떻게 추론되는지 살펴보세요. 이는 더 정확한 검색에 도움이 됩니다!

retriever.retrieve(
    "What are 2 movies by Christopher Nolan were made before 2020?"
)
retriever.retrieve("Has Andrei Tarkovsky directed any science fiction movies")
INFO:llama_index.indices.vector_store.retrievers.auto_retriever.auto_retriever:Using query str: science fiction
Using query str: science fiction
INFO:llama_index.indices.vector_store.retrievers.auto_retriever.auto_retriever:Using filters: {'director': 'Andrei Tarkovsky'}
Using filters: {'director': 'Andrei Tarkovsky'}
INFO:llama_index.indices.vector_store.retrievers.auto_retriever.auto_retriever:Using top_k: 2
Using top_k: 2
INFO:elastic_transport.transport:POST http://localhost:9200/auto_retriever_movies/_search [status:200 duration:0.042s]
POST http://localhost:9200/auto_retriever_movies/_search [status:200 duration:0.042s]




[]

더 알아보기 (Learn more)