ミセバンAI のアーキテクチャ — なぜRustで、なぜエッジ+クラウドか

1. 設計思想

ミセバンAIの設計は、3つの原則から始まりました。

  1. プライバシーファースト — 映像データはクラウドに蓄積しない。AI処理後にメモリから即破棄する
  2. 最小コスト — 店舗側のハードウェア要件を極限まで下げる。月額2,980円で成立するインフラ
  3. 保守性 — 10年運用できるコードベース。依存関係は最小限に、型安全性は最大限に

映像データをクラウドに蓄積しないことは「機能」ではなく「思想」です。お客様の顔が映る映像を保存しないという判断は、技術的な制約ではなく、私たちが選んだ設計方針です。

2. 全体アーキテクチャ図

システムは「店舗側エージェント」と「クラウドAI」の2層で構成されます。店舗側は超軽量なフレーム転送に徹し、重いAI処理はすべてクラウドで実行します。

System Architecture
カメラ (RTSP) エージェント HTTPS (TLS 1.3)

API Gateway フレームキュー AI推論ワーカー 結果DB
LINE / Slack 通知 Web ダッシュボード

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つの動作モード

設定ファイル

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)で計算すると:

一般的なインターネット回線であれば全く問題にならない帯域量です。

5. クラウドAI推論

推論エンジン

物体検出にはYOLOv8-mを採用しています。GPU上で1フレームあたり約15ms(RTX 4090)で処理できるため、1台のGPUサーバーで1,000台以上のカメラを同時処理可能です。

処理パイプライン

  1. フレーム受信 — API Gatewayがエージェントからのフレームを受け取り、キューに投入
  2. 人物検出 — YOLOv8-mでバウンディングボックスを検出
  3. トラッキング — ByteTrackアルゴリズムでフレーム間の同一人物を追跡
  4. 属性推定 — 年齢層・性別・滞在時間を推定
  5. 結果保存 — 統計データのみをDBに保存。元フレームは破棄

元のフレーム画像はAI処理完了後にメモリから即座に破棄されます。ディスクには一切書き込みません。DBに保存されるのは「14:32に30代男性が入店」のような統計データだけです。

スケーリング

カメラ台数の増加に応じてGPUワーカーを水平スケールします。キューベースのアーキテクチャにより、ワーカーの追加・削除は既存の処理に影響を与えません。

6. セキュリティアーキテクチャ

通信の保護

映像データの扱い

サプライチェーンセキュリティ

ツール 用途 タイミング
cargo-deny 全依存クレートの脆弱性・ライセンス監査 CI(毎コミット)
gitleaks シークレット(APIキー等)の混入検知 pre-commit hook
trivy コンテナイメージの脆弱性スキャン CI(ビルド後)
cargo-cyclonedx SBOM生成。依存関係の透明性確保 リリース時

バイナリ・コンテナの署名

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で以下のステップを自動実行します。

  1. セキュリティスキャンcargo-deny + gitleaks で脆弱性・シークレット検知
  2. ビルド・テストcargo test + cargo clippy
  3. コンテナビルド — マルチアーキ(amd64/arm64)Dockerイメージ
  4. コンテナスキャンtrivy でイメージの脆弱性チェック
  5. リリースcosign 署名 + SBOM添付 + GitHub Releases公開
  6. デプロイ — Fly.ioへの自動デプロイ

全工程がCLIで完結します。GUIツールへの依存はゼロ。make release 一発でセキュリティスキャンからデプロイまで自動実行されます。

フィードバック

この設計についてのフィードバックをお待ちしています。GitHubのIssueか、Xで @misebanai までお気軽にどうぞ。