2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【月5ドル】レシート撮るだけ!AI家計簿を1週間で作った

2
Last updated at Posted at 2025-11-17

レシート撮るだけ!AI家計簿アプリを作った話【Amazon Bedrock × Streamlit】

TL;DR(要約)

  • レシート画像を撮影 → AIが自動で家計簿に記録
  • 技術スタック: Amazon Bedrock(Claude 3.7)、Textract、Python、Streamlit
  • 開発期間: 約1週間(試行錯誤含む)
  • コスト: 月額約$5〜10(従量課金)
  • 難易度: ★★☆☆☆(Pythonの基礎知識があればOK)

📖 目次

  1. なぜ作ったのか
  2. 何を作ったのか
  3. どうやって作ったのか
  4. システム構成
  5. 工夫したポイント
  6. ハマったポイント
  7. 今後の展望

なぜ作ったのか

背景:家計簿が続かない問題

2020年、新卒入社。コロナ禍。

  • 焦燥感と不安の中、家計簿アプリを導入
  • でも...めんどくさい
  • 2023年、ほぼ記録なし(レシート山積み)

2024年、物価上昇。

  • 「もう一度ちゃんと管理したい」
  • でもやっぱりめんどくさい
  • レシートすら受け取らなくなる

2025年、転機。

あるイベントでAmazon Bedrockに触れる機会があり、
「これならめんどくさがりな自分でも続けられるかも」と思い、開発を決意。

なぜStreamlit?

  • フロントエンドの知識不要
  • Pythonだけで完結
  • 爆速で試作できる
  • ローカル環境で十分

何を作ったのか

機能概要

レシート撮影 → AI読み取り → 自動で家計簿に記録

具体的には:

  1. スマホでレシートを撮影
  2. Streamlitアプリにアップロード
  3. AIが以下を自動抽出:
    • 店名
    • 購入日
    • 合計金額
    • カテゴリ(食費/外食/雑貨など)
  4. Google Spreadsheetに自動記録

従来の手入力(約3分)と比較して、約18倍高速


どうやって作ったのか

技術スタック

レイヤー 技術 用途
フロントエンド Streamlit UI・画像アップロード
バックエンド Python 3.12 ロジック・API連携
OCR Amazon Textract レシートの文字認識
AI Amazon Bedrock
(Claude 3.7 Sonnet)
テキスト分析・カテゴリ判定
データ保存 Google Spreadsheet 家計簿データ
AI Framework Strands SDK エージェント構築

システム構成図

データフロー

レシート画像(JPG)
  ↓ Streamlit:リサイズ・Base64エンコード
Base64文字列
  ↓ Textract:OCR処理
生テキスト
  例: "セブンイレブン\n2025/11/09\n合計 ¥1,580"
  ↓ Claude 3.7 Sonnet:AI分析
構造化データ
  {
    "店名": "セブンイレブン",
    "日付": "2025-11-09",
    "金額": 1580,
    "カテゴリ": "食費"
  }
  ↓ Google Sheets API
スプレッドシート記録完了 

システム構成

アーキテクチャ図(詳細版)

┌─────────────────────────────────────────────────────────┐
│                    ユーザー環境                         │
│  ┌────────────────────────────────────────────────┐     │
│  │   Streamlit UI (localhost:8501)               │     │
│  │  - 画像アップロード                                 │     │
│  │  - リサイズ処理(800px以下)                         │     │
│  │  - Base64エンコード                                │     │
│  └──────────────┬─────────────────────────────┘     │
│                 │ HTTP POST                           │
│  ┌──────────────▼─────────────────────────────┐     │
│  │   Python Agent (localhost:8080)           │     │
│  │  - HTTP サーバー(aiohttp)                      │     │
│  │  - エージェント制御(Strands SDK)                 │     │
│  │  - ツール管理                                      │     │
│  └──────────────┬─────────────────────────────┘     │
└─────────────────┼─────────────────────────────────────┘
                  │
        ┌─────────┴─────────┐
        │                   │
        ▼                   ▼
┌──────────────┐    ┌──────────────┐
│ 📄 Textract  │    │ 🤖 Bedrock   │
│  (OCR)       │    │  (Claude)    │
│ us-west-2    │    │ us-west-2    │
└──────────────┘    └──────────────┘
        │                   │
        └─────────┬─────────┘
                  │
                  ▼
          ┌──────────────┐
          │  Google    │
          │  Sheets API  │
          └──────────────┘

環境変数

# .env
SPREADSHEET_ID=your-spreadsheet-id
GOOGLE_CREDENTIALS_PATH=/path/to/credentials.json
AWS_DEFAULT_REGION=us-west-2
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key

工夫したポイント

Base64エラー対策

問題:
画像データが大きいとIncorrect paddingエラー

解決策:

# パディング自動追加
padding_needed = (4 - len(image_base64) % 4) % 4
if padding_needed:
    image_base64 += '=' * padding_needed

画像サイズ最適化

問題:
大きい画像(3MB以上)でTextractがタイムアウト

