メインコンテンツへ移動 / Skip to main content

nagaraを作った──AIの返事も小説も、好きな声で「ながら聞き」する【開発記】

Claude Codeの長い返事を、もっと心地よく聴きたかった。AivisSpeechとSwiftで作ったmacOS用OSSプレイヤーnagaraの開発記。静かな受信、文単位の再生、声を変えずに速度を変える設計を紹介する。

イヤホンで文章を聴きながら家事をする人物を描いたAI生成イラスト
テクノロジー
公開日: 2026年9月4日
読了時間: 9
著者: ぽちょ研究所
読了時間: 9

1. 長い返事を、画面から離れて聴きたかった

Claude Codeに何かを頼むと、丁寧な返事が返ってくる。変更した場所、その理由、確認したこと。ありがたい。でも、それを毎回、画面の前で最後まで読むのは少し疲れる。

読み上げればいい、と思った。ところが私が使った環境では、日本語の長い応答が途中から急かされるような早口になり、声も好みに合わせられなかった。内容を理解する前に、聴き続けることのほうがしんどくなる。

そこで作ったのが、nagara(ながら)。Macのメニューバーに置く、小さな音声プレイヤーだ。AIの返事、ブラウザの記事、小説。コピーした文章を好きな声で聴き、一時停止し、聞き逃したら1文戻る。名前は、そのまま「ながら聞き」から取った。MITライセンスのOSSとして公開している。[1]

以前作ったnobetsuは、話した日本語をアプリへ入れる道具だった。今回は逆向き。文字として届いたものを、耳へ返す道具である。どちらも、自分が日常で引っかかった場所から作り始めた。

2. 声で話すことと、好きな声で聴くこと

最初の不満はClaude Codeだったが、日本語の読み上げが製品全体で悪い、と言いたいわけではない。前述の早口は私の使用感で、日本語だけの現象なのか、音声生成や再生のどこに原因があるのかまでは切り分けていない。

音声機能は入口と出口も混同しやすい。Claude Codeの公式ドキュメントで案内される「/voice」は、話した内容をプロンプトへ入れる音声入力だ。応答をどう聴くかとは別の機能である。[2]

Codexでも、通常のテキスト作業の続きを、そのまま好みの声で聴きたかった。ただし、2026年9月4日時点では、OpenAIはCodexのタスクを音声で進めるChatGPT Voiceを案内している。対応状況はアカウントや配信状況などにもよる。「Codexには音声がない」と一括りにはできない。[3]

そのうえで私が欲しいのは、会話を始めることに限らない。できあがった文章を手元に置き、聴く声と速さとタイミングを自分で決めたい。ブラウザの長い記事や、続きを楽しみにしている小説も同じだ。朗読作品のように、声そのものを楽しめたらうれしい。

既存の選択肢もある。たとえばVS Code拡張のResponse Narratorには、再生・一時停止、声や速度の選択、手動再生がある。[4] nagaraで揃えたかったのは、エディタの外でも使えて、日本語のローカル音声モデルを選べて、応答が静かに溜まるという組み合わせだった。

開いた本とイヤホンを組み合わせ、読む時間が聴く時間へつながる様子を表現したAI生成写真

同じ文章でも、どんな声で、いつ聴くかは自分で選びたい。AIの応答から小説まで、その入口を揃える。

3. 声を作るところは、AivisSpeechに任せる

nagaraは音声合成モデルを作っていない。担当するのは、文章を受け取り、聴ける形に整え、再生するところ。声は別に動くAivisSpeechへHTTPで頼む。

AivisSpeechは、感情豊かな日本語の音声合成を扱えるアプリで、AivisHubから音声モデルを追加できる。声質だけでなく、モデルが持つ発話スタイルも選べる。nagaraの声メニューはエンジンの「/speakers」を問い合わせて組み立てるため、話者名をアプリ側へ固定で埋め込む必要がない。[5][6]

