Notion×Claude Codeで議事録を自動化した話:会議後5分で要約・タスク分解まで完了

PR本記事はアフィリエイト広告を含みます。リンク経由でのご購入により運営者に成果報酬が支払われることがありますが、読者への価格や条件は変わりません。

週に4〜5回の打ち合わせをこなしながら副業をしていると、議事録作成に割く時間が馬鹿にならない。1回30分の打ち合わせで議事録に15〜20分かかるとしたら、週で1時間以上が「まとめ作業」に消えていく計算だ。

この問題を解決するために、WhisperでZoom音声を文字起こし → Claude APIで要約・タスク抽出 → Notion APIで自動保存というパイプラインをClaude Codeで組んだ。以来、会議後5分以内に議事録がNotionに届くようになった。

全体のフロー

Zoom/Teams会議録音 → mp4/wav
→ Whisper(文字起こし)→ transcript.txt
→ Claude API(要約・決定事項・タスク抽出)→ JSON
→ Notion API(指定DBにページ追加)

各ステップをPythonスクリプトで繋げており、コマンド1つで全自動実行できる。

Step1: Whisperで文字起こし

OpenAIのWhisperはオープンソースの音声認識モデルで、ローカル実行できる点が重要だ。会議内容をクラウドサービスに送らずに文字起こしできる。

インストールはpipで完了する:

pip install openai-whisper
pip install ffmpeg-python

文字起こしの実行コマンドはシンプルだ:

whisper meeting_2026-04-19.mp4 --model medium --language ja --output_format txt

--model mediumは日本語認識の精度と処理速度のバランスが良い。より高精度を求めるならlarge-v3を使う(処理時間は2〜3倍になる)。

60分の会議音声なら、M2 MacBook Proのmediumモデルで約3〜5分で文字起こしが完了する。

Step2: Claude APIで議事録を構造化

文字起こしテキストをClaude APIに投げ、以下の形式でJSONを返すプロンプトを組んだ:

import anthropic
import json

def extract_meeting_info(transcript: str) -> dict:
    client = anthropic.Anthropic()
    
    prompt = f"""
以下は会議の文字起こしです。日本語で以下のJSON形式で出力してください。

{{
  "title": "会議の一行タイトル",
  "date": "会議日付(YYYY-MM-DD)",
  "summary": "会議全体の3〜5行の要約",
  "decisions": ["決定事項1", "決定事項2"],
  "action_items": [
    {{"task": "タスク内容", "owner": "担当者名", "due": "期日"}}
  ],
  "next_meeting": "次回会議の日程(不明な場合はnull)"
}}

---文字起こし---
{transcript}
"""
    
    message = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=2000,
        messages=[{"role": "user", "content": prompt}]
    )
    
    response_text = message.content[0].text
    # JSONブロックを抽出
    json_match = re.search(r'\{.*\}', response_text, re.DOTALL)
    return json.loads(json_match.group())

このプロンプトのポイントはJSON形式を厳密に指定していること。LLMのJSON出力は不安定になりがちなので、re.searchでJSONブロックだけを抽出してパースしている。

Claude 3.5 Sonnetは日本語の文脈理解が高く、「Aさんがやると言った」という口語から自動的に「担当: A」とアクションアイテムを抽出してくれる。

Step3: Notion APIで自動保存

Notionのデータベースに議事録ページを自動作成する。

まずNotionの「インテグレーション」を作成してAPIキーを取得し、対象のデータベースにインテグレーションをシェアする必要がある。

import requests

def create_notion_page(meeting_data: dict, database_id: str, notion_token: str):
    url = "https://api.notion.com/v1/pages"
    headers = {
        "Authorization": f"Bearer {notion_token}",
        "Content-Type": "application/json",
        "Notion-Version": "2022-06-28"
    }
    
    # アクションアイテムをNotionのブロックに変換
    action_blocks = []
    for item in meeting_data.get("action_items", []):
        action_blocks.append({
            "object": "block",
            "type": "to_do",
            "to_do": {
                "rich_text": [{"text": {"content": f"{item['task']} 【{item['owner']}】 {item['due']}"}}],
                "checked": False
            }
        })
    
    payload = {
        "parent": {"database_id": database_id},
        "properties": {
            "Name": {"title": [{"text": {"content": meeting_data["title"]}}]},
            "Date": {"date": {"start": meeting_data["date"]}},
        },
        "children": [
            {"object": "block", "type": "heading_2",
             "heading_2": {"rich_text": [{"text": {"content": "サマリー"}}]}},
            {"object": "block", "type": "paragraph",
             "paragraph": {"rich_text": [{"text": {"content": meeting_data["summary"]}}]}},
            {"object": "block", "type": "heading_2",
             "heading_2": {"rich_text": [{"text": {"content": "アクションアイテム"}}]}},
            *action_blocks
        ]
    }
    
    r = requests.post(url, headers=headers, json=payload)
    r.raise_for_status()
    return r.json()["url"]

