APIで受け取るリクエストを加工したい時がある。
例えば問い合わせフォームから連絡を貰う場合、個人情報に繋がるデータは保管しない、というルールになっていると格納前にマスキングなどして加工する必要が出てくる。
こういったケースの場合、大昔だと個々に加工することが一般的だった気がする。
最近だと転送前に加工したり、中継サーバやAPI Gatewayなどで加工することも増えている。
ただ、この場合でも加工処理をコーディングする必要があり、作り込むのが結構面倒だったりする。
これをKong GatewayのAI Request Transformer Pluginを使うと加工処理・マスキング処理をAI側にまかせて、開発側ではコーディングなどして実装する必要がなくなる。
今回はこの使い方を確認する。
AI Request Transformer Pluginとは
AI Request Transformer PluginとはKong Gatewayのプラグインであり、バックエンドのサービスにリクエストを投げる前に設定されたLLMのサービスにリクエストを渡してリクエストを加工することが出来るものである。
公式ページのフローがAI Response Transformer Pluginの挙動も混じってて分かりづらかったので、以下公式のフローからAI Request Transformer Pluginのフローだけ抜き出したものを記載する。
ここのAI LLM Serviceは6/26現在ではOpenAI, Azure, Anthropic, Cohere, Mistral, Llama2が選べるようになっている。
今回は機密情報をマスキングするようなユースケースで検証するが、使い方次第では以下のような事も出来ると思われる。
- 特定の会社名が入っていたら電話番号のフィールドに自動で値を追加する
- AIに問い合わせる際に補足情報を足す
コーディングせずにささっとリクエストの内容を加工したい場合に使えるものと思うと良さそう。
検証の前提
検証を行うにあたり、ここでは既に以下があるものとして進める。
- Kong Gateway
- LLMサービスのAPIトークン
- deckコマンド
Kong GatewayのAdmin APIは公開されており、deckコマンドで利用可能になっているものとする。
LLMサービスのAPIトークンはここではOpenAIのものを利用する。
お金をかけずに試したい人はCohereかローカルにLLMサービスを立てて使うとよい。
設定
検証ではhttpbin.orgを使う。
httpbin.orgは/anything
にアクセスすると、リクエストの内容をそのまま表示してくれる。
$ curl -X POST https://httpbin.org/anything -d "key=value"
{
"args": {},
"data": "",
"files": {},
"form": {
"key": "value"
},
"headers": {
"Accept": "*/*",
:(省略)
これを使ってリクエストが書き換わっているかを確認する。
構成としては以下のようになる。
最初にKong Gatewayの設定ファイルを作成する。
以下のdeck用YAMLが設定となる。
LLM_APITOKEN="sk-proj-xxxx"
cat <<EOF > ./ai-transformer.yaml
services:
- name: public-httpbin
host: httpbin.org
path: /
protocol: https
port: 443
routes:
- name: httpbin-transformer
paths:
- /transformer
plugins:
- name: ai-request-transformer
config:
prompt: JSON内のクレジットカードの番号をマスクして
llm:
route_type: llm/v1/chat
auth:
header_name: Authorization
header_value: Bearer $LLM_APITOKEN
model:
provider: openai
name: gpt-4
EOF
services
とroutes
については説明は省略する。
plugins
の部分は設定は非常にシンプルで、prompt
のところに加工したい内容を記載し、llm
のところに使うLLMのサービス、モデル名、認証方法を記載するだけである。
AI側のAPIのエンドポイントはプラグインで隠蔽されており、ユーザが意識する必要はない。
(自前で用意したLLMサービスを使う場合は設定する必要あり)
なおCohereやその他のLLMサービスを使う場合はmodel
部分を以下のような感じで修正し、トークンをCohereのものに変えるだけである。
model:
provider: cohere
name: command-r
YAMLファイルの作成が終わったらdeckコマンドで設定を反映する。
一度今の設定を取り出す。
deck gateway dump -o /tmp/dump.yaml
今の設定に追記する形で作成したYAMLを適用する。
deck gateway sync /tmp/dump.yaml ./ai-transformer.yaml
特に問題なければKong ManagerからService/Routeが作成され、RouteにAI Request Transformer Pluginが適用されていることが確認できる。
検証
Kong Gateway経由でhttpbin.orgにリクエストを送ってみる。
先程プロンプトには以下のように設定した。
prompt: JSON内のクレジットカードの番号をマスクして
リクエスト内にクレジットカードの番号があればマスクされるはずだ。
以下のようにクレジットカードの番号を含むリクエストを投げてみる。
PROXY=https://192.168.64.202
curl -s -k --http1.1 -X POST ${PROXY}/transformer/anything \
--data-raw \
'{"Question": "DMMでVISAのクレジットカードは使えますか?私のクレジットカード番号は1234-5678-9012-3456です。ユーザIDは08642157です。"}' | jq .
出力結果は以下となった。
:(省略)
"files": {},
"form": {
"{\"Question\": \"DMMでVISAのクレジットカードは使えますか?私のクレジットカード番号は****-****-****-3456です。ユーザIDは08642157です。\"}": ""
},
"headers": {
"Accept": "*/*",
"Content-Length": "172",
:(省略)
クレジットカード番号が****-****-****-3456
と末尾の番号を除いてマスキングされ、ユーザIDはマスキングされず期待通りの結果となった。
末尾の番号を含めてマスキングしたいとか、細かな要望はプロンプトを調整することで実現出来る。
prompt
で以下のように「全て」という言葉を追加して再度試してみる。
prompt: JSON内のクレジットカードの番号を全てマスクして
結果は以下。
"{\"Question\": \"DMMでVISAのクレジットカードは使えますか?私のクレジットカード番号はxxxx-xxxx-xxxx-xxxxです。ユーザIDは08642157です。\"}"
上手く行った。
ということで、マスキングのためのコーディングなどを行うことなくリクエストにマスクを掛けることが出来た。
プロンプトエンジニアリングが必要にはなるが、実装コストが不要になる点は大きいので、リクエストの加工が必要なシーンでは利用を検討してみてもよいかと思う。
ただし、有料のLLMサービスを利用する場合は当然コストが掛かるのでその点は注意。