技術の下にはStyle-Bert-VITS2がある。Bert-VITS2を基に、感情や発話スタイルの強さを制御できるようにしたプロジェクトだ。AivisSpeech Engineでは、モデルやスタイル情報などをまとめたAIVMX形式を使い、ONNX Runtimeで推論する。PyTorchへの依存を外し、CPUでも動かせる構成になっている。[7][8]

ここで効くのは、単に「人間らしい」という総合点だけではない。落ち着いて聴ける声、少し明るい声など、長い文章に付き合ってもらいたい声を選べることだ。自然さや読み間違いはモデルと文章に左右されるので、まず自分が普段読む文章で試すのがいい。

標準設定では、合成先は自分のMacの「127.0.0.1:10101」。読み上げ本文を外部のクラウドTTSへ送らずに使える。初回のモデル取得などの通信までなくなるという意味ではない。VOICEVOXにも対応し、接続先と話者を合わせて使う構成だ。ただしAivisSpeechはVOICEVOX互換APIを持つ一方、細かなパラメータの意味には差がある。[8]

4. AIにもう一度読ませず、届いた文章を使う

入口と再生を分けると、構造はかなり素直になる。

text
Claude CodeのStopフック ─┐
CLIから渡した文章 ──────┼→ nagaraの受け口 → 履歴
コピーした文章 ─────────┘                    ↓ 再生操作
                              整形 → 文分割 → 音声合成 → 再生

Claude Codeとの連携では、応答が終わったときのStopフックを使う。フックへ渡る会話ログのパスを受け取り、JSONLから直近のassistant本文を取り出してnagaraへ送る。ターミナルの画面を読む方式ではないため、進捗表示やツールの実行結果を、そのまま朗読に混ぜずに済む。[9][6]

「さっきの返事を読み上げて」と頼むたびに、LLMへ長文を出し直させる必要もない。もう届いている文章を再生する。本文を再生成するためのトークンや待ち時間を増やさず、言い換えられてしまうことも避けられる。[10]

もう一つ大切なのが、目で読むMarkdownを、耳で聴く文章へ整える処理だ。コードブロックは既定で飛ばし、リンクは表示文字を残す。表の区切り線を落とし、セルは読点でつなぐ。見出しや強調の記号も外す。これはLLMの要約ではなく、規則に沿った整形である。

もちろん、表を読み上げると行と列の関係は弱くなるし、コードの詳細は聴けない。音声だけで差分レビューを完了する道具にはしない。説明を耳で受け取り、確かめたいところで画面へ戻る。そのくらいが使いやすい。

5. 「1文戻る」を中心に、再生を組み立てる

プレイヤーの中心はSwiftのAVAudioEngine。合成した音声をAVAudioPlayerNodeへ渡し、その先にAVAudioUnitTimePitchを挟んでいる。速度を変えるのは、音声を作るときではなく、鳴らすときだ。[11][12]

合成APIの「speedScale」で速度を焼き込むと、設定変更のたびに音声を作り直すことになる。再生側で変えれば、声の高さを保ちながら、聴いている途中でも速さを変えられる。既定の選択肢は1.0〜1.5倍。遅く引き伸ばしたときの音の濁りが気になったため、通常のメニューはこの範囲に絞った。これはnagaraの設定であり、AppleのAPIの上限ではない。[10]

戻る単位も、15秒ではなく1文にした。聞き逃した説明をもう一度聴くとき、文の途中に着地されると困るからだ。本文を句点や改行などで分け、その区切りを再生の単位にする。長い文は読点などでも追加分割するので、厳密には「文を中心とした短いまとまり」である。

この分割は待ち時間にも効く。全文の合成完了を待たず、最初の文ができたら再生し、進行に合わせて先を用意する。コードの先読み幅は3文分。エンジン起動や合成の待ち時間は残るが、長文全体が完成するまで黙って待つ必要はない。[11]

