For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション

取得

意味的な類似性を使ってデータを検索します。

Retrieval API を使うと、データに対して セマンティック検索を実行できます。セマンティック検索は、キーワードがほとんど一致しない場合やまったく一致しない場合でも、意味的に類似した結果を見つける手法です。取得は単独でも役立ちますが、OpenAI のモデルと組み合わせて応答を生成する際に特に力を発揮します。

取得の概念図

Retrieval API は、データのインデックスとして機能するベクトルストアを基盤としています。このガイドでは、セマンティック検索の実行方法と、ベクトルストアの詳細を説明します。

クイックスタート

  • ベクトルストアを作成 し、ファイルをアップロードします。

  • ファイルを含むベクトルストアの作成
    from openai import OpenAI
    
    client = OpenAI()
    
    vector_store = client.vector_stores.create(        # Create vector store
        name="Support FAQ",
    )
    
    client.vector_stores.files.upload_and_poll(        # Upload file
        vector_store_id=vector_store.id,
        file=open("customer_policies.txt", "rb")
    )
  • 検索クエリを送信 して、関連性の高い結果を取得します。

  • 検索クエリ
    user_query = "What is the return policy?"
    
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query=user_query,
    )

    検索結果を OpenAI のモデルで活用する方法については、応答の 生成のセクションを参照してください。

    セマンティック検索 は、ベクトル埋め込みを使って、意味的に関連する結果を見つける手法です。特に、共通のキーワードがほとんどない場合やまったくない場合でも、従来の検索手法では見逃される可能性のある結果を見つけられます。

    例として、"When did we go to the moon?" に対してどのような結果が得られるか見てみましょう。

    テキストキーワードの類似度意味的な類似度
    初めての月面着陸は 1969 年 7 月でした。0%65%
    初めて月面に降り立った人はニール・アームストロングでした。27%43%
    月餅を食べたら、おいしかったです。40%28%

    (キーワードの類似度には共通集合と和集合の比を使い、意味的な類似度には text-embedding-3-small によるコサイン類似度を使っています。)

    最も関連性の高い結果には、検索クエリに含まれる単語が 1 つもないことに注目してください。この柔軟性により、セマンティック検索は規模を問わずナレッジベースを検索するための強力な手法となります。

    セマンティック検索はベクトルストアを基盤としています。ベクトルストアについては、このガイドの後半で詳しく説明します。このセクションでは、セマンティック検索の仕組みに焦点を当てます。

    search 関数を使い、query を自然言語で指定することで、ベクトルストアを検索できます。結果はリストとして返され、各結果には関連するチャンク、類似度スコア、元のファイルが含まれます。

    検索クエリ
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query="How many woodchucks are allowed per passenger?",
    )
    結果
    {
      "object": "vector_store.search_results.page",
      "search_query": "How many woodchucks are allowed per passenger?",
      "data": [
        {
          "file_id": "file-12345",
          "filename": "woodchuck_policy.txt",
          "score": 0.85,
          "attributes": {
            "region": "North America",
            "author": "Wildlife Department"
          },
          "content": [
            {
              "type": "text",
              "text": "According to the latest regulations, each passenger is allowed to carry up to two woodchucks."
            },
            {
              "type": "text",
              "text": "Ensure that the woodchucks are properly contained during transport."
            }
          ]
        },
        {
          "file_id": "file-67890",
          "filename": "transport_guidelines.txt",
          "score": 0.75,
          "attributes": {
            "region": "North America",
            "author": "Transport Authority"
          },
          "content": [
            {
              "type": "text",
              "text": "Passengers must adhere to the guidelines set forth by the Transport Authority regarding the transport of woodchucks."
            }
          ]
        }
      ],
      "has_more": false,
      "next_page": null
    }

    レスポンスに含まれる結果はデフォルトで最大 10 件ですが、max_num_results パラメーターを使うと最大 50 件まで設定できます。

    クエリの書き換え

    クエリの書き方によって検索結果の質が変わるため、最適な結果が得られるようにクエリを自動で書き換える設定を用意しています。この機能を有効にするには、search の実行時に rewrite_query=true を設定します。

    書き換えられたクエリは、結果の search_query フィールドで確認できます。

    書き換え前書き換え後
    本社ビルの高さを知りたいです。本社ビルの高さ
    危険物の輸送にはどのような安全規則がありますか?危険物の安全規則
    サービスの問題について苦情を申し立てるにはどうすればよいですか?サービスに関する苦情の申し立て手順

    属性によるフィルタリング

    属性によるフィルタリングでは、検索対象を特定の期間に限定するなどの条件を適用して、結果を絞り込めます。attribute_filter で条件を定義し、組み合わせることで、セマンティック検索を実行する前に、属性に基づいて対象ファイルを絞り込めます。

    ファイルの attributes に含まれる特定の key を指定した value と比較するには、 比較フィルター を使います。andor で複数のフィルターを組み合わせるには、 複合フィルター を使います。

    比較フィルター
    {
      "type": "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "in" | "nin",  // comparison operators
      "key": "attributes_key",                           // attributes key
      "value": "target_value"                             // value to compare against
    }
    複合フィルター
    {
      "type": "and" | "or",                                // logical operators
      "filters": [...]
    }

    以下にフィルターの例を示します。

    地域によるフィルタリング
    {
      "type": "eq",
      "key": "region",
      "value": "us"
    }

    ランキング

    ファイル検索の結果の関連性が不十分な場合は、ranking_options を調整して応答の品質を改善できます。具体的には、rankerautodefault-2024-08-21 などを指定し、score_threshold を 0.0 から 1.0 の範囲で設定します。score_threshold を高くすると、結果がより関連性の高いチャンクに絞られますが、有用な可能性のあるチャンクも除外されることがあります。ranking_options.hybrid_search を指定した場合は、hybrid_search.embedding_weightrrf_embedding_weight)と hybrid_search.text_weightrrf_text_weight)も調整し、逆数順位融合における、埋め込みによる意味的な一致とスパース検索によるキーワードの一致のバランスを制御できます。意味的な類似性を重視するには前者を、テキストの重複を重視するには後者を大きくします。少なくとも一方の重みはゼロより大きくしてください。

    ベクトルストア

    ベクトルストアは、Retrieval API とファイル検索ツールのセマンティック検索を支えるコンテナです。ベクトルストアにファイルを追加すると、自動的にチャンク分割、埋め込み生成、インデックス作成が行われます。

    ベクトルストアには、file オブジェクトを基にした vector_store_file オブジェクトが格納されます。

    オブジェクトの型
    説明
    fileFiles API を通じてアップロードされたコンテンツを表します。ベクトルストアでよく使われますが、ファインチューニングなどのユースケースにも使われます。
    vector_store検索可能なファイルを格納するコンテナです。
    vector_store.fileチャンク分割と埋め込み生成が行われ、vector_store に関連付けられた file を表す専用のラッパー型です。
    フィルタリングに使用する attributes マップを含みます。

    料金

    すべてのベクトルストアの合計ストレージ使用量に基づいて課金されます。使用量は、解析済みチャンクとそれに対応する埋め込みのサイズによって決まります。

    ストレージ費用
    1 GB まで(すべてのストアの合計)無料
    1 GB を超える分$0.10/GB/日

    費用を最小限に抑える方法については、有効期限ポリシーをご覧ください。

    ベクトルストアの操作

    ベクトルストアの作成
    client.vector_stores.create(
        name="Support FAQ",
        file_ids=["file_123"]
    )

    ベクトルストアファイルのオペレーション

    vector_store.filecreate など、一部のオペレーションは非同期で実行され、完了までに時間がかかる場合があります。完了するまで処理をブロックするには、create_and_poll などのヘルパー関数を使用してください。代わりに、状態を確認することもできます。ベクトルストアからのファイル削除は結果整合性に基づくため、削除したファイルの内容が短時間、検索結果に含まれる場合があります。

    ファイルの追加には、ベクトルストア ID ごとのレート制限が適用されます。/vector_stores/{vector_store_id}/files/vector_stores/{vector_store_id}/file_batches へのリクエストには、ベクトルストアごとに毎分 300 リクエストという共通の上限があります。

    ベクトルストアファイルの作成
    client.vector_stores.files.create_and_poll(
        vector_store_id="vs_123",
        file_id="file_123"
    )

    バッチオペレーション

    バッチ作成オペレーション
    client.vector_stores.file_batches.create_and_poll(
        vector_store_id="vs_123",
        files=[
            {
                "file_id": "file_123",
                "attributes": {"department": "finance"}
            },
            {
                "file_id": "file_456",
                "chunking_strategy": {
                    "type": "static",
                    "max_chunk_size_tokens": 1200,
                    "chunk_overlap_tokens": 200
                }
            }
        ]
    )

    バッチを作成する際は、file_ids と、必要に応じて attributeschunking_strategy を指定する方法と、files 配列を使い、ファイルごとに file_id と任意の attributeschunking_strategy を含むオブジェクトを渡す方法があります。この 2 つの方法は併用できません。すべてのファイルで同じ設定を共有するか、ファイルごとに設定を上書きするかを明確に制御できます。

    単一のベクトルストアへの取り込みでスループットを高めるには、可能な限りバッチ作成を使用することをお勧めします。バッチでは 1 回のリクエストに最大 500 ファイルを含められます。通常、ファイルを 1 つずつ作成するリクエストを多数送信する場合に比べて、競合が減り、処理全体のレイテンシが改善します。

    属性

    vector_store.file には、値の辞書である attributes を関連付けられます。この辞書は、属性フィルタリングを使ったセマンティック検索で参照できます。辞書には最大 16 個のキーを設定でき、各キーの上限は 256 文字です。

    属性付きベクトルストアファイルの作成
    client.vector_stores.files.create(
        vector_store_id="<vector_store_id>",
        file_id="file_123",
        attributes={
            "region": "US",
            "category": "Marketing",
            "date": 1672531200      # Jan 1, 2023
        }
    )

    有効期限ポリシー

    expires_after を使って、vector_store オブジェクトに有効期限ポリシーを設定できます。ベクトルストアの有効期限が切れると、関連付けられたすべての vector_store.file オブジェクトが削除され、それらに対する課金も停止します。

    ベクトルストアの有効期限ポリシーの設定
    client.vector_stores.update(
        vector_store_id="vs_123",
        expires_after={
            "anchor": "last_active_at",
            "days": 7
        }
    )

    制限

    ファイルサイズの上限は 512 MB です。各ファイルのトークン数は 5,000,000 以下にしてください(トークン数はファイルを添付する際に自動で計算されます)。

    チャンク分割

    デフォルトでは、max_chunk_size_tokens800chunk_overlap_tokens400 に設定されています。そのため、各ファイルは 800 トークンのチャンクに分割され、連続するチャンク間で 400 トークンが重複する形でインデックス化されます。

    この動作は、ベクトルストアにファイルを追加する際に chunking_strategy を設定することで調整できます。この設定には次の制限があります。

    • max_chunk_size_tokens は 100 以上 4096 以下でなければなりません。
    • chunk_overlap_tokens は 0 以上でなければならず、max_chunk_size_tokens / 2 を超えないようにしてください。

    回答の生成

    クエリの実行後に、その結果をもとに回答を生成したい場合があります。検索結果と元のクエリを OpenAI のモデルに渡すことで、検索結果に基づいた回答を得られます。

    検索クエリの実行と結果の取得
    from openai import OpenAI
    
    client = OpenAI()
    
    user_query = "What is the return policy?"
    
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query=user_query,
    )
    検索結果に基づく回答の生成
    # Use results and user_query from the preceding search step.
    formatted_results = format_results(results.data)
    
    "\n".join("\n".join(c.text for c in result.content) for result in results.data)
    
    completion = client.chat.completions.create(
        model="gpt-6-astra",
        messages=[
            {
                "role": "developer",
                "content": "Produce a concise answer to the query based on the provided sources.",
            },
            {
                "role": "user",
                "content": f"Sources: {formatted_results}\n\nQuery: '{user_query}'",
            },
        ],
    )
    
    print(completion.choices[0].message.content)
    "Our return policy allows returns within 30 days of purchase."

    ここではサンプルの format_results 関数を使用しています。 この関数は、次のように実装できます。

    検索結果を整形する関数の例
    def format_results(results):
        formatted_results = ""
        for result in results.data:
            formatted_result = (
                f"<result file_id='{result.file_id}' file_name='{result.file_name}'>"
            )
            for part in result.content:
                formatted_result += f"<content>{part.text}</content>"
            formatted_results += formatted_result + "</result>"
        return f"<sources>{formatted_results}</sources>"