generate-writeup について
`presentation.md`を含むプレゼンテーションフォルダーから、注釈付きのブログ形式の記事を作成するスキルです。動画とスライドの情報を段階的に集め、中間ファイルをキャッシュして構成されたMarkdown文書を生成します。
主な機能
- 01スライドの取得と変換
- 02文字起こしとスライドテキストの抽出
- 03動画チャプターとスライド概要の作成
- 04注釈付きMarkdown記事の生成
- 05中間データのキャッシュ
活用シーン
- 01録画プレゼンテーションからの記事作成
- 02動画情報を含むスライドごとのノート作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pamelafox/ presentation-skills --skill generate-writeupインストール後、Claude Code で/generate-writeupを入力して読み込まれたか確認します。
詳細
プレゼンテーションから注釈付きの解説記事を生成する
プレゼンテーションをもとに、ブログ形式の解説記事を生成します。ユーザーはプレゼンテーションフォルダーのパス(例:presentations/my-talk)を指定します。このフォルダーには presentation.md ファイルが含まれている必要があります。
presentation.md の形式
# Talk title
- **Date:** 2026-01-15
- **Video:** https://www.youtube.com/watch?v=VIDEO_ID
- **Slides:** slides.pdf
- **Transcript:** transcript.txt
## Notes
Extra notes here
必須項目は Video と Slides です。それ以外はすべて任意です。 Slides には、ローカル PDF のパス、PDF の URL、PPTX の URL、OneDrive のリンク、または RevealJS の URL を指定できます。 Video には、YouTube の URL またはローカルの MP4 パスを指定できます。
パイプライン
以下の手順を順番に実行します。中間出力はすべて <presentation_folder>/outputs/ にキャッシュし、次回以降の実行では完了済みの手順をスキップします。
Step 1: スライドを解決する
- presentation.md の Slides が URL の場合は、取得して PDF に変換します。
これによりuv run .agents/skills/fetch-slides/fetch_slides.py <url> <presentation_folder>/outputsslides.pdf(RevealJS の URL の場合はslides_content.mdも)が生成されます。 - Slides がローカルファイルのパス(プレゼンテーションフォルダーからの相対パス)の場合は、そのファイルを直接使用します。
<presentation_folder>/outputs/slides.pdfがすでに存在する場合はスキップします。
Step 2: スライドを画像に変換する
PDF を個別の PNG ファイルに分割します。
uv run .agents/skills/convert-slides-to-images/convert_slides_to_images.py <pdf_path> <presentation_folder>/outputs/slide_images
<presentation_folder>/outputs/slide_images/ に slide_*.png ファイルがすでにある場合はスキップします。
Step 3: トランスクリプトを抽出する
- presentation.md に Transcript が指定されている場合は、そのパス(プレゼンテーションフォルダーからの相対パス)から読み込みます。
<presentation_folder>/outputs/transcript.txtが存在する場合は、キャッシュされたバージョンを使用します。- それ以外の場合は、YouTube から抽出します。
uv run .agents/skills/extract-transcript/extract_transcript.py <youtube_url> <presentation_folder>/outputs/transcript.txt
Step 4: 動画のチャプターを生成する
<presentation_folder>/outputs/chapters.txt が存在する場合は、キャッシュされたバージョンを使用します。それ以外の場合は、以下を行います。
- Step 3 のトランスクリプトを読み込みます。
- 動画の内容を説明する短い要約文(2~3 文)を作成します。
- 主なトピックを網羅する、タイムスタンプ付きのチャプター一覧を
"MM:SS - Chapter Title"形式で作成します。 <presentation_folder>/outputs/chapters.txtに保存します。
Step 5: スライドのテキストを抽出する
PDF の各ページからテキストを抽出し、各スライドに実際に記載されている内容を確認できるようにします。これにより、埋め込みスクリーンショットやデモ画面のキャプチャを、実際のスライド内容と誤認することを防ぎます。
uv run .agents/skills/extract-slide-text/extract_slide_text.py <pdf_path> <presentation_folder>/outputs/slide_ascii.md <presentation_folder>/outputs/slide_images
<presentation_folder>/outputs/slide_ascii.md がすでに存在する場合はスキップします。
Step 6: スライドの概要を作成する
<presentation_folder>/outputs/outline.txt が存在する場合は、キャッシュされたバージョンを使用します。それ以外の場合は、以下を行います。
<presentation_folder>/outputs/slide_images/内のすべてのslide_*.pngファイルを見つけ、数値順に並べます。- Step 5 の正解データとして、
<presentation_folder>/outputs/slide_ascii.mdを読み込み、各スライドのテキスト内容を確認します。 - 各スライドの画像を確認し、1 文で要約します。要約は主に
slide_ascii.mdから抽出したテキストに基づき、画像は視覚的な文脈(図、レイアウト、スクリーンショット)の把握にのみ使用します。 - 大規模なプレゼンテーション(50 枚以上のスライド)の場合は、50 枚ずつ処理します。
<presentation_folder>/outputs/outline.txtに保存します。
ステップ 7:注釈付き記事を生成する
すべてのコンテキストを集めてから、以下のルールに従って記事を生成します。
集めるコンテキスト:
TRANSCRIPT— 全トランスクリプトのテキスト(ステップ 3)VIDEO_CHAPTERS— チャプターの概要(ステップ 4)SLIDE_TEXT—slide_ascii.mdから抽出したスライドごとのテキスト(ステップ 5)。各スライドの内容を確認する際の信頼できる情報源として使用します。SLIDE_OUTLINE— 番号付きのスライド概要(ステップ 6)VIDEO_SOURCE— YouTube の URL または presentation.md に記載された MP4 パスIS_LOCAL_VIDEO—VIDEO_SOURCEがローカルの MP4 ファイルの場合は trueSLIDES_HTML_CONTENT—slides_content.mdが存在する場合、その内容(RevealJS のみ)SLIDES_HTML_CONTENTに "SECTION HEADING" マーカーが含まれているか確認 →HAS_SECTION_HEADINGS
記事生成プロンプト:
各スライドの内容を説明する注釈付きブログ記事を作成します。
構成要件:
- 講演タイトルを含むレベル 1 の見出し(#)から始めます。
- 講演を紹介する概要の段落を続けます。
- 目次は含めないでください。目次は自動生成されます。
HAS_SECTION_HEADINGS が true の場合(セクションマーカー付きの RevealJS スライド):
- SECTION HEADING スライドにはレベル 2 の見出し(##)を使用します。これらはセクションの区切りです。
- 各セクション内の通常のスライドには、レベル 3 の見出し(###)を使用します。
HAS_SECTION_HEADINGS が false の場合:
- 各スライドの内容を表す説明的なタイトルを付けたレベル 2 の見出し(##)を使用します。
各スライドのセクションには、以下を含めます。
- 見出し
- 見出しの直後にスライド画像への参照:
 - 動画へのタイムスタンプ付きリンク(ローカル MP4 の場合は
[MM:SS]) - 説明文
最後に ## Q&A セクションを設け、質問と回答を含めます。各質問はレベル 3 の見出し(###)にします。
見出しの大文字・小文字:通常の文と同様に最初の文字を大文字にします。それ以外は、固有名詞と略語のみ大文字にします。
- 正しい例:"Hybrid search combines keyword and vector retrieval"
- 誤った例:"Hybrid Search Combines Keyword And Vector Retrieval"(タイトルケース)
構成例:
# Building intelligent agents with RAG
This talk introduces techniques for building AI agents...
## Hybrid search combines multiple retrieval methods

[Watch from 04:12](https://www.youtube.com/watch?v=VIDEO_ID&t=252s)
Hybrid search combines keyword search and vector search...
## Q&A
### How do I configure specific indexes as knowledge sources?
Answer text here...
執筆ガイドライン:
- 発表者用のメモのように書き、実際の情報を提示して仕組みを説明します。外側から講演を説明・分析しないでください。
- 発表者、スライド、講演が何をしたかを語らないでください。「発表者は説明します」「このスライドは示しています」「この講演は実演します」「このセクションでは話題が移ります」「この図は示しています」などの表現は禁止です。代わりに、内容を直接記述します。
- 繰り返しを避け、各文に情報を詰め込みます。
- 読者が動画を見なくても済むよう、スライドごとに十分な詳細を含めます。
- スライドには表示されていない、講演中の補足情報も取り入れます。
- 短い言葉を使い、簡潔に書きます。要点を先に述べます。
- 例を複数挙げるのは避け、1 つで十分なら 1 つにします。つなぎの余分な表現は削ります。
- 箇条書きより、流れるような文章を優先します。
- 平易な言葉を使います。絵文字は使用しません。例外が重要な場合を除き、曖昧な表現は避けます。
- 適切な場合は、スライド内の関連リンクを含めます。
- YouTube 動画の場合、タイムスタンプ付きリンクを作成します:[MM:SS] から視聴](VIDEO_SOURCE&t=SECONDSs)
- ローカル MP4 ファイルの場合は、
[MM:SS]形式のタイムスタンプのみを記載します。 - スライドは
slide_images/slide_1.png、slide_images/slide_2.pngのように参照します。
SLIDES_HTML_CONTENT が存在する場合は、記事に含める URL を探すために使用します。
ステップ 8:目次を挿入する
記事を生成した後、次の手順を実行します。
- 生成した Markdown 内にあるすべての
##見出しを探します。 - 各見出しからアンカーリンクを作成します。
- 小文字に変換します。
- 特殊文字を削除します(英数字、スペース、ハイフンは残します)。
- スペースをハイフンに置き換えます。
- 連続する複数のハイフンを 1 つにまとめます。
- 目次を作成します。
## Table of contents - [Heading text](#anchor-link) - [Another heading](#another-heading) - 最初の
##見出しの前(#タイトルと導入段落の後)に目次を挿入します。
ステップ 9:出力を保存する
最終的な記事を <presentation_folder>/outputs/writeup.md に保存します。
出力構造
<presentation_folder>/
├── presentation.md
└── outputs/
├── writeup.md ← Final output
├── transcript.txt ← Cached transcript
├── chapters.txt ← Cached video chapters
├── slide_ascii.md ← Extracted text per slide
├── outline.txt ← Cached slide outline
├── slides_content.md ← RevealJS extracted content (if applicable)
└── slide_images/
├── slide_1.png
├── slide_2.png
└── ...