社内説明スライドの数字、転記ミスが怖い?ClaudeのCode Executionで出典付きpptxを自動生成する

社内説明スライドの数字、転記ミスが怖い?ClaudeのCode Executionで出典付きpptxを自動生成する

AI実用ラボ│Ai活用で入社3年役付社員

AI実用ラボ│Ai活用で入社3年役付社員

目次
ユウ

AIにそのままスライド文章を書かせた方が早い気がします…わざわざ分ける必要ありますか?

ラボ長

AIに数字まで書かせると、丸めや転記でズレやすいんです。構成案とデータ埋め込みを分けると、数字の出どころを追えます。

Claude APIでKPI出典付きPowerPointを自動生成する方法

【中級者向け】Claude APIキーを取得済み、またはこれから取得してPythonスクリプトを実行できる人向けです。

JSON・CSVの基本、Pythonの基本文法は分かっている前提で進めます。

「社内スライドをAIに作らせたのに、肝心のKPIの数字が毎回“ちょっとだけ”違う」。

この問題は、経営企画・営業企画・カスタマーサクセスで、KPIを資料へ移すときに起こり得ます。

企画メモには「四半期の伸び」を説明する文章があり、KPI数値表(CSVなど)には「売上」「解約率」「NPS」などの数字が整然と並んでいます。

しかし、AIがそれを読み取ってスライド文章にまとめた瞬間に、丸め方(小数点の扱い)、転記の桁、単位の書き換えが“微妙に”ずれてしまうと、元の根拠が分からなくなります。

結果として、発表前の確認時間が増え、チェックのたびに疑念が積み上がります。

TL;DR - AIにスライドの数値を「書かせる」のではなく、AIには構成案(設計図)だけを作らせ、実際の数値はKPIデータからコードが直接埋め込む設計にすると、転記ミス・数値の捏造の入り込む余地を構造的に減らせる。 - Claude公式のStructured Outputs(型安全なJSON生成)とCode execution tool(python-pptx同梱のサンドボックス実行)を組み合わせれば、企画メモとKPI数値表から出典付きの社内説明スライド(.pptx)を生成できる。 - 生成後に「数値が元データと一致しているか」「出典参照があるか」「1枚に詰め込みすぎていないか」を検査すれば、修正が必要な箇所を絞り込める。

この記事でできること

  • Structured OutputsとCode execution toolを組み合わせて、企画メモ+KPI数値表から出典付きの社内説明用pptxと発表者ノートを生成する設計ができるようになります。
  • スライド本文の数値をAIに書き写させず、元データから直接埋め込むことで、数字の捏造・転記ミスを防ぐ設計を理解できます。
  • 生成結果の数値一致・出典参照の有無・1枚あたりの文字量を機械的に検査するスクリプトの設計を、自分の業務に合わせて再利用できます。
  • コンテナの制限(30日失効・ネット不可・事前installedライブラリのみ)を踏まえた運用上の注意点が分かります。

対象読者

経営企画・営業企画・カスタマーサクセスなど、企画メモとKPI数値表から社内説明スライドを作る担当者を想定しています。

Claude APIキーを取得済み、またはこれから取得してPythonスクリプトを実行できることが前提です。

JSON・CSVの基本、Pythonの基本文法は既知として進めます。

プログラミング未経験の方は、まず社内のエンジニアやAI活用担当と一緒に試すことをおすすめします。

この記事で使うサンプル

企画メモとKPI表は説明用の架空データです。

実データを使う場合は、社内の情報管理ルールを確認し、必要に応じて社名・顧客名・実数値を置き換えてください。

公式資料へのリンクは末尾にまとめています。

---

さらに厄介なのは、間違いが「致命的な崩れ」ではなく「人間の注意をかいくぐるレベル」で起きることです。

数字が0.1%違う、あるいは四捨五入の結果が一桁ズレる、といった差は、スライドを見る側にとって“説明の誤差”に見えてしまいます。

そのため、社内説明が進むほど、訂正コスト(説明し直し・資料差し替え・関係者への再共有)が膨らみます。

ここでの本質は、スライドの見た目が綺麗かどうかではなく、「KPIの数字と出典が、機械的にも人間的にも追える状態になっているか」です。

企画資料としての品質を守るには、"作る"だけでなく"照合できる形で作る"必要があります。

ここで重要なのは、AIに数字を文章として転記させるよりも、最終的な数値をKPI数値表(CSV)からコード側で直接埋め込む方針に切り替えることです。Structured OutputsはJSONの型に沿った出力を強く制約でき、さらにCode execution tool側ではpython-pptx(PowerPoint生成のライブラリ)が使えるため、スライドの数値を「生成テキスト」ではなく「データ照合済みの値」に寄せられます。

実務でのよくある場面を、もう少し具体化します。あなたが企画メモ(Markdown)とKPI数値表(CSV)を用意し、AIに「社内説明スライドにして」と頼みます。すると、スライドの各箇所に数字が入りますが、その数字がどこ由来かが曖昧になります。そこで最初にやるべき確認は2つです。(1) スライド内の数値が、元CSVのどの行・どの列か追えるか、(2) 丸め・単位がCSVと同じルールで出ているか。この2点が崩れると、たとえスライドの文章が正しくても、数字の信頼が揺れます。

この問題が厄介な理由は、単なる作業の面倒さではありません。社内の意思決定は、企画資料に書かれたKPIで行われるからです。そこで次の節では、構成案を先にJSON化し、pptx生成、最後に機械検査までを一つの流れにして、最初から"転記ミスが入りにくい設計"にする全体像を示します。

全体像:構成案JSON化→pptx生成→機械検査の3段構え

