本記事は「Kong Advent Calendar 2024」の14日目のエントリで、API GatewayのKongを体感的に使える Kong Cameraを作ってみます
ChatGPT/OpenAI APIに代表されるように、世の中APIの必要性は増すばかり。そんなAPIを統合的に管理するKong API Gatewayの需要が高まってきています。
ここでは、カメラデバイスKong Cameraで写真を撮って、それをAIに画像解析してもらいます。この一連の流れをKong Gatewayを通す事により、API管理の仕組みを学んでいきます。
この記事で学べる事
A. Kong Konnect、API Gatewayの使い方が分かる
B. IoTデバイス(Raspberry Pi)とカメラを連動したAPIの作り方
C. AIの効率的な管理(Kong AI Gateway)について学べる
Kong Cameraの作り方はざっとこんな感じ
- Kong Konnectの導入
- Raspberry PiとウェブカムをつないでカメラAPIの作成
- Kong KonnectへのカメラAPIの登録
- AI Gatewayの設定
- Kong Button、Lampと連動させて完成!
ハードウェアで必要なもの
必要なもの | 部品 |
---|---|
Raspberry Pi | |
ウェブカム | |
その他ケーブル、両面テープ、など | 適宜 |
カメラから映像を撮って、AIが画像解析してくれます。
I. Kong API Gatewayの立ち上げ
まだKong環境を用意していない方は、前回記事 と同様の流れに従って、KongのSAAS環境Kong Konnectで、API Gatewayを立ち上げて下さい。
1. Kong Konnect にアクセス
https://cloud.konghq.com にアクセスして、ユーザー、パスワードなどを登録し、Kong Konnectに入ります。
2. Control Planeを作成
Konnectにログオンできたら、Gateway Managerスクリーンから New Control Plane を押して、新しいGatewayを作ります。
3. Data Planeを作成
Data Plane Nodesには、Kongのフルマネージド環境の Dedicated Cloud Instances を選びます。
そうすると Payment method の設定を求められるので、クレジットカードの支払い方法をセットします。
(無料枠$500があるので、その範囲内の最小限の使い方なら課金されることはありません)
Regionを選ぶ画面が出るので、USなどの適当なRegionを選びます。
4. (Option) ドメインの設定
(オプションですが)左側メニューのCustom Domainsから、個人のドメイン名を紐づけます。
これでhttps://konnect.example.com のようなURLでKong環境にアクセスできるようになりました。
II. Raspberry PiとウェブカムをつないでカメラAPIの作成
ハードウェアとの連携として、Raspberry Pi(ラズパイ)とカメラを接続して、画像撮影ができるAPIを作ります。
1. ラズパイとカメラの接続
今回使ったのはこちらのウェブカムで、ラズパイにUSBで接続します。
ラズパイとUSBでつないだら接続を確認します。
このような記事に従って、ラズパイにSSHでアクセスできるようにします。
以下のコマンドを流してみて下さい。
$ lsusb
Bus 001 Device 003: ID 0411:02da BUFFALO INC. (formerly MelCo., Inc.) USB 2.0 Camera
$ ls /dev/video*
/dev/video1
接続したカメラが見えれば(この場合BUFFALO)撮影に使えます。
次に画像撮影のためのfswebcamをインストールします。
以下のようなコマンドから写真を撮影します。
$ sudo apt install fswebcam
$ sudo fswebcam -r 320x240 kong.jpg
kong.jpgというファイルが作られ、デスクトップ画面で開いてみると、写真が撮れている事が分かると思います。
2. カメラAPIの作成
前回のパトランプAPIの記事を参考に、カメラAPIを作成します。
前回作ったExpressのapp.jsに、以下の部分を追加します。
var express = require('express');
// ...
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var led = require('./routes/led');
var cam = require('./routes/cam'); // << *** Camera API Added ***
// ...
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/led', led);
app.use('/cam', cam); // << *** Camera API added ***
// ...
次にroutesフォルダ下に以下のようなコードで、cam.jsファイルを作成します。
var express = require('express');
var router = express.Router();
const homeDir= "/home/pi/Programs/iot/image/";
router.get('/:action', function(req, res, next) {
var param = {"Camera API":"shot !"};
res.header('Content-Type', 'application/json; charset=utf-8');
imageFile = homeDir+"kong.jpg";
exec('sudo fswebcam -r 320x240 --no-banner -q '+imageFile);
param["imageFile"] = imageFile;
res.send(param);
});
module.exports = router;
これを実行して、APIとして機能するか試してみます。
$ sudo mkdir image
$ sudo chmod 755 image
$ npm start
$ curl localhost:3000/cam/shot
これを実行すると、ローカルフォルダに写真が保存されます。
これで写真撮影するカメラAPIが作成できました。
III. Kong KonnectへのカメラAPIの登録
作ったカメラAPIをKong Konnect上に登録します。
1. ngrokによるトンネル化
まだAPIを公開していない場合は、前回記事に従って、ngrokというサービスでAPIのトンネル化を実行して下さい。
https://ngrok.com にアクセスし、Setup IntroductionからRaspberry Piのngrokの導入を行なっておきます。
こうすると、以下のようにインターネット上からngrokのURLで、ラズパイのCamera APIを起動する事ができるようになります。
$ snap install ngrok
$ ngrok config add-authtoken ngrok_token
$ ngrok http localhost:3000
$ curl https://ngrok-endpoint-free.app/cam/shot
これでKong Konnectに登録するAPIが準備できました。
2. カメラAPIをKongのサービスとして登録
改めてKong Konnectに入ります。
Konnectの左側のGateway Servicesから、New Gateway Serviceを選び、新しいサービスを作成します。
先ほどのngrok Endpointをhostに指定します。Pathは先ほど作った/cam にします。
サービスのルートを以下のように作成します。
3. Kongからの接続確認
設定が済んだら、KONGのプロキシまたは自分で設定したドメイン経由で、カメラAPIにアクセスします。
このようにブラウザから実行すると結果が表示されます。
Kongのプロキシを使って接続して、このような写真が撮れていました。
IV. AI Gatewayの設定
次にKongのAI機能、AI Gatewayの設定を行っていきます。
1. AIサービスの登録
KongのAI機能のAI Gatewayの登録を行います。
以下のようにOpenAIのサービスの追加をします。
以下のように、ルートの追加も行います。
これをCurlから実行してみます。
URLは、https://konnect.example.com/openai/v1/chat/completions のような形になります。
XXXXは、OpenAIのKEYであらかじめ、https://openai.com から取得しておいて下さい。
$ KONG=https://konnect.example.com
$ IMAGE_URL=https://AAAA.com/image.jpg
$ GPT_API_KEY=sk-XXXX
$ curl $PROXY/openai/v1/chat/completions \
$ -H "Content-Type: application/json" \
$ -H “Authorization: Bearer ${GPT_API_KEY}” \
$ -d ‘{
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What is in this image?"
},
{
"type": "image_url",
"image_url": {
"url": ${IMAGE_URL}
}
}
]
}
],
"max_tokens": 300
}’
これを実行して、結果が返ってくれば、Konnect経由でOpenAI APIが実行できています。
...
"model": "gpt-4o-2024-08-06",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "This image shows Mount Fuji, a famous and iconic stratovolcano in Japan. The mountain is snow-capped at the top, and in the foreground, there are lush green fields and trees, along with a view of a town or city with roads and buildings. The sky is clear and blue.",
"refusal": null
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 1118,
"completion_tokens": 60,
"total_tokens": 1178,
"prompt_tokens_details": {
"cached_tokens": 1024,
"audio_tokens": 0
},
...
2. AI Gatewayの設定
このサービスにAIのPluginsを設定します。
ここでは、AIのトークンベースの流量制限AI Rate Limiting Advancedを追加します。
先ほどのOpenAIのサービスを選んで、Pluginsに行きます。
Pluginsから、AI Rate Limiting Advancedを選びます。
このPluginの設定は以下のように行います。
これで60秒間に100トークン以上OpenAIが呼ばれた時に、429 Errorを返すようになります。
これを実行してみると、rate limit exceededのメッセージが出て一時的にAPIがコールできないようになります。
KonnectのAnalytics画面でもそれが確認できます。
V. Kong Buttonと連動させて完成!
Kong Button記事 で作成したものと連動させて、ボタン長押しでカメラから写真を撮り、AIに画像解析させます。
1. カメラAPIへAI機能の追加
ラズパイ上で先ほど作ったカメラAPIで、cam.jsにAIの機能を追加します。
撮影して画像解析した結果をLINEにも送付します。
APIのキーを環境変数に入れておくため、.envファイルを作成しておきます。
ここでは、XXXXはOpenAIのキー、LLLLはLINE Keyの意味です。
$ sudo vi .env
GPT_API_KEY=XXXX
LINE_NOTIFY_TOKEN=LLLL
var express= require('express');
var router = express.Router();
var fs = require('fs');
var axios = require('axios');
var FormData= require('form-data');
var config = require('dotenv').config();
const KONG = "https://konnect.example.com";
const homeDir= "/home/pi/Programs/iot/image/";
const GPT_API= KONG + "/openai/v1/chat/completions";
const GPT_API_KEY = process.env.GPT_API_KEY;
const LINE_NOTIFY_API = KONG + "/line/api/notify";
const LINE_NOTIFY_TOKEN= process.env.LINE_NOTIFY_TOKEN;
router.get('/:action', function(req, res, next) {
var param = {"Result ":"Camera API"};
res.header('Content-Type', 'application/json; charset=utf-8')
imageFile = homeDir+"kong.jpg";
exec('sudo fswebcam -r 320x240 --no-banner -q '+imageFile);
param["fswebcam"] = imageFile;
const imageBuffer = fs.readFileSync(imageFile);
const base64Image = imageBuffer.toString("base64");
var SYSTEM_PROMPT = "ここに写っている画像を20字で説明して下さい。";
const analyzeImageByGPT = async () => {
const messages = [
{role: "system", content: SYSTEM_PROMPT},
{role: "user", content: [
{type: "image_url", image_url: {url: `data:image/jpeg;base64,${base64Image}`}}
]
}
];
try {
const response = await axios.post(GPT_API, {
model: "gpt-4o", messages: messages
}, {
headers: {'Authorization': `Bearer ${GPT_API_KEY}`, 'Content-Type': 'application/json'
}
});
imageResult = response.data.choices[0].message.content;
param["imageResult"] = imageResult;
res.send(param);
const imagefile = fs.createReadStream(imageFile);
const formData = new FormData();
formData.append('message', imageResult);
formData.append('imageFile', imagefile);
const result = await axios({
method: 'POST',
url: LINE_NOTIFY_API,
headers: { Authorization: `Bearer ${LINE_NOTIFY_TOKEN}`, 'apikey': 'AAAA', 'content-type': 'multipart/form-data', ...formData.getHeaders() },
data: formData
})
} catch (error) {
console.error(`画像解析のエラー: ${JSON.stringify(error)}`);
return null;
}
}
});
これを実行すると、写真、解析結果がLINEに送られてきます。
2. Kong Buttonにカメラ機能を追加
最後にKong Buttonに機能を追加します。
ボタンを長押しすると、カメラで写真を撮って、AI Gatewayに送信します。
そのために、前回作った Buttonのスケッチに、以下のように追記します。
#include "M5StickCPlus.h"
// ...
const String cam = "https://konnect.example.com/cam"; // *** Added ***
// ...
void loop(){
M5.update();
// ...
if (M5.BtnA.wasPressed()) {
delay(longPress_ms);
if(M5.BtnA.read() == true){
Serial.print("Red");
M5.Lcd.fillScreen(RED);
M5.Lcd.printf("Help!");
sendLine("問題あるか見て! HELP!", 8522, 16581287);
http_get(led+"/on");
http_get(cam+"/shot"); // *** Added ***
sendOpenAIRequest(prompt); // *** Added ***
delay(500);
http_get(led+"/off"); // *** Added ***
}
}
delay(500);
}
3. 全部つなげて使ってみよう!
ユースケースとしては、家の事が心配になったらボタンを長押して、家の中にあるラズパイに写真を撮らせます。そこに何が写っているかAIが画像解析して、LINEで通知。家のパトランプも光るので、もし不審者が居ても警告できますね!
ボタンを長押しすると、写真を撮って、AIが画像解析します。
スマホには、その写真と解析した内容が送られてきます。
KongのAnalytics画面でAPIコールが確認できます。
またKonnectのAnalytics Reportsを使うと、APIの状況を監視、確認する事ができます。
まとめ
という事で、Kong Konnect上にAPIをセットし、ハードウェアのカメラから写真を撮る事ができるようになりました。
またKongのAI Gatewayを使うと、AI登録や管理が簡単にでき、とても便利な事が分かりました。
Kongを使うとさまざまなAPIをまとめて管理でき、またCloud Gatewayを使うと自分自身で環境を持たなくてもフルマネージドな環境が手に入ります。
今後もさまざまなAPIを追加して、便利な環境にしていこうと思います!
それでは、よいKongを! Happy Kong!
ヨシケン