0Pricing
AI Engineering Academy · 강의

Pinecone 시작하기

Pinecone 인덱스를 만들고, 메타데이터와 함께 벡터를 업서트하며, 필터를 사용해 유사도 질의를 수행하고, 서로 다른 데이터 모음을 분리하도록 네임스페이스를 관리합니다.

Pinecone 시작하기은(는) CoddyKit의 무료 AI Engineering Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Engineering Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

Pinecone이란 무엇인가요

Pinecone은 인프라, 확장, 백업을 자동으로 처리하는 완전 관리형 벡터 데이터베이스입니다. Python SDK를 통해 벡터와 메타데이터를 API 호출로 전송하여 사용합니다. Pinecone은 자체 서버에 이를 저장하고, 벡터가 수십억 개에 이르더라도 낮은 지연 시간으로 유사도 쿼리에 응답합니다.

학습과 소규모 운영 작업에 충분한 무료 요금제를 제공합니다.

Pinecone SDK 설치

Pinecone 클라이언트를 설치하고 API 키로 초기화하십시오. API 키는 환경 변수에 저장하고 소스 파일에 비밀 정보를 직접 입력하지 마십시오. Pinecone 클래스는 모든 작업의 주요 진입점입니다.

# pip install pinecone-client
import os
from pinecone import Pinecone

pc = Pinecone(api_key=os.environ['PINECONE_API_KEY'])

# List existing indexes to verify connection
existing = pc.list_indexes().names()
print('Existing indexes:', existing)

Pinecone 인덱스 생성

Pinecone 인덱스는 벡터를 저장하는 컬렉션입니다. 인덱스를 생성할 때는 dimension(임베딩 모델과 일치해야 함)과 유사도 계산을 위한 metric을 지정해야 합니다. OpenAI 임베딩에는 dimension=1536과 metric='cosine'을 사용하십시오.

인덱스 생성은 멱등적입니다. 서버리스 사양은 용량을 미리 할당하지 않고 필요할 때 인덱스를 생성합니다.

from pinecone import Pinecone, ServerlessSpec
import os

pc = Pinecone(api_key=os.environ['PINECONE_API_KEY'])

index_name = 'my-rag-index'

if index_name not in pc.list_indexes().names():
    pc.create_index(
        name=index_name,
        dimension=1536,         # text-embedding-3-small dimension
        metric='cosine',
        spec=ServerlessSpec(
            cloud='aws',
            region='us-east-1'
        )
    )
    print(f'Created index: {index_name}')
else:
    print(f'Index already exists: {index_name}')

index = pc.Index(index_name)

메타데이터와 함께 벡터 업서트하기

Pinecone은 upsert(삽입 또는 업데이트) 작업을 사용합니다. 각 벡터에는 고유한 id 문자열, values(부동 소수점 목록 형태의 임베딩), 선택적 metadata(필터링할 수 있는 필드의 딕셔너리)가 필요합니다. 기존 id로 upsert하면 기존 벡터가 교체됩니다.

from openai import OpenAI

oai = OpenAI()

documents = [
    {'id': 'doc-001', 'text': 'What is RAG and how does it work?', 'category': 'faq'},
    {'id': 'doc-002', 'text': 'Pinecone is a managed vector database.', 'category': 'docs'},
    {'id': 'doc-003', 'text': 'OpenAI embeddings have 1536 dimensions.', 'category': 'docs'}
]

texts = [d['text'] for d in documents]
resp = oai.embeddings.create(model='text-embedding-3-small', input=texts)

vectors = [
    {
        'id': doc['id'],
        'values': resp.data[i].embedding,
        'metadata': {'text': doc['text'], 'category': doc['category']}
    }
    for i, doc in enumerate(documents)
]

index.upsert(vectors=vectors)
print(f'Upserted {len(vectors)} vectors')

Pinecone 인덱스 쿼리하기

검색하려면 쿼리를 임베딩한 다음 쿼리 벡터와 반환할 결과 수를 지정하는 top_k를 사용하여 index.query()를 호출하십시오. 일치하는 id 및 점수와 함께 저장된 메타데이터도 가져오려면 include_metadata=True로 설정하십시오.

from openai import OpenAI

oai = OpenAI()

query = 'How many dimensions do OpenAI embeddings have?'
q_resp = oai.embeddings.create(model='text-embedding-3-small', input=query)
q_vec = q_resp.data[0].embedding

results = index.query(
    vector=q_vec,
    top_k=3,
    include_metadata=True
)

for match in results['matches']:
    score = match['score']
    text = match['metadata']['text']
    print(f'{score:.4f}: {text}')

메타데이터로 필터링하기

Pinecone은 사전 필터링을 지원합니다. ANN을 실행하기 전에 메타데이터 조건과 일치하는 벡터로 검색 범위를 좁히는 방식입니다. MongoDB 스타일 연산자인 $eq, $in, $gt, $lt, $and, $or와 함께 filter 매개변수를 사용하십시오.

필터 성능을 보장하려면 인덱스를 생성할 때 필터링할 메타데이터 필드를 항상 인덱싱하십시오.

# Filter to only 'docs' category results
results = index.query(
    vector=q_vec,
    top_k=5,
    filter={
        'category': {'$eq': 'docs'}
    },
    include_metadata=True
)

print(f'Filtered results: {len(results["matches"])}')
for m in results['matches']:
    print(f'  [{m["metadata"]["category"]}] {m["metadata"]["text"][:60]}')