次に示すのは、企画メモとKPI数値表から社内スライドを作るための全体フローです。ポイントは、「AIがスライドを書き切る」ではなく「AIは設計図(構成案)を作り、数値はデータから確定させる」ことです。この方針なら、数字の丸めや転記をAI任せにせず、KPIの根拠を追いやすくできます。

まず1段目は、Structured Outputsでスライド構成案をJSONにします。スライド1枚ごとに「タイトル」「使うKPI行のID」「発表者ノート」を用意します。ここでの狙いは、Claude APIが自由形式の文章で数値を出す場面を減らし、スライドの"骨組み"だけを厳密な形で返させることです。Structured Outputsは、指定したJSONスキーマに合う形で出力させるため、項目の抜けや型崩れが起きにくくなります。

ここでの約束は、スライドに入れるKPI名と数値をJSONに書かないことです。AIが値を写したり丸めたりする余地をなくすため、JSONにはCSV行のIDだけを置きます。コードはIDからKPI名と表示値を読み込み、出典IDと一緒に表示します。

次に、Code execution toolでpython-pptxを使い、pptxを生成します。

JSONのKPI行IDを使い、コードがCSVからラベルと表示値を読み込みます。

python-pptxはスライドをプログラムで作るライブラリで、サンドボックスに事前インストールされています。

サンドボックスから外部サイトへ接続できませんが、添付ファイルはAPIへアップロードされます。

通信遮断だけを理由に社内データを送ってよいと判断しないでください。

加えて、Code execution toolの仕様として、生成ファイルは出力ディレクトリ(`$OUTPUT_DIR`)直下に置いたものだけがファイルとして返されます。`$OUTPUT_DIR`直下に生成物を保存し、応答に`file_id`が含まれることを確認できれば、Files APIから取得できます。数値をCSVからコードで入れる設計は、手作業の転記箇所を減らします(コンテナは30日で失効するなどの制約もありますが、これは後半の「運用時の注意」で扱います)。

そして3段目が、機械検査です。

保存したpptxをPythonで読み直し、(1) KPIのラベル・値・出典IDが元CSVと一致するか、(2) 想定したスライド枚数か、を確認します。

文章量の上限はスライド様式に合わせて別途設定します。

「見た目は良いけど数値が怪しい」という状態を機械で潰し、差分のあるスライドを特定できます。

もし検査で数値一致が崩れるスライドが見つかったら、戻る場所は「スライド文章の手直し」ではなく「出典参照とCSV参照の対応」です。

Structured Outputsで返した出典参照がズレていたのか、コード側の参照ロジックが意図と違うのかを切り分けます。

こうすると、原因が"数字を直感で直す"方向に逃げません。

構成案JSON化→pptx生成→機械検査の3段構え

この全体フローは「Claude API」「Code execution tool」「Structured Outputs」「python-pptx」を組み合わせます。

Structured OutputsはJSONの形をそろえ、Code execution toolはpptxを生成し、機械検査は指定した値と出典IDがファイルに残ったかを確認します。

文章の妥当性やKPIの定義までは機械検査だけで保証できません。

続く手順では、Structured OutputsのJSON Schema、Files APIで入力を渡す方法、pptx生成コード、数値と出典IDの読み戻し確認、応用例と注意点を順に説明します。

手順1:企画メモとKPI数値表からStructured Outputsでスライド構成案JSONを作る

社内スライドで起きがちな失敗は「数値の転記ミス」です。

KPI数値表(CSV)にある数値を、企画メモから作ったスライド原稿に手で書き写してしまい、桁や行の取り違えが起きます。

このミスは、見た目の文章だけ直しても根が消えないため、後から発覚すると関係者の信頼を一気に落とします。

だからこそ、最初の段階で"数値を文章に書き写させない"設計にします。

そこで登場するのがStructured Outputsです。Claude APIに「この形のJSONで返して」と指定し、返答を定義したJSON Schemaに沿わせる機能です。ここでは、スライドごとの`title`・`source_refs`(使うKPI行のID)・`notes`をJSON化します。KPIのラベルや実数値はClaudeに書かせず、`source_refs`だけを選ばせます。こうすると、モデルが数値を写し間違える場面を避け、どのCSV行を使ったかも追いやすくなります。

Structured Outputsのスキーマ制限として、`minItems`は0か1のみ、数値・文字列の細かい制約や再帰スキーマ、外部`$ref`は非対応です。つまり、文字数や数値の範囲をSchemaで厳密に縛るより、あとでPython側の検査で弾く設計が安全です。

手順1のゴール(作りたいJSONの形)

この節のゴールは、「社内スライドの構成案JSON」を作ることです。

具体的には、以下を含むJSONを返してもらいます。

  1. `slides[]`:スライドごとのタイトル
  2. `slides[].source_refs[]`:表示するKPI行のID
  3. `slides[].notes`:数字を含めない発表者ノート

数値とラベルはモデルに書かせず、コードがCSVから読み込みます。

最重要は「数値そのものをJSONに書かない」ことです。

JSONの役割は"設計図"であり、実値の注入は次の手順(Code execution toolでpython-pptx生成)に任せます。

実装の考え方:Claudeには数値を書かせず、出典参照だけ書かせる

Claude APIへの依頼文(プロンプト)では、企画メモを構成案にまとめるよう頼みます。

KPIの数字やラベルは書かせず、CSVのIDだけを選ぶよう次の指示を入れます。

  • 「スライド本文の数字やKPI名は生成せず、CSVにあるIDだけを`source_refs`へ入れる」
  • 「タイトルと発表者ノートにも、CSVの値やそこから推測した傾向を書かない」
  • 「JSONはスキーマに必ず適合させる(Structured Outputs)」

Structured OutputsはJSONの形を型安全にしてくれるため、後段でPythonが扱いやすくなります。

