ベクトル・ストアとOCI生成AI APIキーによるドキュメントの検索
ベクトル・ストアを作成し、ドキュメントをアップロードおよび取り込み、OCI生成AI APIキーを使用してcurlまたはOpenAI Python SDKでそのコンテンツを検索します。
概要
ベクトル・ストアは、ドキュメントを意味で検索できるようにします。ファイルをアップロードしてストアに取り込み、自然言語の質問で検索します。このサービスは、関連する通路、ファイル名、および関連性スコアを返します。取得したパスは、言語モデル・アプリケーションのコンテキストを提供することもできます。
ベクトル・ストアを使用して、独自のドキュメント解析および埋込みパイプラインを構築することなく、ポリシー、製品ガイドおよびサポート記事を検索できます。概要は、ベクトル・ストアおよびセマンティック・ストアを参照してください。
このチュートリアルでは:
- ベクトル・ストアを作成、取得およびリストします。
- サンプル・ドキュメントをアップロードし、検索可能なチャンクに収集します。
- ドキュメントを検索し、一致するパスを検査します。
- ストアの名前を変更し、テスト・リソースを削除します。
番号付きの各タスクには、curlの例とPython (OpenAI SDK)の例があります。パスを1つ選択し、最初から最後まで続けます。curlの例では、BashからのHTTPリクエストを行います。Pythonの例では、OCIをコールするように構成されたOpenAI SDKを使用します。どちらのパスもOCI生成AI APIキーで認証されるため、OCI CLIセッションは必要ありません。
始める前に
このチュートリアルを完了するには、次のものが必要です。
- 選択したリージョンおよびコンパートメントに対して認可されたOCI生成AI APIキー。プロンプトが表示されたら、キーのシークレット値のいずれかを使用します。
- そのコンパートメント内のファイルおよびベクトル・ストアを管理する権限。ファイル権限、ベクトル・ストア権限およびAPIキー権限の追加を参照してください。
- ファイル・アップロード用の既存のOCI生成AIプロジェクト。そのOCIDとそのコンパートメントのOCIDをコピーします。必要に応じて、開始する前にプロジェクトを作成します。
- ファイルおよびベクトル・ストアAPIが使用可能なリージョンへのアクセス。この例では、US Midwest (Chicago)、
us-chicago-1を使用します。エンタープライズAIエージェントのリージョンおよびファイルAPIおよびベクトル・ストア・ファイル・バッチAPIのトピックを参照してください。 - curl、Bash、
--fail-with-bodyサポートのcurl、およびjqの場合。Python、Python 3.11以降およびopenaiパッケージの場合。
例では、次のOCIベースURLを使用します。
https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/openai/v1選択したリージョンのサービス・エンドポイントを使用します。チュートリアル全体を通して、同じエンドポイント、コンパートメントおよびプロジェクトを保持します。
サンプル・ドキュメントには、架空のショップ・ポリシーが含まれています。接続プレースホルダのみを独自の値に置き換えます。例では、APIキーを表示またはソース・コードに含めずに、APIキーの入力を求められます。
curlパスの設定
Bashターミナルで、コンパートメントおよびプロジェクトのプレースホルダを置き換え、次を実行します:
set -o pipefail
export GENAI_BASE_URL='https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/openai/v1'
export GENAI_COMPARTMENT_ID='<your-compartment-ocid>'
export GENAI_PROJECT_ID='<your-project-ocid>'
read -r -s -p 'OCI Generative AI API key: ' GENAI_API_KEY
printf '\n'
export GENAI_API_KEY
VECTOR_STORES_URL="$GENAI_BASE_URL/vector_stores"
FILES_URL="$GENAI_BASE_URL/files"設定および返されたリソースIDが使用可能なままになるように、この端末で各curlの例を実行します。リクエストはBearer APIキーおよびopc-compartment-idを送信します。ファイルのアップロードおよびファイル削除では、OCIプロジェクトを識別するためにOpenAI-Projectも送信されます。ベースURLを末尾のスラッシュなしで設定します。
コマンドが失敗した場合は、エラーを解決してから続行します。クリーンアップの正常なリクエストによって返されたIDを保持します。成功した作成コマンドまたはアップロード・コマンドを再実行して、リソースのステータスを取得しないでください。
Pythonパスの設定
仮想環境を作成してアクティブ化し、OpenAI Python SDKをインストールします:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade openai次の設定でvector_store_tutorial.pyを作成します。コンパートメントおよびプロジェクトのプレースホルダを置換します。次に、8つの番号付きタスクのそれぞれからPythonブロックを順番に追加します。すべてのブロックが同じクライアント変数とリソース変数を共有します。
import getpass
import time
from openai import OpenAI
BASE_URL = "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/openai/v1"
COMPARTMENT_ID = "<your-compartment-ocid>"
PROJECT_ID = "<your-project-ocid>"
API_KEY = getpass.getpass("OCI Generative AI API key: ")
client = OpenAI(
api_key=API_KEY,
base_url=BASE_URL.rstrip("/") + "/",
default_headers={"opc-compartment-id": COMPARTMENT_ID},
timeout=30,
)サンプル・ドキュメントを保存し、すべてのPythonブロックをアセンブルした後、同じディレクトリから完了したスクリプトを実行します:
python vector_store_tutorial.py完了したスクリプトによって、リソースが作成され、ドキュメントが検索され、ストアおよびアップロードされたファイルが削除されます。クリーンアップの前にさらに質問を試みるには、タスク6の後、削除ブロックの前に検索コールを追加します。スクリプトがエラーで停止した場合は、エラーの前に出力されたリソースIDを使用して、すでに作成されているリソースを検査およびクリーン・アップします。
サンプル・ドキュメントの準備
この架空のポリシーを、curlコマンドまたはPythonスクリプトを実行するディレクトリにsample-document.txtとして保存します:
Example shop policy
Returns
Customers can return unused purchases within 30 days of delivery.
Include the order number and keep the item in its original packaging.
Contact support before shipping a return.
Refunds go to the original payment method.
Delivery
Standard delivery usually takes 3 to 5 business days.
Express delivery usually takes 1 to 2 business days.1. ベクトル・ストアの作成
認識可能な名前で空のストアを作成します。この例では、last_active_atに基づいて1日の有効期限ポリシーを設定します。ストアを作成しても、ドキュメントのアップロードや取込みは行われません。
curl
STORE_RESPONSE=$(curl --fail-with-body --silent --show-error \
--request POST "$VECTOR_STORES_URL" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
--header 'Content-Type: application/json' \
--data '{"name":"document-search-demo","expires_after":{"anchor":"last_active_at","days":1}}')
printf '%s\n' "$STORE_RESPONSE" | jq '{id, name, status}'
VECTOR_STORE_ID=$(printf '%s' "$STORE_RESPONSE" | jq -er '.id')Python(OpenAI SDK)
store = client.vector_stores.create(
name="document-search-demo",
expires_after={"anchor": "last_active_at", "days": 1},
)
print("Created store:", store.id, store.status)返されたストアIDを保存します。作成は非同期にできます。次のタスクでステータスを確認します。
2. ストアの取得およびそのステータスの確認
ストアのメタデータを取得し、completedを待機してからドキュメントを取り込みます。
curl
curl --fail-with-body --silent --show-error \
"$VECTOR_STORES_URL/$VECTOR_STORE_ID" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
| jq '{id, name, status}'ステータスがin_progressの場合は、2秒待ってから、取得コマンドを再度実行します。ステータスがcompletedの場合にのみ続行します。ストアの有効期限が切れているか、2分を超えて進行中かどうかを停止して調査します。
Python(OpenAI SDK)
store = client.vector_stores.retrieve(store.id)
deadline = time.monotonic() + 120
while store.status == "in_progress":
if time.monotonic() >= deadline:
raise TimeoutError(f"Store creation is still in progress: {store.id}")
time.sleep(2)
store = client.vector_stores.retrieve(store.id)
if store.status != "completed":
raise RuntimeError(f"Store is not ready: {store.id}, {store.status}")
print("Store is ready:", store.id)2分ポーリング・タイムアウトは、この例の制限であり、サービス完了保証ではありません。到達した場合は、ストアIDを保持し、ストアを検査してから再試行します。
その店は飲食の準備ができている。
3. ベクトルストアのリスト
ストアをリストして、すでに作成したリソースを検索します。この例では、最初のページに最大10個のエントリが表示されます。ストアは後のページにある可能性があります。特定の店舗をチェックするためのIDによる取得。
curl
curl --fail-with-body --silent --show-error \
"$VECTOR_STORES_URL?limit=10" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
| jq '.data[] | {id, name, status}'Python(OpenAI SDK)
for item in client.vector_stores.list(limit=10).data:
print(item.id, item.name, item.status)出力には、返される各ストアのID、名前およびステータスが表示されます。
4. 文書のアップロード
サンプル・ドキュメントをアップロードして、ファイル・リソースを作成します。OpenAI-Projectヘッダーは、アップロードをOCI生成AIプロジェクトに関連付けます。次のタスクの取込み後に、ファイルが検索可能になります。
curl
FILE_RESPONSE=$(curl --fail-with-body --silent --show-error \
--request POST "$FILES_URL" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
--header "OpenAI-Project: $GENAI_PROJECT_ID" \
--form 'purpose=assistants' \
--form 'file=@sample-document.txt')
printf '%s\n' "$FILE_RESPONSE" | jq '{id, filename}'
FILE_ID=$(printf '%s' "$FILE_RESPONSE" | jq -er '.id')Python(OpenAI SDK)
with open("sample-document.txt", "rb") as document:
uploaded_file = client.files.create(
file=document,
purpose="assistants",
extra_headers={"OpenAI-Project": PROJECT_ID},
)
print("Uploaded file:", uploaded_file.id, uploaded_file.filename)curlの場合は、マルチパート・コンテンツ・タイプと境界を自動的に設定します。
取り込みとクリーンアップのために返されたファイルIDを保存します。
5. 文書のストアへの取込み
取込みにより、ファイルがストアに関連付けられ、ドキュメントがチャンクに分割され、取得用の埋込みが作成されます。ファイル・バッチには、複数のファイルを含めることができます。この例では、1つのファイルとデフォルトのチャンク設定を使用します。
curl
BATCH_RESPONSE=$(curl --fail-with-body --silent --show-error \
--request POST "$VECTOR_STORES_URL/$VECTOR_STORE_ID/file_batches" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
--header 'Content-Type: application/json' \
--data "$(jq -n --arg file_id "$FILE_ID" '{file_ids:[$file_id]}')")
printf '%s\n' "$BATCH_RESPONSE" | jq '{id, status, file_counts}'
BATCH_ID=$(printf '%s' "$BATCH_RESPONSE" | jq -er '.id')バッチ・ステータスを確認します。
curl --fail-with-body --silent --show-error \
"$VECTOR_STORES_URL/$VECTOR_STORE_ID/file_batches/$BATCH_ID" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
| jq '{id, status, file_counts}'ステータスがin_progressの場合は、2秒待ってからバッチを再度取得します。ステータスがcompletedで、完了したファイル数が1で、失敗した数と取り消された数が0の場合、続行します。取込みが失敗したか、取り消されたか、または2分以上進行中かどうかを停止して調査します。
Python(OpenAI SDK)
batch = client.vector_stores.file_batches.create(
vector_store_id=store.id,
file_ids=[uploaded_file.id],
)
print("Ingestion batch:", batch.id)
deadline = time.monotonic() + 120
while batch.status == "in_progress":
if time.monotonic() >= deadline:
raise TimeoutError(f"Document ingestion is still in progress: {batch.id}")
time.sleep(2)
batch = client.vector_stores.file_batches.retrieve(
batch.id, vector_store_id=store.id,
)
counts = batch.file_counts
if (
batch.status != "completed"
or counts.completed != 1
or counts.failed
or counts.cancelled
):
raise RuntimeError(
f"Ingestion did not succeed: {batch.id}, {batch.status}, {counts}"
)
print("Document is ready to search.")正常に取り込まれた後、ドキュメントを検索する準備ができました。詳細は、「ベクトル・ストア・ファイル・バッチAPI」を参照してください。
6. 文書の検索
自然言語の質問をして、関連する通路を取り戻してください。検索コールはドキュメント・コンテンツを返します。言語モデルの回答は生成されません。
curl
curl --fail-with-body --silent --show-error \
--request POST "$VECTOR_STORES_URL/$VECTOR_STORE_ID/search" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
--header 'Content-Type: application/json' \
--data '{"query":"How long do I have to return a purchase?","max_num_results":3}' \
| jq '.data[] | {filename, score, text:[.content[] | select(.type == "text") | .text]}'Python(OpenAI SDK)
query = "How long do I have to return a purchase?"
results = client.vector_stores.search(
vector_store_id=store.id,
query=query,
max_num_results=3,
)
print("Question:", query)
if not results.data:
print("No matching passages found.")
for result in results.data:
print(f"\n{result.filename} (score: {result.score:.3f})")
for content in result.content:
if content.type == "text":
print(content.text)サンプルポリシーの30日間の戻り期間を含むパスを探します。通過境界、順序付けおよびスコアは異なる場合があります。max_num_resultsは、ドキュメントではなくチャンクの一致を制限します。
速達度はどのくらいですか
、返品には何を含める必要がありますか
など、別の質問をお試しください。ストアとファイルがまだ存在している間、検索コールのみを繰り返します。
7. ストアの名前変更
ストアの名前を更新します。名前を変更すると、ストアのメタデータが変更され、アップロードされたポリシー・テキストは変更されません。
curl
curl --fail-with-body --silent --show-error \
--request POST "$VECTOR_STORES_URL/$VECTOR_STORE_ID" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
--header 'Content-Type: application/json' \
--data '{"name":"document-search-demo-updated"}' \
| jq '{id, name, status}'ステータスがin_progressの場合は、ステータスがcompletedになるまでタスク2から取得コマンドを使用します。例の2分ポーリング期間内に更新が完了していないかどうかを停止して調査します。
Python(OpenAI SDK)
store = client.vector_stores.update(
store.id, name="document-search-demo-updated",
)
deadline = time.monotonic() + 120
while store.status == "in_progress":
if time.monotonic() >= deadline:
raise TimeoutError(f"Store update is still in progress: {store.id}")
time.sleep(2)
store = client.vector_stores.retrieve(store.id)
if store.status != "completed":
raise RuntimeError(f"Store update did not complete: {store.id}, {store.status}")
print("Updated store:", store.id, store.name)ストアには更新された名前があります。更新が完了するまで待ってから、削除します。
8. テスト・リソースの削除
このチュートリアルで作成したストアおよびアップロード済ファイルを削除します。これらは別個のリソースです。ストアを削除しても、ファイルの削除は置換されません。作成したテスト・リソースのIDのみを使用します。
以前のタスクが失敗した場合は、成功したタスクによって出力されたIDを使用して、存在するリソースのみをクリーンアップします。同じエンドポイント、コンパートメント、プロジェクトおよびAPIキー設定を保持します。Pythonの場合、削除ブロックを使用してセットアップ・ブロックを実行し、store.idおよびuploaded_file.idを引用符で囲まれた文字列として保存されたIDに置き換えます。作成されなかったリソースの削除を省略します。
curl
curl --fail-with-body --silent --show-error \
--request DELETE "$VECTOR_STORES_URL/$VECTOR_STORE_ID" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
| jq '{id, deleted}'
curl --fail-with-body --silent --show-error \
--request DELETE "$FILES_URL/$FILE_ID" \
--header "Authorization: Bearer $GENAI_API_KEY" \
--header "opc-compartment-id: $GENAI_COMPARTMENT_ID" \
--header "OpenAI-Project: $GENAI_PROJECT_ID" \
| jq '{id, deleted}'Python(OpenAI SDK)
deleted_store = client.vector_stores.delete(store.id)
print("Store deleted:", deleted_store.id, deleted_store.deleted)
deleted_file = client.files.delete(
uploaded_file.id,
extra_headers={"OpenAI-Project": PROJECT_ID},
)
print("File deleted:", deleted_file.id, deleted_file.deleted)
client.close()正常な削除確認にはdeleted: trueが含まれます。両方のリソースのこの値を確認します。
トラブルシューティング
| 現象 | 確認対象 |
|---|---|
| 認証エラーまたはHTTP 401 | OCI生成AI APIキー・シークレットが選択されたリージョンに対して有効であり、ベアラー・トークンとして送信されていることを確認します。 |
| 認可エラーまたはHTTP 403 | コンパートメントおよびプロジェクトのAPIキー権限およびファイルおよびベクトル・ストアの権限を確認してください。 |
| リソースが見つかりません | ファイル・リクエストのサービスURL、リージョン、コンパートメント、プロジェクト・ヘッダーおよびリソースIDを確認します。 |
| アップロードが拒否されました | ファイルAPIのトピックで、ファイル・タイプおよびアップロード制限を確認します。小さいサンプル・ドキュメントから開始します。 |
| 取込みに失敗しました | バッチを取得し、そのステータスおよびファイル数を検査します。エラーの詳細は、個々のベクトル・ストア・ファイル・レコードを取得してください。 |
| 検索の結果がありません | 取込みが正常に完了し、ドキュメントを含むストアを検索していることを確認します。 |
| ポーリング・タイムアウト | リソースを再度取得して、その現在のステータスを検査します。トラブルシューティングおよびクリーンアップのためにIDを保持します。 |
SDKには、vector_storesまたはsearchメソッドがありません | スクリプトで使用されるPython環境をアクティブ化し、openaiパッケージをアップグレードします。 |