Fugu for All の作り方ガイド
「自分のAPIキーを入れるだけでAIと話せるWebアプリ」を、ゼロから作って世界に公開するまで。
完成形を見る → fugu-for-all.vercel.appこのアプリ「Fugu for All」とは
作り方に入る前に、まず完成品そのものを紹介します。「これ、自分も作ってみたい」と思えたら、そのまま下へ読み進めてください。どう作ったのかを最初から順に解説していきます。
Fugu for All は、Sakana社の新しいAI「Fugu(複数の優秀なAIをまとめて指揮する“まとめ役AI”)」と、日本語でチャットできるWebアプリです。ブラウザでURLを開き、自分の合言葉(APIキー)を入れるだけで、すぐに会話が始められます。
🎯 1. どんな人のためのもの?
- ITやAIに詳しくない人が対象です。専門知識はゼロでも、最先端のAIを実際に触って体験できます。
- たとえば「AIに詳しくない取引先や同僚に、Fuguを実際に試してもらいたい」といった場面を想定しています。難しい設定は不要で、URLを渡すだけ。
- 画面はすべて日本語。パソコンでもスマートフォンでも見やすく作っています。
💬 2. どんなことができる?
- Fugu と自由に日本語で会話できます。旅行プランづくり、長い文章の要約、献立の相談、考えごとの整理など、用途は何でも。
- 用途に合わせて「標準(速い)」と「最高品質(じっくり)」を選べます。
- 何を聞けばいいか迷っても大丈夫。ワンクリックのお手本を用意してあるので、押すだけで体験が始まります。
- 答えは箇条書きや表も見やすく整えて表示。読みやすさにこだわっています。
🧭 3. どんな点に注意して作った?
- 「最初の体験」を最優先。キーを入手して貼り付けるまでを、迷わない2ステップに整理しました。
- 費用を最初に正直に伝える。Fuguは有料で、キー取得にはカード登録が必要・無料枠は無い——この事実を隠さず、最初の画面ではっきり告知します。
- 待たせても不安にさせない。最高品質モデルは答えるまで数分かかることがあるため、経過秒数や「複数のAIに相談しています…」を表示し、「やめる」ボタンも用意しました。
- 専門用語を避け、エラーもすべてやさしい日本語で案内します。
🔒 4. どれだけ安全?
- APIキー(合言葉)は利用者のブラウザの中にだけ保存。アプリのサーバーには保存も記録もしません。サーバーは“通すだけ”の中継役です。
- BYOK(各自が自分の鍵を使う)方式なので、「他人に勝手に使われて自分に高額請求が来る」という事故が構造的に起きません。料金は使った本人の負担です。
- AIの答えは「生のHTMLを実行しない」安全な方法で表示し、悪意ある出力に乗っ取られないようにしています(XSS対策)。
- 通信まわりの安全設定(CSPなどのヘッダ)も付けています。
- サーバーに秘密情報を一切持たないので、公開URLをそのまま誰に配っても安全です。
これだけのことをしていても、心臓部のコードはわずか数十行です。難しい部分は Next.js と Vercel AI SDK という道具が肩代わりしてくれます。「考え方」さえ掴めば、それほど詳しくなくても十分に作れます。次の章から、実際にどう作ったのかを最初から順に解説していきます。
このガイドについて
ここからは、上で紹介した「Fugu for All」を実際にどう作ったのかを解説します。目標は、同じようなAIチャットアプリを、それほど詳しくない人でも作れるようになることです。コマンドやコードは1つずつ写して進められるよう、順を追って説明します。
APIとは「外部のサービスと機械的にやり取りするための窓口」のこと。APIキーは、その窓口を使うための“あなた専用の合言葉”です。これが無いとAIは応答してくれません。
| 対象 | HTMLを見たことはあるが専門家ではない方。コマンドを1行ずつ写して進められれば大丈夫です。 |
|---|---|
| 作るもの | AIと話せるWebアプリ(利用者が自分のAPIキーを入れて使う方式) |
| 使う道具 | Next.js(ウェブ作成の枠組み)、Vercel AI SDK(AIと話す部品)、Vercel(公開する場所) |
| 目安時間 | 慣れていなくても半日ほど。AI(Claudeなど)に手伝ってもらえばさらに短く。 |
BYOK(Bring Your Own Key=自分の鍵を持参)方式にしました。利用者それぞれが自分のAPIキーを使うので、アプリの作者に利用料がかからず、利用者情報を預かるデータベースも要りません。とてもシンプルで安全に作れます。
0. まず全体像をつかむ
コードを書く前に、「誰が誰と話すのか」を絵にしておくと、後がぐっと楽になります。登場人物は3人だけです。
キーはここに保存
キーを中継するだけ
答えを返す
利用者がメッセージを送ると、①ブラウザ → ②自分のサーバー → ③SakanaのAI、と伝わり、答えが同じ道を逆にたどって返ってきます。
なぜ「②自分のサーバー」を間にはさむの?
ブラウザから直接③のAIを呼べそうに見えますが、間に自分のサーバーを置くのには理由があります。
- つながらない問題を避ける:ブラウザから他社のサービスを直接呼ぶと、セキュリティ上の制限(CORS)でブロックされがちです。自分のサーバー経由なら回避できます。
- エラーを日本語にできる:AIからの英語エラーを、サーバーで「カギが正しくないようです」のようにやさしく言い換えられます。
- 鍵を守る:鍵はブラウザに保存し、サーバーは“通すだけ”で保存しません。記録も残しません。
「画面(フロント)」と「裏方(サーバー)」を分け、秘密の合言葉は裏方を通す。これはAIアプリに限らず、ほとんどのWebアプリで共通の作法です。
1. 準備するもの
- Node.js(ノードジェイエス)を入れる … ウェブ作成の土台になる実行環境です。nodejs.org から最新版を入れます。
- 文字を書くエディタ … VS Code が定番。無料です。
- Vercel(バーセル)のアカウント … 完成したアプリを無料で公開できる場所。vercel.com で登録。
- SakanaのAPIキー … console.sakana.ai で取得します(後述の注意点に要注意)。
Fugu のAPIキーを作るには、クレジットカードの登録と有料契約が必要で、無料お試し枠はありません(月額20ドル〜、または使った分だけの従量課金)。「無料で気軽に」とはいかない点を、利用者にも最初に正直に伝える設計にしました(後述)。
2. 土台を1コマンドで作る
ゼロからファイルを並べる必要はありません。Next.js(ネクストジェイエス)という枠組みが、1つのコマンドで土台一式を用意してくれます。
Next.jsは「画面」と「裏方」を1つのプロジェクトでまとめて作れる、人気の枠組みです。ターミナル(黒い画面)は、文字でパソコンに命令する場所。VS Codeのメニューから開けます。
作りたいフォルダの中で、次の1行を実行します。
npx create-next-app@latest . --yes --typescript --app --tailwind --eslint --src-dir --import-alias "@/*" --use-npm
これで、TypeScript(型のある安全なJavaScript)と Tailwind(デザインを楽にする道具)込みの土台ができます。続けて、AIと話すための部品を追加します。
npm install ai@6 @ai-sdk/react@3 @ai-sdk/openai-compatible@2 zod react-markdown remark-gfm
| 追加した部品 | 役割 |
|---|---|
ai / @ai-sdk/react | Vercel AI SDK。AIとの会話・流れるような表示を簡単にしてくれる主役。 |
@ai-sdk/openai-compatible | 「OpenAI互換」のAIにつなぐ部品。Fugu はこれで繋がります。 |
react-markdown | AIの答え(箇条書きや表)を見やすく整える。 |
できあがるフォルダの中身は、ざっくりこんな形です(このガイドで作るファイルに印を付けました)。
3. AIにつなぐ「裏方」を作る
アプリの心臓部です。裏方は2つだけ。(A) 鍵が正しいか確認する窓口と、(B) チャットを中継する窓口です。
まず共通の設定を1か所にまとめる
接続先や、エラーの日本語訳を1ファイルにまとめておくと、後で楽です。
// 接続先やモデル名を1か所に集約(変更に強くなる)
export const SAKANA_BASE_URL = "https://api.sakana.ai/v1";
export const MODELS = {
fugu: { id: "fugu", short: "標準" }, // 速い・低コスト
"fugu-ultra": { id: "fugu-ultra", short: "最高品質" }, // 高品質だが遅い
};
export const DEFAULT_MODEL = "fugu";
// AIからの「番号付きエラー」を、やさしい日本語に翻訳する
export function mapStatusToJp(status) {
if (status === 401 || status === 403)
return "カギ(APIキー)が正しくないようです。貼り直してみてください。";
if (status === 402)
return "残高が不足しているようです。Sakanaのコンソールでご確認ください。";
if (status === 429)
return "アクセスが集中しています。少し待ってからお試しください。";
if (status >= 500)
return "Sakana側で一時的な問題が起きているようです。";
return "接続に失敗しました。APIキーや通信環境をご確認ください。";
}
(A) 鍵が正しいか確認する窓口
利用者が鍵を貼り付けたら、いきなりチャットさせる前に「この鍵、本当に使える?」を確かめます。ポイントはお金がかからない方法で確認すること。AIに文章を生成させると課金されるので、「使えるモデルの一覧をのぞくだけ」(GET /v1/models)にしました。これなら無料です。
import { SAKANA_BASE_URL } from "@/lib/sakana";
import { mapStatusToJp } from "@/lib/errors";
export async function POST(req) {
const { apiKey } = await req.json();
if (!apiKey)
return Response.json({ ok: false, message: "APIキーを入力してください。" });
// モデル一覧をのぞくだけ=課金されない鍵チェック
const r = await fetch(`${SAKANA_BASE_URL}/models`, {
headers: { Authorization: `Bearer ${apiKey}` }, // ← 合言葉を添えて送る
});
if (r.ok) return Response.json({ ok: true, message: "接続に成功しました。" });
return Response.json({ ok: false, message: mapStatusToJp(r.status) });
}
これは「持参人(Bearer)=この合言葉を持っている人を本人として扱ってください」という、合言葉の渡し方の決まり文句です。多くのAIサービスで共通です。
(B) チャットを中継する窓口(心臓部)
ここが一番の山場ですが、AI SDKのおかげで驚くほど短く書けます。やることは「利用者の鍵で接続を用意し、AIの答えを少しずつ流れるように返す」だけです。
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { convertToModelMessages, streamText } from "ai";
import { SAKANA_BASE_URL } from "@/lib/sakana";
export const maxDuration = 300; // 最長5分まで待つ(遅いモデル対策。後述)
export async function POST(req) {
const { messages, apiKey, model } = await req.json();
// 利用者の鍵で「使い捨ての接続」を作る。保存も記録もしない。
const sakana = createOpenAICompatible({
name: "sakana",
baseURL: SAKANA_BASE_URL,
apiKey, // ← 自動で「Bearer 合言葉」を付けてくれる
});
// AIに渡し、答えを少しずつ流す
const result = streamText({
model: sakana(model),
messages: await convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse({
onError: (e) => "送信中にエラーが発生しました。APIキーや残高をご確認ください。",
});
}
たったこれだけで「流れるように表示されるAIチャット」の裏方が完成します。streamText が会話を送り、toUIMessageStreamResponse が答えを少しずつ画面に流す形に整えてくれます。
Fugu は「OpenAI互換」という共通の作法に従っています。だから、接続先(baseURL)を変えるだけで同じ部品が使えます。これは後の「応用」章で効いてきます。
4. 画面を作る
画面は大きく2つ。(1) 鍵を入れてもらう案内画面と、(2) チャット画面です。鍵があるかどうかで自動的に切り替えます。
鍵はブラウザに保存する
鍵はサーバーに送って保存…ではなく、利用者のブラウザの中(localStorage)だけに保存します。これがBYOKの安全さの核心です。
// 鍵をブラウザに保存・読み出し・削除するだけの小道具
localStorage.setItem("sakana_api_key", key); // 保存
localStorage.getItem("sakana_api_key"); // 読み出し
localStorage.removeItem("sakana_api_key"); // 削除
チャット画面の核心
AI SDK の useChat という部品が、メッセージの一覧・送信・「考え中…」の状態まで面倒を見てくれます。私たちがやるのは、毎回の送信に“利用者の鍵とモデル”をこっそり同梱することだけです。
const transport = new DefaultChatTransport({
api: "/api/chat", // さっき作った裏方へ送る
prepareSendMessagesRequest: ({ messages }) => ({
body: { messages, apiKey, model }, // ← 鍵とモデルを毎回同梱
}),
});
const { messages, sendMessage, status, stop } = useChat({ transport });
// 送信ボタンや「お手本」クリックでこれを呼ぶだけ
sendMessage({ text: "週末の旅行プランを立てて" });
あとは messages を画面に並べ、AIの答えは react-markdown で見やすく表示します。「考え中…」の状態(status)を使えば、待ち時間の表示や「やめる」ボタンも作れます。
対象が「ITに詳しくない人」だったので、①費用が要ることを最初に正直に告知、②鍵の入手手順を①②③で図解、③遅いモデルでは「複数のAIに相談中…」と経過秒数を表示して“固まったように見える”のを防ぎました。技術より、この“最初の体験”の配慮が満足度を大きく左右します。
5. 動かして確かめる
自分のパソコンで動かしてみます。
npm run dev
表示された http://localhost:3000 をブラウザで開けば、もう動いています。
わざと間違った鍵を入れてみてください。「カギが正しくないようです」と日本語で出れば、裏方とSakanaの接続・エラー翻訳が正しく動いている証拠です。実際この方法で、本物の鍵を使う前に“配線”の大部分を確認しました。
6. 世界に公開する
手元で動いたら、Vercel に上げて、誰でも開けるURLにします。Vercelは Next.js と相性が良く、無料枠で十分です。
npm i -g vercel # Vercelの道具を入れる(初回のみ)
vercel --prod --yes # 公開! URLが表示される
初回は「ログインしますか?」と聞かれるのでブラウザで承認します。あとは数十秒で、https://〇〇.vercel.app という公開URLが手に入ります(このアプリは fugu-for-all.vercel.app)。
鍵は各利用者のブラウザにしか無く、サーバー側に秘密情報を一切持ちません。だから公開URLをそのまま配っても安全です。
7. つまずきと学び
実際に作る中でぶつかった「ここ大事」を共有します。同じ穴を避けられます。
① 無料枠は無い、と最初に伝える
「すぐ体験」を謳いたくても、鍵の取得にカード登録が要ると、慣れない人はそこで離脱します。ごまかさず最初に正直に告知したほうが、結局は信頼されます。
② 遅いAIは「固まった」と誤解される
最高品質モデルは答えるまで1〜5分かかることがあります。何も出ないと普通の人は「壊れた」と思いリロードし、せっかくの(課金された)答えを失います。経過秒数・進捗バー・「やめる」ボタンを用意して安心感を作りました。
「長時間かかったら中断する」処理を、AI SDK の中断スイッチ(abortSignal)に時間切れを混ぜて実装したところ、SDKがそれを「正常な中断」と解釈して、エラー通知に届かず無言で止まる不具合になりました。
正解は、時間切れを「接続(fetch)の側」に置くこと。そうすると“本物のエラー”として扱われ、ちゃんと日本語メッセージが出ます。この問題は、複数のAIに互いのコードを批判的にレビューさせる工程で発見・修正できました。「自分の書いたものを、別の視点でわざと粗探しさせる」のは効果絶大です。
③ 鍵を守る・出力で乗っ取られない
鍵はブラウザのみ保存、サーバーは記録しない。さらにAIの答えは「生のHTMLを表示しない安全な方法」で描画し、悪意ある出力でブラウザを乗っ取られないようにしました(XSS対策)。
8. 応用:他のAIでも同じ作りで
このアプリの作りは Fugu 専用ではありません。「OpenAI互換」のAIなら、接続先(baseURL)とモデル名を差し替えるだけで、ほぼそのまま使えます。
| 変えるところ | 例 |
|---|---|
SAKANA_BASE_URL | 別のAIサービスの接続先URLに差し替え |
MODELS | そのサービスのモデル名に差し替え |
つまり一度この形を覚えれば、いろいろなAIで「自分専用チャットアプリ」を量産できます。
このアプリ自体、AIコーディング支援(Claude Code)と一緒に作りました。「Next.jsでOpenAI互換APIに繋ぐBYOKチャットを作って」と頼み、出てきたコードを1つずつ確認していけば、未経験でも十分到達できます。
まとめ:作る順番のチェックリスト
- 全体像を絵にする(ブラウザ → 自分のサーバー → AI)
- 土台を1コマンドで作る(
create-next-app+ 部品の追加) - 裏方を2つ作る(鍵チェック + チャット中継)
- 画面を2つ作る(鍵の案内 + チャット)
- 手元で動作確認(間違った鍵で日本語エラーを確認)
- Vercelで公開(
vercel --prod) - 使う人の身になって気配り(費用の告知・待ち時間表示)
難しそうに見えて、心臓部のコードは数十行です。AI SDK と Next.js が大半を肩代わりしてくれるので、「考え方」さえ掴めば、それほど詳しくなくても十分作れます。ぜひ自分のアイデアで作ってみてください。