◉GEMINI LABEN
●OMNI 1.2 — Gemini Omni 1.2 Flash が GA になりました(11/5)。最長15秒の動画生成と会話での編集に対応し、1.1 Flash は 12/3 に自動で 1.2 へ振り替わります●COMPUTER — Computer Use が Interactions / GenerateContent API で GA になりました(10/30)●LIVE — Live と TTS のプレビュー版は最短 11/17 に停止します(残り10日)。移行先は gemini-3.8-live と 3.8 系 TTS です●CLI — Gemini API CLI(gemini-api)がベータで登場(10/27)。エージェントやCI向けのゼロ依存クライアントです●2.5 PRO — gemini-2.5-pro と 2.5-flash は 12/1 から自動で振り替えられます(残り24日)。移行先は 3.8 Flash と 3.5 Flash-Lite です●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…●OMNI 1.2 — Gemini Omni 1.2 Flash が GA になりました(11/5)。最長15秒の動画生成と会話での編集に対応し、1.1 Flash は 12/3 に自動で 1.2 へ振り替わります●COMPUTER — Computer Use が Interactions / GenerateContent API で GA になりました(10/30)●LIVE — Live と TTS のプレビュー版は最短 11/17 に停止します(残り10日)。移行先は gemini-3.8-live と 3.8 系 TTS です●CLI — Gemini API CLI(gemini-api)がベータで登場(10/27)。エージェントやCI向けのゼロ依存クライアントです●2.5 PRO — gemini-2.5-pro と 2.5-flash は 12/1 から自動で振り替えられます(残り24日)。移行先は 3.8 Flash と 3.5 Flash-Lite です●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…
記事一覧/API / SDK
◈ API / SDK/2026-04-03中級

Gemini Embedding API × Pinecone でRAGシステムを本番構築する

Gemini Embedding APIとPineconeを組み合わせてRAGシステムを構築する手順を解説。インデックス設計からクエリ最適化、本番運用のコスト管理まで実践的なPythonコードで学べます。

gemini121rag21pineconeembeddings11vector-database4python112

取り組みの背景 — なぜGemini × Pineconeなのか

RAG(Retrieval-Augmented Generation)は、LLMに外部ナレッジを与えて回答精度を高める技術として、今や多くのプロダクトに採用されています。その中核となるのがベクターデータベースです。

数あるベクターDBの中でもPineconeは、マネージドサービスとして完全クラウド運用できる手軽さが魅力です。一方、Gemini Embedding APIは最大3,072次元のテキスト埋め込みを生成でき、日本語を含む多言語で高い検索精度を発揮します。

この2つを組み合わせることで、サーバー管理不要・スケーラブルなRAGシステムをすばやく構築できます。ここでは環境準備からクエリ最適化、本番運用のポイントまで、実際に動くPythonコードとともに解説します。

前提知識と環境準備

必要なアカウントとキー

作業を始める前に以下を用意してください。

ライブラリのインストール

pip install google-generativeai pinecone-client python-dotenv

.env ファイルを作成してキーを管理します。

# .env
GOOGLE_API_KEY=YOUR_GOOGLE_API_KEY
PINECONE_API_KEY=YOUR_PINECONE_API_KEY

Pineconeインデックスの作成

Pineconeのインデックス(コレクション)を作成する際、次元数をEmbeddingモデルに合わせることが最重要です。gemini-embedding-004 の次元数は 768 です。

import os
from dotenv import load_dotenv
from pinecone import Pinecone, ServerlessSpec
 
load_dotenv()
 
# Pineconeクライアント初期化
pc = Pinecone(api_key=os.environ["PINECONE_API_KEY"])
 
INDEX_NAME = "gemini-rag-index"
 
# インデックスが存在しない場合のみ作成
if INDEX_NAME not in pc.list_indexes().names():
    pc.create_index(
        name=INDEX_NAME,
        dimension=768,          # gemini-embedding-004 の次元数
        metric="cosine",        # コサイン類似度で検索
        spec=ServerlessSpec(
            cloud="aws",
            region="us-east-1"  # フリープランで利用可能なリージョン
        )
    )
    print(f"✅ インデックス '{INDEX_NAME}' を作成しました")
else:
    print(f"✅ インデックス '{INDEX_NAME}' は既に存在します")
 
