Node.js と Claude API で音声起動型 AI アシスタントを作る
面白いものを作りたくなりました。つまり、実際に文脈を理解し、会話の中であなたが先に話した内容を覚えていて、動かすのにかかる費用が月にコーヒー 1 杯未満の音声アシスタントです。
こちらは、SimplyLouie 経由で Claude API にアクセスし、Web Speech API + Node.js を使って作った手順です。
スタック
- フロントエンド:バニラ JS + Web Speech API(Chrome/Edge に組み込み — ライブラリ不要)
- バックエンド:Node.js Express
- AI:SimplyLouie の開発者 API 経由の Claude(毎月定額 $10)
- ストレージ:メモリ上の会話履歴(Redis にアップグレード可能)
手順 1:フロントエンド — 音声入力をキャプチャする
<!DOCTYPE html>
<html>
<head>
<title>Voice AI</title>
</head>
<body>
<button id="startBtn"> 押して話す</button>
<div id="transcript"></div>
<div id="response"></div>
<script>
const btn = document.getElementById('startBtn');
const transcriptEl = document.getElementById('transcript');
const responseEl = document.getElementById('response');
const recognition = new webkitSpeechRecognition();
recognition.continuous = false;
recognition.interimResults = false;
recognition.lang = 'en-US';
btn.addEventListener('mousedown', () => recognition.start());
btn.addEventListener('mouseup', () => recognition.stop());
recognition.onresult = async (event) => {
const transcript = event.results[0][0].transcript;
transcriptEl.textContent = `あなたはこう言いました: ${transcript}`;
const reply = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: transcript })
}).then(r => r.json());
responseEl.textContent = `AI: ${reply.response}`;
// 応答を読み上げる
const utterance = new SpeechSynthesisUtterance(reply.response);
window.speechSynthesis.speak(utterance);
};
</script>
</body>
</html>
手順 2:バックエンド — 会話のコンテキストを扱う
const express = require('express');
const app = express();
app.use(express.json());
// シンプルなインメモリの会話ストア(セッションをキーにする)
const conversations = new Map();
app.post('/api/chat', async (req, res) => {
const sessionId = req.headers['x-session-id'] || 'default';
const { message } = req.body;
// 会話履歴を取得するか新しく作成する
if (!conversations.has(sessionId)) {
conversations.set(sessionId, []);
}
const history = conversations.get(sessionId);
// ユーザーのメッセージを追加
history.push({ role: 'user', content: message });
// コンテキストの制限内に収めるため、直近の10往復分を保持
const recentHistory = history.slice(-20);
try {
const response = await fetch('https://simplylouie.com/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.LOUIE_API_KEY}`
},
body: JSON.stringify({
messages: recentHistory,
system: 'あなたは有能な音声アシスタントです。返答は簡潔にしてください。読み上げられるため、可能な限り2文以内に収めてください。'
})
});
const data = await response.json();
const aiReply = data.response || data.content;
// アシスタントの応答を保存する
history.push({ role: 'assistant', content: aiReply });
res.json({ response: aiReply });
} catch (err) {
res.status(500).json({ error: 'AI unavailable' });
}
});
app.listen(3000, () => console.log('Voice AI running on :3000'));
ステップ3:会話を覚えるためのセッショントラッキングを追加する
フロントエンドは一貫したセッションIDを送る必要があります:
// フロントエンドに追加 — ページ読み込みごとに1回生成
const sessionId = Math.random().toString(36).substr(2, 9);
// fetch呼び出しを更新:
const reply = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-session-id': sessionId // <-- これを追加
},
body: JSON.stringify({ message: transcript })
}).then(r => r.json());
これで、セッション中にあなたが以前話した内容を覚えています。
できること
一度動き始めると:
You: "What's the capital of France?"
AI: "Paris."
You: "What's the population there?"
AI: "Paris has about 2.1 million people in the city proper."
2つ目の質問がうまく機能していることに注目してください。「there」は会話履歴のおかげでパリを指していると理解します。
コスト計算
私はこれを、音声インタラクション約200回で1週間動かしました:
- Claude API(SimplyLouie経由):$10/月の定額(開発者ティア)
- ホスティング(Railway):$5/月
- Web Speech API:free(ブラウザ内蔵)
- 合計:$15/月
比較すると、OpenAIのWhisperで音声→テキスト化+GPT-4 APIでこの仕組みを作る場合、同じ量だと月$40〜60になります。
任意:ウェイクワード検出を追加する
常に聞きっぱなしにしたい場合(Alexaのように):
// 認識を継続的に再起動
recognition.onend = () => {
if (isListening) recognition.start();
};
recognition.onresult = async (event) => {
const transcript = event.results[0][0].transcript.toLowerCase();
// ウェイクワードが検出された場合のみ応答
if (!transcript.includes('hey louie')) return;
const actualMessage = transcript.replace('hey louie', '').trim();
// ... ハンドラの残り
};
let isListening = true;
recognition.start();
始める
これを動かす開発者API: simplylouie.com/developers
$10/月の定額。トークン課金による想定外の請求はありません。APIを叩けば、それが動きます。
このプロジェクトの完全なリポジトリはコメント欄にあります — そこで質問してもらっても大丈夫です。



