0Pricing
AI Engineering Academy · レッスン

Pineconeを始める

Pineconeのindexを作成し、メタデータ付きでベクトルをupsertし、フィルター付きの類似度検索を実行して、異なるデータコレクションを分離するnamespaceを管理します。

「Pineconeを始める」はCoddyKit上の無料AI Engineering Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応の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でアップサートすると、古いベクトルが置き換えられます。

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()を呼び出します。include_metadata=Trueを設定すると、一致したIDやスコアとともに保存済みのメタデータも取得できます。

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を実行する前に、メタデータ条件に一致するベクトルだけに検索範囲を絞り込む機能です。filterパラメータと、MongoDB形式の演算子である$eq、$in、$gt、$lt、$and、$orを使用します。

フィルタの性能を確保するため、インデックス作成時に、フィルタリングする予定のメタデータフィールドを必ずインデックス化してください。

# 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の名前空間は、1つのインデックスを分離されたセグメントに分割します。ある名前空間で実行したクエリが別の名前空間の結果を返すことはありません。そのため、顧客ごとに自分の文書だけを検索させるマルチテナント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"])}')

大規模コーパスのためのバッチアップサート

数千件の文書をインデックス化するときは、ベクトルを1回のアップサート呼び出しあたり最大100個のバッチに分割してください(Pineconeが推奨するバッチサイズです)。リクエストあたり約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()を使うと、各名前空間に保存されているベクトル数と、ベクトルの総数を確認できます。アップサートが正常に完了したことの検証や、時間の経過に伴うインデックスの増加の監視に役立ちます。

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')

ベクトルの削除と更新

index.delete(ids=[...])を使うと、idを指定して特定のベクトルを削除できます。ベクトルを更新する場合(たとえば文書が改訂された場合)は、同じidでアップサートするだけです。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万個分に相当します。それを超えると、サーバーレスの料金は使用した読み取りユニットと書き込みユニットに応じて発生します。

本番ワークロードでは、次の式で月額費用を見積もります。(1日あたりのクエリ数 × 30 × 1クエリあたりの料金)+(ベクトル総数 × ストレージ料金)。トラフィックが変動するワークロードでは、サーバーレスのほうがポッドベースのプランより費用対効果が高いことがよくあります。

クイックチェック

このレッスンで学んだAIエンジニアリングの概念を確認しましょう。

レッスンのまとめ

このレッスンでは、次のことを学びました。Pineconeのインデックスでは、埋め込みモデルに一致する次元数とメトリックが必要である、アップサート操作では一意のidを使用するため、文書の更新は同じidで再度アップサートするだけで行える、そして名前空間によって、1つのインデックス内のベクトルコレクションをマルチテナントの用途向けに分離できるということです。次は、ベクトル検索をPostgreSQLに直接組み込むpgvectorを見ていきます。

よくある質問

「Pineconeを始める」レッスンは無料ですか?

はい。「Pineconeを始める」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Engineering Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Engineering Academyコースには全4レッスンが含まれています。

「Pineconeを始める」で何を学びますか?

Pineconeのindexを作成し、メタデータ付きでベクトルをupsertし、フィルター付きの類似度検索を実行して、異なるデータコレクションを分離するnamespaceを管理します。 ブラウザで直接実行するハンズオンコードでAI Engineering Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

AI Engineering Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAI Engineering Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Pineconeを始める」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAI Engineering Academyレッスンでコードを書いて実行できますか?

はい。すべてのAI Engineering Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Vector Databaseが必要な理由
  2. Pineconeを始める
  3. pgvector:PostgreSQLでEmbeddingを扱う
  4. Vector Storeの選定とベンチマーク
← AI Engineering Academyに戻る