短く区切った青い音声テープを並べ、ひと区切りへ戻れる仕組みを表現したAI生成の造形写真

文の区切りを再生の単位にすると、聞き直す場所と、先に合成する範囲を同じ仕組みで扱える。概念を表したイメージ。

非同期処理には、もう一つ小さな工夫がある。停止や文移動のたびに「世代番号」を進め、前の世代から遅れて届いた合成結果や再生完了通知を捨てる。停止ボタンを押したのに、裏で作っていた音声が後から割り込む、という競合を防ぐためだ。

こういう部分は、画面ではほとんど見えない。でも、戻る・止める・別の文章を聴くという当たり前の操作を、当たり前に受け付けるために要る。音が出たところから、普段使える道具になるまでの差は、案外そこにある。

6. 届いている。でも、鳴っていない

使っていて一番効いたのは、音そのものより、自動再生が既定でOFFになっていることだった。Claude Codeの応答は履歴へ届き、メニューバーに未再生の件数が付く。聴きたくなったら再生する。

毎回しゃべり出すと、ほかの作業や考えごとを遮ってしまう。一方、聴くたびに長文を選択してコピーするのも面倒だ。「受け取る」と「鳴らす」を分けるだけで、その両方を避けられる。なお、現状の履歴はアプリ稼働中のメモリ上にあり、再起動をまたいで残す保存庫ではない。[6]

文章のカードが静かに届き、イヤホンが脇で待つ受信トレーを描いたAI生成イラスト

届くタイミングはAI側、聴くタイミングは自分側。自動で受け取っても、自動で鳴らす必要はない。

Macへの関わり方も、小さくした。nagaraは画面をスキャンせず、渡されたテキストだけを読む。ホットキーにはCarbonのRegisterEventHotKeyを使い、クリップボードは操作時に読む。入力監視やアクセシビリティの許可を求める構成にしていない。右クリックのサービスが出ないアプリでも、コピー経由で使える。[10]

AivisSpeechは必要時に起動し、自分で起こしたものだけ、既定では15分使われなければ終了させる。利用者が先に開いていたエンジンは自動終了の対象にしない。常駐する道具だからこそ、ほかの作業へ余計に口を出さないようにした。[6]

7. まず、普段読んでいる文章を一つ

現在のビルド対象はmacOS 26以降のApple Silicon Mac。AivisSpeechと音声モデルを別途用意し、リポジトリの手順でビルドする。Xcode Command Line Toolsなどの開発環境が必要で、配布アプリを一つ落として終わる段階ではない。[13]

導入後に覚える操作は、まず二つで足りる。コピーしてControl+Option+Cで読む。Control+Option+Pで再生・一時停止する。 記事でも、AIの返事でも、テキストとしてコピーできるものを一つ渡してみてほしい。

Claude Codeの自動取り込みは同梱のインストーラーで接続できる。Codexの自動取り込みは、この記事の確認時点では未実装だが、コピーやCLI経由なら使える。メディアキー対応や、好きな秒数へのシークもまだない。AivisSpeechの起動時にはウィンドウが一瞬見えることがある。日本語モデル中心のため、英語の長文朗読を主目的にする人にも、そのまま最適とは言えない。[1]

nagara本体のMITライセンスと、使う音声モデルの条件は別である。音声を動画や配信に載せる場合は、モデルごとの商用利用・クレジットなどの条件を確認してほしい。AivisHubにはACMLや非商用版など、異なる条件のモデルがある。[14] ソフトウェアは無保証で公開している。

文章を生成する側がどれほど賢くなっても、それを受け取る時間は自分のものだ。読むことが向く場面も、耳に任せたい場面もある。その切り替えと、聴く声くらいは自分で選びたい。 nagaraは、そのために作った。

GitHubでnagaraのコードと導入方法を見る