index = pc.Index(INDEX_NAME)

ドキュメントの埋め込みとインデックス登録

Gemini Embedding APIで埋め込みを生成する

import google.generativeai as genai
 
load_dotenv()
genai.configure(api_key=os.environ["GOOGLE_API_KEY"])
 
def embed_texts(texts: list[str], task_type: str = "RETRIEVAL_DOCUMENT") -> list[list[float]]:
    """
    テキストリストをGemini Embedding APIで埋め込みに変換する。
    task_type:
        RETRIEVAL_DOCUMENT  — インデックス登録時(ドキュメント側)
        RETRIEVAL_QUERY     — 検索クエリ側
    """
    result = genai.embed_content(
        model="models/gemini-embedding-004",
        content=texts,
        task_type=task_type
    )
    # result["embedding"] は texts の長さと同じリストを返す
    return result["embedding"]

task_type を使い分けるのがポイントです。ドキュメント登録時は RETRIEVAL_DOCUMENT、検索時は RETRIEVAL_QUERY を指定することで、検索精度が向上します。

ドキュメントをPineconeに登録する

import hashlib
import json
 
def upsert_documents(docs: list[dict], index, batch_size: int = 50) -> None:
    """
    docs: [{"id": "...", "text": "...", "metadata": {...}}, ...]
    バッチサイズ50件ずつPineconeにアップサート
    """
    for i in range(0, len(docs), batch_size):
        batch = docs[i : i + batch_size]
        texts  = [d["text"] for d in batch]
        embeds = embed_texts(texts, task_type="RETRIEVAL_DOCUMENT")
 
        vectors = [
            {
                "id":       d["id"],
                "values":   embed,
                "metadata": {**d.get("metadata", {}), "text": d["text"]}
            }
            for d, embed in zip(batch, embeds)
        ]
        index.upsert(vectors=vectors)
        print(f"  登録済: {i + len(batch)}/{len(docs)} 件")
 
# 使用例
sample_docs = [
    {
        "id": "doc-001",
        "text": "Gemini 2.5 Proは2026年3月にリリースされたGoogleの最新AIモデルです。",
        "metadata": {"source": "news", "lang": "ja"}
    },
    {
        "id": "doc-002",
        "text": "Pineconeはサーバーレスアーキテクチャのベクターデータベースで、スケールアウトが容易です。",
        "metadata": {"source": "docs", "lang": "ja"}
    },
    {
        "id": "doc-003",
        "text": "RAG(Retrieval-Augmented Generation)は検索とLLMを組み合わせて回答精度を上げる手法です。",
        "metadata": {"source": "tutorial", "lang": "ja"}
    },
]
 
upsert_documents(sample_docs, index)
# 期待出力: 登録済: 3/3 件

RAGパイプラインの実装

セマンティック検索でコンテキストを取得する

def search_context(query: str, index, top_k: int = 5) -> list[dict]:
    """
    クエリに関連するドキュメントをPineconeから取得する。
    戻り値: [{"text": ..., "score": ..., "metadata": ...}, ...]
    """
    # クエリ用埋め込みを生成
    query_embed = embed_texts([query], task_type="RETRIEVAL_QUERY")[0]
 
    results = index.query(
        vector=query_embed,
        top_k=top_k,
        include_metadata=True
    )
 
    contexts = []
    for match in results["matches"]:
        contexts.append({
            "text":     match["metadata"].get("text", ""),
            "score":    match["score"],
            "metadata": match["metadata"]
        })
    return contexts

Geminiに検索結果を渡して回答を生成する

model = genai.GenerativeModel("gemini-2.5-flash")
 
def answer_with_rag(question: str, index, top_k: int = 5) -> str:
    """
    RAGパイプライン全体: 検索 → コンテキスト構築 → 生成
    """
    # 1. セマンティック検索
    contexts = search_context(question, index, top_k=top_k)
 
    if not contexts:
        return "関連するドキュメントが見つかりませんでした。"
 
    # 2. コンテキストをプロンプトに組み込む
    context_text = "\n\n".join(
        f"[参考{i+1}(類似度: {c['score']:.3f})]\n{c['text']}"
        for i, c in enumerate(contexts)
    )
 
    prompt = f"""以下の参考情報をもとに、質問に正確かつ簡潔に答えてください。
参考情報に含まれない内容は「情報がありません」と答えてください。
 
## 参考情報
{context_text}
 
## 質問
{question}
"""
 
    response = model.generate_content(prompt)
    return response.text
 