解決策:

# 800px以下にリサイズ
max_dimension = 800
if image.width > max_dimension or image.height > max_dimension:
    ratio = min(max_dimension / image.width, 
                max_dimension / image.height)
    new_size = (int(image.width * ratio), 
                int(image.height * ratio))
    image = image.resize(new_size, Image.Resampling.LANCZOS)

効果:

  • サイズ: 3.2MB → 150KB(約95%削減)
  • 処理時間: 15秒 → 3秒(5倍高速化)

カテゴリ自動判定

Claudeにルールベースの判定をさせる:

system_prompt = """
カテゴリ自動判定ルール:
1. 食費: スーパー、コンビニ(食品)
2. 外食: レストラン、カフェ
3. 雑貨: ドラッグストア、100円ショップ
4. 交通費: 電車、バス、タクシー
5. 娯楽費: 書店、映画館
6. 日用品: トイレットペーパー、洗剤
7. その他: 上記以外
"""

精度:

  • 正解率: 約92%(100件テスト)
  • 誤判定例: 「コンビニでの切手購入」→「食費」(本来は「その他」)

エラーハンドリング

try:
    response = textract_client.detect_document_text(
        Document={'Bytes': image_bytes}
    )
except ClientError as e:
    if e.response['Error']['Code'] == 'UnsupportedDocumentException':
        return "画像形式が非対応です(JPEG/PNG推奨)"
    elif e.response['Error']['Code'] == 'InvalidParameterException':
        return " 画像が小さすぎます"
    else:
        return f" Textractエラー: {str(e)}"

Google Sheets の月別シート対応

# 日付から月を判定
date_obj = datetime.strptime(date, "%Y-%m-%d")
sheet_name = f"{date_obj.month}"  # 例: "11月"

# シートが存在しない場合は最初のシートを使用
try:
    sheet = spreadsheet.worksheet(sheet_name)
except:
    sheet = spreadsheet.sheet1
    print(f"{sheet_name}シートが見つかりません")

ハマったポイント

Textractの日本語対応

問題:
日本語レシートの認識精度が低い

対策:

  • 画像の解像度を上げる(最低 800x600px)
  • コントラストを調整
  • 斜めの写真は避ける

結果:

  • 認識率: 75% → 95%に向上

Base64データの切り詰め

問題:
AIに渡す際、プロンプトで{image_base64[:50]}...と省略していた

原因:

#  NG
prompt = f"画像データ: {image_base64[:50]}..."

#  OK
prompt = f"画像データ:\n{image_base64}"

Google Sheets API の書き込み遅延

問題:
書き込み直後に読み込むと古いデータが返ってくる

対策:

# 1秒待機
time.sleep(1)

Bedrock のリージョン

問題:
us-east-1では Claude 3.7 Sonnet が使えない

対策:

  • us-west-2を使用

コスト試算

月間100件のレシート処理(想定)

サービス 料金 月額
Textract $1.50 / 1000ページ $0.15
Bedrock(Claude 3.7) 入力: $3/MTok
出力: $15/MTok
約$5〜8
Google Sheets API 無料(60回/分まで) $0
Streamlit ローカル実行 $0
合計 - 約$5〜8/月

コーヒー1杯分で家計簿が自動化!


今後の展望

Phase 1: 機能拡張

  • スマホアプリ化(Flutter/React Native)
  • レシート画像の自動トリミング
  • 月次レポート自動生成
  • 予算アラート機能

Phase 2: 精度向上

  • ファインチューニング(店名辞書)
  • 手書きレシート対応
  • 複数レシート一括処理

Phase 3: クラウド化

  • AWS Lambda + API Gateway でサーバーレス化

  • S3 で画像保管

  • DynamoDB でメタデータ管理

  • Amplify でホスティング

  • AWS BedRock ⇨ AWS AgentCoreに移行予定( BedRockが更新されなくなったから)


学んだこと

技術面

  1. Amazon Bedrock の使いやすさ

    • ファインチューニング不要
    • プロンプトだけで高精度
  2. Textract の限界

    • 日本語の縦書きは苦手
    • 手書き文字は要前処理
  3. Streamlit の爆速開発

    • 1日でプロトタイプ完成
    • デバッグが楽

非技術面

  1. めんどくさがり屋こそ自動化すべき

    • 最初の投資(開発時間)を惜しまない
    • 長期的には時間を取り戻せる
  2. 完璧主義は捨てる

    • 92%の精度で十分
    • 100%を目指すとコストが爆増

まとめ

作ってよかったこと:

  • 家計簿が続くようになった(3ヶ月継続中)
  • AWS の知識が深まった
  • AI の実用的な活用方法が分かった

みなさんへのメッセージ:

「めんどくさい」は最高の開発動機です。
自分の困りごとを解決するアプリを作ると、
モチベーションが続きます。

ぜひ、あなたも「めんどくさい」を自動化してみてください!


参考リンク


実装で詰まった点や改善案があれば、コメント欄で教えてください!

いいねとストックお願いします!👍

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?