公式ドキュメントでも、厳密なJSONスキーマ適合が必要な場面ではStructured Outputsの利用が案内されています。

たとえばKPI数値表に「今期の解約率」「来月の商談数」などが載っているとします。

ClaudeにはKPIの値やラベルを作らせません。

次のような構成案を返させます。

{
  "slides": [
    {
      "title": "月ごとの解約率",
      "source_refs": ["churn_2026_04", "churn_2026_05"],
      "notes": "数値の変化を説明し、背景は確認済みの情報だけを話す。"
    }
  ]
}

この設計では、Claudeが数字を写す工程をなくします。コードは`source_refs`のIDをKPI表から引き、CSVのラベルと値をスライドへ配置します。

期待結果と確認方法

期待結果は、「Claude APIが返したJSONが、そのままパースできる」ことです。

具体的な確認は次の通りです。

  1. 返ってきたレスポンスがJSONとして正しく解析できること
  2. `slides`が想定の形式で存在すること
  3. 各`source_refs`のIDがCSVに存在すること
  4. タイトルと発表者ノートにKPI値がなく、値と出典IDはCSVからコードが挿入すること

もし失敗した場合は、プロンプト(出典参照の書き方の指示)か、スキーマ(必須項目や配列構造)を調整して、スライド構成案JSONの生成をやり直します。

ここが崩れると次段のpython-pptx生成で整合が崩れ、修正コストが跳ね上がるため、pptx生成へ進む前にここを確定させることが重要です。

APIリクエストの骨格(Structured Outputs)

次の例では、会議の目的と使ってよいKPI IDをメッセージに含めます。実データのKPI値はこの段階では送らず、構成案が返った後、次の手順でCSVと一緒に扱います。スキーマはClaude公式の`output_config.format`形式に、本記事の項目を当てはめています。

curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-opus-5-5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "次の企画メモをもとに社内説明用のスライド構成案を作ってください。タイトルとノートにKPIの数値を書かないでください。source_refsには利用可能なIDだけを入れてください。\n\n企画メモ: 解約率の月次推移を共有し、次回会議で確認する質問を整理する。\n利用可能なKPI: churn_2026_04(解約率), churn_2026_05(解約率)"}],
    "output_config": {
      "format": {
        "type": "json_schema",
        "schema": {
          "type": "object",
          "properties": {
            "slides": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "title": {"type": "string"},
                  "source_refs": {"type": "array", "items": {"type": "string"}},
                  "notes": {"type": "string"}
                },
                "required": ["title", "source_refs", "notes"],
                "additionalProperties": false
              }
            }
          },
          "required": ["slides"],
          "additionalProperties": false
        }
      }
    }
  }'

`additionalProperties: false`を各階層に付けることで、想定外のフィールド(たとえば数値をそのまま書いた`value`フィールドなど)が紛れ込むのを防げます。スキーマ側で防げない「本文中に数値が混ざる」ケースは、前述の通りプロンプトの指示と、後段の機械検査で潰します。

ユウ

JSON Schemaでガチガチに縛れば安全じゃないですか?

ラボ長

実はStructured Outputsには数値制約や再帰スキーマが使えない制限があるんです。だから検査はコード側に寄せるのが安全です。

手順2:Code execution toolでpython-pptxを使いpptxファイルを生成する

次に、手順1のスライド構成案JSONとKPI数値表から.pptx(PowerPoint)を生成します。

数値やラベルはモデルの返答ではなく、CSVからコードが読み込んで挿入します。

その実行基盤としてCode execution toolを使います。Code execution toolは、APIリクエストの`tools`に追加して使い、サンドボックス内でPythonを実行できます。事前インストール済みのライブラリとしてpython-pptxが含まれているため、ネット接続なしでもPowerPointファイルを作れます。コード側では、JSON(スライド設計)を読み取り、CSV(KPIデータ)から該当する`source_refs`を引いて、その実値をスライドの本文に差し込みます。

手順2の前提(必要な道具・制約)

ここで使う道具は以下です。

  • Claude API(Code execution toolを呼ぶ側)
  • python-pptx(スライドを組み立てるライブラリ、Code execution toolのサンドボックスに事前インストール済み)
  • スライド構成案JSON(手順1の出力)
  • KPI数値表(CSV)

Code execution toolの実行環境には制約があります。

公式ドキュメントによると、実行環境はPython 3.11/Linuxコンテナで、メモリ5GiB、ディスク5GiB、CPU1です。

ネットワーク接続は完全に遮断されています。

加えてコンテナは30日で失効し、5分操作がないとチェックポイントされます(30日以内なら再利用可)。

このため、外部URLへ取りに行く処理は設計に入れられません。

ファイル出力のルールも重要です。コード実行時に、生成ファイルは`$OUTPUT_DIR`の直下に置く必要があります。そうすると生成物がファイルとして返され、Files APIで`file_id`を使って取得できます。「どこに保存するか」を間違えると、生成されたはずのpptxが手元で見えません。

Code execution toolにKPI表と構成案を渡す

Code execution toolは、リクエストに加えたツールをClaudeが必要に応じて呼び出す仕組みです。コードをMessages APIへ直接入れるのではなく、Claudeへ実行内容を依頼します。構成案JSONとCSVはFiles APIへアップロードし、メッセージ内の`container_upload`で渡します。Files APIは現在ベータヘッダーなしで使えます。

