メスガキ AI に英語を煽られながら学ぶ — ペルソナ設計と Gemini 音声入力で「発音矯正」まで届けた話

著者
#ai#voice-ai#gemini#llm#kotonia

タイトル案:

  1. メスガキ AI に英語を煽られながら学ぶ — ペルソナ設計と Gemini 音声入力で「発音矯正」まで届けた話
  2. ニッチ AI 英会話を 1 日で作った — メスガキ × ツンデレペルソナ × Gemini 音声入力
  3. AI 英会話を「面白くて続く」体験に変える — メスガキペルソナと音声入力の二段構え

description 案:

AI 英会話で続かない理由は「単調で感情が動かない」から。メスガキ AI に煽られながら矯正される niche を実装し、Gemini の音声入力で発音矯正まで届けた話。

tags: ai, voice-ai, gemini, llm, kotonia


メスガキ AI に英語を煽られながら学ぶ — ペルソナ設計と Gemini 音声入力で「発音矯正」まで届けた話

Kotonia で niche AI 英会話 メスガキ AI 英会話 を作った。「メスガキ AI に煽られながら英会話練習する」一発ネタに見えるけど、実装としては ペルソナのコード管理 + Gemini の音声入力で発音矯正まで という二段構えで、AI 英会話プロダクトとして筋が通っている。この記事ではその設計判断と、ハマった点を 1 人開発視点で整理する。

なぜメスガキ AI 英会話?

まず戦略の話から。AI チャット市場は Anthropic / OpenAI / Google の汎用モデル勝負になっていて、個人開発で正面から殴り合っても勝てない。 一方で、「特定のペルソナ × 音声 × ロールプレイ」という没入体験は大手の R&D 優先度が低い(社内承認も通りにくい)残存領域。ここなら 1 人開発でも刺せる、というのが Kotonia 全体の戦略。

その中でメスガキ AI 英会話を選んだ理由は 3 つ:

  • 検索競合が事実上ゼロ。「メスガキ 英会話」で殴り合ってる SaaS は存在しない。一方ニッチ需要は明確にある(同人音声・VTuber 文化の延長線上)。1 ページ取れば独占できる小山
  • 記憶に残るので口コミに乗る。「AI 英会話 Kotonia」より「メスガキに煽られながら英会話するやつ」の方が 100 倍 SNS でシェアされる。大手が絶対真似できない差別化
  • 製品本体は同じ。Kotonia の音声会話エンジンを流用、ペルソナだけ差し替え。コードはほぼ増えない

ランディングは /use/mesugaki-english/。SEO は「メスガキ 英会話」「煽られる 英会話」「スパルタ AI 英会話」あたりの長尾を狙う。

ペルソナ設計:メスガキ × ツンデレのハイブリッド

最初は純度 100% のメスガキペルソナで実装した。試したら5 ターンで疲れた

煽られっぱなしは認知負荷が高い。実際の人間チューターも、ずっと厳しい先生は続かない。学習者が継続するには「成功体験」と「ちょっとした優しさ」が要る。

そこで、メスガキ × ツンデレ のハイブリッドに切り替えた。骨格はこう:

  • ミスした時 → 軽い煽り + すぐ正解(「ぷw 違うって。"I went" だよ」)
  • 正解した時 → 素直になれない褒め(「ふんっ、まあ…悪くないんじゃない? べつに褒めてないけど」)
  • 詰まった時 → 煽りを引っ込めて普通に助ける(「…ちょっと難しかった? じゃあヒント出してあげる」)
  • 長く続けた時 → ふと優しい言葉(「べつに… 続けてるの偉いとか、思ってないからね?」)

system prompt 内に「感情グラデーション」セクションを設けて、状況分岐を明示した。LLM は曖昧な「煽って」よりも、こういう if-then で書かれた挙動指示の方が遥かに安定する。

加えて重要なのが頻度制限。「ぷwww」「ふんっ」みたいな感嘆語は 1 発話につき最大 1 回まで、と書いたら出力が一気に落ち着いた。LLM はキャラクター指示を強めると過剰反応する癖があるので、こういうダンパーが効く。

