本稿では、YOMLLを「なぜ作り、どう設計し、どのように運用しているか」を、読者が自分のプロジェクトに持ち帰れる形で要点中心に記します。箇条書きは必要最小限にとどめ、意思決定の背景も簡潔に補足します。
TL;DR
- 個人開発中心で、設計・実装・運用を主担当。必要に応じて軽量な進行管理やドキュメント/LP更新も兼務。
- 「低コストで自由度の高いOCR」をコンセプトに、生成AIとサーバレスで 0→1 を実現。リリースして運用中。
- ユーザーがドラッグ&ドロップで独自フォーマットを作成し、ゼロショット抽出で初見の帳票にも対応。
- AWS サーバレス+SaaS連携(Stripe/Azure DI 等)で スケーラビリティとコスト最適化を両立。
- 認識精度・コスト・運用性の三重最適化に挑み、フォーマット定義×AI補正×多段エンジンで突破。
なぜ作ったか(課題と着想)
日本の現場では、請求書・配送伝票・入金控えなど多様で統一されない帳票が日々発生します。既存OCRは「テンプレート前提」「追加費用が嵩む」「設定が難しい」などの敷居があり、小規模事業者が導入しづらい課題がありました。
テンプレート不要で、初見でも動く。しかも“ページ単価が低い”。
この仮説の検証から YOMLL の開発を開始しました。
サービス概要(何ができるか)
YOMLLは、日々ばらつく帳票を「設定に頼り切らずに」実務で通すための道具です。現場が初回からつまずかないことと、運用後に手戻りが少ないことを重視して設計しています。以下は主要な機能面の概観です。
- 自由なフォーマット定義:GUI で項目・型・正規化ルールを作成。複数帳票を一括管理。
- ゼロショット抽出:生成AIを用いて初見レイアウトでも候補値を提示。表/明細の行抽出にも対応。
- 多段OCR:レイアウト推定→テキスト化→AI 構造化→バリデーション(Pydantic)。
- 低コスト志向:画像前処理・トークン節約・スロットリングで1枚あたりの原価を最小化。
- SaaSとして提供:Stripe でサブスク/従量課金、組織・ユーザー管理、監査ログ、API 提供。
自分の役割
実務の重心はエンジニアリングです。必要に応じて周辺業務も最小限の範囲で兼務しています。
- 主担当(エンジニアリング)
- バックエンド/インフラ(IaC、セキュリティ、監視、デプロイ)
- AI‑OCRパイプライン(候補生成・スコアリング・再抽出戦略、Pydantic バリデーション)
- 画像前処理、パフォーマンス/コスト最適化
- フロント/モバイルの基盤整備(必要機能の実装・保守)
- 兼務(必要最低限)
- 軽量な進行管理(タスク分解、優先順位付け、簡易ロードマップ)
- 簡易 PdM 対応(要件の粒度調整、ユーザーフィードバックの反映)
- ドキュメント/LP の更新、簡易的なマーケ施策の実行
- 問い合わせ一次対応・オンボーディング
- 請求/会計の連携(Stripe の設定・対処)
技術アーキテクチャ
実装詳細は多岐にわたりますが、狙いは可観測性とコスト最適化の両立です。過剰な複雑化を避けつつ、失敗時の戻り道を常に確保する構成にしています。骨格のみを示します。
- クラウド:AWS マルチアカウント(dev/prd)。API Gateway / Lambda(Python 3.13, x86_64/ARM64) / S3 / DynamoDB / SQS / CloudFront / WAF / Cognito / Parameter Store / Secrets Manager / SNS-Chatbot。
- アプリ層:
- 抽出フロー:画像前処理(Pillow/Lambda Layer)→ OCR エンジン(組み合わせ)→ 生成AIで構造化 → Pydantic で厳格バリデーション → フォールバック/再試行。
- フォーマット定義:ユーザー定義スキーマ(型・必須・正規化・正規表現)を DynamoDB に保存し、実行時に適用。
- フロント:Next.js(shadcn UI)、ドラッグ&ドロップのフォーマットビルダー。
- モバイル:React Native / Expo(撮影→即アップロード→サーバ処理)。
- 課金:Stripe(プラン+従量のハイブリッド、メーターイベント/エンタイトルメント活用)。
- CI/CD:GitHub Actions → OIDC Assume Role → 環境別デプロイ。IaC は CDK/SAM 併用。
- 監視:CloudWatch Logs / Metrics / Alarms、X-Ray、DLQ 可視化、Slack 通知。
[Client/Web/Mobile]
│ Upload/REST
▼
API Gateway ─▶ SQS(ジョブ)
│ │
▼ ▼
Lambda(前処理) Lambda(抽出/構造化)
│ │
▼ ▼
S3 DynamoDB(結果/メタ)
│ │
└──▶ Stripe(課金)/SNS→Slack
[Client/Web/Mobile]
│ Upload/REST
▼
API Gateway ─▶ SQS(ジョブ)
│ │
▼ ▼
Lambda(前処理) Lambda(抽出/構造化)
│ │
▼ ▼
S3 DynamoDB(結果/メタ)
│ │
└──▶ Stripe(課金)/SNS→Slack
難しかった点と突破口
現場のボトルネックは机上の想定よりも運用側に寄って発生します。以下では、実際に詰まった箇所と、前に進めるためにどこで判断軸を置いたかを簡潔にまとめます。
- ページ単価の最小化
- 課題:生成AIのトークン/外部OCRの従量がコストドライバ。
- 対応:前処理で二値化・傾き補正・領域切り出し→入力トークン削減/二段化(軽量→高精度)→キャッシュで再処理抑制。スロットリング&バッチ化で外部 API コストを平準化。
- 初見レイアウトの頑健性
- 課題:フォーマットが毎回違う。
- 対応:レイアウトヒント+ゼロショット抽出を併用。複数候補にスコアリングを付与し、Pydantic バリデーション(型/範囲/一致率)で自動棄却→再抽出。表は行列の輪郭推定+言語モデル補完で復元。
- フォールバック戦略
- 課題:外部OCRの稀な 4xx / 5xx、画像破損。
- 対応:多段エンジン(軽量OCR→外部OCR→AI 補完)+指数バックオフ+DLQ。破損/非対応はユーザー通知と再アップロード誘導。
- スループットと在庫(キュー)管理
- 課題:瞬間風速のトラフィックでレイテンシが悪化。
- 対応:SQS で段階分離、並列度=Lambda 同時実行+バッチサイズで制御。アイデンポテンスキー採用、再実行でも二重計上しない。
- 課金モデル(ティア+従量)の整合
- 課題:プラン/上限/追加従量を Stripe とアプリで一貫管理。
- 対応:メーターイベントで使用量を逐次送信、エンタイトルメントで機能フラグを制御。請求確定の Webhook を整合ポイントに採用。
- セキュリティ/個人情報保護
- 課題:帳票に個人情報・機微情報。
- 対応:S3 SSE‑KMS、署名付き URL(短 TTL)、WAF、IP 制限(企業向け)、最小権限 IAM、監査ログ。OCR 入力は自動マスキングオプション(住所/口座/番号の部分マスク)。
- 運用事故の予防
- 課題:外部 API 仕様変更や一時障害での連鎖失敗。
- 対応:ヘルスチェックとカナリア、API バージョンの段階ロールアウト、アラートをSLO 起点に見直し(閾値→エラーバジェット運用)。
リリース後の運用
リリースは終点ではなく、初回成功体験の再現性を高め続けるフェーズの始まりです。日々の改善を回すために、運用方針とKPIを明確にし、観測可能性を保ったまま小さく更新します。
- 安定稼働:エラー率・再抽出率・平均処理秒数を主要 KPI に運用。
- ユーザーフィードバック駆動:誤抽出のアノテーション UIで学習データ化/精度改善サイクルを短縮。
- 費用監視:コスト異常検知(Athena/QuickSight or Looker Studio)で日次モニタリング。
実装スタック(抜粋)
採用技術は「再現性が高く、壊れにくく、学習コストが抑えられる」ことを基準に選定しています。流行に寄り過ぎず、運用負荷を上げない構成を意識しています。
- 言語/ランタイム:Python 3.13 / Node.js(フロント)
- LLM/AI:OpenAI API(構造化・補完)、レイアウト推定、表復元
- 画像処理:Pillow、OpenCV(必要に応じて)
- IaC/CI:AWS CDK / SAM、GitHub Actions(OIDC AssumeRole)
- データ:DynamoDB(結果・定義)、S3(原本・サムネ)
- 認証/認可:Cognito(OIDC連携)、RBAC
- 決済:Stripe(サブスク+従量、Entitlements / Meter Events)
- 監視:CloudWatch / X‑Ray / DLQ / SNS‑Chatbot
- フロント/モバイル:Next.js(shadcn/ui)、React Native / Expo
学び
まず小さく作って早く出すことが最も効きました。動く最小機能を短期間で公開し、実際の利用から得た気づきを次の更新に反映することで、机上の検討に費やす時間を減らせました。併せて、価値と価格のズレは早めに確かめる必要があります。無料期間を長引かせず、少額でも対価をいただくことで「何にお金を払っていただけるのか」が明確になり、機能の優先順位も定まりました。初期の運用は手作業で問題ないと割り切り、人手で回して流れを確認し、同種の作業が続く箇所から段階的に自動化しました。
次に、最初の導入体験を短くすることが定着率に直結しました。登録から初回成功までの道筋をサンプル・テンプレート・簡潔なガイドで補助し、迷いどころを減らします。見る指標は絞るほど良いと実感しました。初回成功までの所要時間、やり直し率、継続利用の有無の三点を毎週確認するだけでも、余計な数値に振り回されません。機能は足すより減らす判断が難しいのですが、使われていないものは統合または削除し、選択肢を整理するほど体験は改善しました。
最後に、コストは常に意思決定の材料です。1枚あたりの目安を持ち、品質とのバランスを見ながら判断します。ひとり運営では、作る時間と対応する時間を分けるだけで生産性が大きく変わりました。通知は重要なものに絞り、リズムを一定に保つことが、継続的な改善の土台になっています。
リリース状況
想定ユーザーの実務に入れてもらい、改善点を短いサイクルで反映しています。数値の開示は控えますが、問い合わせ内容と再抽出率を主な判断材料に運用しています。
- 正式リリース済み・運用中(2025年10月)
- 早期ユーザーの実業務で稼働。改善サイクルを継続中!