次の例は、作成済みの`slide_plan.json`と`kpi.csv`を添付し、Code execution toolにPowerPoint作成を依頼します。`generate_deck.py`も添付し、Pythonコード自体を固定しておくと、生成手順を再利用できます。実行する側にはPython 3.10以上とAnthropic公式Python SDKが必要です。SDKの導入例は次の通りです。APIキーは環境変数`ANTHROPIC_API_KEY`などの秘密管理手段に登録します。Files APIにアップロードしたファイルはワークスペース内で共有され、明示的に削除するか有効期限に達するまで保存されます。顧客情報や社内限定情報を含むファイルは、組織の利用ルールとアクセス範囲を確認してから扱ってください。有効期限はアップロード時に設定でき、1時間から90日まで指定できます。

pip install anthropic
from pathlib import Path
from anthropic import Anthropic

client = Anthropic()  # ANTHROPIC_API_KEYを環境変数から読み込む
uploaded_ids = []
created_ids = []
try:
    plan_file = client.files.upload(file=Path("slide_plan.json"))
    uploaded_ids.append(plan_file.id)
    kpi_file = client.files.upload(file=Path("kpi.csv"))
    uploaded_ids.append(kpi_file.id)
    script_file = client.files.upload(file=Path("generate_deck.py"))
    uploaded_ids.append(script_file.id)

    response = client.messages.create(
        model="claude-opus-5-5",
        max_tokens=4096,
        tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
        messages=[{
            "role": "user",
            "content": [
                {"type": "text", "text": (
                    "添付の構成案JSON、KPI CSV、Pythonスクリプトを使ってください。"
                    "3つの添付ファイルを同じ作業場所に置き、Pythonスクリプトを実行してください。"
                    "生成物を$OUTPUT_DIR直下へ保存し、保存後に開き直して確認してください。"
                )},
                {"type": "container_upload", "file_id": plan_file.id},
                {"type": "container_upload", "file_id": kpi_file.id},
                {"type": "container_upload", "file_id": script_file.id},
            ],
        }],
    )

    for block in response.content:
        if block.type != "bash_code_execution_tool_result":
            continue
        result = block.content
        if result.type != "bash_code_execution_result":
            continue
        created_ids.extend(
            item.file_id for item in result.content if getattr(item, "file_id", None)
        )

    if not created_ids:
        raise RuntimeError("出力ファイルが返っていません。Code execution toolの結果を確認してください")
    for file_id in created_ids:
        metadata = client.files.retrieve_metadata(file_id)
        client.files.download(file_id).write_to_file(metadata.filename)
        print(f"取得しました: {metadata.filename}")
finally:
    for file_id in uploaded_ids + created_ids:
        client.files.delete(file_id)

APIキーは環境変数などの秘密管理手段へ置き、コードや記事、ログに直接書かないでください。生成結果の`bash_code_execution_tool_result`内にある`file_id`を取り出し、Files APIからダウンロードします。Code execution toolの実行料金とMessages APIのトークン料金にはそれぞれ条件があります(次節を参照)。アップロードしたファイルはワークスペース内で共有されます。この例は完了後にアップロード元と生成物を削除します。組織で定められた情報管理ルールに沿ってデータを選んでください。

生成スクリプトの例

以下は、CSVのIDからラベル・表示値を取り出してスライドに埋め、保存したpptxを開き直して出典付きの行が残っているか確認する例です。`slide_plan.json`の`source_refs`だけをモデルに選ばせ、数字・ラベル・出典表示はコードが作ります。

import csv
import json
import os
from pathlib import Path
from pptx import Presentation

HERE = Path(__file__).resolve().parent
plan = json.loads((HERE / "slide_plan.json").read_text(encoding="utf-8"))
with (HERE / "kpi.csv").open(encoding="utf-8-sig", newline="") as f:
    rows = list(csv.DictReader(f))

kpi = {}
for row in rows:
    key = row["id"]
    if not key or key in kpi:
        raise ValueError(f"KPI IDが空、または重複しています: {key}")
    if not row.get("label") or not row.get("value_display"):
        raise ValueError(f"KPIのlabel/value_displayが不足: {key}")
    kpi[key] = row

slides = plan.get("slides", [])
if not slides:
    raise ValueError("slidesが空です")

prs = Presentation()
expected = []
for spec in slides:
    refs = spec.get("source_refs", [])
    if not refs:
        raise ValueError("各スライドにsource_refsが必要です")
    title = spec.get("title", "").strip()
    if not title or any(ch.isdigit() for ch in title):
        raise ValueError("タイトルが空、または数字を含んでいます")
    slide = prs.slides.add_slide(prs.slide_layouts[1])
    slide.shapes.title.text = title
    frame = slide.placeholders[1].text_frame
    frame.clear()
    source_lines = []
    if len(set(refs)) != len(refs):
        raise ValueError("source_refsに重複IDがあります")
    for index, ref in enumerate(refs):
        if ref not in kpi:
            raise ValueError(f"CSVに存在しないID: {ref}")
        row = kpi[ref]
        line = f"{row['label']}:{row['value_display']}(出典ID: {ref})"
        paragraph = frame.paragraphs[0] if index == 0 else frame.add_paragraph()
        paragraph.text = line
        source_lines.append(line)
    notes = spec.get("notes", "")
    if any(ch.isdigit() for ch in notes):
        raise ValueError("発表者ノートに数値を直接書かず、確認済みの説明を使ってください")
    expected_notes = notes + "\n" + "\n".join(source_lines)
    slide.notes_slide.notes_text_frame.text = expected_notes
    expected.append((title, source_lines, expected_notes))

out_dir = Path(os.environ.get("OUTPUT_DIR", "."))
out_path = out_dir / "slide_deck.pptx"
prs.save(out_path)

# 保存後のpptxを読み直し、各スライドにCSV由来の値と出典IDが残っているか確認
saved = Presentation(out_path)
errors = []
if len(saved.slides) != len(expected):
    errors.append("スライド枚数が構成案と一致しません")