参考文献・出典

  1. [1]nagara README。2026年9月4日確認。公開ソースの確認基準はコミット7f11917。利用動機・機能・未実装項目はこの時点のもの。
  2. [2]Claude Code公式:Voice dictation。音声をプロンプトへ文字起こしする機能。
  3. [3]OpenAI公式:ChatGPT Voice。2026年9月4日確認。Codexタスクでの音声対話、配信状況・アカウント等による利用条件を案内。
  4. [4]Response Narrator:作者による機能説明。再生制御・手動モード・声と速度の選択。
  5. [5]AivisSpeech公式。アプリと音声モデルの利用案内。
  6. [6]nagaraのソースおよびStopフック。Aivis、Ingest、History、Sanitizer、Settingsなどを確認。
  7. [7]Style-Bert-VITS2。発話スタイルと感情表現の制御。
  8. [8]AivisSpeech Engine。AIVMX、ONNX Runtime、VOICEVOX互換APIと仕様差。
  9. [9]Claude Code公式:Hooks reference。Stopイベントとtranscript_path。
  10. [10]nagara DESIGN.md。再生方式、操作、許可を減らす設計判断。
  11. [11]nagara Player.swift。3文分の先読み、再生速度、世代番号の実装。
  12. [12]Apple Developer:AVAudioUnitTimePitch。再生速度とピッチを扱う音声ユニット。
  13. [13]nagara build.sh。arm64-apple-macos26.0を対象にSwiftとOS標準フレームワークでビルド。
  14. [14]Aivis Project:ACMLおよびAivisHub。モデルに適用されるライセンスと個別の利用条件を参照。

関連記事

2026年8月23日

nobetsuを作った──日本語音声入力が止まらないためのIME迂回と差分注入【開発記】

日本語を話しながら直接入力するだけならmacOS標準でもできる。それでもnobetsuを作った理由は、長文で詰まりやすいIMEとライブ変換を迂回し、変換済みの未確定文を安全に差分注入するためだった。全ソースを公開した設計を実測と図解で解説する。

一般続きを読む
2026年9月2日

Claude Desktopを捨てなくていい。それでもCLIを選ぶ理由──SubagentsとAgent Teams実践ガイド

DesktopのCodeタブでもSubagentsは動く。それでもCLIにしかないAgent Teams、パイプ、シェル環境の直結は何を変えるのか。個人向けClaude契約で使うClaude Codeを前提に、teammateとSubagentが継承する推論モデルとeffort、設定ファイル、Git除外、コピペ可能なレビュー・ログ監視エージェントまで実務目線で解説する。

テクノロジー続きを読む
2026年9月2日

ClaudeのBypass permissions(権限をバイパス)って実際危ない?──Auto modeとの違いとEnterprise導入の判断基準【Claude Code】

Claude CodeのManual、Accept Edits、Plan、Auto、Don't Ask、Bypass permissionsを整理し、Claude Desktop・CLI・Coworkの違いと、EnterpriseでBypassを解放すべき条件を一次資料と実測から検証する。

テクノロジー続きを読む
2026年8月31日

なぜ「ファイル名だけ」のAGENTS.mdが勝ったのか—AIコーディング設定ファイル戦国時代、18か月の終戦史

Cursor、Copilot、Claude Code、Cline、Windsurf──ツールごとに増殖した指示ファイルは、なぜ必須項目ゼロのAGENTS.mdへ収束したのか。Ampの単数形からLinux Foundation移管、変換CLIの実利用、不可視Unicode攻撃、2026年の実践構成まで一次情報でたどる。

テクノロジー続きを読む
2026年8月5日

ベンチマーク王は、なぜ現場でコードを壊すのか|Google Antigravityが流行らない本当の理由

Google Antigravityはなぜ現場でデグレードを起こすのか。月額2,900円の圧倒的コスパと、天下のGoogleがAIエージェント開発で出遅れた謎を、モデルの知能と製品品質の違いから徹底解剖する。

テクノロジー続きを読む