OSS · Python CLI + Streamlit

speech-habit-lens

原稿は書き直すのに、声の癖は放置している。

1分スピーチを3層で解析します。ESAS 20パラメータの時系列、認識テキスト、両者を突合して声と言葉のズレを名指しするクロス層。全主張に時刻+パラメータ+引用の3点根拠を強制します。

GitHubで見る サンプルレポート(Stallman 60秒) →

  • 1分で癖が見える 3層解析を1コマンドで
  • 認識ノイズに強い ESASは言語非依存 — 音響層は文字が荒れても切り込める
  • 声と言葉のズレを暴く クロス層が「結論手前で声量が落ちる」を名指す
  • ハルシネーション抑制 全主張に時刻+パラメータ+引用を強制
  • オープンソース · MIT
  • CLI + Streamlit UI
  • ESAS 20パラメータ全件実測確認済み
  • 作者: Ken Imoto
ターミナルデモ: shlのヘルプ表示に続き、60秒のStallmanスピーチ実解析のMarkdownレポートを描画。時刻+パラメータ+引用の3点根拠つきで音響×言葉の連動パターンが並ぶ

2コマンドで回る

  1. shl analyze speech.wav --out report.md 音声認識 → ESAS抽出 → Claude三層 → Markdownレポート。エンドツーエンドで3-4分
  2. shl serve Streamlit UIをlocalhost:8501で起動。ブラウザマイク録音、Plotly時系列、クロス層カード付き
  3. --model claude-opus-4-7 解析モデルを1発ごとに切替。Sonnet 4.6(既定)、難しいクロスパターンにはOpus 4.7、コスト削減はHaiku 4.5

誰のためのツールか

  • 登壇者・創業者 これから話すピッチを事前に監査。本番の前に癖を捕まえる
  • プロダクトマネージャー アップデートの説明で聴衆が降りる文を特定して、そこだけ直す
  • コーチ・教育者 「なんとなく平板」ではなく、時刻+パラメータ+引用でフィードバックを根拠付ける
  • 好奇心のあるエンジニア 自分のスピーチの癖を、1分の音源で楽器のように見る

どんな時に使うか

  • ピッチ・トークの練習中: 開幕の癖を本番前に聞く
  • ウケなかったデモの後: 声が言葉から遅れた瞬間を特定する
  • スピーカーをコーチするとき: 印象論の代わりに、時刻+パラメータの根拠付きレポートを渡す
  • 自分の話し方を月次で棚卸しするとき: 気づいていなかった癖を1分の録音から読む

インストール

git clone https://github.com/kenimo49/speech-habit-lens
cd speech-habit-lens
pip install -e .

cp .env.example .env   # AMIVOICE_API_KEY + ANTHROPIC_API_KEY

AmiVoice APIキー(月60分まで無料)と Anthropic APIキーが必要です。1解析あたりClaude Sonnet使用量は約¥18、月60本回して¥1,080ほどが目安です。

三層解析

  • 音響層: ESAS 20パラメータの時系列。テンション推移、抑揚の偏り、出だしのエネルギー、終端の失速
  • テキスト層: 認識テキストからフィラー、結論位置、繰り返し語、論理展開
  • クロス層: 「結論手前で声量が落ちる」のような身体×言語の連動パターン
  • Grounding Rule: 全主張に時刻+パラメータ+引用の3点引用を強制。ハルシネーションを抑制
  • ESASは言語非依存: テキスト認識が荒れても音響的な癖は鋭く出る
  • ESAS 20パラメータの実フィールド名を全件live APIで実測確認済み(公式docsの記載は5例のみ)
  • Streamlit UI: ブラウザマイク録音、PlotlyのインタラクティブESAS時系列、クロス層カード、Markdownレポート DL

4本ピッチの実測

同じツールで、Jobs・孫正義・西野・落合の60秒スピーチ4本を解析した結果。数字はツールが出したピーク値です。

