DALL-E 3を活用した日記アプリの作り方
経緯
先日個人開発で作ったAI語学日記アプリ「Vanilla for Web」をリリースしました。
機能概要
最近、Vanilla for Webのフレーズ登録機能にAI画像生成機能を追加したんです。学習したいフレーズに対して、そのイメージを視覚的に補強できるようになりました。例えば、"The early bird catches the worm"というフレーズを登録する時に、早起きの鳥が虫を捕まえている様子の画像を生成できます。
アーキテクチャ
シンプルな構成を心がけました:
フロントエンド: React + TypeScript
バックエンド: Express
画像生成: OpenAI DALL-E 3
データストア: Cloud Firestore
画像生成のリクエストは、クライアントからバックエンドのAPIエンドポointを経由してDALL-E 3に送られ、生成された画像URLをFirestoreに保存する流れです。
利用したAPI
主に2つのAPIを使っています:
DALL-E 3 API - OpenAIの最新の画像生成モデル
Firestore API - 画像URLと生成履歴の保存用
DALL-E 3を選んだ理由は、プロンプトに対する理解力が高く、教育目的の画像生成に適していたからです。
実装の流れ
以下の流れで実装を進めました。
- フロントエンドでの画像生成UIの実装
- 入力フォームとプレビュー表示
- ローディング状態の制御
- エラーハンドリング
- バックエンドでの画像生成処理
- OpenAIクライアントの設定
- プロンプトの最適化
- レート制限の実装
- 画像生成履歴の管理
- Firestoreでの履歴保存
- 無料ユーザーの利用制限実装
工夫したポイント
プロンプトの最適化
教育目的の画像生成を確実にするため、プロンプトに教育的なコンテキストを追加しています。
const safePrompt = `A safe, educational illustration of: ${text}`;
無料ユーザーへの配慮
無料ユーザーには1日2回までの制限を設けつつ、プレミアムユーザーには無制限で提供しています。
if (!hasSubscription) {
// 1日2回までの制限を実装
const querySnapshot = await getDocs(
query(
collection(db, `UserInfo/${user.uid}/ImageGenerations`),
where('createdAt', '>=', today.toISOString()),
where('createdAt', '<', tomorrow.toISOString())
)
);
}
エラーハンドリング
不適切なプロンプトや生成エラーに対して、ユーザーフレンドリーなエラーメッセージを表示するようにしました。
例:クライアントサイドでのバリデーション
// 入力値の検証
if (!imagePrompt.trim()) {
toast({
title: "入力エラー",
description: "画像生成のプロンプトを入力してください",
variant: "destructive",
});
return;
}
// ユーザー認証の確認
if (!user) {
toast({
title: "認証エラー",
description: "ログインが必要です",
variant: "destructive",
});
return;
}
例:OpenAIのエラーハンドリング
let errorMessage = "画像生成に失敗しました";
if (error instanceof Error) {
if (error.message.includes('content_policy_violation')) {
errorMessage = "不適切なコンテンツが含まれている可能性があります";
} else if (error.message.includes('rate_limit_exceeded')) {
errorMessage = "APIの利用制限に達しました";
}
}
toast({
title: "画像生成エラー",
description: errorMessage,
variant: "destructive",
});
まとめ
AI画像生成をフレーズ学習に組み込むことで、ユーザーの学習体験を視覚的にサポートできるようになりました。特に、DALL-E 3の高品質な画像生成能力と、きめ細かいエラーハンドリング、そして無料/プレミアムユーザーの区別化された機能提供により、より付加価値の高いサービスを実現できました。
今後は、生成された画像の共有機能や、AIによる自動プロンプト生成など、さらなる機能拡張を検討していきたいと思います。
Discussion