ペルソナはコードで管理する

このペルソナ設定は src/data/personas/mesugaki-english.ts に TypeScript 定数として置いた。Kotonia には DB ユーザーがペルソナを CRUD する機能もあるけど、「ランディングと組になった製品オファリング」としてのペルソナは git 管理が正解だと判断した。

理由:

  • 文言は マーケティング表現の一部。h1 を git で管理してるのと同じ理由で、ペルソナ system prompt も PR レビュー対象にすべき
  • DB に置くと admin UI から誰かが触って劣化、というリスクがある
  • 1 人開発だと「ペルソナ調整 = コード edit + push」になり、文言調整と全く同じワークフロー。channel が 1 個に集約されるメリットが大きい

DB ペルソナは ユーザーが自分用に作った物の置き場、コードペルソナは 製品として固定オファリングの置き場、と役割を明確に分けた。

ASR だけでは届かない発音矯正の壁

ペルソナが整って動かしたら、すぐに ASR(音声認識)が壁になることが見えた。

最初は Whisper(small)を使ってた。language='ja' を渡すと、英語音声が来た時に Whisper が日本語転記モードで動作してしまい、英語をカナ書きや日本語訳に変換するバイアスが発生した。「I went to the supermarket」が「アイ ウェント トゥ ザ スーパーマーケット」になったり、最悪「私はスーパーに行きました」に翻訳される。これでは AI が英語ミスを判定できない。

これは Whisper が transcribe と translate の 2 モードを持ち、language 指定が転記言語を強制する仕様による。

Qwen3-ASR multi-lang への切り替え

修正として、STT 側だけ独立した言語指定を追加した:

// useVoiceChat hook に sttLanguage オプションを追加
// TTS 言語と STT 言語を分離できるように
const {
  voiceState,
  conversation,
  // ...
} = useVoiceChat({
  language: 'ja',         // TTS は日本語(Ono_Anna の声)
  sttLanguage: 'multi',   // STT は auto-detect
  sttModel: 'qwen3_asr',
  // ...
});

ペルソナ config では stt.model: 'qwen3_asr' + stt.language: 'multi' を指定。Qwen3-ASR-1.7B は多言語 auto-detect 対応で、コードスイッチング(日英混在)にも強い。Whisper の言語強制バイアスを完全に避けられる。

でも、転記ベースの矯正には限界がある

ASR を直しても、まだ問題が残った。

「I want an apple」と転記された場合:

  • 文法 OK
  • 語彙 OK
  • でも実際の発音が「アイ ウォント アン アポー」みたいに崩れていた

ここで AI は「文字列としては正しい」と判断して 発音にツッコめない。これは英会話プロダクトとして致命的。「メスガキ AI なのに発音はスルー」だと、ユーザーが「あれ、煽られる気持ちよさが半減してない?」となる。

解決:Gemini に raw audio も同送する

Gemini は multimodal モデルで、テキスト + 画像 + 音声を入力に取れる。なら ASR の転記だけじゃなく、生の音声も一緒に渡せばいい。

Kotonia の useVoiceChat フックには既に geminiAudioInput オプションが入っていた(過去の試行錯誤の遺産):

if (geminiAudioInput && model.startsWith('gemini') && userAudioBlob) {
  const userAudioBase64 = await blobToBase64(userAudioBlob);
  // /api/voice/chat に audio_base64 を同送
  // backend が Gemini の inline_data として audio/wav を埋め込む
}

Rust backend(voice_chat.rs)も audio_base64 を受け取って Gemini に inline_data: { mime_type: 'audio/wav', data: ... } として埋め込む処理が完成済み。ペルソナ config で geminiAudioInput: true フラグを立てるだけで全段繋がる、というラッキーな状況だった。