데이터 격리를 위한 네임스페이스

Pinecone 네임스페이스는 하나의 인덱스를 서로 격리된 세그먼트로 나눕니다. 한 네임스페이스에서 실행한 쿼리는 다른 네임스페이스의 결과를 절대 반환하지 않으므로, 각 고객이 자신의 문서만 검색해야 하는 멀티 테넌트 RAG 시스템에 적합합니다.

upsert와 query 모두 선택적 namespace 문자열을 받습니다. 기본 네임스페이스는 빈 문자열입니다.

# Upsert into a specific namespace
index.upsert(
    vectors=[{'id': 'doc-001', 'values': q_vec, 'metadata': {'text': 'Tenant A doc'}}],
    namespace='tenant-a'
)

# Query only tenant-a's documents
results = index.query(
    vector=q_vec,
    top_k=5,
    namespace='tenant-a',
    include_metadata=True
)
print(f'Tenant-A results: {len(results["matches"])}')

대규모 말뭉치를 위한 배치 업서트

수천 개의 문서를 인덱싱할 때는 Pinecone이 권장하는 배치 크기에 따라 벡터를 upsert 호출당 최대 벡터 100개의 배치로 나누십시오. 요청당 약 4MB인 페이로드 크기 제한 때문에 더 큰 배치는 크기 제한에 걸릴 수 있습니다.

def batch_upsert(index, vectors, batch_size=100):
    total = len(vectors)
    for start in range(0, total, batch_size):
        batch = vectors[start:start + batch_size]
        index.upsert(vectors=batch)
        print(f'Upserted {min(start + batch_size, total)}/{total}')

# Usage:
# batch_upsert(index, all_vectors, batch_size=100)

인덱스 통계 확인

index.describe_index_stats()를 사용하면 각 네임스페이스에 저장된 벡터 수와 전체 벡터 수를 확인할 수 있습니다. upsert가 성공적으로 완료되었는지 확인하고 시간에 따른 인덱스 증가를 모니터링하는 데 유용합니다.

stats = index.describe_index_stats()

print(f'Total vectors: {stats["total_vector_count"]}')
print(f'Namespaces:')
for ns, info in stats.get('namespaces', {}).items():
    print(f'  {ns!r}: {info["vector_count"]} vectors')

벡터 삭제 및 업데이트

id로 특정 벡터를 제거하려면 index.delete(ids=[...])를 사용하십시오. 벡터를 업데이트하려면(예: 문서가 수정된 경우) 동일한 id로 upsert하면 됩니다. Pinecone이 기존 항목을 덮어씁니다.

네임스페이스의 모든 벡터를 삭제하려면(예: 전체 새로 고침 후 다시 인덱싱하려는 경우) index.delete(delete_all=True, namespace='...')를 사용하십시오.

# Delete specific vectors by id
index.delete(ids=['doc-001', 'doc-002'])

# Update a vector (upsert overwrites by id)
index.upsert(vectors=[{
    'id': 'doc-003',
    'values': q_vec,            # new embedding
    'metadata': {'text': 'Updated content.'}
}])

# Delete all vectors in a namespace
# index.delete(delete_all=True, namespace='tenant-a')

Pinecone 요금 및 무료 요금제

Pinecone은 저장 공간 2GB를 제공하는 무료 서버리스 요금제를 제공하며, 1536차원 벡터를 약 30만 개까지 저장할 수 있습니다. 이를 초과하면 서버리스 요금제에서는 사용한 읽기 단위와 쓰기 단위에 따라 요금이 부과됩니다.

운영 작업의 월 비용은 다음과 같이 계산하여 추정할 수 있습니다. (일일 쿼리 수 × 30 × 쿼리당 비용) + (전체 벡터 수 × 저장소 비용). 트래픽이 변동하는 작업에서는 서버리스가 포드 기반 요금제보다 비용 효율적인 경우가 많습니다.

간단한 확인

이 강의에서 다룬 AI 엔지니어링 개념을 얼마나 이해했는지 확인해 보십시오.

강의 요약

이 강의에서 배운 내용은 다음과 같습니다. Pinecone 인덱스의 차원과 지표는 임베딩 모델과 일치해야 합니다. upsert 작업은 고유한 id를 사용하므로, 문서를 업데이트할 때 동일한 id로 다시 upsert하면 됩니다. 또한 네임스페이스는 멀티 테넌트 사용 사례를 위해 하나의 인덱스 안에서 벡터 컬렉션을 격리합니다. 다음으로 PostgreSQL에 벡터 검색을 직접 추가하는 pgvector를 살펴보겠습니다.

자주 묻는 질문

“Pinecone 시작하기” 강의는 무료인가요?

네 — “Pinecone 시작하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Engineering Academy 강의 전체를 잠금 해제할 수 있습니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“Pinecone 시작하기”에서 뭘 배우나요?

Pinecone 인덱스를 만들고, 메타데이터와 함께 벡터를 업서트하며, 필터를 사용해 유사도 질의를 수행하고, 서로 다른 데이터 모음을 분리하도록 네임스페이스를 관리합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Engineering Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Engineering Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Engineering Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“Pinecone 시작하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Engineering Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Engineering Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 벡터 데이터베이스가 필요한 이유
  2. Pinecone 시작하기
  3. pgvector: PostgreSQL의 임베딩
  4. 벡터 저장소 선택 및 벤치마킹
← AI Engineering Academy(으)로 돌아가기