Pinecone 벡터 스토어
Pinecone 벡터 스토어
Pinecone을 LlamaIndex의 벡터 스토어로 사용해 문서를 벡터화하고 검색하는 방법을 노트북 형태로 보여드릴게요. 노트북이든 실제 앱이든, PineconeVectorStore로 인덱스를 만들고 질의하는 흐름을 그대로 따라 하시면 됩니다. 먼저 llama-index-vector-stores-pinecone 패키지를 설치하겠습니다.
출처: 문서
본문
Colab에서 노트북을 여신다면 LlamaIndex 🦙를 설치해야 할 수 있어요.
%pip install llama-index llama-index-vector-stores-pinecone
import logging
import sys
import os
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
Pinecone 인덱스 만들기
from pinecone import Pinecone, ServerlessSpec
os.environ["PINECONE_API_KEY"] = "..."
os.environ["OPENAI_API_KEY"] = "sk-proj-..."
api_key = os.environ["PINECONE_API_KEY"]
pc = Pinecone(api_key=api_key)
# 필요하면 삭제
# pc.delete_index("quickstart")
# 차원은 text-embedding-ada-002 용
pc.create_index(
name="quickstart",
dimension=1536,
metric="euclidean",
spec=ServerlessSpec(cloud="aws", region="us-east-1"),
)
# Pod 기반 Pinecone 인덱스가 필요하다면 이렇게도 만들 수 있어요:
#
# from pinecone import Pinecone, PodSpec
#
# pc = Pinecone(api_key='xxx')
#
# pc.create_index(
# name='my-index',
# dimension=1536,
# metric='cosine',
# spec=PodSpec(
# environment='us-east1-gcp',
# pod_type='p1.x1',
# pods=1
# )
# )
#
pinecone_index = pc.Index("quickstart")
문서를 불러와 PineconeVectorStore와 VectorStoreIndex 만들기
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.vector_stores.pinecone import PineconeVectorStore
from IPython.display import Markdown, display
데이터 다운로드
!mkdir -p 'data/paul_graham/'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'
# 문서 로드
documents = SimpleDirectoryReader("./data/paul_graham").load_data()
# 메타데이터 필터 없이 초기화
from llama_index.core import StorageContext
if "OPENAI_API_KEY" not in os.environ:
raise EnvironmentError(f"Environment variable OPENAI_API_KEY is not set")
vector_store = PineconeVectorStore(pinecone_index=pinecone_index)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents, storage_context=storage_context
)
인덱스 질의하기 (Query Index)
인덱스가 준비되기까지 1분 정도 걸릴 수 있어요!
# 더 자세한 출력을 보려면 Logging을 DEBUG로 설정
query_engine = index.as_query_engine()
response = query_engine.query("What did the author do growing up?")
INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK"
HTTP Request: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK"
INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
display(Markdown(f"<b>{response}</b>"))
저자가 어릴 때 글쓰기와 프로그래밍에 몰두했다는 답변이 나옵니다. 단편 소설을 쓰고 IBM 1401에서 프로그램을 작성해 봤고, 나중에 마이크로컴퓨터를 얻은 뒤에는 간단한 게임과 워드 프로세서를 만들며 본격적으로 프로그래밍을 시작했다는 내용이네요.
필터링 (Filtering)
필터를 사용해 노드 목록을 직접 가져올 수도 있어요.
from llama_index.core.vector_stores.types import (
MetadataFilter,
MetadataFilters,
FilterOperator,
FilterCondition,
)
filter = MetadataFilters(
filters=[
MetadataFilter(
key="file_path",
value="/Users/loganmarkewich/giant_change/llama_index/docs/examples/vector_stores/data/paul_graham/paul_graham_essay.txt",
operator=FilterOperator.EQ,
)
],
condition=FilterCondition.AND,
)
필터로 노드를 직접 가져올 수 있어요. 아래 코드는 필터와 일치하는 모든 노드를 반환합니다.
nodes = vector_store.get_nodes(filters=filter, limit=100)
print(len(nodes))
22
top-k와 필터를 함께 사용해 가져올 수도 있어요.
query_engine = index.as_query_engine(similarity_top_k=2, filters=filter)
response = query_engine.query("What did the author do growing up?")
print(len(response.source_nodes))
INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK"
HTTP Request: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK"
INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
2