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)

쿼리 엔진을 포함한 인덱스 노드가 검색되면, 쿼리 엔진이 실행되고 결과 응답이 노드로 반환돼요.

자세한 내용은 가이드를 확인하세요.

더 알아보기 (Learn more)