Haruto Miyakawa
ツール・ライブラリ

講義議事録ジェネレーター

聞き逃した講義も、後から確実に拾い直す。AIの「もっともらしい嘘」を仕組みで捕まえる、ローカル完結の文字起こしツール。

Role
個人開発
体制
個人 (Solo)
種類
ツール・ライブラリ
ステータス
公開(OSS)
スタック
Python, Whisper, Gemini API
なぜ作ったか

きっかけは二つありました。ひとつは、大学で共同研究が始まり、ミーティングの内容を後から確認できるようにしたかったこと。もうひとつは、講義中に聞き逃した——資料に載っていない口頭の補足を、後から確実に拾い直したかったことです。調べてみると、既存のクラウド型文字起こしツールには二つの根本的な問題がありました。コスト——API の従量課金では、長時間の講義を毎日処理していると費用がかさみ、学生が使い続けられない。そしてハルシネーション——専門用語や固有名詞の多い講義では、LLM がもっともらしい誤った内容を生成し、それをそのまま試験勉強に使うとむしろ逆効果になる。この二つを同時に解くツールが欲しくて、自分で作りました。

どう解いたか

音声ファイルをアップロードすると、ローカルの GPU で動く Whisper が文字起こしし、Gemini 2.5 Flash が議事録の形に整えます。文字起こしはローカル実行なのでクラウド従量課金が発生せず、長時間講義を何本処理してもゼロコスト。さらに講義資料(PDF)を AI に同時に渡して専門用語の精度を補正し、誤認識を自動で検知したら精度優先の設定で処理をやり直します。生成された議事録はアプリ内で直接編集でき、PDF や Markdown で書き出せます。

ホーム画面。音声ファイル(mp3 / m4a)をドロップしてローカル処理を開始する
ホーム画面。音声ファイル(mp3 / m4a)をドロップしてローカル処理を開始する
文字起こし画面。ローカル GPU の Whisper がタイムスタンプ付きでテキスト化する
文字起こし画面。ローカル GPU の Whisper がタイムスタンプ付きでテキスト化する
議事録画面。Gemini が見出し・要点に整形した議事録をアプリ内で編集し、PDF / Markdown で書き出せる
議事録画面。Gemini が見出し・要点に整形した議事録をアプリ内で編集し、PDF / Markdown で書き出せる
役割分担

個人開発です。これまでの「つむぐ」「家電ガイド」と同じく、Claude Code との協働だけで開発しました。同じ開発スタイルで、執筆支援・接客支援・音声処理という異なる領域のアプリを作っています。

技術判断とトレードオフ

01ハルシネーションを仕組みで検知する — AI の誤りを鵜呑みにしない

このツールの一番の肝です。Whisper は無音区間や不明瞭な音声に対して、定型文を繰り返したり、ありもしない内容をもっともらしく出力することがあります。試験勉強に使う議事録でこれが起きると致命的です。そこで、三つの条件——定型文フレーズの一致、音声長に対して出力文字数が極端に少ない、無音確率(no_speech_prob)の平均が 0.7 を超える——のいずれかで誤認識を検知したら、精度優先の設定(condition_on_previous_text=False など)で自動的にやり直す仕組みを入れました。ポイントは、この精度優先設定を通常時には使わないことです。常に適用すると通常時の精度がかえって落ちるため、検知したときだけフォールバックとして発動させる。AI の出力を信頼しきらず、誤りを後段で捕まえて補正するという考え方を、文字起こしの品質保証として実装した部分です。

02ローカル Whisper — コストを設計の前提に置いた

文字起こしには、クラウドの Whisper API ではなくローカル実行の Whisper を選びました。API は 1 分あたり約 0.006 ドル。2 時間の講義を週 15 本も処理すれば、月に数千円かかります。学生が毎日使い続けるツールでこの金額は重い。手元に CUDA 対応の GPU があったので、ローカルで動かせばゼロコスト・無制限になる。「安く速く」より一段手前の、「そもそも継続して使えるか」を最優先した判断です。

03Gemini と RAG — 用途に合わせた使い分けと、幻覚の抑制

議事録の整形には Gemini 2.5 Flash を選びました。整形という用途では品質の差が小さく、コストは Claude のおよそ五分の一に収まり、100 万トークンの長いコンテキストが長時間講義の文字起こしを一度に扱えるからです。さらに、講義資料の PDF を整形時に同時に渡すことで、外部のベクトルデータベースを用意せずに専門用語の文脈を AI に与え、固有名詞の取り違えを抑えました。(文章エディタ「つむぐ」では日本語の質を最優先して Claude を選び、こちらでは用途とコストで Gemini を選ぶ——コア機能が何かによって最適な AI は変わる、という使い分けです。)

04SSE で進捗を可視化する — 長い処理を待てる UX に

Whisper は別の Python プロセスとして動くため、Node.js 側から処理の進捗を直接知ることができません。何分も無言で待たされるのは、長時間の文字起こしでは苦痛です。そこで Whisper の進捗表示(tqdm)に手を入れて、進捗を JSON として標準出力に流し、それを Node.js が SSE(Server-Sent Events)に変換してブラウザにリアルタイム表示する構成にしました。WebSocket より実装が軽量で、この一方向の進捗通知には十分です。

現在地

実際の大学講義で継続的に使い、当時は小テストで安定して点を取れていました。今は、ローカル Whisper が GPU を占有して研究作業と競合するため、毎回の講義ではなく期末前に講義内容をまとめ直す使い方へ切り替えています。ゼロコストと引き換えに GPU を使うという選択の帰結を、運用の側で調整した形です。開発の過程は記事として公開し、自分の学習効率のために作ったツールが、そのまま発信の題材にもなっています。

技術スタック
NNext.js 16 (App Router)
TSTypeScript 5
~Tailwind CSS v4
PyPython 3
WOpenAI Whisper (large-v3, local)
GGoogle Gemini 2.5 Flash
SDsimple-diarizer
SSSE

ご質問やご依頼など、お気軽にご連絡ください。