指標Jobs(締め)孫正義(開幕)西野(開幕)落合(開幕)
energy peak21443239
concentration peak10010090100
anticipation peak681003591
emo_cog peak207136276244
passionate peak64118
結論位置backfrontmiddleback
フィラー「ね」×1「ね」×1「ちょっと」×5「あの」×1
認識confidence0.74–0.890.99–1.000.93–1.000.70–0.82

単一の指標では良し悪しは決まりません。Jobsのenergyピークは21、孫正義は44、両者とも聴衆に届いています。ツールが見せるのは、各話者の癖がどこに宿るか — 西野は「ちょっと」を5回、孫正義は結論を頭で言い切る型、落合は音響が濃いまま認識confidenceが0.70まで落ちる型。数字で決めるのではなく、タイムライン上に癖を名指しできることが目的です。

印象論では見えない2つの動き

ツールが日常的に暴くのはこの2つです。印象論ではそのまま抜け落ちる箇所。

開幕のズレ

anticipation 65 × energy 2

Stallmanの開幕。先取り感は最大、声のエネルギーは最小。頭は踏み出したが声は地面から離れていません。印象論では「緊張していた」で片付く場面を、ツールは秒単位で名指しします。

passionateは伸びない

4本すべてでpassionateピーク ≤ 11

Jobs・孫正義・西野・落合の4本すべてで、ESAS passionateは11を超えません。届く話し方は「熱量」では現れず、anticipation・concentration・抑揚の振れに現れます。クロス層が見に行くのはそこです。

使い方

# 解析: recognize → ESAS → Claude×3層 → Markdownレポート
shl analyze examples/sample.wav --out report.md

# Claudeモデルを1発ごとに指定
shl analyze examples/sample.wav --model claude-opus-4-7 --out report.md

# localhost:8501でマイク録音付きブラウザUI
shl serve

Web UI

shl serveでStreamlit UIがlocalhost:8501に立ち上がります。ブラウザのマイク録音か.wavのドラッグ&ドロップで解析し、ESAS時系列をPlotlyでインタラクティブに眺めて、クロス層カードを開き、Markdownレポートをダウンロード。APIキーは.envからサーバー側で読み込まれ、ブラウザには露出しません。

60秒サンプルスピーチの実解析後のStreamlit UI: パラメータ選択つきESAS時系列のインタラクティブチャートと認識テキスト

実際に返ってくる判定

ツールが実際のスピーチから拾ってきた3パターン。すべて時刻+パラメータ+引用付き。

  • Stallman開幕(0.0s, anticipation=65, energy=2, confidence=15): 先取り感は最大、声のエネルギーは最小。「なんか噛み合ってなかった」と印象で語られる、その具体的な1秒
  • intensive_thinking=62 × energy=3: 最も激しく考えている瞬間に声の出力が最低になる逆相関。ツールを回した長尺トークではほぼ全部で観測
  • passionate=0 多発 × フィラーゼロ: 言葉は止まらないが情動信号は0。よく練習されたピッチが陥る「流暢だが熱量無し」の型。クロス層でしか見えない

ツールは鏡であって、コーチではありません。タイムラインに癖を名指しするところまでがツールの仕事で、その先はあなたのものです。

v0.2、Zennfes Spring 2026提出版。推奨クリップ長は30-90秒(AmiVoiceの月60分無料枠を保護)。解析はエンドツーエンドで約3-4分かかります。ESASパラメータの意味づけは実測+公式パラメータ一覧からの逆算で、クロス層の所見は臨床測定ではなくコーチングのヒントとして扱ってください。

なぜ作ったか

登壇のフィードバックは印象で語られがちです。「緊張していた」「終わりが弱かった」「途中で聴衆が降りた」。印象が言葉になったときには、その瞬間を作った具体的な1秒はもう手元にありません。ここでの3層は、その1秒を離さないためのものです。音響層は言葉を認識できたかどうかに関係なく1秒を測り、テキスト層は実際に何が話されたかを記録し、クロス層が両者を同じタイムラインに揃えて、癖を印象ではなく引用に変えます。原稿と同じように、話し方もデバッグできるはずです。

