このページの内容は Apigee に適用されます。Apigee ハイブリッドには適用されません。
Apigee Edge のドキュメントを表示する。
このページでは、セマンティック類似性に基づいてレスポンスをインテリジェントに再利用できるようにするための、Apigee セマンティック キャッシング ポリシーの構成と使用方法について説明しています。この例では、ポリシーは プライベート(Private Service Connect)エンドポイントにデプロイされたベクトル検索インデックスに対して類似性検索を実行します。これらのポリシーを Apigee の API プロキシで使用することで、バックエンドでの API 呼び出しの冗長性を最小限に抑え、レイテンシを減らし、運用コストを削減できます。
始める前に
始める前に、次のタスクを完了します。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Compute Engine, AI Platform, and Cloud Storage APIs.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.- Google Cloud プロジェクトで Vertex AI の Text embeddings API を有効にして構成します。
- プライベート(Private Service Connect)エンドポイントにデプロイされたベクトル検索インデックスを作成する(またはアクセス権がある)。このチュートリアルでは、ベクトル検索の設定手順は重複していません。SemanticCacheLookup 固有の要件とベクトル検索のドキュメントへのリンクについては、ベクトル検索インデックスの前提条件をご覧ください。
- Apigee インスタンスで中間環境または包括的環境が使用可能であることを確認します。セマンティック キャッシュ ポリシーは、中間環境または包括的環境にのみデプロイできます。
- API プロキシにリクエストを送信するために使用できるランタイム ホスト名を持つ環境グループがあることを確認します。
必要なロール
セマンティック キャッシュ ポリシーの作成と使用に必要な権限を取得するには、Apigee プロキシのデプロイに使用するサービス アカウントに対する AI Platform ユーザー (roles/aiplatform.user)の IAM ロールを管理者に付与してもらってください。ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
環境変数を設定する
Apigee インスタンスを含む Google Cloud プロジェクトで、次のコマンドを使用して環境変数を設定します。
export PROJECT_ID=PROJECT_IDexport REGION=REGIONexport RUNTIME_HOSTNAME=RUNTIME_HOSTNAME
ここで
PROJECT_ID: Apigee インスタンスを含むプロジェクトの ID。REGIONは Apigee インスタンスの Google Cloud リージョンです。RUNTIME_HOSTNAMEは Apigee ランタイムのホスト名です。
環境変数が正しく設定されていることを確認するには、次のコマンドを実行して出力を確認します。
echo $PROJECT_ID $REGION $RUNTIME_HOSTNAME
プロジェクトを設定する
開発環境で Google Cloud プロジェクトを設定します。
gcloud auth logingcloud config set project $PROJECT_ID
ベクトル検索インデックスの前提条件
このチュートリアルでは、プライベート(Private Service Connect)エンドポイントにデプロイされたベクトル検索インデックスがすでに存在するか、作成されることを前提としています。ベクトル検索インデックスの作成、フォーマット、デプロイについては、ベクトル検索ガイドに記載されているため、このチュートリアルではこれらの手順を繰り返しません。ベクトル検索のドキュメントに沿って、次の操作を行います。
インデックスを作成する際は、次の SemanticCacheLookup 固有の要件を満たす必要があります。
- SemanticCachePopulate ポリシーの
upsertDatapoints呼び出しがほぼリアルタイムでクエリ可能になるように、インデックスでSTREAM_UPDATE("indexUpdateMethod": "STREAM_UPDATE")を使用する必要があります。 - インデックス
dimensionsは、SemanticCacheLookup ポリシーで使用するエンベディング モデルの出力ディメンションと一致している必要があります。このチュートリアルではgemini-embedding-001を使用します。このモデルは、デフォルトで 3, 072 次元のエンベディングを生成します。出力をより低い次元(768 や 1,536 など)に切り捨てる場合は、dimensionsを同じ値に設定します。 - ポリシーの
<DistanceMeasureType>に一致する距離測定(distanceMeasureType)を使用してインデックスを作成します。SemanticCacheLookup ポリシーの<SimilaritySearch><VertexAI><DistanceMeasureType>要素は省略可能で、デフォルトはDOT_PRODUCT_DISTANCEです。COSINE_DISTANCEもサポートされています。インデックス距離測定とポリシー<DistanceMeasureType>は同じである必要があります。
次の最小限の例では、互換性のあるインデックスを作成します。リクエスト本文全体と使用可能なすべてのオプションについては、インデックスを作成して管理するをご覧ください。
ACCESS_TOKEN=$(gcloud auth print-access-token) && curl -X POST \ "https://$REGION-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/indexes" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "displayName": "semantic-cache-index", "metadata": { "config": { "dimensions": 3072, "distanceMeasureType": "DOT_PRODUCT_DISTANCE" } }, "indexUpdateMethod": "STREAM_UPDATE" }'
レスポンスで返された数値の INDEX_ID をメモします。これは SemanticCachePopulate ポリシーで使用します。インデックスを作成したら、Private Service Connect インデックス エンドポイントを作成し、インデックスをデプロイします。
Private Service Connect インデックス エンドポイントを作成する場合は、次の SemanticCacheLookup 固有の要件を満たす必要があります。
projectAllowlistには、接続を開始する Apigee プロジェクトを含める必要があります。- Apigee: Apigee テナント プロジェクトを使用します。Organizations API(
apigeeProjectIdフィールド)からテナント プロジェクト ID を取得します。
projectAllowlistを変更することはできません。間違ったプロジェクトを許可リストに登録した場合は、インデックス エンドポイントを削除して再作成する必要があります。- Apigee: Apigee テナント プロジェクトを使用します。Organizations API(
インデックス エンドポイントの数値 INDEX_ENDPOINT_ID をメモします。
Apigee プロキシのサービス アカウントを構成する
Apigee プロキシは、Vertex AI REST 呼び出しにサービス アカウントを使用します。SemanticCacheLookup ポリシーの Embeddings API、SemanticCachePopulate ポリシーの upsertDatapoints、モデル ターゲットです。そのサービス アカウントに AI Platform User(roles/aiplatform.user)ロールを付与します。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:SERVICE_ACCOUNT" \ --role="roles/aiplatform.user"
ここで、SERVICE_ACCOUNT はプロキシが使用するサービス アカウントのメールアドレスです。このサービス アカウントは、ステップ 4: API プロキシをインポートしてデプロイするでプロキシをデプロイするときに参照します。
概要
セマンティック キャッシュ ポリシーにより、LLM モデルを使用する Apigee ユーザーは、同一または意味的に類似したプロンプトを効率的に提供し、バックエンド API 呼び出しを最小限に抑えてリソース消費を削減できます。
SemanticCacheLookup ポリシーと SemanticCachePopulate ポリシーは、それぞれ Apigee API プロキシのリクエスト フローとレスポンス フローにアタッチされています。プロキシがリクエストを受信すると、SemanticCacheLookup ポリシーはそのリクエストからユーザー プロンプトを抽出し、Text embeddings API を使って数値表現に変換します。セマンティックな類似性検索は、ベクトル検索を使用して類似したプロンプトを見つけるために実行されます。類似したプロンプト データポイントが見つかった場合は、キャッシュ検索が実行されます。キャッシュに保存されているデータが見つかった場合、キャッシュに保存されているレスポンスがクライアントに返されます。
類似性検索で過去の類似したプロンプトが返されなかった場合、LLM モデルはユーザー プロンプトに対してコンテンツを生成し、そのレスポンスを Apigee キャッシュに保存します。フィードバック ループが作成され、今後のリクエストに備えてベクトル検索インデックス エントリが更新されます。
このシナリオでは、ベクトル検索インデックスは gRPC 経由でプライベート(Private Service Connect)エンドポイントにデプロイされます。ベクトル検索の Private Service Connect のサポートの詳細については、プライベート サービス アクセスまたは Private Service Connect インデックスをクエリするをご覧ください。
以降のセクションでは、セマンティック キャッシュ ポリシーを作成して構成するための手順をご案内します。
- リソースを確認し、Apigee が必要とする値を取得します。
- サービス アタッチメントに接続します。
- API プロキシ バンドルをビルドします。
- API プロキシをインポートしてデプロイします。
- セマンティック キャッシュ保存ポリシーをテストする。
ステップ 1: リソースを確認し、Apigee に必要な値を取得する
Apigee を構成する前に、ベクトル検索インデックス エンドポイントで Private Service Connect が有効になっており、インデックスがデプロイされていることを確認します。次に、Apigee プロキシが使用する 2 つの値(サービス アタッチメントと DEPLOYED_INDEX_ID)を読み取ります。
インデックスがデプロイされ、エンドポイントが Private Service Connect サービス アタッチメントを公開していることを確認します。
gcloud ai index-endpoints describe INDEX_ENDPOINT_ID \ --project=$PROJECT_ID --region=$REGION \ --format="value(deployedIndexes.privateEndpoints.serviceAttachment)"
このコマンドは、projects/TENANT_PROJECT/regions/REGION/serviceAttachments/SERVICE_ATTACHMENT_NAME 形式のサービス アタッチメント リソース名を返します。このガイドでは、この値を SERVICE_ATTACHMENT と呼びます。コマンドが空の値を返した場合、インデックスは Private Service Connect エンドポイントにまだデプロイされていません。ベクトル検索インデックスの前提条件に戻り、続行する前にインデックスのデプロイを完了します。
エンドポイントにデプロイされたインデックスの DEPLOYED_INDEX_ID を読み取ります。
gcloud ai index-endpoints describe INDEX_ENDPOINT_ID \ --project=$PROJECT_ID --region=$REGION \ --format="value(deployedIndexes.id)"
このガイドでは、この値を DEPLOYED_INDEX_ID と呼びます。これは、ステップ 3: API プロキシ バンドルをビルドするの SemanticCacheLookup ポリシーで使用します。
プライベート インデックス エンドポイントのデプロイとクエリの詳細については、Private Service Connect エンドポイントにインデックスをデプロイするとPrivate Services Access または Private Service Connect インデックスをクエリするをご覧ください。
ステップ 2: サービス アタッチメントに接続する
このステップでは、プロキシの <GrpcEndpoint> が呼び出すプライベート ホストを取得します。Apigee で、Apigee エンドポイント アタッチメントを作成します。エンドポイント アタッチメントは、Apigee の Private Service Connect コンシューマー側です。ベクトル検索サービス アタッチメントに接続し、プロキシが呼び出すプライベート ホストを提供します。
curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -d '{ "location": "'"$REGION"'", "serviceAttachment": "SERVICE_ATTACHMENT" }' \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/endpointAttachments?endpointAttachmentId=ENDPOINT_ATTACHMENT"
アタッチメントの state が ACTIVE になり、connectionState が ACCEPTED になるまでポーリングし、ホストをメモします。
curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/endpointAttachments/ENDPOINT_ATTACHMENT"
レスポンスには、host フィールドにホストが含まれます。このガイドでは、この値を TARGET_HOST と呼びます。
プロキシからベクトル検索サービス アタッチメントに接続するには、次のいずれかを使用します。
- IP アドレス:
hostフィールドで返された IP アドレスをTARGET_HOST(例:7.0.3.4)として直接使用します。 - プライベート DNS レコード: Apigee への DNS ピアリングを使用して Google Cloud プロジェクトで限定公開 Cloud DNS ゾーンを構成した場合は、エンドポイント アタッチメントの IP アドレスを参照する限定公開ゾーンに A レコードを作成し、そのドメイン名(
vectorsearch.example.comなど)をTARGET_HOSTとして使用できます。詳細については、DNS レコードを使用するとプライベート DNS ピアリング ゾーンとの接続をご覧ください。
ステップ 3: API プロキシ バンドルをビルドする
プロキシ バンドルを作成する
次のディレクトリ レイアウトを作成します。
apiproxy/ ├── PROXY_NAME.xml ├── proxies/default.xml ├── targets/default.xml └── policies/ ├── SCL-1.xml └── SCP-1.xml
policies/SCL-1.xml - SemanticCacheLookup ポリシー。<SimilaritySearch> ブロックは <PrivateServiceConnect><GrpcEndpoint>(<URL> なし)を使用します。
注: <GrpcEndpoint> ルール:
- 形式は
grpc://TARGET_HOST:PORTです。スキームはgrpc://にする必要があります。このバージョンではgrpcs://(TLS)はサポートされていません。 - ベクトル検索のポートは
10000です。Private Service Connect データプレーン エンドポイントはポート 10000 で gRPC を提供するため、エンドポイントは常にgrpc://TARGET_HOST:10000になります。 TARGET_HOSTには、エンドポイント アタッチメントの IP アドレス(ステップ 2)またはプライベート DNS ゾーンに作成されたカスタム DNS レコードを指定できます。- gRPC ホップはプレーンテキストで認証されていません(ネットワーク分離によって保護されています)。
<SemanticCacheLookup async="false" continueOnError="false" enabled="true" name="SCL-1"> <DisplayName>SCL-1</DisplayName> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource> <Embeddings> <VertexAI> <URL>https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/publishers/google/models/gemini-embedding-001:predict</URL> </VertexAI> </Embeddings> <SimilaritySearch> <VertexAI> <PrivateServiceConnect> <GrpcEndpoint>grpc://TARGET_HOST:10000</GrpcEndpoint> </PrivateServiceConnect> <DeployedIndexID>DEPLOYED_INDEX_ID</DeployedIndexID> <Threshold>0.95</Threshold> </VertexAI> </SimilaritySearch> </SemanticCacheLookup>
policies/SCP-1.xml - SemanticCachePopulate ポリシー。Populate は REST 専用であり、<URL> を使用する必要があります(デプロイ時に <PrivateServiceConnect> を拒否します)。
<SemanticCachePopulate async="false" continueOnError="true" enabled="true" name="SCP-1"> <DisplayName>SCP-1</DisplayName> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <SimilaritySearch> <VertexAI> <URL>https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/indexes/INDEX_ID:upsertDatapoints</URL> </VertexAI> </SimilaritySearch> <TTLInSeconds>3600</TTLInSeconds> </SemanticCachePopulate>
targets/default.xml - モデルのターゲット。ターゲットは Google API を呼び出すため、トークンが必要です。<GoogleAccessToken> はデプロイのサービス アカウントを使用します。
<TargetEndpoint name="default"> <PreFlow name="PreFlow"><Request/><Response/></PreFlow> <PostFlow name="PostFlow"><Request/><Response/></PostFlow> <HTTPTargetConnection> <Authentication> <GoogleAccessToken> <Scopes> <Scope>https://www.googleapis.com/auth/cloud-platform</Scope> </Scopes> </GoogleAccessToken> </Authentication> <URL>https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/publishers/google/models/gemini-2.5-flash:generateContent</URL> </HTTPTargetConnection> </TargetEndpoint>
proxies/default.xml - リクエストで SemanticCacheLookup ポリシーを実行し、レスポンスで SemanticCachePopulate ポリシーを実行します。
<ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <Request><Step><Name>SCL-1</Name></Step></Request> <Response><Step><Name>SCP-1</Name></Step></Response> </PreFlow> <PostFlow name="PostFlow"><Request/><Response/></PostFlow> <HTTPProxyConnection> <BasePath>/PROXY_NAME</BasePath> </HTTPProxyConnection> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
PROXY_NAME.xml - バンドル記述子:
<APIProxy name="PROXY_NAME"> <BasePaths>/PROXY_NAME</BasePaths> <Policies><Policy>SCL-1</Policy><Policy>SCP-1</Policy></Policies> <ProxyEndpoints><ProxyEndpoint>default</ProxyEndpoint></ProxyEndpoints> <TargetEndpoints><TargetEndpoint>default</TargetEndpoint></TargetEndpoints> </APIProxy>
ステップ 4: API プロキシをインポートしてデプロイする
バンドルを圧縮し、インポートして新しいリビジョンを作成し、サービス アカウントを使用してリビジョンをデプロイします。
TOKEN=$(gcloud auth print-access-token)(cd BUNDLE_DIR && zip -r ../PROXY_NAME.zip apiproxy)curl -X POST -H "Authorization: Bearer $TOKEN" \ -F "file=@PROXY_NAME.zip" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/apis?action=import&name=PROXY_NAME"curl -X POST -H "Authorization: Bearer $TOKEN" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/ENV/apis/PROXY_NAME/revisions/REVISION/deployments?override=true&serviceAccount=SERVICE_ACCOUNT"
ここで
BUNDLE_DIRは、apiproxy/フォルダを含むディレクトリです。アーカイブのルートにapiproxy/フォルダが含まれている必要があります。ENVは、プロキシをデプロイする Apigee 環境です。環境は、中間環境または包括的環境である必要があります。REVISIONは、インポート呼び出しによって返されるリビジョン番号です。SERVICE_ACCOUNTは、プロキシのデプロイに使用するサービス アカウントのメールアドレスです。
デプロイから READY が報告されるまで待ちます。
curl -s -H "Authorization: Bearer $TOKEN" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/ENV/apis/PROXY_NAME/revisions/REVISION/deployments" | jq .state
ステップ 5: セマンティック キャッシュ保存ポリシーをテストする
新しいプロンプトを送信します。これはキャッシュミスです。モデルが呼び出され、回答がキャッシュに保存されます。
curl -X POST "https://$RUNTIME_HOSTNAME/PROXY_NAME" \ -H "Content-Type: application/json" \ -d '{"contents":[{"role":"user","parts":[{"text":"Explain in one sentence why the sky appears blue."}]}]}'
同じプロンプトをもう一度送信します。これはキャッシュ ヒットです。レスポンスはキャッシュから提供され、モデルは呼び出されません。
curl -i -X POST "https://$RUNTIME_HOSTNAME/PROXY_NAME" \ -H "Content-Type: application/json" \ -d '{"contents":[{"role":"user","parts":[{"text":"Explain in one sentence why the sky appears blue."}]}]}'
ヒットの場合、レスポンスには Cached-content: true ヘッダー、同じ回答、大幅に低いレイテンシが含まれます。
デバッグ セッションでキャッシュ保存を確認することもできます。ヒットすると、SemanticCacheLookup ポリシーは次のフロー変数を設定します。
| 変数 | ヒットの値 |
|---|---|
SemanticCacheLookup.SCL-1.dense_embeddings |
プロンプトのエンベディング ベクトル。 |
SemanticCacheLookup.SCL-1.is_nearest_neighbor_hit |
true |
SemanticCacheLookup.SCL-1.cache_hit |
true |
SemanticCacheLookup.SCL-1.cached_llm_response |
キャッシュに保存された回答。 |
ヒットすると、モデル ターゲットは呼び出されません。フローがショートサーキットし、キャッシュに保存されたレスポンスが返されます。
トラブルシューティング
エラー リファレンスの完全版については、SemanticCacheLookup ポリシーをご覧ください。
次のステップ
- ベクトル検索でプライベート サービス アクセスまたは Private Service Connect インデックスをクエリする方法について説明します。
- パブリック エンドポイントに対するセマンティック キャッシュ保存を構成する方法については、セマンティック キャッシュ保存ポリシーを使ってみるをご覧ください。
- Model Armor ポリシーの使用を開始する方法を確認する。