for index, (slide, (title, lines, expected_notes)) in enumerate(zip(saved.slides, expected), start=1):
    text = "\n".join(shape.text for shape in slide.shapes if shape.has_text_frame)
    if slide.shapes.title.text != title:
        errors.append(f"スライド{index}のタイトルが構成案と一致しません")
    if len(text) > 100:
        errors.append(f"スライド{index}の表示文字数が100字を超えています: {len(text)}")
    for line in lines:
        if line not in text:
            errors.append(f"スライド{index}にCSV由来の表示行がありません: {line}")
    notes_text = slide.notes_slide.notes_text_frame.text
    if expected_notes not in notes_text:
        errors.append(f"スライド{index}の発表者ノートが保存後に一致しません")
if errors:
    raise SystemExit("\n".join(errors))
print(f"OK: {len(saved.slides)}枚を作成し、CSV値と出典IDを保存後に確認しました")

`slide_plan.json`はStructured Outputsで作成し、`kpi.csv`は次のような列を用意します。`value_display`は「2.7%」「1,250,000円」のように表示したい書式を含めた文字列です。

id,label,value_display
churn_2026_04,解約率,3.1%
churn_2026_05,解約率,2.7%

`source_refs`に存在しないIDやCSV側の重複IDは、pptxを作る前にエラーになります。`python-pptx`はスライドのノート欄も扱えます。数字と出典をコードが機械的に入れるため、AIの説明文が正しいか、期間比較の意味が正しいかまではこのスクリプトでは判断できません。たとえば「改善した」という評価は、元データと定義を人が確認してから入れてください。

python-pptxでスライドを組み立てる

python-pptxでは、スライドごとに次のような処理を行います。

  • スライド枚数ぶんループする
  • 各スライドの`title`を配置する
  • `source_refs[]`を読み取り、出典参照`source_refs[]`からCSVの行を引く
  • 実値を含む文章を組み立て、箇条書きとして配置する
  • `notes`を発表者ノートとして設定する

この例では、JSONの`source_refs`を使ってCSVの表示値を本文に追加します。モデルが返すのはIDだけなので、数値・ラベル・出典IDの表示文字列はCSVからコードが組み立てます。python-pptxでスライドを追加し、テキストを書き、pptxとして保存する処理をCode execution tool内で行います。

生成物の確認手順

この段階での期待結果は、`.pptx`が作成されて、スライドに次が入っていることです。

  • タイトルが入っている
  • 箇条書きが入っている
  • 各KPI行に、CSVの値と出典IDが表示されている
  • 発表者ノートにも`notes`が入っている

確認の手順は、まず`file_id`を受け取って、それでダウンロードできることを確かめます。その上で、PowerPointで開き、該当スライドの文字と数値が想定通りか目視確認します。ただし、この段階ではPowerPointで文字のはみ出しや配置を確認します。機械検査は次の手順で行います。

失敗時の戻り方

失敗パターンはいくつかあります。

  1. pptxファイルが返ってこない → `$OUTPUT_DIR`へ保存できていない可能性があります。まず保存パスとファイル名を確認します。
  2. スライドの数が想定より少ない/多い → 手順1のJSONが意図した構造になっているかを確認します。`slides`配列の解釈ミスが起きやすいです。
  3. 箇条書きの数値が空欄や「不明」になる → `source_refs`とCSVのキー(行・列の対応)が一致していない可能性があります。構成案のIDとCSVのIDを照合し、誤ったIDなら構成案を修正します。CSV値がpptxに反映されない場合は、コードの参照・配置処理を確認します。
  4. スライドの文章に想定外の数値が入っている → JSON側に数値が紛れ込んでいるケースです。手順1の設計("数値を書かせない指示")へ戻ります。

原則として、手順1と手順2の役割分担を守れば、原因切り分けが速くなります。

手順3:生成物を検査する(数値一致・出典参照・1枚あたりの文字量)

最後にやることは、出来上がった社内スライドが「元データと合っているか」を機械的に検査することです。

ここで手を抜くと、せっかく自動生成しても転記ミスが残ります。

出典参照(どのKPIを根拠にしているか)が本文から消えると、説明の場で根拠の追跡ができません。

だから、検査項目を最初に固定し、落ちたスライドだけ作り直す運用にします。

生成スクリプトの末尾に、保存したpptxを読み戻す検査を組み込んでいます。

検査方針(3つの観点)

検査は最低でも次の3点を見ます。

  1. 数値を含む文章に出典参照があるか
  2. 出典参照先の数値と本文の数値が一致しているか
  3. 1枚あたりの文字量が閾値を超えていないか

これにより、「数値の転記ミス」「根拠抜け」「読みづらさ」の3種類の問題を同時に潰せます。

特に1つ目と2つ目は、KPIの説明責任に直結します。

検査スクリプトの設計

検査スクリプトは次のように役割分担します。

  • 入力:手順1のスライド構成案JSON、元のKPI数値表(CSVまたはJSON)、生成されたスライド(.pptx)
  • 処理:
  • 構成案の`slides[]`と保存後のスライドを対応させる
  • CSVのIDから期待する「ラベル・値・出典ID」の行を作る
  • 保存したpptxのスライド本文に、その行が存在するか照合する
  • スライド枚数と必要なら1枚あたりの文字量を確認する

掲載スクリプトは、値と出典IDの読み戻し確認を実行します。

保存後の確認は、生成スクリプトの最後にある読み戻し処理で行います。期待する表示行は`CSVのlabel/value_display + 出典ID`からコードが作り、保存したpptxの各スライド内に同じ行があるか比較します。また、参照IDがCSVに存在しない場合は生成前に止めます。

この検査で分かるのは「指定したCSVの値と出典IDがスライドに残ったか」です。

