うちの犬は世界で一番かわいい。異論は認めない。

散歩中にiPhoneを片手に持って、GPTに音声で話しかけるのが最近の習慣になっている。「うちの犬って世界で一番かわいいよな。だからたまにエンジェルちゃんって呼ぶけど、お前はどう思う?」みたいな。キーボードを打つより速いし、歩きながらでも思ったことをそのまま流せる。

ただ、困ったことがあった。

ChatGPT以外のAIだと、音声認識の精度がガクッと落ちる。

ClaudeやGeminiのアプリに切り替えると、同じように話しかけても文字起こしが微妙にズレる。同じ犬の話なのに、なんか違う感じになって帰ってくる。


なぜChatGPTだけ精度が高いのか

最初は「ChatGPTはOpenAIが開発した Whisper という音声認識モデルを使っているから」だと思っていた。

Whisperは単純に音を文字に変換するだけでなく、文脈を読んで書き起こしてくれるのが強みだ。だから「エンジェルちゃん」みたいな固有名詞っぽい表現も、わりとちゃんと拾ってくれる。

ただ調べてみると、話はもう少し複雑だった。ChatGPTには Advanced Voice Mode というモードがあり、これはWhisperすら使わずGPT-4oが音声をネイティブに直接処理している。テキスト変換を経由しないぶん情報損失がなく、精度も速度もさらに高い。

ただし、私はAdvanced Voice Modeを使っていない。 音声で会話したいわけじゃなくて、テキストで返ってきてほしいからだ。ということは私の使い方は「Whisperで音声入力 → テキストで受け取る」に限定される。そうなると、WhisperKeyboardで完全に代替できる。GPT-4oのネイティブ音声処理がどれだけすごくても、私の用途には関係ない話だった。

このWhisperを、ClaudeでもGeminiでも使えるようにしたかった。どのアプリを開いていても、Whisper精度でポエムを届けたかった。


WhisperKeyboard とは

WhisperKeyboard は、iOSのカスタムキーボードとして動くアプリだ。

キーボードにこんな感じで表示される

iOSには「Keyboard Extension」という仕組みがあって、サードパーティ製のキーボードをシステムに追加できる。WhisperKeyboardはそれとして実装している。だからどのアプリでも使える。Claudeのアプリを開いていても、Geminiを開いていても、キーボードをWhisperKeyboardに切り替えるだけでWhisper精度の音声入力ができる。

音声データはすべてデバイス内で処理する。クラウドには何も送らない。誰かに聞かれたくない犬への愛の言葉も、安心して話しかけられる。

使い方はシンプルです。

  1. アプリをインストールして設定からキーボードを追加(フルアクセスを許可)
  2. 任意のアプリでWhisperKeyboardに切り替える
  3. 初回はモデルが自動ダウンロードされる(数分、約75MB)
  4. マイクボタンを長押しして話す → 離すとテキストに変換されてカーソル位置に挿入

使い方


作ってみてぶつかった壁

Xcodeをまともに触るのはこれが初めてだった。iOSアプリ作るのも初めてで「これどういう意味?」「なんでビルドできないの?」「あ〜あ、VSCodeの方が使いやすなっ!」とGPTにひたすら愚痴を言いながら進めた。AIへのポエムを届けるためのアプリを、AIに愚痴りながら作るという構図が完成。

技術的な壁で一番困ったのは3つ。

壁① Keyboard Extensionはマイクにアクセスできない

iOSのセキュリティ制約で、キーボード拡張からは直接マイクが使えない。なので「録音ボタンを押したらメインアプリをDeep Linkで起動して、メインアプリ側で録音する」という構成にした。キーボードが起動係、メインアプリが録音係、という分業制だ。これは既存アプリを参考にした。

壁② 変換結果をキーボード側に戻せない

メインアプリで変換したテキストをキーボード拡張に渡す方法が必要だった。App Groupsという仕組みを使って、アプリ間で共有できるストレージ経由で受け渡している。念のためクリップボードにもコピーするようにしたので、うまく動かなくても貼り付けで対処できる。

壁③ モデル選定のトレードオフ

WhisperのモデルはサイズによってTiny(軽い・速い・精度低め)からLarge(重い・遅い・精度高め)まである。オンデバイスで動かすので、ダウンロードサイズとバッテリーを考えてTinyを採用した。ただ精度はやっぱりクラウドAPIには及ばない。

副産物として、中国語で話しかけたら日本語に自動翻訳されて出てきた。Whisperがデフォルトで翻訳機能を持っているらしく、狙っていなかった機能がついていた。妻に見せたら「え、すごいじゃん」と驚いていた。自分でも驚いた。


開発プロセスの話

個人開発なのに、Claude CodeにSuperpowersというプラグインを入れてTDD(テスト駆動開発)で進めた。単体テスト → 結合テスト → 統合テストの順に品質を積み上げていくやつだ。

「個人開発には過剰では?」と自分でも思いつつ、将来的にApp Storeに出すつもりなのでこの時点から品質を気にしておこうというのと、純粋に使ってみたかったというのが理由だ。いつもの仕事のノリでやってみたら、ちゃんと「仕事してる」感が出た。一人なのに。


現状と正直な話

今の状態を正直に言うと、自分ではまだあまり使えていない

変換に数秒かかることがあるし、Tinyモデルの精度は思ったより控えめだった。結局いまも「ChatGPTで音声入力 → テキストをコピー → Claudeのアプリに貼り付け」という面倒なことをやっている。自分が嫌だと思っていたことを、まだやっている。

ただ、次のステップは見えている。

OpenAIのWhisper APIなどクラウドAPIに切り替えれば、大きなモデルをサーバー側で動かせる。速度も精度も今とは別物になるはずだ。ローカル処理のプライバシーメリットは薄れるけど、「どのAIにもWhisper精度で話しかけられる」という最初の動機は、こっちの方が早く達成できそうだと思っている。

プロトタイプとしては悪くない。次のバージョンが楽しみ。 将来的には既存アプリより安い料金でだせたらなぁとか思っています。


まとめ

  • ChatGPT以外のAIでも高精度な音声入力がしたくて、iOSカスタムキーボードを自作した
  • Keyboard ExtensionとWhisperKitを組み合わせることで、どのアプリからでも使える構成にした
  • まだ自分では使えていないが、クラウドAPI化という次の一手が見えている
  • 将来的にはApp Storeで公開予定

犬へのポエムを高精度でAIに届ける夢は、まだ道半ば


技術スタック: Swift / SwiftUI / UIKit / WhisperKit / AVFoundation / iOS 16.0+