# 使用例
answer = answer_with_rag("Gemini 2.5 Proとは何ですか?", index)
print(answer)
# 期待出力: Gemini 2.5 Proは2026年3月にリリースされたGoogleの最新AIモデルです。

本番運用での最適化ポイント

メタデータフィルタリングで検索精度を上げる

Pineconeはメタデータを使った絞り込みに対応しています。大量のドキュメントを扱う場合、まずメタデータでフィルタリングしてからベクター検索すると精度と速度が向上します。

# 日本語ドキュメントだけを対象に検索する例
filtered_results = index.query(
    vector=query_embed,
    top_k=5,
    filter={"lang": {"$eq": "ja"}},  # メタデータフィルター
    include_metadata=True
)

チャンキング戦略でRAG精度を上げる

長文ドキュメントをそのままEmbeddingすると、重要な情報が希薄になります。実運用ではチャンク分割が必要です。

def chunk_text(text: str, chunk_size: int = 500, overlap: int = 50) -> list[str]:
    """
    テキストをオーバーラップ付きでチャンク分割する。
    chunk_size: 1チャンクの最大文字数
    overlap:    前後チャンクとの重複文字数(文脈の連続性を保つため)
    """
    chunks = []
    start = 0
    while start < len(text):
        end = start + chunk_size
        chunks.append(text[start:end])
        start = end - overlap  # オーバーラップ分だけ戻る
    return chunks

Pineconeフリープランのコスト管理

フリープランでは 5つのインデックス と 2GBのストレージ が利用できます。本番環境での費用管理のポイントをまとめます。

  • 不要なベクターを定期的に削除: index.delete(ids=["old-doc-001"]) で個別削除
  • バッチ処理で登録コストを下げる: 1件ずつ upsert するより50〜100件まとめてリクエストする
  • クエリ頻度の監視: Pineconeダッシュボードで月次クエリ数を確認し、スロットリングを避ける

Gemini Embedding APIのコスト最適化については、Gemini API コンテキストキャッシュ完全ガイド でさらに詳しく解説しています。

まとめ

ここではGemini Embedding API と Pinecone を組み合わせたRAGシステムの構築手順を解説しました。

  • Pineconeインデックス作成: 次元数768・cosine類似度で設定
  • Embedding生成: task_type でドキュメント用とクエリ用を使い分け
  • バッチ登録: 50件単位でアップサートしてAPI呼び出しを最小化
  • メタデータフィルター: 検索対象を絞り込んで精度と速度を向上
  • チャンキング: 500文字・50文字オーバーラップで長文の情報密度を確保

さらに高度なRAGパターン(マルチモーダル対応・リランキング・ハイブリッド検索)を学びたい方には、Gemini APIマルチモーダルRAGパイプライン構築ガイド がおすすめです。

Pinecone × Gemini の組み合わせは、ゼロからのベクターDB構築が不要なため、プロトタイプから本番まで迅速に移行できます。ぜひ自社のナレッジベースに適用してみてください。

シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

◈ API / SDK2026-09-04
ループ音源のプチノイズは、Gemini に聴かせる前に波形の端で切り分けられます
環境音のループ再生で折り返しだけがプチッと鳴る。音声理解に丸ごと投げる前に、波形の端の段差を内部の変化量で正規化してふるい分ける手順と、配布形式への変換で継ぎ目が作り直される落とし穴をまとめました。
◈ API / SDK2026-05-18
Gemini Vision で壁紙アプリの自動カテゴリ分類を実装した話
個人開発の壁紙アプリで Gemini Vision API を使い、画像の自動カテゴリ分類を実装した実体験です。精度改善のプロセスと、公式ドキュメントには載っていない落とし穴、GPT-4o Vision とのコスト比較までまとめました。
◈ API / SDK2026-05-16
Gemini Vision で壁紙アプリのカテゴリ自動分類を試した — 精度と落とし穴の実記録
壁紙アプリの画像カテゴリ自動分類を Gemini Vision で実装した記録。精度67%から87%への改善手順と、confidence 閾値で人間レビューを全体の15%に絞り込む運用設計を紹介します。