ミセバンAI のアーキテクチャ — なぜRustで、なぜエッジ+クラウドか
1. 設計思想
ミセバンAIの設計は、3つの原則から始まりました。
- プライバシーファースト — 映像データはクラウドに蓄積しない。AI処理後にメモリから即破棄する
- 最小コスト — 店舗側のハードウェア要件を極限まで下げる。月額2,980円で成立するインフラ
- 保守性 — 10年運用できるコードベース。依存関係は最小限に、型安全性は最大限に
映像データをクラウドに蓄積しないことは「機能」ではなく「思想」です。お客様の顔が映る映像を保存しないという判断は、技術的な制約ではなく、私たちが選んだ設計方針です。
2. 全体アーキテクチャ図
システムは「店舗側エージェント」と「クラウドAI」の2層で構成されます。店舗側は超軽量なフレーム転送に徹し、重いAI処理はすべてクラウドで実行します。
3. なぜRustか
エージェント(店舗側): 圧倒的な軽さ
エージェントの実行時メモリはわずか50MB以下。Go製の同等プログラムと比べて約1/3、Pythonと比べて1/5以下です。Raspberry Pi Zero 2 W(512MB RAM)でも余裕で動作します。
クラウドAPI: 桁違いのスループット
WebフレームワークAxumは、実測ベンチマークでExpressの10倍、Flaskの50倍のリクエスト処理能力を示します。少ないサーバー台数で多くのカメラを捌けることは、直接コスト削減につながります。
| 指標 | Rust (Axum) | Node (Express) | Python (Flask) |
|---|---|---|---|
| req/sec | ~150,000 | ~15,000 | ~3,000 |
| メモリ (idle) | 8 MB | 50 MB | 30 MB |
| Dockerイメージ | 23 MB | 180 MB | 350 MB |
安全性: メモリ安全の保証
カメラから送られてくるRTSPストリームは外部入力です。C/C++で書かれたパーサーではバッファオーバーフローのリスクが常につきまといますが、Rustではそのクラスの脆弱性がコンパイル時に排除されます。
単一バイナリ: デプロイの単純さ
cargo build --release で生成される単一バイナリをコピーするだけ。ランタイムの依存なし。Dockerイメージは23MBに収まり、デプロイは数秒で完了します。
実際のコード: エージェントのメインループ
async fn run_agent(config: &Config) -> Result<()> {
let client = reqwest::Client::new();
let mut stream = RtspStream::connect(&config.camera.url).await?;
let interval = Duration::from_secs_f64(1.0 / config.camera.fps);
loop {
let frame = stream.next_jpeg_frame().await?;
let res = client
.post(&config.cloud.endpoint)
.bearer_auth(&config.cloud.token)
.body(frame)
.timeout(Duration::from_secs(10))
.send()
.await;
if let Err(e) = res {
tracing::warn!("upload failed, retrying: {e}");
}
tokio::time::sleep(interval).await;
}
}
わずか15行。RTSPからフレームを取得し、HTTPSでクラウドに送るだけ。AI処理のコードは一切含まれていません。
4. エージェント設計
超軽量設計
エージェントの責務は明確です: RTSP受信 → JPEGフレーム抽出 → HTTPS POST。それだけです。AI推論はゼロ。映像の保存もゼロ。単なるフレーム転送器として設計しています。
3つの動作モード
- Docker (PC) —
docker run miseban/agentで即起動。既存サーバーやNASで動作 - アプリ (スマホ) — iOS/Androidアプリとしてカメラ映像を直接送信
- ネイティブ (RPi) — Raspberry Pi向けARMバイナリ。専用カメラデバイスとして利用
設定ファイル
TOMLフォーマットのシンプルな設定ファイルで動作します。
[camera]
url = "rtsp://admin:password@192.168.1.100/stream1"
fps = 0.2 # 5秒に1フレーム
[cloud]
endpoint = "https://api.misebanai.com/v1/frames"
token = "mbn_xxxx"
リトライ戦略
ネットワーク障害に備え、exponential backoff(初回1秒、最大60秒)でリトライします。RTSPストリームの接続断が発生した場合は自動再接続を試みます。通信断の間、フレームは単純に破棄されます。映像を溜め込んで後から送信するような複雑な処理は行いません。
帯域使用量
1フレーム約50KB、5秒に1回送信(0.2fps)で計算すると:
- 1分あたり: 50KB × 12回 = 600KB
- 1日あたり: 600KB × 60 × 24 = ~830MB
- 1ヶ月あたり: ~25GB
一般的なインターネット回線であれば全く問題にならない帯域量です。
5. クラウドAI推論
推論エンジン
物体検出にはYOLOv8-mを採用しています。GPU上で1フレームあたり約15ms(RTX 4090)で処理できるため、1台のGPUサーバーで1,000台以上のカメラを同時処理可能です。
処理パイプライン
- フレーム受信 — API Gatewayがエージェントからのフレームを受け取り、キューに投入
- 人物検出 — YOLOv8-mでバウンディングボックスを検出
- トラッキング — ByteTrackアルゴリズムでフレーム間の同一人物を追跡
- 属性推定 — 年齢層・性別・滞在時間を推定
- 結果保存 — 統計データのみをDBに保存。元フレームは破棄
元のフレーム画像はAI処理完了後にメモリから即座に破棄されます。ディスクには一切書き込みません。DBに保存されるのは「14:32に30代男性が入店」のような統計データだけです。
スケーリング
カメラ台数の増加に応じてGPUワーカーを水平スケールします。キューベースのアーキテクチャにより、ワーカーの追加・削除は既存の処理に影響を与えません。
6. セキュリティアーキテクチャ
通信の保護
- TLS 1.3必須 — 1.2以下は拒否。証明書ピニングにより中間者攻撃を防止
- 認証 — Bearer Token(APIキー)による認証。将来的にmTLS(相互TLS認証)へ移行予定
映像データの扱い
- メモリ上のみ — フレームデータはAI処理後に即破棄。ディスクに書かない
- 統計データ — AES-256-GCMで暗号化保存
サプライチェーンセキュリティ
| ツール | 用途 | タイミング |
|---|---|---|
cargo-deny |
全依存クレートの脆弱性・ライセンス監査 | CI(毎コミット) |
gitleaks |
シークレット(APIキー等)の混入検知 | pre-commit hook |
trivy |
コンテナイメージの脆弱性スキャン | CI(ビルド後) |
cargo-cyclonedx |
SBOM生成。依存関係の透明性確保 | リリース時 |
バイナリ・コンテナの署名
- バイナリ —
minisignで署名。ユーザーはダウンロード後に検証可能 - コンテナ —
cosign(Sigstore) でイメージ署名。改ざん検知
7. オープンソース戦略
ミセバンAIは「エージェントは公開、クラウドAIはプロプライエタリ」のハイブリッドモデルを採用しています。
| コンポーネント | ライセンス | 理由 |
|---|---|---|
| エージェント | MIT License | 店舗に設置するソフトウェアの透明性を確保 |
| クラウドAI | プロプライエタリ | ビジネスの核となるAI推論・分析ロジックを保護 |
店舗オーナーにとって、自分の店に設置するソフトウェアの中身が見えることは信頼の基盤です。一方で、クラウド側のAI推論ロジックは継続的な研究開発投資の成果であり、イノベーションを保護する必要があります。
このモデルはLinuxカーネル(GPL公開、クラウドサービスで収益)やChromium(BSDライセンス公開、Google Chromeとして収益)と同じ「コアを公開し、サービスで収益を上げる」パターンです。
8. 開発環境とCI/CD
ローカル開発
# コンパイルチェック(型エラーの検出)
cargo check
# Lintチェック(コード品質)
cargo clippy -- -D warnings
# テスト実行
cargo test
# フォーマット
cargo fmt --check
CI/CDパイプライン
GitHub Actionsで以下のステップを自動実行します。
- セキュリティスキャン —
cargo-deny+gitleaksで脆弱性・シークレット検知 - ビルド・テスト —
cargo test+cargo clippy - コンテナビルド — マルチアーキ(amd64/arm64)Dockerイメージ
- コンテナスキャン —
trivyでイメージの脆弱性チェック - リリース —
cosign署名 + SBOM添付 + GitHub Releases公開 - デプロイ — Fly.ioへの自動デプロイ
全工程がCLIで完結します。GUIツールへの依存はゼロ。make release 一発でセキュリティスキャンからデプロイまで自動実行されます。
フィードバック
この設計についてのフィードバックをお待ちしています。GitHubのIssueか、Xで @misebanai までお気軽にどうぞ。