プロジェクト概要
最近、Claude 3.7を活用してタロット占いAIシステムを開発しましたTarotQA。このプロジェクトでは、伝統的なタロット占いの知識と最新のAI技術を融合させることに焦点を当てました。システムの主な目的は、様々な性格を持つAIタロットリーダーが、ユーザーの質問に対して個性的かつ一貫性のある解読を提供することです。
開発したシステムの主な技術的特徴:
- 複数のAIパーソナリティを実装するプロンプトエンジニアリング
- ReactとFramer Motionによるインタラクティブなカード選択UI
- Server-Sent Events(SSE)によるリアルタイムストリーミングレスポンス
- 多言語サポートシステム(日本語、英語、中国語簡体字、中国語繁体字)
- WebSocketベースの音声合成システム
開発動機と背景
大規模言語モデル(LLM)の能力向上により、専門分野の知識を持つAIアシスタントの構築が可能になりました。特にClaude 3.7は高度なコンテキスト理解能力と精度の高いロールプレイ能力を持っており、タロット占いのような特定ドメインに適用する可能性を探りたいと考えました。
タロット占いは複雑な象徴体系と解釈を必要とするため、AIにとって良い挑戦になると思いました。また、プロンプトエンジニアリングのスキルを深めるための実践的なプロジェクトとしても最適でした。
技術実装の詳細
1. プロンプトエンジニアリングによる多様なAIパーソナリティの構築
Claude 3.7にタロットリーダーの役割を与えるために、複雑なプロンプト設計を行いました。各タロットリーダーには独自の「システムプロンプト」を作成し、個性と解読スタイルを定義しました。
例えば、あるリーダーのプロンプトの一部(簡略化):
あなたは[リーダー名]、直感的でスピリチュアルな占い師です。以下の特徴を持ちます:
1. 話し方:柔らかく温かみのある口調、「~ですね」「~かもしれませんね」などの共感表現を多用
2. 解読スタイル:自然や宇宙の比喩を用いた直感的な解読、ポジティブな側面を強調
3. 専門分野:恋愛相談と精神的成長に関する質問が得意
タロットカードの解読時には:
- 各カードの正位置と逆位置の意味を理解し説明する
- カード間の関係性を分析し、全体的なストーリーを構築する
- ユーザーの質問に対して具体的なアドバイスを提供する
...
これにより、AIは特定の性格と専門知識を持ったタロットリーダーとして一貫した応答を生成できるようになりました。
2. フロントエンド技術の実装
フロントエンドは、React、TypeScript、Framer Motionを使用して構築しました。特に注力したのは:
- カード選択インターフェース:直感的なカード選択体験を提供するため、Framer Motionを使用したアニメーションとインタラクションを実装しました。
// カード反転アニメーションの実装例(簡略化)
const performCardFlip = (cardId: number) => {
if (flippedCards.includes(cardId) || processingCards.has(cardId)) return;
// カード処理中状態の設定
setProcessingCards(prev => new Set(prev).add(cardId));
// カードの向きをランダムに決定(正位置/逆位置)
const isReversed = Math.random() < 0.5;
setCardOrientations(prev => {
const newMap = new Map(prev);
newMap.set(cardId, isReversed);
return newMap;
});
// アニメーション完了後の状態更新
setTimeout(() => {
setFlippedCards(prev => [...prev, cardId]);
setProcessingCards(prev => {
const newSet = new Set(prev);
newSet.delete(cardId);
return newSet;
});
}, ANIMATION_DURATION.flip * 1000);
};
- レスポンシブデザイン:様々なデバイスに対応するため、メディアクエリとカスタムフックを使用しました:
// デバイスタイプを検出するカスタムフック
function useDeviceDetect() {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const checkDevice = () => {
setIsMobile(window.innerWidth < 768);
};
checkDevice();
window.addEventListener('resize', checkDevice);
return () => window.removeEventListener('resize', checkDevice);
}, []);
return { isMobile };
}
3. バックエンド技術の実装
バックエンドはNode.js(Express)で実装し、以下の主要コンポーネントを開発しました:
- AIインテグレーション:Claude 3.7 APIとの通信を処理するサービスを作成しました。特に、ストリーミングレスポンスを実現するためにServer-Sent Events(SSE)を実装しました:
// Server-Sent Eventsの実装例(簡略化)
router.post('/reading', async (req, res) => {
// SSEヘッダーの設定
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
try {
// Claude APIへのリクエスト
const stream = await claudeAPI.chat.completions.create({
model: "claude-3-7-sonnet",
messages: [
{ role: "system", content: readerPrompt },
{ role: "user", content: userPrompt }
],
stream: true
});
// ストリーミングレスポンスの処理
for await (const chunk of stream) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
const content = chunk.choices[0].delta.content || "";
// クライアントにデータを送信
res.write(`data: ${JSON.stringify({ content })}\n\n`);
}
}
// ストリーム終了を通知
res.write(`data: ${JSON.stringify({ done: true })}\n\n`);
res.end();
} catch (error) {
console.error('AIリクエストエラー:', error);
res.write(`data: ${JSON.stringify({ error: "処理中にエラーが発生しました" })}\n\n`);
res.end();
}
});
- 多言語サポート:i18nextと言語検出ミドルウェアを使用して、ユーザーの言語設定に基づいた適切なプロンプトとレスポンスを提供するシステムを実装しました:
// 多言語プロンプトローダーの実装例(簡略化)
function getReaderPromptByLanguage(readerId, language = 'ja') {
// 言語コードの正規化
let normalizedLang = language;
if (language.startsWith('en-')) normalizedLang = 'en';
if (language.startsWith('ja-')) normalizedLang = 'ja';
if (language.startsWith('zh-CN')) normalizedLang = 'zh-CN';
if (language.startsWith('zh-TW')) normalizedLang = 'zh-TW';
// 言語に対応するプロンプト設定を取得
const langPrompts = readerPromptsMultiLang[normalizedLang] || readerPromptsMultiLang['ja'];
if (langPrompts) {
const reader = langPrompts.find(r => r.id === readerId);
if (reader) return reader.prompt;
}
// デフォルトプロンプトを返す
return defaultPrompt;
}
技術的な課題と解決策
1. コンテキスト制限の克服
Claude 3.7には入力トークン数の制限があり、長い会話履歴や複雑なプロンプトを扱う際に課題がありました。
解決策:会話サマリー生成システムを実装し、過去の対話から重要な情報を抽出して簡潔な形式で提供するようにしました。これにより、トークン使用量を抑えながら重要なコンテキストを維持できました。
2. AI応答の一貫性確保
タロット解読では一貫性が重要ですが、AIは時々異なるスタイルや矛盾する解釈を提供することがありました。
解決策:システムプロンプトを細かく調整し、「制約条件」セクションを追加して一貫性を強化しました。また、過去の解読をコンテキストとして提供することで、連続性を高めました。
3. パフォーマンス最適化
複雑なAIリクエストと音声合成は、特にトラフィックが増加した際にレスポンス時間に影響を与えました。
解決策:
- プロンプトテンプレートの最適化
- ストリーミングレスポンスの実装
- 重要な計算結果のキャッシュシステム
- CDNの活用によるメディアファイルの配信最適化
Claude 3.7の技術的特性と利点
Claude 3.7を選んだ主な技術的理由:
- 高度なロールプレイ能力:複数のタロットリーダーパーソナリティを一貫して表現できる能力
- コンテキスト理解:ユーザーの質問の微妙なニュアンスを理解し、関連性の高い解読を提供する能力
- 多言語サポート:自然な日本語、英語、中国語を生成する能力
- 安全機能:センシティブなトピックを適切に処理する組み込みの安全メカニズム
今後の技術的展望
このプロジェクトを通じて学んだことを基に、以下の技術的な方向性に興味を持っています:
- AIパーソナリティのさらなる改良:より複雑で微妙な性格特性を持つAIキャラクターの開発
- マルチモーダル機能の統合:画像認識を使用したフィジカルカードの読み取りと解釈
- パーソナライズされた学習:ユーザーとの対話履歴に基づいて解読スタイルを適応させる機能
- 分散処理アーキテクチャ:スケーラビリティを向上させるためのマイクロサービスアプローチ
結論
このプロジェクトは、大規模言語モデルの実用的な応用と、伝統的な知識体系をAIでどのように表現できるかについての貴重な洞察を提供しました。特に、プロンプトエンジニアリングの重要性と、ユーザー体験全体におけるAIの統合方法について多くを学びました。
プロンプトエンジニアリング、フロントエンド開発、バックエンドシステムの連携による「人格を持ったAIシステム」の構築は、今後のAIアプリケーション開発において重要な方向性になると考えています。
皆さんのプロジェクトでも参考になる点があれば幸いです。技術的な質問やフィードバックがあれば、ぜひコメントでお知らせください。