【2026年版・コード全文】Claude Code × python-pptx でPowerPointスピーカーノートをAI自動生成する完全手順(1分=300字制御 / 日英併記対応)
目次 クリックで開く
「PowerPoint資料は出来た。けど発表用のスピーカーノートを書く時間がない」——多くの現場で発生する地味なボトルネックです。本記事では Claude Code(Anthropic 公式 CLI) と python-pptx を組み合わせて、スライド本文を読み取り→各スライドのスピーカーノートを自動生成し、.pptx に書き戻す仕組みをコード全文付きで解説します。
python build_speaker_notes.py 一発で、5枚のQ1営業レビューに「読みやすい話し言葉のスピーカーノート」が自動付与された .pptx を生成する。
- スピーカーノートが書かれない3つの理由
- 完成イメージ(プレビュー画像)
- 処理フロー:python-pptx × Claude API
- プロンプト設計のコツ
- 完成スクリプト全文
- 運用パターン:定例会議・取締役会・営業提案
- FAQ
1. スピーカーノートが書かれない3つの理由
- 発表者と資料作成者が別人で、引き継ぎ時間が取れない
- 箇条書きスライドを「補足する話し言葉」に翻訳する作業が単純につらい
- スライド差し替えのたびにノートも書き直しになり、保守できない
これらは「同じスライド本文から、同じトーンで毎回生成する」という、まさにLLMが得意な領域です。
2. 完成イメージ