これでNotionのデータベースに「タイトル・日付・要約・アクションアイテム(チェックボックス付き)」が自動生成される。

全部つなげた実行スクリプト

3つのステップを1コマンドで実行するmain.pyを作った:

import sys, re
from pathlib import Path

def main(audio_file: str):
    print(f"[1/3] 文字起こし中: {audio_file}")
    import subprocess
    subprocess.run(["whisper", audio_file, "--model", "medium",
                    "--language", "ja", "--output_format", "txt"])
    
    txt_path = Path(audio_file).with_suffix(".txt")
    transcript = txt_path.read_text(encoding="utf-8")
    
    print("[2/3] Claude APIで議事録構造化中...")
    meeting_data = extract_meeting_info(transcript)
    
    print("[3/3] Notionに保存中...")
    page_url = create_notion_page(
        meeting_data,
        database_id="YOUR_DB_ID",
        notion_token="YOUR_NOTION_TOKEN"
    )
    
    print(f"完了: {page_url}")

if __name__ == "__main__":
    main(sys.argv[1])

実行は python meeting_auto.py zoom_recording.mp4 だけでよい。

実際に使ってみた感想

精度は想像以上に高い。特にClaude 3.5 Sonnetは文脈理解が優秀で、「次回は来週月曜でいいですか?はい、承知しました」という会話から「次回会議: 来週月曜」を正確に抽出してくれた。

ただし注意点もある。複数人が同時に話すシーンや雑音が多い録音は文字起こし精度が落ちる。Zoomで「レコーディング」した音声は比較的クリーンなので問題ないが、対面会議をスマホで録音した場合は前処理が必要になることがある。

Claude Codeで最初に組んだのは2時間ほどだった。自動化の達成感とともに、毎週1〜2時間が永遠に返ってくる感覚は格別だ。

よくある質問

Whisperはどのくらいの精度ですか?

日本語の精度はかなり高く、会議音声なら大部分は正確に起こせます。ただし固有名詞(社名・人名)や専門用語は誤認識が起きやすいです。Whisperの出力をClaude APIに渡す段階で、Claudeが文脈から補正してくれることも多いです。

APIの費用はどのくらいかかりますか?

1時間の会議(約10,000〜15,000トークンの文字起こし)をClaude 3.5 Sonnetで処理すると、1回あたり約3〜8円程度です。週5回の会議で月200〜300円ほどの試算です。Notion APIは無料プランで利用できます。

ZoomやTeamsの録音データは自動取得できますか?

ZapierやMakeなどのノーコードツールを組み合わせれば、Zoom CloudのRecordingをトリガーに自動実行するパイプラインを組めます。ただしZoom APIの設定が必要で、エンタープライズプランが必要なケースもあります。

まとめ

Whisper + Claude API + Notion APIを組み合わせた議事録自動化パイプラインは、繰り返し会議が多いフリーランス・副業者にとって非常に効果的だ。

1度作ってしまえば保守コストはほぼゼロで、毎週確実に時間を取り戻せる。Claude Codeを使えばスクリプト作成自体も数時間で完成する。「会議のたびに議事録作成がしんどい」と感じている方は、ぜひ試してほしい。

関連ツールを見る

この記事で紹介したツール・サービスをまとめてチェック。

おすすめ

エックスサーバー

国内シェアNo.1のレンタルサーバー。WordPressブログをすぐに始められる。このブログも実際にXserverで運営しています。

Xserverを見てみる →

ムカイ
この記事を書いた人

ムカイ

個人事業主エンジニア。C#フルリモート案件に参画しながら、Claude Codeを使ってAI×副業の自動化・コンテンツ制作を実践中。「稼ぐ仕組みを作るのが好き」がモットー。

コメントを残す