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
샘플 데이터 정의하기
먼저 영화 데이터셋을 정의합니다:
- 각 노드는 영화 하나를 설명합니다.
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를 포함하고 싶다면 다음과 같이 할 수 있습니다: