🥹

【公式Docs補足】Vertex AI Matching Engineへのcurlリクエスト方法!

2024/05/14に公開

はじめに

業務にて、より良い商品をレコメンドすべく、Google CloudのVertex AI Matching Engineというサービスを利用することになりました。
依存関係の影響で、Rubyのnet/httpを用いてデータの取得を行うことになったのですが、公式ドキュメントに情報が少なく詰まってしまうことがあったので、忘備録として記事にしておきます。

前提

IndexおよびIndex Endpointをデプロイ済みであること
https://cloud.google.com/vertex-ai/docs/vector-search/deploy-index-public?hl=ja

クエリ

最近傍の取得(ベース)

マッチングエンジンのIndexに対して、近似最近傍探索を行います。
こちら単体で使うことは少ないかと思います。

curl
$ curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://1957880287.asia-northeast1-181224308459.vdb.vertexai.goog/v1/projects/181224308459/locations/asia-northeast1/indexEndpoints/3370566089086861312:findNeighbors" \
-d '{deployedIndexId:"test_index_public1", "queries":[{datapoint:{"datapointId":"<DATA_POINT_ID>"}}], returnFullDatapoint:false}'

以下のような内容が返ってきます。

response
{
  "nearestNeighbors": [{
    "id": "test",
    "neighbors": [
      {
        "datapoint": {
          "datapointId": "test",
          "crowdingTag": {
            "crowdingAttribute": "0"
          }
        },
        "distance": 0.99999994039535522
      },
      {
        "datapoint": {
          "datapointId": "test_2",
          "crowdingTag": {
            "crowdingAttribute": "0"
          }
        },
        "distance": 0.0455654114484787
      }
    ]
  }]
}

トークン制限(allow)

取ってくるデータを事前に制限することができます。
例えば、赤色の商品のみを表示したい!と言ったケースで便利です。

curl
$ curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://1957880287.asia-northeast1-181224308459.vdb.vertexai.goog/v1/projects/181224308459/locations/asia-northeast1/indexEndpoints/3370566089086861312:findNeighbors" \
-d '{
  "deployedIndexId": "test_index_public1",
  "queries": [{
    "datapoint": {
      "datapointId": "<DATA_POINT_ID>",
      "restricts": [{
        "namespace": "color",
        "allowList": ["red"],
        "denyList": []
      }]
    }
  }],
  "returnFullDatapoint": false
}'

トークン制限(deny)

特定のデータを事前に除外することができます。
例えば、青色の商品を除外したいと言ったケースに使えます。

curl
$ curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://1957880287.asia-northeast1-181224308459.vdb.vertexai.goog/v1/projects/181224308459/locations/asia-northeast1/indexEndpoints/3370566089086861312:findNeighbors" \
-d '{
  "deployedIndexId": "test_index_public1",
  "queries": [{
    "datapoint": {
      "datapointId": "<DATA_POINT_ID>",
      "restricts": [{
        "namespace": "color",
        "allowList": [],
        "denyList": ["blue"]
      }]
    }
  }],
  "returnFullDatapoint": false
}'

データポイントの検索

Index Endpoint内に登録したデータの中身が返ってきます。
idsに複数指定や、returnFullDatapointをtrueにして中身を省略せずに表示できます。

curl
$ curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://1957880287.asia-northeast1-181224308459.vdb.vertexai.goog/v1/projects/181224308459/locations/asia-northeast1/indexEndpoints/3370566089086861312:readIndexDatapoints" \
-d '{
  "deployedIndexId": "test_index_public1",
  "ids": ["<DATA_POINT_ID>"],
  "returnFullDatapoint": true
}'

Q&A

検索した時にdistance 1として自分自身が返ってこない

最近傍探索の精度や速度により、distanceが1にならない場合があります。
自分自身を除外したい場合は、deny listを使いましょう。

リクエスト時まれに403エラーになる

キャッシュの影響により、古いトークンが排出されることがあります。
metaサーバーのトークンを使うと回避できます。

curl
$ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" -s
> {"access_token":"ya29.c...","expires_in":2926,"token_type":"Bearer"}

まとめ

GAされたばかりか情報が少なく、結構躓きました。
リクエスト時の構造が間違っていてもエラーが返ってこないことがあるので、おかしいなと思ったら、まずはリクエストボディを再確認してみましょう!

追記

upsert時にallow listにのみ追加したものをdenyできる現象を確認しています。
おそらくバグかと思います。。。

GitHubで編集を提案

Discussion