ClaudeCodeで議事録を自動作成する方法【会議録音から要約・タスク抽出まで】
会議の議事録、毎回誰が書いていますか。書記担当が会議中ずっとタイピングし、終わってから清書し、決定事項とタスクを整理して全員に送る。たった30分の会議でも、議事録に1時間かかることは珍しくありません。ClaudeCodeとWhisperを組み合わせれば、この一連の流れを「録音ファイルを置いてコマンドを1つ叩くだけ」に短縮できます。本記事では、文字起こしから要約・決定事項抽出・タスク化・共有テンプレートまで、実際に動くプロンプトとコードで全体を解説します。Mac/Windows問わず、無料の範囲で始められる手順をまとめました。
結論:Whisperで文字起こし、ClaudeCodeで構造化、Markdownで配布
最初に全体像をお伝えします。議事録自動化のパイプラインは3段階です。
第一段階は文字起こしです。OpenAIのWhisper(オープンソース版)をローカルで動かし、録音ファイルをテキストに変換します。クラウド版もありますが、社内情報を含む会議ならローカル実行が安心です。第二段階はClaudeCodeで構造化します。生の文字起こしテキストを、(a)要約、(b)決定事項、(c)タスク(誰が・何を・いつまでに)、(d)未決事項、の4つに整理します。第三段階はMarkdownテンプレートに流し込み、Slackやメールに自動配布します。
このパイプラインの良いところは、各段階を独立して改善できる点です。Whisperの精度に不満が出てきたらモデルを大きいものに変える。要約の質を上げたければClaudeCodeのプロンプトを磨く。配布先を増やしたければ最終段階だけ拡張する。本記事ではこの3段階それぞれに、初心者がそのまま使えるプロンプトとコードを用意しています。
1. 必要な準備(30分で完了)
最初に環境を整えます。所要時間は約30分です。
必要なものは3つだけです。Python(3.10以上)、ffmpeg、ClaudeCodeです。Whisperはpipでインストールします。
brew install ffmpeg # Macの場合
# Windowsは https://ffmpeg.org/download.html からダウンロード
python3 -m venv .venv && source .venv/bin/activate
pip install -U openai-whisper
Whisperは初回実行時にモデルファイル(数百MB〜数GB)をダウンロードします。日本語の会議なら medium か large-v3 が推奨です。CPUでも動きますが、medium なら録音時間の2〜3倍の処理時間を見込んでください。GPUがあれば数分で終わります。
録音ファイルの形式はmp3, wav, m4a, mp4などWhisperが対応する一般的な形式ならOKです。ZoomやTeamsの録音、iPhoneのボイスメモ、いずれもそのまま使えます。
2. 録音から文字起こしまで
Whisperをコマンドラインから使うのが最もシンプルです。
whisper meeting_20260512.m4a \
--model medium \
--language Japanese \
--output_format txt \
--output_dir ./transcripts
このコマンドで transcripts/meeting_20260512.txt というファイルが生成されます。中身は会議の発話を時系列で書き起こしたプレーンテキストです。ClaudeCodeでこのコマンドをラップしたPythonスクリプトを作っておくと便利です。
プロンプト例:
カレントディレクトリの recordings/ 配下にある音声ファイル(m4a, mp3, wav)を
すべて文字起こしして transcripts/ に保存するPythonスクリプトを書いてください。
要件:
- whisper を subprocess で呼び出す
- モデルは medium、言語は Japanese、出力形式は txt
- すでに同名のtxtがあればスキップ
- 処理開始時刻と所要時間をログに表示
- エラー時はファイル名と共に記録して継続
生成される典型コード:
import subprocess
from pathlib import Path
import time
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
REC_DIR = Path("recordings")
OUT_DIR = Path("transcripts")
OUT_DIR.mkdir(exist_ok=True)
EXTS = {".m4a", ".mp3", ".wav", ".mp4"}
def transcribe(audio_path: Path):
txt_path = OUT_DIR / (audio_path.stem + ".txt")
if txt_path.exists():
logging.info(f"skip (already exists): {txt_path.name}")
return
start = time.time()
subprocess.run([
"whisper", str(audio_path),
"--model", "medium",
"--language", "Japanese",
"--output_format", "txt",
"--output_dir", str(OUT_DIR)
], check=True)
elapsed = time.time() - start
logging.info(f"done {audio_path.name} in {elapsed:.1f}s")
def main():
for audio in REC_DIR.iterdir():
if audio.suffix.lower() not in EXTS:
continue
try:
transcribe(audio)
except Exception as e:
logging.error(f"failed {audio.name}: {e}")
if __name__ == "__main__":
main()
これで「録音ファイルを recordings/ に置いてスクリプトを実行」するだけで、文字起こしが揃います。
3. 文字起こしの品質を上げるコツ
Whisperの精度は録音状況に大きく左右されます。以下は実務で効くチューニングです。
ノイズの少ない録音にする。マイクは口元に近づけて、エアコンの真下を避ける。これだけで誤認識が半分以下になります。
専門用語をプロンプトで与える。Whisperには --initial_prompt というオプションがあり、ここに想定される固有名詞や用語を入れておくと精度が上がります。
whisper meeting.m4a --model medium --language Japanese \
--initial_prompt "ClaudeCode, Cloudflare, Workers, D1, OKR, KPI, 株式会社例"
複数話者の議事録が必要なら、話者分離(speaker diarization)を組み合わせます。pyannote.audio などのライブラリがありますが、設定が複雑なので、最初は「全員の発話を一塊にする」運用で十分です。会議名や日時、参加者は手動で議事録のヘッダに入れる方が早くて確実です。
4. ClaudeCodeで議事録を構造化する
ここが本記事の核心です。生の文字起こしテキストから、要約・決定事項・タスク・未決事項を抽出します。
汎用プロンプト:
以下は会議の文字起こしです。日本語で議事録を作成してください。
出力フォーマット (Markdown):
# 議事録: {会議名}
- 日時: {日時}
- 参加者: {参加者リスト}
## サマリー (200字以内)
## 決定事項
- 項目を箇条書きで列挙
## タスク
| 担当者 | タスク内容 | 期限 |
|---|---|---|
## 未決事項・持ち越し
- 項目を箇条書きで列挙
## 議論のハイライト (発言の要点を3〜5個)
- 〇〇さん: ...
ルール:
- 推測で内容を補わない。文字起こしに無い情報は書かない
- タスクの期限が明示されていなければ「未定」と書く
- 個人名が不明瞭な箇所は「発言者A」「発言者B」と表記する
会議名: {meeting_title}
日時: {meeting_date}
参加者: {participants}
文字起こし:
{transcript}
このプロンプトの肝は最後のルール部分です。「推測で補わない」「不明な情報は明示する」と書いておかないと、Claudeはそれらしい議事録をでっち上げてしまうことがあります。会議の議事録で「誰も発言していないこと」が書かれているのは事故の元です。必ず明示しましょう。
これをPythonから呼び出すスクリプト例:
import subprocess
from pathlib import Path
PROMPT_TEMPLATE = open("prompts/minutes.md", "r", encoding="utf-8").read()
def build_prompt(transcript, meeting_title, meeting_date, participants):
return PROMPT_TEMPLATE.format(
meeting_title=meeting_title,
meeting_date=meeting_date,
participants=participants,
transcript=transcript
)
def make_minutes(txt_path, meta):
transcript = Path(txt_path).read_text(encoding="utf-8")
prompt = build_prompt(transcript, **meta)
result = subprocess.run(
["claude", "-p", prompt],
capture_output=True, text=True, timeout=300
)
out = Path("minutes") / (Path(txt_path).stem + ".md")
out.parent.mkdir(exist_ok=True)
out.write_text(result.stdout, encoding="utf-8")
return out
if __name__ == "__main__":
meta = {
"meeting_title": "週次ロードマップMTG",
"meeting_date": "2026-05-12 10:00-10:45",
"participants": "田中, 鈴木, 山田, 佐藤"
}
path = make_minutes("transcripts/meeting_20260512.txt", meta)
print(f"saved: {path}")
これだけで、minutes/meeting_20260512.md に整った議事録ができあがります。
5. タスク抽出の精度を上げる専用プロンプト
「タスクをきっちり抜き出す」という用途では、汎用プロンプトより専用プロンプトの方が精度が出ます。
タスク抽出プロンプト:
以下は会議の文字起こしです。決定したタスク(アクションアイテム)だけを抽出してください。
抽出基準:
- 「〜する」「〜やっておく」「〜までに対応」など、具体的な行動を含む発言
- 担当者が特定できるもの、または「誰かがやる」と明示されたもの
- 単なる感想や雑談、未決の議論は除外
出力形式 (JSON):
[
{"assignee": "担当者名", "task": "タスク内容(50字以内)", "due": "期限 or 未定", "source": "該当発言の引用(30字以内)"}
]
注意:
- 担当者が不明確なら "未定" にする
- 期限が文字起こしに無ければ "未定" にする
- ねつ造禁止。文字起こしに無いタスクは出力しない
文字起こし:
{transcript}
JSONで出力させると、後段のSlack通知やNotion連携が楽になります。Pythonで受け取ってパース。
import json, subprocess
def extract_tasks(transcript):
prompt = TASK_PROMPT.replace("{transcript}", transcript)
r = subprocess.run(["claude", "-p", prompt], capture_output=True, text=True, timeout=180)
text = r.stdout.strip()
start = text.find("[")
end = text.rfind("]") + 1
return json.loads(text[start:end])
タスクをそのままSlackに流すなら、こんな整形プロンプトを併用します。
以下のJSONタスクリストを、Slack投稿用に整形してください。
フォーマット:
:clipboard: 本日のMTG タスク (YYYY-MM-DD)
1. @担当者 タスク内容 (期限: YYYY-MM-DD)
2. @担当者 タスク内容 (期限: YYYY-MM-DD)
@担当者 が「未定」の場合は @here とする。
期限が「未定」の場合は (期限: 未定 - 要相談) とする。
6. 決定事項と未決事項を分ける
議事録で最も重要なのは「何が決まったか」「何が決まらなかったか」を明確にすることです。曖昧な書き方をすると、次回会議で「あれってどうなったっけ?」と同じ議論が再燃します。
決定事項抽出プロンプト:
以下の文字起こしから「決定事項」と「未決事項」を分けて抽出してください。
決定事項の基準:
- 「〜することにする」「〜で行く」など、明確な合意があったもの
- 複数人が同意した方針
未決事項の基準:
- 議論されたが結論が出なかった
- 「次回検討」「持ち帰り」と明言されたもの
- 担当者を決めずに保留になったもの
出力形式 (Markdown):
## 決定事項
1. 項目 (合意した発言者: 〇〇)
2. ...
## 未決事項
1. 項目 (次のアクション: 〇〇)
2. ...
文字起こし:
{transcript}
このプロンプトの工夫は、各項目に「合意した発言者」「次のアクション」を添えさせている点です。後から「これは誰が決めたの?」と聞かれたときに即答できます。
7. 共有テンプレートと配布
完成した議事録は、Slackやメール、Notionに自動で投げます。
Slack配信スクリプト:
import os, requests
WEBHOOK = os.environ["SLACK_WEBHOOK_URL"]
def post_minutes(md_text, channel_note=""):
payload = {
"text": channel_note,
"blocks": [
{"type": "section", "text": {"type": "mrkdwn", "text": md_text[:2900]}}
]
}
r = requests.post(WEBHOOK, json=payload, timeout=10)
r.raise_for_status()
Webhook URLは必ず環境変数に入れてください。コードに直書きするとリポジトリ公開時に漏れます。
メール配信ならPythonの smtplib で送れますが、社内利用ならGmail APIやMicrosoft Graphの方が安全です。プロンプトを書いてClaudeCodeに作らせるなら次のように指示します。
minutes/ にある最新のMarkdown議事録を読み込み、
Gmail APIで指定の宛先に送信するPythonスクリプトを書いてください。
要件:
- 件名: 「[議事録] {会議名} {日付}」
- 本文: Markdownをそのまま貼る
- 認証はOAuthでローカルにトークン保存
- 送信履歴を sent.log に追記
8. 自動化パイプラインの全体像
ここまでのパーツをまとめて、1コマンドで動くパイプラインにします。
# pipeline.py
import sys
from pathlib import Path
from transcribe import transcribe
from minutes import make_minutes
from tasks import extract_tasks, save_tasks
from notify import post_minutes
def run(audio_path: Path, meta: dict):
txt = transcribe(audio_path)
md = make_minutes(txt, meta)
tasks = extract_tasks(Path(txt).read_text(encoding="utf-8"))
save_tasks(tasks, audio_path.stem)
post_minutes(Path(md).read_text(encoding="utf-8"))
if __name__ == "__main__":
audio = Path(sys.argv[1])
meta = {
"meeting_title": sys.argv[2],
"meeting_date": sys.argv[3],
"participants": sys.argv[4]
}
run(audio, meta)
実行例:
python pipeline.py recordings/meeting_20260512.m4a \
"週次ロードマップMTG" \
"2026-05-12 10:00-10:45" \
"田中, 鈴木, 山田, 佐藤"
これで「録音→文字起こし→構造化→タスク抽出→Slack通知」が1コマンドで完了します。
9. プライバシーとセキュリティの注意
議事録の自動化で最も重要なのは情報管理です。以下を必ず守ってください。
会議録音は機密情報を含みます。社内サーバまたはローカルマシンで処理し、外部のクラウドアップロードは避けるのが基本です。Whisperはローカルで完結するので、この点で優れています。
ClaudeCodeをローカルで使う場合、入力したテキストは外部に送信されます(Anthropicのサーバ)。完全に閉じた環境が必要なら、エンジニアに相談してください。多くの企業ではAnthropicとの契約で「学習に使わない」設定にできます。
Slack Webhook URL、Gmail APIトークン、その他の認証情報は環境変数(または Cloudflare の Secrets)に入れ、絶対にコードに書かないでください。Privateリポジトリでも事故は起きます。
個人情報を含む発言(顧客名、健康情報、評価面談など)を扱う議事録は、配布範囲を最小化してください。「全社共有」ではなく「該当チームのみ」が原則です。
実践チュートリアル:30分会議を5分で議事録化
実際に手を動かしてみます。サンプル音声がなければ、3分ほど自分で会議のフリをして録音してください。
ステップ1: 環境準備
mkdir minutes-bot && cd minutes-bot
python3 -m venv .venv && source .venv/bin/activate
pip install openai-whisper requests
mkdir recordings transcripts minutes prompts
ステップ2: プロンプトファイルを作る
prompts/minutes.md に本記事の「汎用プロンプト」を保存します。
ステップ3: ClaudeCodeに指示
minutes-bot/ にpipeline.pyを作ってください。引数で受け取った音声ファイルを
whisperで文字起こしし、prompts/minutes.md のプロンプトで claude -p を実行して
minutes/{audio_name}.md に保存してください。
ステップ4: 実行
python pipeline.py recordings/test.m4a "テスト会議" "2026-05-12" "私"
cat minutes/test.md
実際の30分会議で試すと、3〜5分で議事録ができあがります。書記担当の負担は大幅に減ります。
FAQ
Q1. Whisperの精度はどれくらいですか?
日本語の medium モデルで、はっきり録音された会議なら90%以上の精度が出ます。large-v3 ならさらに上がります。専門用語や固有名詞は誤認識しやすいので --initial_prompt で補助するのがコツです。
Q2. クラウド版Whisper(OpenAI API)とローカル版、どちらが良いですか? 社内の機密会議ならローカル版一択です。社外向けや一般的な議論ならクラウド版でも構いません。料金はクラウド版で1時間あたり数十円程度です。
Q3. ZoomやTeamsの自動文字起こしと何が違うのですか? Zoom/Teamsの文字起こしは便利ですが、(1)精度が会議ツール任せ、(2)Claudeのような高度な要約は別ツールが必要、(3)社内の独自フォーマットに整形しづらい、という弱点があります。本記事のパイプラインは精度・要約・フォーマットを自分でコントロールできます。
Q4. 議事録を完全自動化して、人のチェックを省略しても良いですか? 推奨しません。Whisperの誤認識やClaudeの要約ミスは必ず起こります。配布前に最低5分の目視チェックを入れてください。「人のチェックを5分に短縮する」のがこの自動化の本当の価値です。
Q5. 複数話者を分けたいです。どうすれば良いですか?
pyannote.audio などの話者分離ライブラリを使えば可能です。ただし設定が複雑で精度も完璧ではありません。最初は「全員の発話を一塊」で運用し、必要が出てきたら追加実装するのが現実的です。
Q6. 議事録の体裁(社内テンプレ)に合わせたいです。 本記事のプロンプトの「出力フォーマット」部分を、自社のテンプレに書き換えるだけです。見出し名、表の列、必須項目を変えれば、社内標準フォーマットの議事録が出力されます。
Q7. 録音ファイルが長い場合(2時間以上)はどうすれば良いですか? Whisperは長尺でも処理できますが、文字起こしも長くなりClaudeのコンテキスト上限に近づきます。30分単位でファイルを分割するか、文字起こしを章ごとに分けて要約→最終的にメタ要約する2段階方式を取ります。
まとめ
議事録の自動化は、ClaudeCodeとWhisperを組み合わせれば1日で構築できます。鍵は「文字起こし→構造化→配布」を分離して、それぞれに専用プロンプトを用意することです。完全自動化を目指さず、人の最終チェックを5分残す運用が現実的で安全です。今日の会議から、書記担当の負担を半分以下に減らしましょう。