こんにちは。
「会社のテンプレートを使ったパワーポイント資料をAIに作ってもらいたい」
そんなシンプルな願いから始まった開発が、企業環境の壁にぶつかり、最終的に思わぬ形で解決した話をお届けします。
この記事は、Kiro(AI搭載IDE)とAnthropic Claude Opus(今回使用したKiroのバックエンドLLM)を用いて開発した記録です。実際にKiroと会話しながら実装し、試行錯誤した過程をそのままお伝えしています。
開発環境
Kiroとは?
Kiroは、AWSが提供するAI搭載の統合開発環境(IDE)です。
主な特徴:
- Spec駆動開発: 仕様書(Spec)をAIと一緒に作りながら開発を進めるスタイル。要件定義→設計→タスク分解→実装を一貫してサポート
- AIとの対話: チャットしながらコードを書ける
- ローカル実行: Pythonスクリプトなどをローカルで実行可能
- IDE版とCLI版: デスクトップアプリとコマンドライン両方で使える
- Web検索機能: 最新情報を取得してコードに反映
Anthropic Claudeとは?
Claudeは、Anthropic社が開発した大規模言語モデル(LLM)です。
主な特徴:
- 高い推論能力: 複雑なコーディングタスクも的確に処理
- 長いコンテキスト: 大量のコードや仕様書を一度に理解
- 安全性重視: 有害なコンテンツを生成しにくい設計
今回の開発では、KiroのバックエンドモデルとしてClaude Opus 4.6を使用しました。Kiroに話しかけると、Claude Opusが考えてコードを生成してくれます。
開発スタイル
私: 「パワポを自動生成する機能を作りたい」
Kiro: 「いいね!まずは要件を整理しよう...」
↓
Spec作成 → 設計 → 実装 → テスト
↓
私: 「ここ、ちょっと違うかも」
Kiro: 「了解!修正するね」
このように、会話しながら開発を進められるのがKiro + Claudeの強みです。
開発のきっかけ
みのるんさん(@minorun365)が公開しているパワポつくるマンを見て、「これ、社内でやりたい!」と考えました。
名前の使い分け: みのるんさんのツールが「パワポつくるマン」、わたしがKiroで作ったのが「パワポつくるちゃん」です。
パワポつくるマンは、AIが情報を集め、Markdownを組み立てて、スライドを自動生成する素敵なツール。でも、会社のPowerPointテンプレートを使いたい...
そして、社内のルールが厳しいので、みのるんさんのアプリをそのまま利活用するのは難しい...
そこで思いついたのが、社内で利用可能な Copilot Studio + Code Interpreter での実現でした。
目指したアーキテクチャ
┌─────────────────────────────────────────────────────────┐
│ Microsoft 365 環境 │
├─────────────────────────────────────────────────────────┤
│ Teams / Copilot Studio UI │
│ ↓ │
│ Copilot Studio Agent (GPT-4.1) │
│ ↓ │
│ Code Interpreter (python-pptx) │
│ ↓ │
│ Power Automate → SharePoint Online │
└─────────────────────────────────────────────────────────┘
- フロントエンド: Teams / Copilot Studio チャットUI
- AI処理: Copilot Studio Agent + GPT-4.1
- コード実行: Code Interpreter (python-pptx)
- ワークフロー: Power Automate エージェントフロー
- ストレージ: SharePoint Online
完璧なプランに見えました...この時点では。
Step 1: SharePointセットアップ
まずはSharePointにテンプレートと生成ファイルを保存するライブラリを作成。
-
PPTXTemplates(テンプレート格納) -
GeneratedPresentations(生成ファイル格納)
Step 2: Copilot Studioエージェント作成
エージェント名は、みのるんさんのアプリにあやかって「パワポつくるちゃん」に決定。
設定内容
- モデル: GPT-4.1 (Standard)
- プロンプトアクション①: スライド構成生成(JSON出力)
- プロンプトアクション②: PPTX生成(Code Interpreter有効)
- Web検索: Bing検索を有効化
プロンプトアクション①: スライド構成生成
Copilot Studioで「プロンプトアクション」を作成し、以下の設定を行います。
アクション名: Generate-Slide-Structure
入力パラメータ:
| 名前 | 型 | 説明 |
|---|---|---|
| Theme | テキスト | プレゼンテーションのテーマ |
| AdditionalInstructions | テキスト(オプション) | 追加指示(スライド枚数、対象者など) |
プロンプト指示:
あなたはプレゼン資料の構成を考えるエキスパートです。
ユーザーが入力したテーマ「{Theme}」に基づいて、プレゼンテーションのスライド構成を考えてください。
追加指示: {AdditionalInstructions}
## 出力形式
以下のJSON形式で出力してください。JSONのみを出力し、説明文は不要です。
{
"metadata": {
"theme": "プレゼンテーションのテーマ",
"createdAt": "ISO8601形式の日時",
"slideCount": スライド数,
"targetAudience": "対象者(指定がない場合は「一般」)"
},
"slides": [
{
"slideNumber": 1,
"layoutType": "title",
"title": "プレゼンタイトル",
"subtitle": "サブタイトル(オプション)",
"notes": "発表者ノート(オプション)"
},
{
"slideNumber": 2,
"layoutType": "content",
"title": "スライドタイトル",
"content": {
"type": "bullet_points",
"items": ["ポイント1", "ポイント2", "ポイント3"]
},
"notes": null
}
]
}
## レイアウトタイプ
以下のレイアウトタイプを適切に使い分けてください:
- title: タイトルスライド(1枚目に使用)
- content: コンテンツスライド(箇条書き)
- two_column: 2カラムレイアウト(比較や対比に使用)
- section_header: セクション区切り(大きなセクションの開始時)
- blank: 白紙スライド(画像のみの場合など)
## ルール
1. 1枚目は必ず title レイアウトのタイトルスライド
2. 最後は「まとめ」または「ご清聴ありがとうございました」のスライド
3. 各スライドの箇条書きは3〜5個程度
4. ビジネス向けの簡潔な表現を使用
5. 追加指示でスライド枚数が指定されていない場合は5〜8枚程度
Step 3: スライド構成生成の確認 → 成功!
テーマを入力すると、Web検索で情報を集めて、JSON形式でスライド構成を自動生成!
{
"metadata": { "theme": "AWS Ambassador", "slideCount": 6 },
"slides": [
{ "slideNumber": 1, "layoutType": "title", "title": "AWS Ambassador とは?" },
{ "slideNumber": 2, "layoutType": "content", "title": "プログラムの概要", "content": {...} }
]
}
ここまでは順調でした。
プロンプトアクション②: PPTX生成(Code Interpreter)
重要: このアクションでは Code Interpreter を有効 にする必要があります。
アクション名: Generate-PPTX-From-Template
入力パラメータ:
| 名前 | 型 | 説明 |
|---|---|---|
| SlideStructure | テキスト | スライド構成のJSON文字列 |
| TemplateFile | ファイル | 会社テンプレート(.pptx) |
| UserId | テキスト | ユーザー識別子 |
設定:
- Code Interpreter: 有効
- 出力: ドキュメント/画像
プロンプト指示:
以下のスライド構成データ {SlideStructure} と、
添付されたPowerPointテンプレート {TemplateFile} を使って、
新しいプレゼン資料を生成してください。
ユーザーID: {UserId}
## 処理手順
1. テンプレートファイルを読み込む
2. テンプレートの既存スライドを削除(マスターは保持)
3. スライド構成に従って新しいスライドを追加
4. 各スライドはテンプレートのレイアウトを使用
5. ファイル名にタイムスタンプとユーザーIDを含める
## Pythonコード
以下のコードを実行してPPTXファイルを生成してください:
(以下のPythonコードをプロンプトに含める)
Code Interpreter用Pythonコード:
クリックしてPythonコードを展開
from pptx import Presentation
from pptx.util import Inches, Pt
import json
from datetime import datetime
import re
# スライド構成をパース
slide_structure = json.loads('''{SlideStructure}''')
# テンプレート読み込み
prs = Presentation('template.pptx')
# 既存スライドを削除(マスターは残る)
while len(prs.slides) > 0:
rId = prs.slides._sldIdLst[0].rId
prs.part.drop_rel(rId)
del prs.slides._sldIdLst[0]
# レイアウトマッピング(テンプレートに合わせて調整)
# ※ご自身のテンプレートに合わせてインデックスを変更してください
layout_mappings = {
"title": 0, # タイトルスライド
"content": 1, # タイトルとコンテンツ
"two_column": 3, # 2つのコンテンツ
"section_header": 2, # セクション見出し
"blank": 6 # 白紙
}
def get_layout(layout_type):
idx = layout_mappings.get(layout_type, 1)
if idx >= len(prs.slide_layouts):
idx = 1
return prs.slide_layouts[idx]
def add_title_slide(slide_data):
layout = get_layout("title")
slide = prs.slides.add_slide(layout)
if slide.shapes.title:
slide.shapes.title.text = slide_data.get("title", "")
subtitle = slide_data.get("subtitle")
if subtitle:
for shape in slide.placeholders:
if shape.placeholder_format.idx == 1:
shape.text = subtitle
break
def add_content_slide(slide_data):
layout = get_layout("content")
slide = prs.slides.add_slide(layout)
if slide.shapes.title:
slide.shapes.title.text = slide_data.get("title", "")
content = slide_data.get("content", {})
items = content.get("items", [])
for shape in slide.placeholders:
if shape.placeholder_format.idx == 1:
tf = shape.text_frame
tf.clear()
for i, item in enumerate(items):
if i == 0:
tf.paragraphs[0].text = item
else:
p = tf.add_paragraph()
p.text = item
p.level = 0
break
def add_two_column_slide(slide_data):
layout = get_layout("two_column")
slide = prs.slides.add_slide(layout)
if slide.shapes.title:
slide.shapes.title.text = slide_data.get("title", "")
content = slide_data.get("content", {})
left_col = content.get("leftColumn", {})
right_col = content.get("rightColumn", {})
placeholders = list(slide.placeholders)
# 左カラム
if len(placeholders) > 1:
tf = placeholders[1].text_frame
tf.clear()
if left_col.get("header"):
tf.paragraphs[0].text = left_col["header"]
tf.paragraphs[0].font.bold = True
for item in left_col.get("items", []):
p = tf.add_paragraph()
p.text = item
# 右カラム
if len(placeholders) > 2:
tf = placeholders[2].text_frame
tf.clear()
if right_col.get("header"):
tf.paragraphs[0].text = right_col["header"]
tf.paragraphs[0].font.bold = True
for item in right_col.get("items", []):
p = tf.add_paragraph()
p.text = item
def add_section_header_slide(slide_data):
layout = get_layout("section_header")
slide = prs.slides.add_slide(layout)
if slide.shapes.title:
slide.shapes.title.text = slide_data.get("title", "")
subtitle = slide_data.get("subtitle")
if subtitle:
for shape in slide.placeholders:
if shape.placeholder_format.idx == 1:
shape.text = subtitle
break
# スライド追加
for slide_data in slide_structure["slides"]:
layout_type = slide_data.get("layoutType", "content")
if layout_type == "title":
add_title_slide(slide_data)
elif layout_type == "content":
add_content_slide(slide_data)
elif layout_type == "two_column":
add_two_column_slide(slide_data)
elif layout_type == "section_header":
add_section_header_slide(slide_data)
else:
slide = prs.slides.add_slide(get_layout("blank"))
# ファイル名生成
def sanitize(text):
text = re.sub(r'[<>:"/\\|?*]', '', text)
text = re.sub(r'\s+', '_', text)
return text[:50]
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
theme = sanitize(slide_structure["metadata"]["theme"])
user_id = sanitize("{UserId}")
filename = f"{theme}_{user_id}_{timestamp}.pptx"
# 保存
prs.save(filename)
print(f"生成完了: {filename}")
テンプレートのレイアウト確認方法
自分のテンプレートのレイアウトインデックスを確認するには、以下のPythonコードを使います。
from pptx import Presentation
prs = Presentation('your_template.pptx')
for i, layout in enumerate(prs.slide_layouts):
print(f"{i}: {layout.name}")
Step 4: PPTX生成...しかし
Code Interpreterでpython-pptxを実行 → 成功!(のハズ)
PPTXファイル生成完了のメッセージが表示され、ダウンロードリンクも出てきました。
...しかし、クリックしても何も起きない。
Microsoft TeamsにAgentを公開しても状況変わらず。ファイルは生成されているハズなのに、ダウンロードができない!
立ちはだかるDLPの壁
「Power Automateでファイルを保存すればいいのでは?」
しかし... DLPポリシー(データ損失防止ポリシー)でブロック!
トリガー: エージェントがフローを呼び出したとき
アクション: SharePointにファイルを作成
エラー: コネクタが競合しています
- SharePoint (ビジネス)
- Direct Line channels in Copilot Studio (非ビジネス)
会社のセキュリティポリシーが厳格で、SharePointコネクタとCopilot Studioの組み合わせが許可されていませんでした。
代替案を模索
仕方ないので、以下のような代替案を考えました。
| No. | 案 | 結果 |
|---|---|---|
| 1 | Base64エンコードで出力しローカルで復号化 | PPTXファイルは大きすぎて非現実的 |
| 2 | 会社提供の生成AIチャットBot | Sharepoint出力対応はこれから |
| 3 | IT管理者にDLPポリシー例外申請 | 恐らく承認されない |
そこで思いついたのが...
Kiroをパワポつくるちゃんに!
発想の転換: これまで伴走してもらっていた Kiro 自身をパワポつくるちゃんになってもらう。
前述の通り、KiroはAWSが提供するAI搭載IDE。ローカルでPythonスクリプトを実行できます。
つまり、以下のような環境を想定しました。
┌─────────────────────────────────────────┐
│ 環境 │
├─────────────────────────────────────────┤
│ Kiro (IDE版 or CLI版) │
│ ↓ │
│ slide_builder.py (python-pptx) │
│ ↓ │
│ ローカルにPPTX保存 │
└─────────────────────────────────────────┘
パワポつくるちゃんにおけるKiroの強み
冒頭でKiroの概要を紹介しましたが、今回のパワポ生成において特に活きたポイントは以下の通りです。
- Web検索機能内蔵: テーマに関する最新情報を取得してスライドに反映
- 生成物をローカルに保存: Python スクリプトの実行はローカルなので、DLPポリシーに抵触しない
- 会話しながらPPTX生成: 構成を確認→修正→生成のサイクルが速い
- Spec駆動開発: slide_builder.pyの設計から実装まで一貫してサポート
- IDE版とCLI版の連携: 同じワークスペースでどちらからでも作業可能
Kiro版「パワポつくるちゃん」の実装
slide_builder.py - スライド生成ライブラリ
Kiro版では、slide_builder.pyというライブラリを作成しました。Markdown風の記法でスライドを定義できます。
slide_builder.pyの特徴
Kiro に相談しながら少しずつブラッシュアップを重ねて、以下のような機能を作りこんでいきました。
- 会社テンプレート対応(レイアウトインデックスを調整可能)
- Markdown風の書式(例:
##で見出し、-で箇条書き) - PPTネイティブの箇条書き機能を使用(編集時も箇条書きが維持される)
- テーブルスライドも対応
- メソッドチェーンで直感的に記述可能
- アジェンダ(目次)スライド対応
- 章扉(セクション区切り)スライド対応
- Closingスライド対応
- 番号付きリスト(
1. テキスト)対応 - コードブロック(
```で囲む)→ ダーク背景+黄緑文字のターミナル風表示 - 本文が長い場合の自動スライド分割(プレースホルダー高さベースの動的計算)
- タイトルが長い場合のフォントサイズ自動縮小
Markdown風記法の全ルール
| 記法 | 意味 | 例 |
|---|---|---|
## テキスト |
小見出し(太字) | ## 本日のアジェンダ |
- テキスト |
箇条書き(レベル1) | - 項目1 |
- テキスト |
サブ箇条書き(レベル2) | - サブ項目 |
1. テキスト |
番号付きリスト | 1. 最初の項目 |
1. テキスト |
サブ番号付きリスト | 1. サブ項目 |
``` 〜 ```
|
コードブロック(ターミナル風) | コマンドやコード |
| 通常テキスト | 箇条書きなし | これは通常テキストです |
| 空行 | 空白行 | "" |
スライド種別一覧
| メソッド | 説明 |
|---|---|
add_cover(title) |
表紙スライド |
add_agenda(title, items) |
アジェンダ(目次)スライド |
add_section(section_title) |
章扉スライド(セクション区切り) |
add_body(section_title, lines) |
本文スライド(自動分割・コードブロック対応) |
add_table(section_title, headers, rows) |
テーブルスライド |
add_closing() |
Closingスライド |
最終的な動作
Kiroに作ってほしいテーマをプロンプトで指定することで、スライドを作ってくれます。
例えば、「AWS Ambassadorについて5枚のスライドを作って」と話しかけるだけで、Web検索で最新情報を取得し、会社テンプレートを使ったPPTXファイルを生成してくれます。
# Kiroが内部で実行するコード例
from slide_builder import SlideBuilder
sb = SlideBuilder("output/aws_ambassador.pptx")
sb.add_cover("AWS Ambassador とは?")
sb.add_body("今日話すこと", [
"## アジェンダ",
"- AWS Ambassadorプログラムの概要",
"- 認定要件と特典",
"- 活動内容の紹介",
])
# ... 以下続く
sb.save()
成果物は以下のようになりました。
AWS Ambassador について 5枚のスライドを作って の例
Anthropic Claude のライセンス形態についてまとめて の例
必要に応じて、この成果物を直接編集したり、 Kiro に修正させてブラッシュアップします。
問題なければそのまま使ってもOK。
既存資料の読み込み機能
「この資料を参考にしてスライドを作って」という使い方もできます。
doc_to_markdown.py - PPTX/Word → Markdownに変換
既存のPPTXファイルやWordファイルをMarkdownに変換して、Kiroが読み取れるようにするスクリプトです。
from doc_to_markdown import convert_to_markdown, convert_folder
# 単一ファイル変換
convert_to_markdown("資料.pptx")
# フォルダ内の全ファイルを変換
convert_folder("C:\\資料フォルダ")
使い方の例:
Kiroに対して以下のように指示するだけ:
「C:\資料\企画書.pptx と C:\資料\要件定義.docx を
参考にして、プロジェクト概要のスライドを10枚で作って」
「C:\資料\ フォルダの中身を参考にしてスライド作って」
Kiroが自動で:
- PPTX/Wordファイルをスクリプトで変換
- 変換されたMarkdownを読み込み
- 内容を把握してスライドを作成
Kiro IDE版とCLI版の連携
Kiro IDE版とkiro-cli(CLI版)を同じワークスペースで実行することで、どちらからでもスライドを作ることが可能です。
# CLI版でパワポ作成
kiro-cli chat "AWS Ambassadorについて5枚のスライドを作って"
IDE版で修正したコードは、CLI版でもそのまま使えます。その逆も同様です。
学び
- 企業環境にはよっては、DLPポリシーなどの制約がある
- うまくいかなくても代替案を探す。 クラウドがダメならローカル
- AIツールは使い分けが大事。 Copilot Studio、Kiro、それぞれに得意分野がある
- 発想の転換。 制約を回避する方法は必ずある
-
python-pptxは奥が深い。 箇条書きの制御にはXMLレベルの操作(
a:buChar、a:buNone、a:lstStyleなど)が必要で、python-pptxのAPIだけでは完結しなかった
補足:Copilot Studioで成功させるには
DLPポリシーが許可されている環境であれば、Copilot Studioでの実現は可能です。
なお、Code Interpreterで実行するPythonコードは開発途中のため、完璧に動作させるには追加の実装が必要です。
以下のポイントを確認してください。
-
DLPポリシーの確認: IT管理者に以下のコネクタの組み合わせが許可されているか確認
- SharePoint コネクタ
- Direct Line channels in Copilot Studio
-
Power Automateフローの設定:
- トリガー: 「エージェントがフローを呼び出したとき」
- アクション: 「SharePointにファイルを作成」
-
Copilot Studioのアクション設定:
- 「アクション」タブ → 「フローを追加」
- 作成したPower Automateフローを選択
もしDLPに抵触する場合は、この記事で紹介したKiro版「パワポつくるちゃん」をお試しください!
まとめ
Copilot Studioでの実現は叶いませんでしたが、結果的にKiroを用いた使い勝手の良いツールを生み出せました。
「パワポつくるちゃん」は今、Kiroとともに元気に動いています。会社のテンプレートを使って、会話しながらスライドを生成してくれます。
企業環境でのAIの利活用は制約が多くありますが、それを乗り越える過程で新しい発見があるものですね。
記載されている会社名、製品名、サービス名、ロゴ等は各社の商標または登録商標です。

