セキュアリンク // 0x00F4B00 暗号化: AES-256-GCM オーバーライド: 偽
システムメモリ // 0.0MB VRAM // 0.0MB
ノード // オンライン レイテンシ // 14ms
> 起動シーケンス // カーネルロード... OK
チャットボット (ポートフォリオ: サイバーパンク)
コンテキスト対応ターミナルチャットボット & MCP 統合
LIVE DEMO • [GITHUB: Private Source]
概要
役割 : フルスタックエンジニアリング(アーキテクチャ、バックエンドAPI、状態管理、UI/UX、オーディオ統合を含むシステム全体をゼロから作成)
スタック : React, Next.js, TypeScript, Tailwind CSS, Framer Motion, next-intl, MCP
主要な成果 : サイバーパンクポートフォリオの主要なインタラクティブノードとして機能する没入型のコンテキスト対応 V2 チャットボット
要約 : ポートフォリオ: サイバーパンクのための深く統合された V2 チャットボットシステム。オリジナルの V1 チャットボット (ポートフォリオ: Glass) の大幅な進化として構築されました。リアルタイムダビング、ToolBadge インジケーターを介した動的な MCP ツールの実行、システムコマンド、およびアクティブなコンテキスト制限管理を特徴とする、「Oz」という名前の AI 構築ターミナルをシミュレートします。フランツを代表する完全な自律型エージェントとして機能します。
問題
課題 : サイバーパンクポートフォリオには、単なる後付けのウィジェットではなく、組み込みのターミナルや AI アシスタントのように感じられるチャットボットが必要でした。標準的な会話インターフェースであった V1 の Glass チャットボットとは異なり、この V2 の反復では、複数のシステムレベルコマンドの処理、LLM ツール呼び出しの視覚的レンダリング (ナビゲーションや音楽の再生など)、音声の重複のない同期された AI ダビングの再生、およびコンテキストウィンドウの効率的な処理が必要でした。
対象読者 : ポートフォリオを探索するテクニカルリクルーター、開発者、および訪問者。
制約 : 音声の再生、UI レイアウトの変更、ユーザーの入力、非同期ツール呼び出しのレンダリング、および API 制約 (トークン制限の処理) を伴う複雑な状態管理には、60fps のアニメーションを損なうことなく、慎重なアーキテクチャ計画が必要でした。
アプローチと決定事項
アーキテクチャ : コンポーネントをモジュール機能 (ChatHeader, ChatInput, ChatMessage, ChatHistory, DubPopup, ToolBadge) に分離しました。スパムを回避しつつ音声を安全に調整するために useChatbotAudio を利用しました。
重要な決定事項 :
ツール実行 (ToolBadge) : AI のアクションを視覚的かつ透過的にするために、ToolBadge コンポーネントを構築しました。AI が MCP ツール(例:音楽の切り替え、履歴書のダウンロード、テーマの変更、サイトの翻訳)を実行すると、アクションの詳細を示す洗練されたアニメーションターミナルバッジがチャットフローにドロップされます。これにより、通常のテキストとシステム操作が根本的に分離されます。
アイデンティティと自律的行動 : AI は「Oz」のペルソナの下で動作し、プロフェッショナルな AI アシスタントとして機能します。価格の問い合わせ (隠された内部価格表の表示)やお問い合わせフォームのルーティング (Oz がユーザーのためにメールを起草しますが、厳密なレビューと承認の UI ループを強制します)などの複雑なワークフローを動的に処理します。
LLM エンジンとフォールバックアーキテクチャ : 復元力のあるバックエンドフォールバックチェーンを構築しました。長いコンテキストの保持をサポートするために、ハイブリッドアテンションアーキテクチャを使用してネイティブに最大 100 万のコンテキストトークンを処理します。レート制限や一時的な停止が発生した場合、クエリはプライマリの高速モデルから堅牢なセカンダリネットワークにグレースフルにカスケードされます。
RAG とコンテキスト管理 : RAG (query_portfolio_data) を利用して、ユーザーが深い技術的な質問をしたときに MDX ケーススタディ全体を取得します。アダプティブスライディングウィンドウは、コンテキスト制限の 90〜98% に達すると最も古いメッセージをドロップします。
モデレーションのロックダウン : 自動化された lockdown システムを実装しました。このシステムでは、Oz は暴言やスパムのためにユーザーを一時的にバン (短、中、長時間のタイムアウト) することができ、サーバー側の Cookie と完全に同期しています。
トレードオフ : 複雑な状態に Redux を使用する代わりに、ローカライズされた状態管理のために React Context と useSyncExternalStore に依存しました。これによりバンドルサイズは最適化されましたが、不要な再レンダリングを防ぐために正確なフックの設計が必要になりました。
主要な結果と影響
成果 : サイバーパンクの物語を強化しながら、真のユーティリティ (質問への回答、音楽の制御、スキルの披露など) を提供する、印象的で高機能なアシスタント。
影響 : 高度な Next.js パターン、MCP を介したシステム統合、カスタムフック、および正確なオーディオビジュアルの調整を示しています。
技術的なディープダイブ
注目すべき詳細 :
ライブ診断 (ラウンドトリップ時間、アクティブなモデル、トークン) を UI で直接追跡します。
ツールの呼び出し : ToolBadge.tsx コンポーネントは、AI が単なるテキストではなく action オブジェクトを返すたびにトリガーされます。ツールのパラメーター (例:{ type: "toggle_theme", theme: "dark" }) を解析し、チャットフィード内で実行されたタスクを要約する未来的な光るバッジをレンダリングします。
ハッカーのようなタイプライター効果でマークダウンを安全にレンダリングするためのカスタム TypewriterMarkdown。
DubPopup ビジュアライザーは、API アクションに基づいて「AI が話している」状態を非同期的に反映します。
検証 : 乱用やレート制限を適切に処理するための堅牢な制限 (ロックダウン状態、スパム保護) を構築し、サーバー構成を直接 UI に反映させました。
コード品質 : ToolDetail、ChatSession のための TypeScript インターフェースの広範な使用、および Ref や視覚的なレイアウト操作に対する厳格な null チェック。
振り返り
改善点 : モバイルデバイスで長いオーディオファイルをデコードする際のメインスレッドのスタッターを完全に排除するために、オーディオプレーヤーエンジンを汎用ワーカーに切り離すこともできたかもしれません。
成功 : アシスタントがチャットとサイトナビゲーションの境界を越えてウェブサイト内で真に「行動」できるように、useMusicPlayer コンテキストを AI コマンドとシームレスに接続しました。
教訓 :「クール」なサイバーパンク効果(タイプライター、グリッチしたツール)とアクセシビリティのバランスを取るには、継続的なテストが必要です。固定配置とスクロールロックを備えたモバイルフレンドリーなフローティングチャットウィンドウの設計は、ブラウザーの特異性に大きく依存します。
私の貢献
システムアーキテクチャ : チャット状態エンジン、ライブ診断のためのポーリングロジック、およびセッションストレージ履歴の設計。
オーディオエンジニアリング : シーケンスベースのダビングおよびサウンドエフェクトフック (useChatbotAudio) のプログラミング。
UI/UX : ターミナルのような本物の外観にするための、Tailwind と Framer Motion を使用したコンポーネント (ChatSettings、ChatInput) のスタイリング。
統合 : アプリ全体に影響を与える実行可能なツール (ToolBadge) への AI 出力のマッピング(言語の変更、履歴書のダウンロード、テーマの切り替えなど)。
プロジェクトのアーキテクチャ
components/chatbot/ ディレクトリは、アシスタントのロジックを調整します。
コアエンジン : Chatbot.tsx はメインコントローラーとして機能します。
UI コンポーネント : ChatMessage.tsx, ChatInput.tsx, ChatHistory.tsx。
特殊機能 : 視覚的な効果のための TypewriterMarkdown.tsx、音声プレゼンスのための DubPopup.tsx、およびツール実行の要約のための ToolBadge.tsx。
統合 : グローバルプロバイダー (useMusicPlayer、useTheme、useLocale) と統合します。
ライブプレビュー
ライブデモリンク : ライブポートフォリオサイト franzdomingo.dev でチャットボットを直接体験してください。
試してみる機能 : /help と入力してコマンドを表示するか、「Play music」(音楽を再生して) と頼んでグローバル音楽プレーヤーがトリガーされるのを確認します。