このページは Apigee と Apigee ハイブリッドに適用されます。
Apigee Edge のドキュメントを表示する
このチュートリアルでは、Apigee を AI ゲートウェイとして構成して使用し、ポリシーベースの柔軟なルーティング ルールに基づいて、大規模言語モデル(LLM)リクエストをさまざまなバックエンド モデルにルーティングする方法について説明します。AI ゲートウェイは、モデル トラフィックの保護、管理、最適化に役立ち、費用を管理してモデルの乱立を防ぎます。
チュートリアルの各ステージでは、再利用可能な Apigee Feature Template(AFT)ファイルを使用して特定の機能を追加することで、前の構成をベースに構築します。
- ステージ 1: 単一の LLM プロバイダをフロントエンドとする最小限の API プロキシをデプロイします。
- ステージ 2: Model Armor のプロンプトとレスポンスのサニタイズを追加して、悪意のある入力をフィルタし、機密データの漏洩を防ぎます。
- ステージ 3: クロス プロバイダ モデル ルーティングと、Agent Platform ベクトル検索に基づくセマンティック キャッシュを追加します。
- ステージ 4: プライマリ ターゲットが
4xxまたは5xxHTTP ステータス コードを返した場合に、セカンダリ プロバイダに対してリクエストを自動的に再試行するように、プロバイダ間のフォールバックを構成します。
機能を追加するには、テンプレートの features ブロックに 1 行追加します。AFT ファイルやヘルパー スクリプトなど、サンプル ファイルの完全なセットを表示またはダウンロードするには、GitHub の Apigee テンプレート リポジトリをご覧ください。
始める前に
このチュートリアルを最後まで進めるには、次のものが必要です。
- 課金が有効になっているアクティブな Google Cloud プロジェクト。
- Apigee インスタンスで包括的な環境が使用可能であること。Model Armor、
SemanticCacheLookup、SemanticCachePopulateのポリシーは、包括的環境でのみデプロイできます。 - Google Cloud CLI(
gcloud)がインストールされ、アプリケーションのデフォルト認証情報(ADC)で構成されている。認証情報を生成するには、gcloud auth application-default loginを実行します。 - 次の IAM ロールを持つランタイム サービス アカウント。
roles/aiplatform.userroles/modelarmor.user
- ステージ 2、3、4 では、Model Armor テンプレートのリソースパスを指定します。たとえば、
projects/YOUR_PROJECT/locations/us-central1/templates/apigee-aft-demo-maのようになります。 - ステージ 3 と 4 の場合: 有効な OpenAI API キーを含む
api-keyエントリを含む、環境内のopenai-credentialsという名前の Apigee Key-Value マップ(KVM)。 - ステージ 3 と 4 の場合: セマンティック キャッシュ用にデプロイされた Vertex AI ベクトル検索インデックス エンドポイント。インデックス設定の手順については、GitHub の Apigee テンプレート リポジトリの README をご覧ください。
概要
4 つのステージはすべて、/v1/chat/completions[-stageN] で OpenAI Chat Completions リクエストの形式を受け入れるため、同じクライアント SDK がすべてのステージで機能します。model フィールドの接頭辞によってモデル ルーティングが決定されます。google/* モデルのリクエストは Agent Platform の Gemini にルーティングされ、他のすべてのリクエストは OpenAI にルーティングされます。このデフォルトの反転により、o1-*、o3-*、chatgpt-* などの新しい OpenAI モデル ファミリーが、gpt-* 接頭辞の一致がサイレントに欠落するのではなく、正しくルーティングされます。
| ステージ | 機能を追加しました | Base path |
|---|---|---|
| 1 | Hello LLM(Agent Platform での Gemini への OpenAI 形式のリクエスト) | /v1/chat/completions |
| 2 | Model Armor(プロンプト インジェクション、責任ある AI、Sensitive Data Protection のフィルタ) | /v1/chat/completions-stage2 |
| 3 | プロバイダ間のルーティングと Agent Platform ベクトル検索セマンティック キャッシュ | /v1/chat/completions-stage3 |
| 4 | クロスプロバイダ フォールバック(完全な AI ゲートウェイ) | /v1/chat/completions-stage4 |
ステージ 1: LLM の概要
最小限のプロキシは、OpenAI 互換のエンドポイントを介して単一の Gemini ターゲットをフロントエンドします。2 つの小さな機能ファイルが、ベース プロキシのスケルトンと JSON エクストラクタを提供します。抽出ツールは、$.model と $.messages[-1].content を llm.model と llm.prompt のフロー変数にコピーし、後続のステージで一貫した入力が得られるようにします。
llm-base.yaml は、ベース プロキシ スケルトンを定義します。
gateway: apigee schemaVersion: 1.0.0 name: llm-base type: feature parameters: - name: BASE_PATH default: /v1/chat/completions endpoints: - name: default basePath: "{BASE_PATH}" routes: - name: primary target: gemini-target
llm-openai-format.yaml は、OpenAI 形式のリクエスト フィールドを抽出します。
gateway: apigee schemaVersion: 1.0.0 name: llm-openai-format type: feature defaultEndpoint: name: default flows: - name: PreFlow mode: Request steps: - name: EV-ExtractOpenAIRequest policies: - name: EV-ExtractOpenAIRequest type: ExtractVariables content: ExtractVariables: metadata: name: EV-ExtractOpenAIRequest continueOnError: "true" Source: _text: request JSONPayload: Variable: - metadata: name: model JSONPath: _text: "$.model" - metadata: name: prompt JSONPath: _text: "$.messages[-1].content" VariablePrefix: _text: llm
target-vertex-gemini.yaml は、OpenAI 互換エンドポイントを使用する Agent Platform ターゲットを定義します。
gateway: apigee schemaVersion: 1.0.0 name: target-vertex-gemini type: feature targets: - name: gemini-target httpTargetConnection: URL: https://aiplatform.googleapis.com/v1/projects/{organization.name}/locations/global/endpoints/openapi/chat/completions Authentication: GoogleAccessToken: Scopes: Scope: https://www.googleapis.com/auth/cloud-platform
機能ファイルをステージ 1 テンプレート 01-hello-llm.yaml に作成します。
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-01-hello-llm features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml
テンプレートをデプロイします。
gcloud beta apigee apis import aft-demo-01-hello-llm \ --from-template=01-hello-llm.yaml \ --organization=APIGEE_ORG
プロキシをテストします。
curl -X POST https://APIGEE_HOSTNAME/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"google/gemini-2.5-flash", "messages":[{"role":"user","content":"Explain how AI works in a few words"}]}'
次のように置き換えます。
APIGEE_ORG: Apigee の組織名。APIGEE_HOSTNAME: Apigee 環境グループのホスト名(通常はロードバランサ)。 Google Cloud
ステージ 2: Model Armor を追加する
Model Armor は、ターゲット呼び出しの前に、受信したプロンプトを検査して、プロンプト インジェクション、許可されていないコンテンツ、センシティブ データが含まれているかどうかを確認します。次に、レスポンスがクライアントに到達する前にモデルのレスポンスをスキャンします。
テンプレート llm-model-armor.yaml に 1 つの機能ファイルを追加します。
gateway: apigee schemaVersion: 1.0.0 name: llm-model-armor type: feature parameters: - name: MA_TEMPLATE_PATH default: projects/{organization.name}/locations/us-central1/templates/apigee-aft-demo-ma defaultEndpoint: name: default flows: - name: PreFlow mode: Request steps: - name: MA-SanitizeUserPrompt - name: PostFlow mode: Response steps: - name: MA-SanitizeModelResponse policies: - name: MA-SanitizeUserPrompt type: SanitizeUserPrompt content: SanitizeUserPrompt: metadata: name: MA-SanitizeUserPrompt ModelArmor: TemplateName: _text: "{MA_TEMPLATE_PATH}" UserPromptSource: _text: "{llm.prompt}" - name: MA-SanitizeModelResponse type: SanitizeModelResponse content: SanitizeModelResponse: metadata: name: MA-SanitizeModelResponse ModelArmor: TemplateName: _text: "{MA_TEMPLATE_PATH}" UserPromptSource: _text: "{llm.prompt}" LLMResponseSource: _text: "{jsonPath('$.choices[-1].message.content',response.content,true)}"
ステージ 2 のテンプレート 02-add-model-armor.yaml では、1 行が追加されます。
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-02-add-model-armor features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml - llm-model-armor.yaml # <-- the change from Stage 1 parameters: - name: BASE_PATH default: /v1/chat/completions-stage2
MA_TEMPLATE_PATH パラメータのデフォルトは、us-central1 の apigee-aft-demo-ma という名前のテンプレートです。独自の Model Armor テンプレートを使用するには、テンプレートの parameters ブロックでパラメータをオーバーライドします。
ステージ 3: クロス プロバイダ ルーティングとセマンティック キャッシュを追加する
ステージ 3 では、2 つ目のターゲット(OpenAI)を追加し、単一ルートルールをモデルベースのルーティングに置き換え、両方のターゲットの前に Agent Platform ベクトル検索を基盤とするセマンティック キャッシュを構成します。
ステージ 3 を構成するには、テンプレートの features ブロックに 3 つの機能ファイルを追加します。
target-openai-gpt.yaml: OpenAI をセカンダリ ターゲット エンドポイントとして追加します。llm-routing.yaml: リクエストされたモデル名に基づいてリクエストを動的にルーティングします。llm-semantic-cache.yaml: 両方のプロバイダの前にセマンティック キャッシュを追加します。
次の例は、llm-routing.yaml 機能ファイルでルーティング ロジックを定義する方法を示しています。
gateway: apigee schemaVersion: 1.0.0 name: llm-routing type: feature parameters: - name: BASE_PATH default: /v1/chat/completions endpoints: - name: default basePath: "{BASE_PATH}" routes: - name: gemini condition: llm.model StartsWith "google/" target: gemini-target - name: openai target: openai-target # default when the condition is false
セマンティック キャッシュは、キャッシュミスの場合にのみ、リクエスト PreFlow で SemanticCacheLookup を実行し、レスポンス PostFlow で SemanticCachePopulate を実行します。どちらのポリシーも、個別にプロビジョニングする Agent Platform ベクトル検索インデックス エンドポイントを使用します。次の抜粋は、ポリシー定義の重要な部分を示しています。
policies: - name: SCLLookup type: SemanticCacheLookup content: SemanticCacheLookup: UserPromptSource: _text: "{llm.prompt}" Embeddings: VertexAI: URL: _text: "https://{EMBEDDINGS_LOCATION}-aiplatform.googleapis.com/v1/projects/{organization.name}/locations/{EMBEDDINGS_LOCATION}/publishers/google/models/{EMBEDDINGS_MODEL}:predict" SimilaritySearch: VertexAI: URL: _text: "https://{VECTOR_INDEX_ENDPOINT_SUBDOMAIN}.{EMBEDDINGS_LOCATION}-{PROJECT_NUMBER}.vdb.vertexai.goog/v1/projects/{organization.name}/locations/{EMBEDDINGS_LOCATION}/indexEndpoints/{VECTOR_INDEX_ENDPOINT_ID}:findNeighbors" DeployedIndexID: _text: "{DEPLOYED_INDEX_ID}" Threshold: _text: "{THRESHOLD}" - name: SCPPopulate type: SemanticCachePopulate # ... (see the GitHub repository for the full definition)
ステージ 3 のテンプレートは、すべての特徴ファイルを作成します。
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-03-add-routing-and-cache features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml - llm-model-armor.yaml - target-openai-gpt.yaml # <-- add OpenAI target - llm-routing.yaml # <-- add model-name routing - llm-semantic-cache.yaml # <-- add semantic cache parameters: - name: BASE_PATH default: /v1/chat/completions-stage3 - name: VECTOR_INDEX_ENDPOINT_ID default: "YOUR_INDEX_ENDPOINT_ID" - name: VECTOR_INDEX_ID default: "YOUR_INDEX_ID" - name: VECTOR_INDEX_ENDPOINT_SUBDOMAIN default: "YOUR_SUBDOMAIN" - name: PROJECT_NUMBER default: "YOUR_PROJECT_NUMBER" - name: DEPLOYED_INDEX_ID default: "YOUR_DEPLOYED_INDEX_ID"
ステージ 1 で使用したのと同じ gcloud beta apigee apis import コマンドと --from-template フラグを使用して、テンプレートをデプロイします。
ステージ 4: プロバイダ間のフォールバックを追加する
ステージ 4 では、両方のターゲットに DefaultFaultRule をアタッチします。プライマリ ターゲットが 4xx または 5xx ステータスを返すと、障害ルールは同じプロンプトを含む ServiceCallout を他のプロバイダに送信し、そのレスポンスをクライアントに返します。クライアントは、正常に完了した 200 レスポンスを受け取ります。独自の再試行ロジックやエラー処理は必要ありません。
この動作は、llm-fallback.yaml 機能ファイルによって追加されます。次の例は省略されています。完全なファイルについては、GitHub リポジトリをご覧ください。
gateway: apigee schemaVersion: 1.0.0 name: llm-fallback type: feature targets: # Vertex primary; on 4xx/5xx, fall back to OpenAI. - name: gemini-target httpTargetConnection: Properties: Property: metadata: name: success.codes _text: "2XX" URL: https://aiplatform.googleapis.com/v1/projects/{organization.name}/locations/global/endpoints/openapi/chat/completions Authentication: GoogleAccessToken: Scopes: Scope: https://www.googleapis.com/auth/cloud-platform flows: - name: PostFlow mode: Response steps: - name: RF-TargetErrorToFault condition: response.status.code >= 400 defaultFaultRule: name: FallbackToOpenAI steps: - name: KVM-GetOpenAIKey - name: AM-BuildOpenAIFallbackRequest - name: SC-FallbackToOpenAI - name: AM-CopyOpenAIFallbackResponse # OpenAI primary; on 4xx/5xx, fall back to Vertex. - name: openai-target httpTargetConnection: Properties: Property: metadata: name: success.codes _text: "2XX" URL: https://api.openai.com/v1/chat/completions flows: - name: PreFlow mode: Request steps: - name: JS-StripOpenAIModelPrefix - name: KVM-GetOpenAIKey - name: AM-SetOpenAIAuth - name: PostFlow mode: Response steps: - name: RF-TargetErrorToFault condition: response.status.code >= 400 defaultFaultRule: name: FallbackToVertex steps: - name: AM-BuildVertexFallbackRequest - name: SC-FallbackToVertex - name: AM-CopyVertexFallbackResponse policies: # RaiseFault converts a target 4xx/5xx into a fault so DefaultFaultRule fires. - name: RF-TargetErrorToFault type: RaiseFault content: RaiseFault: IgnoreUnresolvedVariables: "true" # empty FaultResponse -- DefaultFaultRule builds the real response # ... AM-Build*, SC-Fallback*, AM-Copy* policies -- see GitHub repository
フォールバックは次の 2 つの設定に依存します。
- 両方の
httpTargetConnectionブロックでsuccess.codes: 2XXを使用します。Apigee は、2xx以外のターゲット レスポンスをターゲット エラーとして扱い、障害フローに直接移行します。 - 各ターゲットのレスポンス PostFlow の
RaiseFaultポリシー。response.status.code >= 400でゲートされます。このポリシーにより、すべてのエラー レスポンスに対してDefaultFaultRuleが実行されます。
ステージ 4 のテンプレートを作成します。これにより、ステージ 3 のテンプレートに 1 行追加されます。
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-04-add-fallback features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml - llm-model-armor.yaml - target-openai-gpt.yaml - llm-routing.yaml - llm-semantic-cache.yaml - llm-fallback.yaml # <-- the change from Stage 3 parameters: - name: BASE_PATH default: /v1/chat/completions-stage4 # ... Model Armor and Vector Search parameters as in Stage 3
テンプレートをデプロイします。
gcloud beta apigee apis import aft-demo-04-add-fallback \ --from-template=04-add-fallback.yaml \ --organization=APIGEE_ORG
エンドツーエンドの動作を確認する
GitHub リポジトリには、トピックが多様なプロンプトを使用して、すべてのルーティング パスとフォールバック パスをテストする routing-diagnostic.sh スクリプトが含まれています。セマンティック キャッシュは類似したプロンプトをショートサーキットするため、各テストプロンプトは明確に異なる表現にする必要があります。
STAGE=4 ./routing-diagnostic.sh
このスクリプトは、ステージ 4 プロキシを介して 5 つのリクエストを送信します。
- 正規の OpenAI モデル
google/接頭辞が付いた Gemini モデル- 接頭辞のない Gemini モデル名。反転したデフォルトで OpenAI にルーティングされます
- OpenAI の推論モデル
openai/接頭辞が付いたモデル名
スクリプトは、リクエストごとに、レスポンスを配信したアップストリーム プロバイダと、フォールバックが発生したかどうかを報告します。
単一のリクエストのすべてのポリシー ステップ、ターゲット呼び出し、障害ルール遷移を確認するには、デプロイされたリビジョンに対して Apigee デバッグ セッションを作成します。
DEBUG_URL="https://apigee.googleapis.com/v1/organizations/APIGEE_ORG/environments/APIGEE_ENV/apis/aft-demo-04-add-fallback/revisions/REVISION/debugsessions" curl -X POST -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ -d '{"filter":"","count":10,"timeout":"600","validity":600}' \ "$DEBUG_URL"
次のように置き換えます。
APIGEE_ORG: Apigee の組織名。APIGEE_ENV: プロキシをデプロイした環境。REVISION:aft-demo-04-add-fallbackプロキシのデプロイされたリビジョン番号。
次に、フォールバックを実行するリクエストを送信します。
curl -X POST https://APIGEE_HOSTNAME/v1/chat/completions-stage4 \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini", "messages":[{"role":"user","content":"Describe nuclear fusion in stars in two sentences."}]}'
Apigee API を使用して、キャプチャされたデバッグ セッション メッセージを取得すると、トレースに次の実行フローが表示されます。
- リクエスト変数を抽出する: Apigee は、受信ペイロードから
llm.model変数とllm.prompt変数を抽出します。 - 安全性ポリシーを評価する: リクエストは Model Armor セキュリティ フィルタリングを通過します。
- セマンティック キャッシュを確認する: ルックアップでセマンティック キャッシュが見つからないため、リクエストはターゲットに続行されます。
- ルーティング条件を評価する: 条件
llm.model StartsWith "google/"はfalseと評価されます。 - プライマリ ターゲットへのルート: Apigee はリクエストを
openai-targetに転送します。 - ターゲット エラーを処理する: OpenAI ターゲットが
2xx以外の HTTP ステータス コードを返すと、Apigee はターゲット エラーを発生させます。 - 障害ルールを実行する:
DefaultFaultRuleは、AM-BuildVertexFallbackRequest、SC-FallbackToVertex、AM-CopyVertexFallbackResponseを実行してフォールバック シーケンスをトリガーします。 - レスポンスを返す: クライアントは、Agent Platform の Gemini によって生成されたペイロードを含む HTTP
200レスポンスを受信します。
次のステップ
- 認証を構成する: プロキシの前にフェデレーション JWT、OpenID Connect(OIDC)、または Apigee API キーを実装して、テナント固有のトークン割り当てとプロバイダ アクセス制御を適用します。
- 費用とレイテンシをモニタリングする: Apigee 分析ダッシュボードを API プロキシに接続して、モデルごとにレイテンシと運用コストを追跡します。
- テナント固有の安全ポリシーを適用する:
MA_TEMPLATE_PATHパラメータを使用してテナントごとの Model Armor テンプレートを構成し、エンタープライズ、デベロッパー、パブリック トラフィックにカスタマイズされたサニタイズ ルールを適用します。 - サンプル構成を確認する:
llm-fallback.yamlテンプレート、8 つの機能ファイル、routing-diagnostic.shスクリプト、KVM、Model Armor、Agent Platform Vector Search のプロビジョニング スクリプトを含む完全なサンプルセットをダウンロードするには、GitHub の Apigee 進化型 AI ゲートウェイ リポジトリをご覧ください。