「AIプロジェクトを『サービス』にする過程で直面した5つの問題」
デモ動画
https://drive.google.com/file/d/1xtQXkrt4IGIjD6P26lMW2l6e6EtZAB-S/view?usp=drive_link
- 画像アップロード → 欠陥判定 → 結果保存までの動作
- DockerベースのAPI + MySQLコンテナ実行
- AWS環境で実際のリクエスト → DB保存までを確認
この記事を書く理由
今回のプロジェクトは、単なるモデル実験ではなく 「AIモデルを実際のサービスにする」 という目標からスタートした。
特に以下の構成を軸に進めた:
- Frontend: React
- Backend: FastAPI
- Database: MySQL
- Infra: Docker + AWS
核心は「モデルではなくシステム」だった。
開発中に踏んだ失敗を整理しながら、 デモ → ベータへどう拡張するかまで一緒にまとめてみた。
1. MySQL初期化SQLの実行順序問題
問題
Dockerの docker-entrypoint-initdb.d/ は SQLファイルをアルファベット順に実行する。
そのため、こんな事態が起きた:
indexes.sql→ 先に実行されるschema.sql→ 後から実行される- テーブルが存在しない状態でインデックス作成を試みる → エラー
解決策
ファイル名に番号を付けて順序を強制した。
01_schema.sql
02_indexes.sql
01_schema.sql
02_indexes.sql
学んだこと
「DockerでのDB初期化は『順序』まで含めて設計する必要がある」
2. Dockerコンテナ内部のhostname
問題
DB_HOST=localhost
DB_HOST=localhost
→ APIコンテナからDBへの接続が失敗
原因
コンテナ内部での localhost は 「自分自身」を意味する
解決策
DB_HOST=db
DB_HOST=db
(docker-composeのサービス名を使用)
学んだこと
「コンテナ間通信はlocalhostではなくサービス名を使う」
3. MySQL 8.0のrootユーザー設定
問題
MYSQL_USER=root
MYSQL_USER=root
→ コンテナ起動失敗
原因
MySQL公式イメージのルール:
MYSQL_USER→ 一般ユーザー用- root →
MYSQL_ROOT_PASSWORDでのみ設定可能
解決策
MYSQL_ROOT_PASSWORD=xxx
MYSQL_ROOT_PASSWORD=xxx
のみを使用
学んだこと
「Docker公式イメージのルールを知らないと、普通に壊れる」
4. CORS設定(デプロイ環境の罠)
問題
フロントエンドからAPIを呼び出した際:
Failed to fetch
Failed to fetch
原因
開発環境:
http://localhost:5173
http://localhost:5173
デプロイ環境:
http://localhost:80
http://localhost:80
originが異なるためブロックされた
解決策
ALLOWED_ORIGINS=http://localhost,http://localhost:80
ALLOWED_ORIGINS=http://localhost,http://localhost:80
学んだこと
「CORSはハードコードではなく環境変数で管理すべき」
5. 外部キー vs 認証未実装
問題
uploaded_images.user_id → users.id FK
uploaded_images.user_id → users.id FK
しかし… JWT認証はまだ未実装 userデータが存在しない
→ INSERT失敗
(デモ段階での解決)
- 一時的に構造を単純化して、まずフローを繋いだ
学んだこと
「MVPでは完璧な整合性より『フローをつなぐこと』が先」
今は「デモバージョン」
現在の状態はここまでだ:
- 画像アップロード
- モデル推論
- 結果返却
- DB保存
- Docker実行
- AWSデプロイ確認
つまり、
「サービスの最小フロー(MVP)を検証した状態」
次のステップ:ベータバージョン
ここからが本番だ。
1. 認証 + ユーザーシステム
- JWTログイン / 会員登録
- ユーザーごとのデータ管理
- FK正規化
2. ログ & 運用機能
- request_logs
- error_logs
- 障害追跡可能な構造
3. 管理者機能
- review_queue
- 低信頼ケースの管理
- humanラベルの記録
4. データ拡張
- dataset_candidates
- 再学習候補の管理
- 失敗ケースの蓄積
DB構造の拡張(ベータ)
デモでは最小構成のみを使ったが、 ベータではこう進める:
現在(デモ)
- uploaded_images
- predictions
追加(ベータ)
users
request_logs
error_logs
review_queue
dataset_candidates
users
request_logs
error_logs
review_queue
dataset_candidates
追加フィールド(核心)
is_low_confidence
failure_reason
ai_review_summary
similar_case_group
is_low_confidence
failure_reason
ai_review_summary
similar_case_group
これが核心だ:
「単純な保存ではなく → 改善可能なデータ構造」
自分が作りたいもの
これはただのAI APIではなく
「継続的に改善されるAI SaaSシステム」
- 推論 → 保存
- 失敗 → 分析
- レビュー → データ化
- 再学習 → 性能改善
まとめ
今回のプロジェクトで一番強く感じたのはこれだ:
モデルよりシステムの方が難しい。
そして、もっと面白い。
次の記事では
- JWT認証の実装
- レビューシステム
- ログベースの改善構造
まで続けてまとめていく予定だ。