値が最新か、KPIの定義や期間が正しいか、要約文の「増加」「改善」が妥当かは別途確認が必要です。

スライド上の文字数検査はレイアウト崩れを見つける目安であり、見た目の確認を置き換えるものではありません。

文字量の上限も組織のスライド様式に合わせて設定し、タイトルや注記を含めるかを決めてください。

判定ロジックで注意したいのは、数値一致の判定を"文字列の一致"に寄せすぎないことです。

フォーマット(カンマ、%記号、桁区切り、小数桁など)が変わると、見た目が一致していても厳密比較で落ちることがあります。

実運用では「元データの値を表示形式に整形してから比較する」処理を挟むと事故に強くなります。

Structured Outputsのスキーマ制限の話と同様に、文字量の上限はSchemaで縛らず、Python側で検査します。

スキーマは"形"の保証に集中させ、閾値のようなビジネスルールはコード側に置く、という役割分担です。

「検査に落ちたスライドだけ再生成」する運用

検査をしたら、次の運用ルールを決めます。

  • 合格したスライドはそのまま採用する
  • 不合格のスライドだけ作り直す
  • 全体を作り直さない(コストと手戻りを抑える)

戻る場所は明確です。

「出典参照がない・不正なら手順1の構成案へ、CSV値が一致しないならCSV参照やコードへ、表示文字数が上限を超えたらスライドの情報量へ戻ります。

応用パターン:複数部署向けテンプレートの使い分けと既存スライドの差分更新

社内スライドは、部署が変わると「見た目」も「章立て」も変わります。

営業企画は「商談→パイプライン→受注」の流れを重視し、カスタマーサクセスは「導入→活用→更新」の流れを重視する、といった具合です。

企画資料のKPIも部署ごとに違うため、スライド構成を毎回ゼロから作ると、転記ミスの温床になります。

テンプレート(配色・章立て・見出し粒度)を部署ごとに分けつつ、同じ仕組みで社内スライドとKPIを自動生成したいところです。

狙いはシンプルで、テンプレートは"構成案JSON側"で切り替え、数字は"コード側でデータから埋める"ように分業します。これにより、モデルに数字の書き写しをさせない設計(捏造防止)を保ったまま、部署ごとの見た目と運用の違いを吸収できます。

部署別テンプレートを構成案JSONで切り替える

テンプレートを「配色・章立て・スライド種別(例:目的、現状、KPIサマリ、打ち手)」の集合として扱います。部署や会議体を示す`template_id`は、構成案JSONとは別にアプリケーション設定で管理します。

  • `template_id`とPowerPointテンプレートの対応表
  • 構成案JSONに含めるスライド(タイトル、出典参照、ノート)
{
  "slides": [
    {
      "title": "今月のKPI一覧",
      "source_refs": ["sales_revenue", "sales_orders"],
      "notes": "会議で確認する論点を説明する。"
    }
  ]
}

この例のJSONスキーマには`template_id`を含めていません。テンプレートを切り替える場合は、アプリケーション側で許可済みの`template_id`とPowerPointテンプレートを対応付け、同じ構成案JSONを選んだテンプレートへ渡す処理を追加します。数値は引き続き`source_refs`からCSVを引いてコードが配置します。

テンプレートを増やすときの設計ルール

テンプレートを複数部署分に増やすと、次に起きがちな問題は「どこを変えたらいいか分からなくなる」ことです。

おすすめの順番は次の通りです。

  1. 章立て(スライド種別の順序)をテンプレート側に定義する
  2. 見た目(配色、フォント、余白、レイアウト)をPowerPointのテンプレートにまとめる
  3. 表示するKPI IDを構成案へ記録し、CSVの行と照合する

章立てが揺れると、既存スライドとの照合ロジックが複雑になり、差分更新が難しくなります。一方、配色は見た目だけの差分なので、章立てを固定すれば差分更新の検知もしやすくなります。`template_id`には「部署名」だけでなく「会議体」も含めると事故が減ります。「営業企画×月次」と「営業企画×四半期」では章立てが変わりやすいので、`sales_monthly_v1`/`sales_qtr_v1`のように分けます。

部署別テンプレートの分岐と差分更新のイメージ(数値は説明用の例です)

既存スライドの差分更新:KPIだけ差し替えて全体を作り直さない

月次更新の運用では、理想は「同じ構成案JSONと同じテンプレートで、KPIだけ新しい数値を流し込む」ことです。実運用では企画メモの一部だけ修正されたり、打ち手の文章が変わったりするため、"全部再生成"ではなく"差分だけ再生成"が有効です。

この方式では、ワークフローを次の2段に分けます。

  • 段1:Structured Outputsでスライド構成案JSON(数値は"出典参照"だけ)
  • 段2:python-pptxでデータから実値を埋め、さらに機械検査(一致チェック)をする

この掲載スクリプトは毎回pptx全体を作り直します。

APIを再度呼び出さずに済ませたい場合は、既存の構成案JSONを保存し、更新が必要なスライドだけを同じCSV参照ロジックで差し替える処理を別途用意します。

差分更新は設計上の応用案であり、このコードだけで実行される機能ではありません。

他の作成手段との比較

社内スライド作成では、次の選択肢が現場に出ます。

選択肢向いている場面注意点
人手でPowerPointを作るKPIが少なく数字の整合チェックがそこまで厳密でない場合数字が多いほど転記ミスの発見コストが高くなる
別のAIサービスで自動生成する手早く見た目を作りたい場合数値と出典の機械照合まで自前で組む必要がある場合が多い
Claude API + Code execution tool + python-pptxKPIが主役で数字一致が重要、部署別テンプレが多い、差分更新を回したい場合初回の作り込みコストが重いので、月次で構成が大きく変わらないチームから始めるとスムーズ

