Auto-Retrieval from a Vectara Index

Auto-Retrieval from a Vectara Index

Vectara를 이용해 LlamaIndex에서 **자동 검색(auto-retrieval)**을 수행하는 가이드예요. 쿼리를 Vectara에 보내기 전에 해석해서 더 짧은 쿼리와 메타데이터 필터로 재작성하는 과정을 예시로 보여드릴게요.

출처: 문서

본문

이 가이드는 LlamaIndex에서 Vectara와 함께 자동 검색을 수행하는 방법을 보여줍니다.

자동 검색에서는 검색 쿼리를 Vectara에 제출하기 전에 해석해서, 쿼리를 더 짧은 쿼리와 몇 가지 메타데이터 필터로 재작성할 수 있는 가능성을 식별합니다.

예를 들어 "what is the revenue in 2022" 같은 쿼리는 "what is the revenue"로 재작성되고 doc.year = 2022라는 필터가 붙을 수 있습니다. 예시를 통해 이것이 어떻게 작동하는지 살펴봅시다.

Setup

이 노트북을 colab에서 여는 경우 LlamaIndex 🦙를 설치해야 할 수 있습니다.

!pip install llama_index llama-index-llms-openai llama-index-indices-managed-vectara
import logging
import sys


logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
from llama_index.core.schema import TextNode
from llama_index.core.indices.managed.types import ManagedIndexQueryMode
from llama_index.indices.managed.vectara import VectaraIndex
from llama_index.indices.managed.vectara import VectaraAutoRetriever


from llama_index.core.vector_stores import MetadataInfo, VectorStoreInfo


from llama_index.llms.openai import OpenAI

샘플 데이터 정의하기

먼저 영화 데이터셋을 정의합니다:

  1. 각 노드는 영화 하나를 설명합니다.
  2. text는 영화를 설명하고, metadata는 연도, 감독, 평점, 장르 같은 특정 메타데이터 필드를 정의합니다.

Vectara에서는 필터링이 가능하도록 이 메타데이터 필드들을 corpus에서 필터 가능한 속성으로 정의해야 합니다.

nodes = [
    TextNode(
        text=(
            "A pragmatic paleontologist touring an almost complete theme park on an island "
            + "in Central America is tasked with protecting a couple of kids after a power "
            + "failure causes the park's cloned dinosaurs to run loose."
        ),
        metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"},
    ),
    TextNode(
        text=(
            "A thief who steals corporate secrets through the use of dream-sharing technology "
            + "is given the inverse task of planting an idea into the mind of a C.E.O., "
            + "but his tragic past may doom the project and his team to disaster."
        ),
        metadata={
            "year": 2010,
            "director": "Christopher Nolan",
            "rating": 8.2,
        },
    ),
    TextNode(
        text="Barbie suffers a crisis that leads her to question her world and her existence.",
        metadata={
            "year": 2023,
            "director": "Greta Gerwig",
            "genre": "fantasy",
            "rating": 9.5,
        },
    ),
    TextNode(
        text=(
            "A cowboy doll is profoundly threatened and jealous when a new spaceman action "
            + "figure supplants him as top toy in a boy's bedroom."
        ),
        metadata={"year": 1995, "genre": "animated", "rating": 8.3},
    ),
    TextNode(
        text=(
            "When Woody is stolen by a toy collector, Buzz and his friends set out on a "
            + "rescue mission to save Woody before he becomes a museum toy property with his "
            + "roundup gang Jessie, Prospector, and Bullseye. "
        ),
        metadata={"year": 1999, "genre": "animated", "rating": 7.9},
    ),
    TextNode(
        text=(
            "The toys are mistakenly delivered to a day-care center instead of the attic "
            + "right before Andy leaves for college, and it's up to Woody to convince the "
            + "other toys that they weren't abandoned and to return home."
        ),
        metadata={"year": 2010, "genre": "animated", "rating": 8.3},
    ),
]

그런 다음 샘플 데이터를 Vectara Index에 로드합니다.

import os


os.environ["VECTARA_API_KEY"] = "<YOUR_VECTARA_API_KEY>"
os.environ["VECTARA_CORPUS_ID"] = "<YOUR_VECTARA_CORPUS_ID>"
os.environ["VECTARA_CUSTOMER_ID"] = "<YOUR_VECTARA_CUSTOMER_ID>"


index = VectaraIndex(nodes=nodes)

VectorStoreInfo 정의하기

VectorStoreInfo 객체를 정의합니다. 이 객체는 Vectara Index가 지원하는 메타데이터 필터에 대한 구조화된 설명을 담습니다. 이 정보는 이후 자동 검색 프롬프트에서 사용되어, LLM이 특정 쿼리에 사용할 메타데이터 필터를 추론할 수 있게 합니다.

vector_store_info = VectorStoreInfo(
    content_info="information about a movie",
    metadata_info=[
        MetadataInfo(
            name="genre",
            description="""
                The genre of the movie.
                One of ['science fiction', 'fantasy', 'comedy', 'drama', 'thriller', 'romance', 'action', 'animated']
            """,
            type="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",
        ),
    ],
)

자동 검색 실행하기

이제 VectaraAutoRetriever 인스턴스를 만들고 retrieve()를 시도해 봅시다:

from llama_index.indices.managed.vectara import VectaraAutoRetriever
from llama_index.llms.openai import OpenAI


llm = OpenAI(model="gpt-3.5-turbo", temperature=0)


retriever = VectaraAutoRetriever(
    index,
    vector_store_info=vector_store_info,
    llm=llm,
    verbose=True,
)
retriever.retrieve("movie directed by Greta Gerwig")

"movie directed by Greta Gerwig" 쿼리를 실행하면 LLM이 director 필드의 필터를 추론합니다. 로그를 보면 Using query str: movie directed by Greta Gerwig, Using implicit filters: [('director', '==', 'Greta Gerwig')], final filter string: (doc.director == 'Greta Gerwig') 처럼 쿼리 텍스트는 그대로 두고 director 메타데이터 필터만 적용해 검색하는 것을 확인할 수 있습니다. 결과로 Barbie(감독 Greta Gerwig, 평점 9.5) 노드가 반환됩니다.

retriever.retrieve("a movie with a rating above 8")

"a movie with a rating above 8" 쿼리에서는 rating 필터로 ('rating', '>', 8)을 사용해 (doc.rating > '8') 필터가 적용됩니다. 결과로 평점 8.3의 Toy Story, 평점 8.2의 Inception(Christopher Nolan), 평점 9.5의 Barbie, 평점 8.3의 Toy Story 3 등 평점 8을 초과하는 영화들이 반환됩니다.

표준 VectaraRetriever 인자도 VectaraAutoRetriever에 포함할 수 있습니다. 예를 들어 쿼리 자체에서 오는 추가 필터링에 더해질 filter를 포함하고 싶다면 다음과 같이 할 수 있습니다:

더 알아보기 (Learn more)