Pinecone 벡터 스토어 - 메타데이터 필터

Pinecone 벡터 스토어 - 메타데이터 필터

Pinecone 벡터 스토어에서 메타데이터 필터를 활용하는 방법을 보여드릴게요. 노드에 메타데이터를 넣어 저장하고, 검색할 때 특정 메타데이터 조건(테마·연도·작가 등)을 걸러 원하는 결과만 가져올 수 있어요. MetadataFilters와 FilterOperator·FilterCondition 조합으로 AND·OR 조건을 자유롭게 구성할 수 있습니다.

출처: 문서

본문

Colab에서 노트북을 여신다면 LlamaIndex 🦙를 설치해야 할 수 있어요.

%pip install llama-index-vector-stores-pinecone
# !pip install llama-index>=0.9.31 pinecone-client>=3.0.0
import logging
import sys
import os


logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
import os


os.environ[
    "PINECONE_API_KEY"
] = "<Your Pinecone API key, from app.pinecone.io>"
os.environ["OPENAI_API_KEY"] = "sk-..."

Pinecone 인덱스를 만들고 연결하기

from pinecone import Pinecone
from pinecone import ServerlessSpec


api_key = os.environ["PINECONE_API_KEY"]
pc = Pinecone(api_key=api_key)
# 필요하면 삭제
# pc.delete_index("quickstart-index")
# 차원은 text-embedding-ada-002 용
pc.create_index(
    "quickstart-index",
    dimension=1536,
    metric="euclidean",
    spec=ServerlessSpec(cloud="aws", region="us-west-2"),
)
pinecone_index = pc.Index("quickstart-index")

PineconeVectorStore와 VectorStoreIndex 만들기

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.pinecone import PineconeVectorStore
from llama_index.core.schema import TextNode


nodes = [
    TextNode(
        text="The Shawshank Redemption",
        metadata={
            "author": "Stephen King",
            "theme": "Friendship",
            "year": 1994,
        },
    ),
    TextNode(
        text="The Godfather",
        metadata={
            "director": "Francis Ford Coppola",
            "theme": "Mafia",
            "year": 1972,
        },
    ),
    TextNode(
        text="Inception",
        metadata={
            "director": "Christopher Nolan",
            "theme": "Fiction",
            "year": 2010,
        },
    ),
    TextNode(
        text="To Kill a Mockingbird",
        metadata={
            "author": "Harper Lee",
            "theme": "Mafia",
            "year": 1960,
        },
    ),
    TextNode(
        text="1984",
        metadata={
            "author": "George Orwell",
            "theme": "Totalitarianism",
            "year": 1949,
        },
    ),
    TextNode(
        text="The Great Gatsby",
        metadata={
            "author": "F. Scott Fitzgerald",
            "theme": "The American Dream",
            "year": 1925,
        },
    ),
    TextNode(
        text="Harry Potter and the Sorcerer's Stone",
        metadata={
            "author": "J.K. Rowling",
            "theme": "Fiction",
            "year": 1997,
        },
    ),
]
vector_store = PineconeVectorStore(
    pinecone_index=pinecone_index, namespace="test_05_14"
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex(nodes, storage_context=storage_context)

(upsert 실행 로그 생략 — 임베딩 생성 후 7개 벡터가 upsert됩니다)

메타데이터 필터 정의하기

from llama_index.core.vector_stores import (
    MetadataFilter,
    MetadataFilters,
    FilterOperator,
)


filters = MetadataFilters(
    filters=[
        MetadataFilter(
            key="theme", operator=FilterOperator.EQ, value="Fiction"
        ),
    ]
)

필터로 벡터 스토어에서 검색하기

retriever = index.as_retriever(filters=filters)
retriever.retrieve("What is inception about?")

(실행 로그 및 임베딩 배열 출력 생략)

AND 조건의 메타데이터 필터 여러 개

from llama_index.core.vector_stores import FilterOperator, FilterCondition


filters = MetadataFilters(
    filters=[
        MetadataFilter(key="theme", value="Fiction"),
        MetadataFilter(key="year", value=1997, operator=FilterOperator.GT),
    ],
    condition=FilterCondition.AND,
)


retriever = index.as_retriever(filters=filters)
retriever.retrieve("Harry Potter?")

(실행 로그 및 임베딩 배열 출력 생략)

OR 조건의 메타데이터 필터 여러 개

from llama_index.core.vector_stores import FilterOperator, FilterCondition




filters = MetadataFilters(
    filters=[
        MetadataFilter(key="theme", value="Fiction"),
        MetadataFilter(key="year", value=1997, operator=FilterOperator.GT),
    ],
    condition=FilterCondition.OR,
)


retriever = index.as_retriever(filters=filters)
retriever.retrieve("Harry Potter?")

(실행 로그 및 임베딩 배열 출력 생략)

Pinecone 특화 키워드 인자 사용하기

필터를 직접 구성하는 대신, Pinecone 고유의 filter 딕셔너리를 vector_store_kwargs로 넘겨 줄 수도 있어요.

retriever = index.as_retriever(
    vector_store_kwargs={"filter": {"theme": "Mafia"}}
)
retriever.retrieve("What is inception about?")

(실행 로그 및 임베딩 배열 출력 생략)

더 알아보기 (Learn more)