判断基準は"数値の正しさ"と"差分更新の必要性"です。

数字の裏取りが必要な場面ほど、構成案を型安全に寄せてデータを機械的に埋める今回の方式との相性が良くなります。

運用時の注意:コンテナ30日失効・ネット接続不可・事前installedライブラリのみという制約への対処

社内スライドの自動生成を運用に乗せると、実行環境の制約という壁が来ます。Code execution toolは、Python 3.11/Linuxコンテナ/x86_64の環境で動作し、メモリやディスク、CPUにも上限があります。さらに重要なのは、インターネット接続が完全に遮断されていることです。実行中に追加ライブラリをインストールして解決する、という発想は使えません。

加えて、コンテナは30日で失効します。期限を過ぎたら、前のコンテナIDを使わず、新しいリクエストとして開始します。

30日失効とチェックポイントを踏まえた運用

Code execution toolのコンテナは作成から30日で失効します。

約5分操作がない状態はチェックポイントであり、30日以内なら同じコンテナIDを指定して再開できます。

チェックポイント自体は失敗ではありません。

  • 構成案JSONの生成(Claude API側)と、スライド生成(Code execution tool側)を分ける
  • Code execution tool側では、「ファイル読み込み→python-pptxで生成→保存→読み戻し確認」までを1回にまとめる
  • 5分の無操作でコンテナがチェックポイントされても、30日以内はIDを指定して再開できる。これは失敗ではない

失敗したときの戻り先も決めておきます。

たとえば月次運用で失敗が起きた場合、①その月は前月の完成版にテンプレは同じでKPIだけ差し替える想定で暫定対応する、②数値だけ差し替え文面は据え置く運用に切り替える、のいずれかを事前にルール化しておくと、コンテナ期限やチェックポイントで止まっても業務が止まりません。

ネット接続不可:追加ライブラリを前提にしない

Code execution toolではインターネット接続が完全に遮断されており、実行時にライブラリをインストールできません。

必要なライブラリは"事前に入っているもの"に依存する必要があります。

公式ドキュメントに明記されている事前installedライブラリには、PowerPoint生成に必要なpython-pptxのほか、python-docx、pandas、openpyxlなども含まれます。

スライド生成の核はpython-pptxに寄せるのが安全です。

実務的には、「やりたいこと」を(A)事前installedライブラリで実現できる部分と、(B)追加のライブラリがないと厳しい部分に分けます。

Bをこの仕組みに持ち込むほど運用時の詰まりが増えるため、表や数値整形、画像配置などはpython-pptxで完結できる設計に寄せ、どうしても外部依存が必要な処理は別の実行環境に分離するのが安全です。

料金の注意:web検索・web取得併用と単体利用の差

料金は使い方によって変わります。

web searchまたはweb fetchツールを同じAPIリクエストに含める場合、Code execution tool自体の追加料金はありません。

含めない場合は実行時間課金となり、実行時間は1回あたり最低5分で計上されます。

組織あたり月1,550時間までは無料、超過分は1時間・コンテナあたり0.05米ドルです。

ファイルを添付すると、ツールが呼び出されなくても実行時間の課金対象になります。

別途、Messages APIの入出力トークンも課金されます。

実際の請求はAPIレスポンスのusageと管理画面で確認してください。

運用設計では「必要なときだけCode execution toolを呼ぶ」「呼び出し回数を増やしすぎない」が効きます。

差分更新を導入すると、KPIが崩れたスライドだけ生成するため呼び出しが減り、コストにも直結します。

入力ファイル(企画資料、KPIデータ)と生成成果物(pptx)を役割ごとに整理し、必要最小限の添付に留めることも意識してください。

ユウ

せっかく作ったpptxがFiles APIから取れないことがあるって聞いて不安です…

ラボ長

$OUTPUT_DIRの直下に保存されていないのが原因です。保存先とファイル名を最初に確認しましょう。

エラー対処(3パターン)・早見表・まとめ

社内スライドの自動生成で起きやすいトラブルは、だいたい型が決まっています。

ここでは、(1)生成ファイルが取得できない、(2)JSON Schema制約で構成案が作れない、(3)コンテナが30日を超えて再利用できない、という3パターンに絞って対処を示します。

パターン1:生成ファイルが`$OUTPUT_DIR`直下に置かれず取得できない

Code execution toolでは、生成ファイルを`$OUTPUT_DIR`直下に置いたものだけが`file_id`として返る仕組みです。スクリプトが別のフォルダに保存していたり、ファイル名の扱いがズレたりすると、Files APIでダウンロードしようとしても取得できません。

対処手順は次の通りです。

  1. 保存先を確認する:`.pptx`の保存処理が必ず`$OUTPUT_DIR`直下を指しているか見直す
  2. ファイル名を固定する:`slide_deck.pptx`のように固定名に寄せ、拡張子も含めて確実に一致させる
  3. Code execution toolの返却内容(content一覧)を確認する:`file_id`が返っていない場合、保存先の問題を疑う

期待結果は「`file_id`が返り、Files APIでダウンロードできる」ことです。保存まわりだけに絞って直すのがコツで、全生成ロジックを一度に触ると原因が見えなくなります。

パターン2:JSON Schemaの制約に引っかかって構成案が作れない

Structured Outputsは、JSON Schemaに沿った出力を保証しますが、Schema自体に制約があります。`minItems`は0か1のみ、`minimum`/`maximum`などの数値制約は非対応、再帰スキーマ・外部`$ref`は非対応です。スキーマを理想通りの制約でがちがちにすると、出力が作れない状況が起き得ます。