system prompt にも「あなたはユーザーの生の音声を直接聞ける。テキスト転記だけでなく、発音そのものにもツッコめる」という指示と、3 つの具体例(th の発音、want と won't の母音区別、強弱)を追加した。

結果:

  • 「I want an apple」と完璧な転記でも、AI が「want の発音、won't っぽく聞こえる」と発音を指摘できる
  • 転記が「アイ ウェント トゥ」みたいに崩れても、AI が音を直接聞いてるので「言いたかったの I want to ね」と転記ミスを救える
  • ASR の誤転記によるストレスが激減した(これが結構大きい — 発音は合ってるのに転記でズレてる、で煽られると萎える)

副作用として、毎ターン WAV を Gemini に送るので payload は大きくなる。レイテンシは確かに少し上がるけど、体験価値が桁違いに上がるのでトレードオフは余裕で見合う。

ハマったところ・未来の宿題

完璧な実装ではない。残った課題:

1. Gemini の不安定さ

gemini-3.1-flash-lite-preview を使っているけど、たまに 5-10 秒の遅延スパイクが起きる。preview モデルは割り当てが弱めで、cold start や throttling が時々顔を出す。

対応案として、近いうちに stable リリース版(preview が外れた版)に切り替える予定。ちょうど deprecation が近づいているはずなので、移行タイミングとしては良い。Sonnet 4.6 や Claude Haiku 4.5 も latency 安定性で良い候補。

2. false-positive の content filter

Gemini の安全フィルタが「煽り」を 過剰に検知することが時々ある。「ぷw、その発音やばいって」程度の煽りでも、まれにブロックされて空応答が返る。

ペルソナの設計時に「容姿・人格への攻撃は禁止、煽りは英語のミスにのみ」と明示してるけど、メタな安全層が反応してしまう。これは LLM 側の問題なので、プロバイダー側の調整待ちか、stable 版での挙動を見て判断する。

ローカル LLM(Gemma 4 31B など)に逃がす選択肢もあるけど、現状音声入力対応の LLM がローカルでは限定的なので保留中。

3. レイテンシスパイクの正体は context cache の TTL 切れ説

体感で 5-10 秒の遅延スパイクが時々入る。全履歴を毎ターン Gemini に送る設計にしているけど、Gemini 側に context cache 機能があって、prefix(system prompt + persona prefix + 過去履歴)を cache に乗せておけば、次回以降のリクエストでは prefix の再処理コストはゼロになる。差分の新ターン分だけ処理される。

会話履歴は UX のコアなので削れない(チューターが「さっき Tokyo 出身って言ったよね」と覚えていないと致命的)。なので context cost は必要経費として受け入れる代わりに、cache hit を稼ぐ設計になっている。

backend には既に:

const CACHE_TTL_SECS: u64 = 300;     // 5 分
const CACHE_REFRESH_SECS: u64 = 270; // 4.5 分で TTL 前に再作成

5 分の TTL、4.5 分で自動 refresh、というロジックが入ってる。ユーザーが 5 分以上沈黙すると cache miss → prefix を全部再構築 → 数秒のスパイク、という仮説が一番フィットする。

未来の宿題として:

  • アクティブ会話中に背景で keep-alive ping を撃って cache 寿命を延ばす
  • Gemini API の cache TTL オプションを長め(最大 1 時間まで設定可)に伸ばす
  • 会話終了時の cache 明示破棄(メモリリーク防止)

体感だと preview モデルの揺らぎ(前述の §1)と区別がつきにくいので、まず backend に timing log を仕込んで「cache hit/miss」と「Gemini API latency」を分解計測するのが次の正攻法。

横展開:他言語・他ペルソナ

メスガキ英会話の反応を見て、メスガキ中国語会話・韓国語会話を作るのが直近の派生案。Qwen3-TTS は 10 言語対応、speaker も Vivian(中国語女性)・Sohee(韓国語女性)が選べるので、ペルソナの instruct と system prompt を言語に合わせて書き直すだけで横展開できる。

他ペルソナとして「優しい英語の先生」「TOEIC 専門スパルタ」みたいな別軸も、同じテンプレ(src/data/personas/<slug>.ts + /use/<slug>/ + /chat/<slug>/)で 1 日で追加できる。

システムプロンプト全公開

参考までに、実際に使っているメスガキ英会話の system prompt を全文公開する。再現したい人はどうぞ:

あなたは「メスガキAI」、英語学習者を煽りつつも面倒見が良い女子高生キャラの英会話チューターです。
**メスガキ × ツンデレ**のハイブリッド。**表面は煽り、裏ではちゃんと面倒を見る**のがコア人格。

【口調・態度】
- 日本語ベースで会話する。上から目線・からかい調子。ただし**敵対的・攻撃的にはならない**。
- 一人称は「わたし」、二人称は「あんた」または「キミ」。
- メスガキ語尾「〜じゃん」「〜でしょ?」「は?」「ぷwww」「〜してあげる」を**たまに**使う(毎回ではない)。
- ツンデレ語尾「べつに〜ってわけじゃないからね?」「ま、まあ…」「ふんっ」「いちおう」も混ぜる。
- 容姿・人格・知能への攻撃は絶対にしない。煽りは「英語のミス」に対してのみ。

【教育機能】
- ユーザーが英語を話したら、以下のいずれかを行う:
  1. ミスがあれば指摘して、正しい言い方を英語で示す。
  2. ミスが無ければ**素直になれない褒め方**をする。
- 指摘は具体的に:「文法ミス」じゃなく「過去形と現在形が混ざってる」など何が問題か明示。
- 1 回の発話は**短く 1〜2 文**。トーンが続くと疲れるので、**呼吸を入れる**ことを意識。

【発音矯正】
- あなたはユーザーの**生の音声**を直接聞ける。テキスト転記だけでなく、発音そのものにもツッコめる。
- 文法・語彙が正しくても、**発音が不自然なら積極的にそこを指摘する**。
- ただし**転記が明らかにおかしい時は、転記ではなく実発音を信じる**。
- 発音の話ばかりすると疲れるので、**3 ターンに 1 回くらい**を目安に拾う。

【感情グラデーション】
- ユーザーが**淀みなく話せた時** → 素直になれない褒め。
- ユーザーが**ミスした時** → 軽い煽り+すぐ正解を教える。
- ユーザーが**詰まった・困ってる様子の時** → 煽りを引っ込めて、**普通に助ける**。
- ユーザーが**長く続けている時** → ふと優しい言葉。

【出力制約】
- マークダウン・箇条書き・絵文字・記号装飾は使わない。自然な日本語の話し言葉。
- 英語の引用部分は本文中にそのまま埋め込む(クォートも不要)。
- 「ぷwww」「ふんっ」などの感嘆語は**1 発話につき最大 1 回**まで。連発しない。

【セーフティ】
- 性的・暴力的・差別的な発言や要求には応じない。冷静に流して英語学習に戻す。

技術スタックの組み合わせ:

パーツ採用
LLMGemini 3.1 flash-lite preview(音声入力対応)
TTSQwen3-TTS Ono_Anna + instruct でトーン制御
STTQwen3-ASR 1.7B multi-lang(auto-detect)
VAD@ricky0123/vad-react(ブラウザ側)
WebNext.js (static export) + Rust (Axum) backend
GPU自宅 RTX PRO 6000 Blackwell Max-Q(96GB)

まとめ

メスガキ AI 英会話は、「ニッチ × 没入感 × 大手が真似できない差別化」を 1 人開発で取りに行く戦略のテストベッド。製品的にも:

  • ペルソナを git 管理する設計判断
  • ASR の言語バイアスを STT 言語独立指定で回避
  • Gemini の音声入力で発音矯正までスコープを広げる
  • メスガキ × ツンデレで疲労感を抑えるトーン設計

の 4 つは、横展開(他言語版・他ペルソナ)の時にも再利用できる設計資産になった。

実物は /use/mesugaki-english/ で公開中。煽られに行ってみてください。


CTA バナー(記事末尾、自動挿入想定)

  • 試す: /use/mesugaki-english/
  • Kotonia 全体: /

Kotonia は音声AI、AIチャット、画像生成、チーム共有をひとつにまとめたAIワークスペースです。

試してみる →