VectorStoreIndex 사용하기
VectorStoreIndex 사용하기
벡터 스토어는 검색 증강 생성(RAG)의 핵심 컴포넌트로, LlamaIndex로 만드는 거의 모든 애플리케이션에서 직접이든 간접이든 사용하게 될 거예요. 벡터 스토어는 Node 객체 목록을 받아 그로부터 인덱스를 구축해요.
출처: 문서
본문
인덱스에 데이터 로딩하기
기본 사용법
벡터 스토어를 사용하는 가장 간단한 방법은 문서 세트를 로딩하고 from_documents로 인덱스를 구축하는 거예요:
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
# Load documents and build index
documents = SimpleDirectoryReader(
"../../examples/data/paul_graham"
).load_data()
index = VectorStoreIndex.from_documents(documents)
팁: 커맨드라인에서 from_documents를 사용한다면 인덱스 구축 중 진행 표시줄을 보여주기 위해 show_progress=True를 전달하는 것이 편리해요.
from_documents를 사용하면 Document가 청크로 분할되고 메타데이터와 관계를 추적하는 텍스트 문자열의 가벼운 추상화인 Node 객체로 파싱돼요.
문서 로딩에 대해 더 알아보려면 Loading 이해하기를 참고하세요.
기본적으로 VectorStoreIndex는 모든 것을 메모리에 저장해요. 영속 벡터 스토어 사용법은 아래 Vector Stores 사용하기를 참고하세요.
팁: 기본적으로 VectorStoreIndex는 2048개 노드 배치로 벡터를 생성하고 삽입해요. 메모리가 제한적이거나(또는 넉넉하다면) 원하는 배치 크기로 insert_batch_size=2048을 전달해 수정할 수 있어요. 원격 호스팅 벡터 데이터베이스에 삽입할 때 특히 도움이 돼요.
Ingestion pipeline으로 노드 만들기
문서가 어떻게 인덱싱되는지 더 잘 제어하고 싶다면 ingestion pipeline 사용을 권장해요. 이를 통해 노드의 청킹, 메타데이터, 임베딩을 커스터마이즈할 수 있어요.
from llama_index.core import Document
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.extractors import TitleExtractor
from llama_index.core.ingestion import IngestionPipeline, IngestionCache
# create the pipeline with transformations
pipeline = IngestionPipeline(
transformations=[
SentenceSplitter(chunk_size=25, chunk_overlap=0),
TitleExtractor(),
OpenAIEmbedding(),
]
)
# run the pipeline
nodes = pipeline.run(documents=[Document.example()])
팁: ingestion pipeline 사용법에 대해 더 알아볼 수 있어요.
노드를 직접 만들고 관리하기
인덱스를 완전히 제어하고 싶다면 노드를 수동으로 만들고 정의한 다음 인덱스 생성자에 직접 전달할 수 있어요:
from llama_index.core.schema import TextNode
node1 = TextNode(text="<text_chunk>", id_="<node_id>")
node2 = TextNode(text="<text_chunk>", id_="<node_id>")
nodes = [node1, node2]
index = VectorStoreIndex(nodes)
문서 업데이트 처리
인덱스를 직접 관리할 때는 시간에 따라 변하는 데이터 소스를 다뤄야 해요. Index 클래스에는 삽입, 삭제, 업데이트, 새로고침 연산이 있으며, 아래에서 더 자세히 알아볼 수 있어요:
벡터 인덱스 저장하기
LlamaIndex는 수십 가지 벡터 스토어를 지원해요. 사용할 스토어를 지정하려면 StorageContext를 전달하고, 그 안에 vector_store 인자를 지정하면 돼요. Pinecone을 쓰는 예시는 다음과 같아요:
import pinecone
from llama_index.core import (
VectorStoreIndex,
SimpleDirectoryReader,
StorageContext,
)
from llama_index.vector_stores.pinecone import PineconeVectorStore
# init pinecone
pinecone.init(api_key="<api_key>", environment="<environment>")
pinecone.create_index(
"quickstart", dimension=1536, metric="euclidean", pod_type="p1"
)
# construct vector store and customize storage context
storage_context = StorageContext.from_defaults(
vector_store=PineconeVectorStore(pinecone.Index("quickstart"))
)
# Load documents and build index
documents = SimpleDirectoryReader(
"../../examples/data/paul_graham"
).load_data()
index = VectorStoreIndex.from_documents(
documents, storage_context=storage_context
)
VectorStoreIndex 사용 예시가 더 필요하면 vector store index 사용 예시 노트북을 참고하세요.
특정 벡터 스토어와 함께 VectorStoreIndex를 사용하는 예시는 Storing 섹션의 vector stores를 확인해 보세요.
구성 가능한 검색 (Composable Retrieval)
VectorStoreIndex(및 다른 어떤 인덱스/검색기도)는 다음을 포함한 일반 객체를 검색할 수 있어요:
- 노드 참조
- 쿼리 엔진
- 검색기
- 쿼리 파이프라인
이러한 객체가 검색되면 제공된 쿼리를 사용해 자동으로 실행돼요. 예를 들어:
from llama_index.core.schema import IndexNode
query_engine = other_index.as_query_engine
obj = IndexNode(
text="A query engine describing X, Y, and Z.",
obj=query_engine,
index_id="my_query_engine",
)
index = VectorStoreIndex(nodes=nodes, objects=[obj])
retriever = index.as_retriever(verbose=True)
쿼리 엔진을 포함한 인덱스 노드가 검색되면, 쿼리 엔진이 실행되고 결과 응답이 노드로 반환돼요.
자세한 내용은 가이드를 확인하세요.