対処は「制約を減らして、検査はコード側に寄せる」ことです。

  1. Schemaの制約を"必要な構造"だけ残す(数値の範囲などはSchema側で縛らず、出典セル参照として設計し、実値はコード側で埋める)
  2. 検査(バリデーション)をPython側の機械検査に寄せる(数値一致や出典参照の有無などは、生成後に機械照合する)

変更は1つずつ行い、どれが原因だったか切り分けます。

パターン3:コンテナが30日を超えて失効し、再利用できない

コンテナは30日で失効します。

失効した場合、前の環境のまま再実行しても動きません。

対処の順番は次の通りです。

  1. 失敗時のログで、実行の開始段階で落ちていないか確認する
  2. 同じ入力(企画メモ、KPIデータ、テンプレートID、出力方針)を使って再実行する
  3. 差分更新で"最小の再実行"にする(月次更新では差分だけ再生成すれば、再実行回数も減る)

コンテナ失効は"環境の問題"なので、数字やテンプレのロジックまで同時に変えないほうが原因を追いやすくなります。

早見表

状況典型原因(仕様由来)まず確認すること次の一手
pptxが取得できない`$OUTPUT_DIR`直下に保存されていないと`file_id`が返らない保存先が`$OUTPUT_DIR`を指しているか、拡張子が.pptxか保存先・ファイル名を最小修正し再実行
構成案JSONが作れないSchema制約に非対応要素(再帰、外部`$ref`、数値制約など)Schemaに再帰・外部`$ref`・`minimum`/`maximum`がないか制約を削り、検査をコード側へ寄せる
30日以降に動かないコンテナが30日で失効実行開始段階で失敗していないか同じ入力で再実行し、差分更新で回数を減らす
ユウ

結局、一番守るべきポイントはどこですか?

ラボ長

数値はAIに書かせず、コードがデータから埋めること。ここさえ守れば、転記ミスはかなり減らせます。

まとめ

  • 部署別テンプレートはアプリケーション側の許可済み`template_id`とファイルの対応表で切り替える
  • Structured Outputsは"構成案の型"に使い、数値は出典セル参照に留める(数字の捏造を避ける)
  • python-pptxは元データの実値を埋める役に徹する(一致検査で運用の安心を作る)
  • Code execution toolは`$OUTPUT_DIR`直下保存と`file_id`取得を最優先で確認する
  • Schemaでがちがちに縛らず、制約が厳しいものはコード側の機械検査に寄せる
  • コンテナ30日失効とチェックポイントを前提に、短いバッチで回し、戻り手順を決める
  • インターネット遮断なので、追加ライブラリ前提の設計にしない
  • 料金や添付による課金に配慮し、必要な実行回数と添付を最小化する

この方針で回すと、社内スライドのKPIが"元データと一致しているか"を運用の中心に置けます。

結果として、転記ミスの不安を減らし、企画メモとKPI数値表から毎月スムーズに社内説明のアウトプットへつなげられます。

参考にした公式情報

  • Anthropic Python SDK(Messages APIなどの公式クライアント) https://platform.claude.com/docs/en/cli-sdks-libraries/overview (確認日: 2026-09-28)
  • Code execution tool(python-pptx事前インストール、Files API入力、$OUTPUT_DIR出力、コンテナ仕様・料金・データ保持) https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool (確認日: 2026-09-28)
  • Files API(ファイルの利用、保存期間、アップロード後の取り扱い) https://platform.claude.com/docs/en/build-with-claude/files (確認日: 2026-09-28)
  • python-pptx Notes Slides(発表者ノートの書き込み) https://python-pptx.readthedocs.io/en/latest/user/notes.html (確認日: 2026-09-28)
  • Structured Outputs(JSON Schema厳密出力、スキーマ制限) https://platform.claude.com/docs/en/build-with-claude/structured-outputs (確認日: 2026-09-28)
  • Increase output consistency(出力フォーマット指定・例示による制約などの一貫性向上手法) https://platform.claude.com/docs/en/test-and-evaluate/strengthen-guardrails/increase-consistency (確認日: 2026-09-28)

この記事が少しでも参考になったら、AI実用ラボをフォローしていただけるとうれしいです。初心者にも分かりやすいAI活用情報をこれからもお届けします。


あなたも記事の投稿・販売を
始めてみませんか?

Tipsなら簡単に記事を販売できます!
登録無料で始められます!

Tipsなら、無料ですぐに記事の販売をはじめることができます Tipsの詳細はこちら
 

この記事の販売者

AI実用ラボ│Ai活用で入社3年役付社員

仕事や暮らしの面倒な作業を、AIで少し楽にする方法を紹介します。専門知識がない方にも分かるよう、準備・操作・完成例・確認方法を順番に説明。必要な道具や費用、つまずいた時の対処もまとめます。難しい言葉はできるだけ使わず、必要な用語はその場で説明します。まずは身近な作業から、無理なくAIを試したい方に向けた情報をお届けします。

この販売者が書いた他の記事

  • Claude CodeのMCPツール説明文に2,048字上限、実際のサーバーで測ってみた

  • Claudeの教科書:初めての人のための使い方ガイド(全11章)

    ¥1,480
    1 %獲得
    (14 円相当)
  • AIが書いたGitHub Actions、マージ前に確認する3点:権限・SHA固定・pull_request_target

関連のおすすめ記事

  • ゼロから3日で始動|AIコンサル大全

    ¥124,800
    1 %獲得
    (1,248 円相当)
    水口一星

    水口一星

  • 【AI自動化・マネタイズ実例書】たった2週間〜機械オンチなママでもできた全作業過程

    ¥37,800
    1 %獲得
    (378 円相当)
    みお

    みお

  • 【5年更新型コンテンツ】AIを最大活用するためのリテラシー強化バイブル

    ¥59,800
    1 %獲得
    (598 円相当)
    こはく

    こはく