LLM以外は無料で回す。Vercel × Supabase × Inngest × Render × Claude 4.5でAI要約基盤
はじめに
技術記事を保存する。でも読まない。
あとで読む、時間があるときに読む、週末に読む。
そうやって raindrop.io にリンクが積み上がっていく。
エンジニアなら心当たりがあるはずです。
その状況をどうにかしたくて作ったのが raindary というAI要約基盤です。
- raindrop.io に保存した記事を取得
- 本文を抽出
- Claude 4.5 で事実整理+要約生成
- トーン付きで保存
ソースコードは公開しています。
この記事では「どう作ったか」ではなく、どう設計したかを中心に書きます。
テーマは明確です。
LLM以外は無料プランで回す
AIアプリはコストが高い、という印象があります。
しかし設計を工夫すれば、ランニングコストはClaudeのトークン消費だけにできます。
設計の出発点
raindaryはRSSリーダーではありません。
記事管理は raindrop.io に完全に任せています。
raindrop.ioは単なるブックマークサービスではなく、OAuth2とREST APIを提供する外部データ基盤です。
つまり、
- 記事URL
- タイトル
- タグ
- 保存日時
をAPIで取得できる。
ここで重要なのは「一次データを持たない」という方針です。
raindaryは記事データをコピーしません。
保存するのはAIが生成した要約のみ。
これにより:
- データ重複を防げる
- 記事削除と同期できる
- 設計がシンプルになる
外部サービスを信頼し、自分は付加価値層に集中する。
これが最初の設計思想です。
技術スタック全体像
現在の構成は以下です。
- フロントエンド / 軽量API: Next.js 15(Vercel Hobby)
- 非同期処理: Inngest Cloud(Hobby)
- 本文抽出: FastAPI + trafilatura(Render Free)
- データベース: Supabase PostgreSQL(Free)
- LLM: Claude Haiku 4.5 / Claude Sonnet 4.5
ポイントは、LLM以外はすべて無料プランで構成していることです。
Vercel × Next.js 15
フロントエンドとAPIはVercel上で動いています。
プランは Hobby(無料)。
Next.js 15のApp Routerを使い、
- Raindrop OAuth受付
- APIエンドポイント
- ダッシュボードUI
を実装しています。
重要なのは、
Vercelで重い処理をしないこと
- 本文抽出
- LLM呼び出し
はすべて非同期イベントに逃がしています。
Serverlessは「軽い入り口」として使い、
重い処理は外に出す。この割り切りが重要です。
非同期設計(Inngest)
重い処理はInngest Cloudで管理しています。
Inngestはイベント駆動型のワークフローサービスです。
raindaryでは以下のイベントを使っています。
- import.requested
- extract.requested
- summarize.requested
UIはイベントを投げるだけ。
実処理はすべてバックグラウンドで行われます。
Inngestを使うことで、
- リトライ
- 並列制御
- エラーハンドリング
を宣言的に管理できます。
ワーカーを自前で持たなくてよいのは、個人開発では非常に大きいです。
Render(Free)で本文抽出
本文抽出にはPythonの trafilatura を使っています。
HTMLから本文だけを抽出する精度が高く、
技術ブログのような記事でも安定します。
これをFastAPIとしてRenderに常駐させています。
プランは Render Free。
注意点があります。
RenderのFree Web Serviceは、
約15分間リクエストがないとスリープする
という仕様があります。
次のアクセスでコールドスタートが発生します。
しかしraindaryは非同期設計です。
- ユーザーは待たない
- 抽出はバックグラウンドで行う
ため、この制限は許容できます。
設計によって無料プランでも成立させています。
Claude 4.5の使い分け
LLMは2段階構成にしています。
1. 事実抽出:Claude Haiku 4.5
価格(標準API):
- 入力 $1 / 1M tokens
- 出力 $5 / 1M tokens
本文をそのまま文章生成に使うのではなく、
まず構造化JSONに変換します。
抽出する情報は:
- keyPoints
- mainClaim
- caveats
- techKeywords
軽量モデルで十分です。
2. 要約生成:Claude Sonnet 4.5
価格(標準API):
- 入力 $3 / 1M tokens
- 出力 $15 / 1M tokens
最終的な文章生成を担当します。
トーンは:
- snarky
- neutral
- enthusiastic
- casual
などを切り替え可能にしています。
なぜ2段階にするのか
Sonnetに全文を直接投げると、
- トークン消費が増える
- コストが増える
- 出力が不安定になる
そこで、
- Haikuで圧縮
- Sonnetで文章生成
という構造にしています。
これは単なるコスト削減ではなく、
出力品質の安定化にもつながっています。
コストは必ず可視化する
AIアプリで一番危険なのは、
コストが見えないこと
raindaryでは api_usage テーブルを持ち、
- input_tokens
- output_tokens
- cost_usd
- model
を保存しています。
月間コストを集計できる設計です。
AIアプリは「作る」よりも「回す」ことの方が難しい。
だからこそ、コストは最初から可視化します。
Supabase Freeでのマルチユーザー設計
データベースはSupabase Freeプラン。
全テーブルに user_id を持たせ、
Row Level Security(RLS)で隔離しています。
ポリシーはシンプルです。
auth.uid() = user_id
これにより、
- 他ユーザーのデータは見えない
- APIバグでも漏洩しない
という設計になります。
AIアプリでもセキュリティは妥協しません。
LLM以外は無料で回る構成
現在の構成は以下です。
- Vercel Hobby
- Supabase Free
- Inngest Hobby
- Render Free
- Claude APIのみ有料
つまり、ランニングコストはClaudeのトークン消費だけ。
この構成を成立させるために、
- 非同期前提
- 重処理分離
- コールドスタート許容
- コスト可視化
を徹底しています。
まとめ
raindaryは単なるAI要約ツールではありません。
- 責務分離設計
- 非同期アーキテクチャ
- コスト最適化
- 無料枠活用
- RLSによる安全設計
を意識した基盤プロジェクトです。
コードはこちらにあります。
AIアプリは派手なデモよりも、
地味な設計で差が出ると考えています。
今後はRSS日次サマライズや分析基盤への拡張も検討しています。
設計で勝ちたい人の参考になれば幸いです。
技術設計や個人開発についてはブログでも発信しています。
こちらも是非、よろしくお願いします!
Discussion