3. 処理フロー
| ステップ | 処理 | 使用ツール |
|---|---|---|
| 1 | スライドのタイトル + 箇条書きを抽出 | python-pptx |
| 2 | 抽出テキストを LLM プロンプトに埋め込み | Claude API(sonnet推奨) |
| 3 | 返ってきたノート文を notes_text_frame に書き戻し | python-pptx |
| 4 | 監査用に slide / notes の対応表を JSON 出力 | 標準ライブラリ |
4. プロンプト設計のコツ
OK: 話す時間(例:1分)、想定聴衆(例:取締役)、口調(例:です・ます調)、必ず触れる論点(例:数字の妥当性)を明示する。
本記事のサンプルでは、決定論的なテンプレで「Claude Code が生成するであろうノートの形」を示しています。実運用では、抽出したスライド本文を Claude API に投げ、上記4点をプロンプトに含めるだけで品質が一段安定します。
5. 完成スクリプト全文
"""Generate speaker notes for an existing-style PowerPoint with python-pptx.
Demo flow:
1. Build a sample 5-slide deck (Q1営業レビュー) with bullets only.
2. For each slide, derive speaker notes from the slide content using a
prompt template — in production this calls Claude API; here we use a
deterministic stub that mirrors what Claude Code would produce so the
article focuses on the integration shape.
3. Save deck and write notes preview JSON.
"""
from pathlib import Path
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
import json, textwrap
ROOT = Path(__file__).parent
OUT_PPTX = ROOT / "q1_sales_review.pptx"
OUT_JSON = ROOT / "speaker_notes.json"
slides_data = [
{
"title": "Q1 営業レビュー 2026",
"bullets": [
"目標 ¥420M / 実績 ¥438M(達成率 104%)",
"新規受注 47件(前年同期比 +18%)",
"既存深耕 ARPU ¥820k(前期比 +6%)",
"重点アジェンダ:Q2の継続成長施策",
],
},
{
"title": "1. 売上ハイライト",
"bullets": [
"Tokyo支社:¥152M(+22% YoY)— 製造業大型案件牽引",
"Osaka支社:¥118M(+11% YoY)— 既存リプレイス順調",
"Fukuoka支社:¥94M(+5% YoY)— 新規開拓に課題",
"Nagoya支社:¥74M(−3% YoY)— 担当者離任の影響残存",
],
},
{
"title": "2. 商品別の動き",
"bullets": [
"Software A:継続率 92%、追加販売の伸び大",
"Software B:価格改定後の解約微増(要モニタリング)",
"Consulting:粗利率 58%(過去最高)",
"Support:自動化で原価 12%圧縮",
],
},
{
"title": "3. リスクと課題",
"bullets": [
"Nagoya後任の早期戦力化(90日プラン要)",
"Software B 解約防止:CS連携の強化",
"大型案件3件の検収期ズレリスク(合計 ¥38M)",
"為替前提:¥150 → ¥155 円安継続を織り込み",
],
},
{
"title": "4. Q2 アクションプラン",
"bullets": [
"Nagoya 新人 OJT:Tokyo SE 2名を週次派遣",
"Software B:3か月解約予兆スコアの導入",
"新規開拓:Fukuoka×製造業ABM 30社にフォーカス",
"受注前倒し:検収条件の事前合意ワークショップ実施",
],
},
]
def claude_code_style_speaker_notes(title: str, bullets: list[str]) -> str:
"""In production: call Claude API. Here: deterministic template that
mirrors the kind of speaker notes Claude Code generates from slide text."""
intro = f"このスライドのメインメッセージは「{title}」です。"
body = []
for i, b in enumerate(bullets, 1):
body.append(f"{i}つ目のポイント:{b} について、聞き手が一番気になる「数字の妥当性」と「次の打ち手」を中心に説明してください。")
transition = "次のスライドでは、ここで挙げた論点をさらに具体的なアクションに落とし込みます。"
return intro + "\n\n" + "\n".join(body) + "\n\n" + transition
def add_slide(prs: Presentation, title: str, bullets: list[str], notes: str):
layout = prs.slide_layouts[1]
slide = prs.slides.add_slide(layout)
slide.shapes.title.text = title
body = slide.placeholders[1].text_frame
body.text = bullets[0]
for b in bullets[1:]:
p = body.add_paragraph()
p.text = b
for p in body.paragraphs:
for run in p.runs:
run.font.size = Pt(20)
run.font.color.rgb = RGBColor(0x0F, 0x17, 0x2A)
notes_tf = slide.notes_slide.notes_text_frame
notes_tf.text = notes
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
speaker_notes_dump = []
for sd in slides_data:
notes = claude_code_style_speaker_notes(sd["title"], sd["bullets"])
add_slide(prs, sd["title"], sd["bullets"], notes)
speaker_notes_dump.append({"title": sd["title"], "bullets": sd["bullets"], "notes": notes})
prs.save(OUT_PPTX)
OUT_JSON.write_text(json.dumps(speaker_notes_dump, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"[save] {OUT_PPTX} ({OUT_PPTX.stat().st_size:,} bytes)")
print(f"[save] {OUT_JSON} ({OUT_JSON.stat().st_size:,} bytes)")
print(f"[stats] slides={len(slides_data)}, total_notes_chars={sum(len(s['notes']) for s in speaker_notes_dump)}")
6. 運用パターン
6-1. 定例会議:毎週の進捗スライドにノート自動付与
週次の進捗テンプレに対し、当週分の数字だけ差し替えて build_speaker_notes.py を実行 → ノートが毎回最新の数字を反映した話し言葉になります。
6-2. 取締役会:質問予測と想定問答も同時生成
プロンプトに「想定される質問3つと回答も notes に追記して」と一行加えるだけで、取締役会用のQA準備が同時に終わります。
6-3. 営業提案:話者交代時の引き継ぎ高速化
担当変更があっても、ノートが揃っていれば後任が同じトーンでプレゼンできます。引き継ぎ会議が不要になります。
7. FAQ
Q1. Microsoft Copilot for PowerPoint ではダメ?
A. Copilot は GUI で対話する設計のため、複数ファイル一括処理や CI 組み込みが不得意です。本記事のような「スクリプトを叩けば全社配布資料のノートが一斉更新される」用途では Claude Code + python-pptx の方が圧倒的に楽です。
Q2. 既存 .pptx に対しても適用できる?
A. はい。Presentation(existing.pptx) で開いて各スライドの notes_slide.notes_text_frame を上書きすれば、デザインを保ったままノートだけ差し替えられます。
Q3. ノートのトーンを「英語」「英日併記」にするには?
A. プロンプトに「日本語と英語の両方で書いてください、英語が下」と書くだけで対応可能。海外法人共有時の翻訳作業がそのまま消えます。
Q4. 機密スライドを LLM に投げて大丈夫?
A. Claude API は「学習に使わない」設定がエンタープライズ標準です。とはいえ社外秘の取り扱いは社内ポリシー次第なので、ローカル LLM(例:llama.cpp + Mixtral)への切り替えも、本スクリプトの claude_code_style_speaker_notes 関数を差し替えるだけで可能です。
Q5. テンプレ通りに見えてしまう問題
A. プロンプトに「このスライド固有の数字(達成率、前年比、製品名)を必ず1つ以上織り込む」と書くと、画一的な話し方が消えます。
9. 上位記事との差別化:スピーカーノート品質の作り込み
9-1. 発表時間に合わせた文字数制御(1分=約300字)
「30秒で話して」と「3分で話して」では必要な情報量が10倍違います。プロンプトに発表時間を明示し、目安文字数を計算して渡すと暴れません。
def build_prompt(title, bullets, minutes_per_slide):
target_chars = int(minutes_per_slide * 300)
return (
f"このスライド「{title}」を {minutes_per_slide} 分で話す前提で、"
f"スピーカーノートを {target_chars}±50文字で書いてください。"
f"箇条書き: {bullets}"
)
9-2. 本文との整合性チェック(要約過剰・逸脱の検知)
LLMはたまに「スライドにない数字」を勝手に追加します。生成後にスライド本文の数字を抽出し、ノートに「スライド本文に存在しない固有名詞・数字」が混入していないかを re でセルフチェック。混入していたら再生成。
9-3. 多言語ノート(日英併記)対応
prompt += "\n出力フォーマット: 日本語ノート → 空行 → English Notes(半分の長さ)"
海外法人にもそのまま配布できるpptxが、追加工数ゼロで完成します。
9-4. テンプレ(.pptx)流し込み vs ゼロ生成
| 方式 | 使い所 |
|---|---|
既存テンプレを開いて notes_text_frame だけ上書き |
定例会議・社内ブランド維持 |
| 完全ゼロ生成(本記事の方式) | 新規プロジェクト、レイアウトも自動化したい |
9-5. notes_slide の基礎
各スライドオブジェクトに slide.notes_slide.notes_text_frame プロパティがあり、ここに text = "..." で書き込むだけ。add_paragraph() で複数段落、runs[0].font.size = Pt(10) で書式も制御できます。
関連記事(クラスター)
- 【ピラー】AI業務自動化完全ガイド【2026年版】n8n・Dify・ChatGPT・Claude徹底比較
- Claude CodeでExcel業務を自動化する完全ガイド|月次レポート・予実管理・集計を爆速化
- Claude CodeでPowerPoint業務を自動化する完全ガイド|提案書・月次レポート・営業資料
- Claude CodeでWord業務を自動化する完全ガイド|契約書・報告書・見積書を爆速化
- Claude Code + Microsoft Graph API でTeams業務を自動化する完全ガイド
- Claude Code × Outlook API で社内ニュースレターを自動作成・配信する完全ガイド
- Claude Code × openpyxl でKPIダッシュボードを毎日自動更新する完全ガイド
- BtoB業界向け Claude Code 活用ガイド|検証〜本格運用まで4フェーズ
本記事は「AI業務自動化完全ガイド」のクラスター記事です。Excel・PowerPoint・Outlook・Teams 各領域の Claude Code 実装サンプルを上記ガイドからまとめて参照できます。
AI・業務自動化
ChatGPT・Claude APIを活用したAIエージェント開発、n8n・Difyによるワークフロー自動化で繰り返し業務を削減します。まずはどの業務をAI化できるか診断します。