はじめに
こんにちは、遠藤太一 です。
自身のポートフォリオサイト(Next.js製)に、
**「医療分野のユースケースを想定した情報提供AIチャット」**を
技術検証目的で実装しました。
本記事では、その実装過程で遭遇した Vercel AI SDK 利用時のトラブル と、
最終的に ライブラリに依存しないシンプルな実装(Vanilla Fetch) に切り替えて
安定動作させた経験を共有します。
※本記事は個人による技術検証・個人開発の記録です
※医療行為・診断を目的としたものではありません
※特定の医療機関・実案件・契約業務とは一切関係ありません
開発環境
Framework: Next.js 16(App Router)
Language: TypeScript
Styling: Tailwind CSS
AI API: OpenAI API(GPT-4o)
Deployment: Vercel
実装した機能概要(技術検証)
本実装では、
**「医療相談UIを想定したAIチャット」**として、
以下のような情報整理を行う構成を試しました。
状況の整理(緊急性の目安)
受診先の一般的な案内
想定されるリスク要因の整理
一般的な注意点・セルフケア情報
あくまで 情報提供・整理を目的としたUI検証 であり、
診断や医療判断を行うものではありません。
利用範囲は メンバー限定エリア に制限し、
技術検証用途としてのみアクセスできる形にしています。
実装のポイント:システムプロンプト設計
単なる Chat UI ではなく、
AIの振る舞いを制御するためのシステムプロンプトを設計しました。
const systemPrompt = `
あなたは医療分野の一般的な情報整理を支援するAIアシスタントです。
ユーザーの入力内容をもとに、以下の形式で一般的な情報提供を行ってください。
1. 【状況整理の目安】
2. 【受診先の一般的な案内】
3. 【考えられるリスク要因】
4. 【一般的な注意点・アドバイス】
※必ず「これはAIによる情報提供であり、医師の診断ではありません」
という注意書きを含めてください。
`;
役割を「診断」ではなく「情報整理・案内」に限定している点が重要です。
直面した問題:ライブラリ依存の落とし穴
当初は、Next.js で AI チャットを簡単に構築できる
Vercel AI SDK(ai / @ai-sdk/react) を利用しました。
しかし、デプロイ後に以下の問題が発生しました。
① Module not found エラー
Module not found: Can't resolve 'ai/react'
SDK のバージョンアップ(v6系)により import パスが変更されており、
@ai-sdk/react を別途導入する必要がありました。
② クライアントサイドでの予期せぬクラッシュ
一見正常に動作しているように見えたものの、
デプロイ後に以下のエラーで画面が真っ暗に。
Uncaught TypeError: Cannot read properties of undefined (reading 'trim')
useChat フックが返す input が、
特定のタイミングで undefined になるケースがあり、
.trim() 呼び出しでクラッシュしていました。
ライブラリ内部の挙動がブラックボックス化しており、
原因特定が難しい状態でした。
解決策:ライブラリを使わず自前実装する
最終的に、
「必要なことは fetch と state 管理だけ」
と割り切り、
ライブラリをすべて外して 自前実装 に切り替えました。
シンプルなチャット実装(骨子)
const [messages, setMessages] = useState<Message[]>([]);
const [input, setInput] = useState("");
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!input.trim()) return;
const userMessage = { role: 'user', content: input };
setMessages(prev => [...prev, userMessage]);
setInput("");
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages: [...messages, userMessage] }),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
setMessages(prev => [...prev, { role: 'assistant', content: '' }]);
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
setMessages(prev => {
const newMessages = [...prev];
newMessages[newMessages.length - 1].content += chunk;
return newMessages;
});
}
};
結果
自前実装に切り替えたことで、
✅ 不定期に発生していたクラッシュが解消
✅ ライブラリ依存による破壊的変更リスクがゼロ
✅ UI・挙動を完全にコントロール可能
というメリットが得られました。
まとめ
便利なライブラリは開発を加速してくれますが、
AI系ライブラリは進化が速く、挙動が不安定になることも多いと感じました。
シンプルな要件であれば、
「一度、素の React / Fetch に立ち返る」
ことが、
結果的に最も堅牢で理解しやすい実装になる場合もあります。
ポートフォリオとしても
**「実際に動く AI アプリ」**は強いアピール材料になりますね。
セキュリティに関する注意
本番環境で AI API を利用する場合は、
必ずサーバーサイド(API Routes / Edge Functions)で API Key を管理し、
クライアントに直接露出させないようにしましょう。