はじめに
初めての技術ブログなので温かい目で見ていただけると幸いです。
少し前に、LLMが小説家などの物書きの執筆を支援してくれるwebサービス「Reola」を開発しました。
Reolaについて
このツールの魅力について語りたいと思います。
1. 様々なLLMモデルが執筆を手伝ってくれる
GrokやClaude、DeepseekやChatGPT、Geminiなど色んなモデルを使用できます。
2. ジャンルやスタイルなどを設定できる

最初にタイトルと説明をはじめ、ジャンル、文体スタイル、対象読者を設定でき、その後LLMはこの設定に従って執筆支援してくれます。
3. メタデータ(物語の設定)のLLMによる管理

コンテンツ分析ボタンを押せば文章中の登場人物やプロット(伏線など)、世界観等の設定をLLMが分析し以降はそれに従って執筆してくれます。
4. その他機能
他にもLLMによる機能として、言い回し提案機能、チャット機能、チーム共同執筆機能、次の展開の提案機能などがあり、どれも作成時の設定やメタデータなどを常に参照しています。
また、基本的なMarkdown記法や巻き戻しや保存などの、通常の執筆ツールにある機能は実装されています。
この記事を読んで欲しい人
- LLM統合アプリケーションの開発に興味がある方:複数のAIプロバイダーを統合した実践的な実装例を知りたい
- サブスクリプション型SaaSの構築を検討している方:Stripe決済とクレジット制課金システムの実装を学びたい
- Next.js 14とSupabaseを使った開発者:Clerk認証とSupabaseの組み合わせ、RLS無効化の理由を理解したい
- RAG(Retrieval-Augmented Generation)の実装に関心がある方:pgvectorを使ったベクトル検索の実装例を見たい
サービスの特徴
他サービスとの差別化ポイント
-
マルチAIモデル対応
- Gemini 1.5 Flash(デフォルト、コスト効率重視)
- GPT-4o、Claude Sonnet 4、Grok-4(プレミアムプラン)
- ユーザーがサブスクリプションプランに応じてモデルを選択可能
-
柔軟なクレジット制課金
- 月額サブスクリプション(ミニ・スタンダード・プロ)
- 追加クレジットパック(スモール・メガ)
- 使用量に応じた透明性の高い料金体系
-
プロジェクト管理とシリーズ機能
- 従来の単一プロジェクト管理
- 新しいシリーズ・エピソード管理
- タイムライン可視化機能
-
RAG機能による文脈理解
- pgvector拡張を使用したドキュメント埋め込み
- 類似性検索によるコンテキスト取得
- ユーザーデータの分離(RLSポリシー)
技術スタック詳細
フロントエンド
- Next.js 14(App Router)
- React 18
- TypeScript
- Tailwind CSS + shadcn/ui
- Lucide React(アイコン)
バックエンド
- Next.js API Routes(サーバーレス関数)
- Clerk(認証・ユーザー管理)
- Supabase(PostgreSQL、リアルタイムDB)
- pgvector(ベクトル検索拡張)
AI統合
利用可能なモデル:
- Gemini 1.5 Flash(低コスト、高速)
- GPT-4o(高品質)
- Claude Sonnet 4(精度重視)
- Grok-4(革新的)
決済システム
- Stripe Checkout(サブスクリプション・単発購入)
- Stripe Customer Portal(サブスク管理)
- Webhook処理(決済完了時の自動クレジット付与)
アーキテクチャ解説
認証フロー(Clerk + Supabase)
Reolaでは、ClerkとSupabaseのハイブリッド認証を採用しています。
重要な設計判断:
- Clerkを認証に使用:優れたUX、マネージドサービス
- SupabaseをDB専用:PostgreSQL機能、ベクトル検索
-
RLSを無効化:ClerkのユーザーIDは
TEXT型(user_xxxxx形式)で、Supabaseのauth.uid()(UUID型)と互換性がないため
代わりに、APIルートレベルで認証チェックを実装しています。
クレジット制課金システム
データベーススキーマ
主要テーブル:
- users: ユーザー情報、クレジット残高
- credit_transactions: クレジット取引履歴
アトミックな更新処理
クレジットの更新は、競合状態を避けるためにPostgreSQL関数で実装:
CREATE OR REPLACE FUNCTION update_user_credits_with_transaction(
p_user_id TEXT,
p_delta INTEGER,
p_new_balance INTEGER,
p_reason TEXT,
...
) RETURNS VOID AS $$
BEGIN
-- トランザクション内で更新と履歴記録を同時実行
UPDATE users SET credits = p_new_balance WHERE id = p_user_id;
INSERT INTO credit_transactions (...) VALUES (...);
END;
$$ LANGUAGE plpgsql;
料金プラン
- ミニプラン: ¥500/月、600クレジット
- スタンダードプラン: ¥1,980/月、2,500クレジット
- プロプラン: ¥3,980/月、6,000クレジット
- スモールパック: ¥980、1,000クレジット
- メガパック: ¥2,480、2,500クレジット
RAG(Retrieval-Augmented Generation)実装
ベクトルストアのセットアップ
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL,
metadata JSONB,
embedding VECTOR(1536) -- OpenAI text-embedding-3-small
);
-- 類似性検索用インデックス
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);
類似ドキュメント検索関数により、ユーザーの過去のコンテンツから関連情報を取得し、AI生成時のコンテキストとして活用します。
エクスポート機能
複数フォーマットへの対応:
- Markdown:安定動作(推奨)
-
DOCX:
docxライブラリを使用した本格的なWord文書生成 - PDF:Puppeteerを使用、タイムアウト時はHTMLフォールバック
エラーハンドリングとフォールバック機能により、確実なファイル出力を実現しています。
プロジェクト管理の移行
従来のシステムと新しいシステムが共存:
従来:
-
projectsテーブル:単一プロジェクト -
file_contentカラムに全コンテンツ格納
新システム:
-
storiesテーブル:物語の親管理 -
episodesテーブル:各エピソード - シリーズ化と続編管理に対応
この2層構造により、長編作品の管理が容易になりました。
補足
関連技術スタック
- Next.js 14 App Router:https://nextjs.org/docs/app
- Clerk認証:https://clerk.com/docs
- Supabase:https://supabase.com/docs
- pgvector:https://github.com/pgvector/pgvector
- Stripe:https://stripe.com/docs
- shadcn/ui:https://ui.shadcn.com/
主要ディレクトリ構成
src/
├── app/ # Next.js App Router
│ ├── api/ # APIエンドポイント
│ │ ├── ai/ # AI機能
│ │ ├── projects/ # プロジェクト管理
│ │ ├── user/ # ユーザー情報
│ │ ├── stripe/ # 決済処理
│ │ └── clerk/ # 認証Webhook
│ ├── (main)/ # メインページ
│ └── auth/ # 認証ページ
├── components/ # Reactコンポーネント
│ └── ui/ # shadcn/ui
├── lib/ # ユーティリティ
│ ├── auth.ts # 認証ヘルパー
│ ├── supabase/ # Supabaseクライアント
│ ├── stripe.ts # Stripe設定
│ └── limits.ts # 無料プラン制限
├── contexts/ # Reactコンテキスト
└── middleware.ts # Clerk認証ミドルウェア
supabase/
└── migrations/ # データベーススキーマ
おわりに
Reolaは、最新のWebテクノロジーとAI技術を組み合わせた実践的なフルスタックアプリケーションです。自分自身これらの情報を調べながらだったので、苦戦しましたがかなり勉強になりました:
- Clerk認証とSupabaseの組み合わせ:マネージド認証とPostgreSQLの強力な機能を両立
- RLS無効化の判断:TEXT型ユーザーIDとUUID型の非互換性への対処
- クレジット制課金:PostgreSQL関数によるアトミックな更新処理
- マルチAIプロバイダー対応:柔軟な統合アーキテクチャ
- RAG機能:pgvectorを使った実用的なベクトル検索