Whisper・pyAudioAnalysisとの位置関係

役割が違います。Whisperは書き起こし、pyAudioAnalysisは音響フレームの分類。speech-habit-lensはその上の層で、感情パラメータの時系列と書き起こしを同じタイムラインに並べて、厳格な引用ルールでLLMに癖を名指させます。

speech-habit-lensWhisperpyAudioAnalysis
答える問い 自分の話し方の癖は、秒単位でどこにある? 話者は何を言った? このフレームはどの音響クラス?
感情パラメータの時系列 ✓ ESAS 20パラメータを秒に揃える 手作り音響特徴量
声×言葉のクロス層 ✓ 根拠付き引用でLLM解析
ハルシネーション対策 ✓ Grounding Rule(時刻+パラ+引用) 該当なし(書き起こしのみ) 該当なし(分類器のみ)
Web UI ✓ Streamlit + ブラウザマイク
ライセンス MIT MIT Apache-2.0

「—」はそのツールが標準で提供しない面を示します。speech-habit-lensは書き起こしエンジンと音響信号の上に載る層(現在はAmiVoice ESAS)で、上流を差し替えてもクロス層解析は同じ形で動きます。

よくある質問

APIキーは何が必要ですか?

認識とESAS取得にAmiVoice APIキー(月60分まで無料)、3層LLM解析にAnthropic APIキーが必要です。1解析あたりClaude Sonnet 4.6で約¥18、月60本回して¥1,080程度が目安です。

クリップの長さはどれくらい?

30-90秒が本命です。120秒超は拒否、60秒超は警告を出します(AmiVoice月60分無料枠を保護)。ツールはピッチ長の観察窓のために作ってあり、長尺トーク全編を通すためのものではありません。

対応言語は?

テキスト層の書き起こしはAmiVoiceのエンジン依存(既定は日本語)なので、テキスト層の解析は日本語が最強です。ESASは言語非依存で、音響層とクロス層は言語に関係なく動きます。書き起こしがノイズまみれでもクロス層は鈍りません。

ESAS 20パラメータは実在しますか? どう検証しましたか?

AmiVoice公式docsの記載は5例のみです。20フィールド名は2026年5月にlive APIで実測し、6月にパラメータ一覧エンドポイントで再検証しました。値域は全部プロンプトテンプレに明記してあるので、LLMが範囲外の値を出せない設計です。

Grounding Ruleはハルシネーションをどう止めますか?

各層のプロンプトが、全主張に時刻+パラメータ+引用の3点根拠を要求します。3点セットは構造化JSONで下流に渡り、クロス層も同じルールを継承します。引用なし=主張なし。根拠のない発見はパーサーが落とします。

Claudeモデルはどれを選べばいい?

Sonnet 4.6が既定で、ケーススタディはこれで着地します。難しいクロスパターンにはOpus 4.7を試す価値あり(コスト約3倍)。素早いトリアージだけならHaiku 4.5でコスト削減。1発ごとに--modelで切替できます。

ローカルモデル・オンデバイス認識は?

v0.2はクラウド前提です(AmiVoice + Anthropic)。音響信号をローカルのESAS相当に、テキスト層をローカルWhisperに差し替えるのは同梱していませんが、クロス層はモデル非依存なので自然な拡張ポイントです。

臨床測定ですか?

いいえ。クロス層の所見はコーチングのヒントとして扱ってください。パラメータの意味づけは実測+ベンダーのパラメータ一覧からの逆算で、どの癖を直すべきかの判断はあなたに残ります。ツールの仕事は、癖を名指しして秒を引用するところまでです。

作者について

作者はKen Imoto。Zenn・Qiita・Dev.to・当サイトで技術記事300本以上、4言語で書籍40冊以上、Zenn・Qiitaで累計40万PV超、Zenodoで研究論文4本を公開し、LLMO Frameworkを設計しています。

関連する開発ツール

プロダクト一覧 →

← プロダクト一覧へ