Langchainとpython-pptxによるスライド生成を試してみる

すでに本格的に取り組まれている方がいらっしゃいますが、自分もpython-pptxの勉強も兼ねて動かしてみます。

https://zenn.dev/aidemy/articles/69af8390f6ec3b

# python-pptx

PythonからPowerPointファイルを操作できるライブラリ。

https://python-pptx.readthedocs.io/en/latest/index.html

> *python-pptx*は、PowerPoint (.pptx) ファイルを作成、読み取り、更新するためのPythonライブラリです。
>
> 一般的な使用例としては、データベースクエリ、分析結果、またはJSONペイロードなどの動的コンテンツからPowerPointプレゼンテーションを生成し、HTTPリクエストに応答して生成されたPPTXファイルをダウンロードすることが考えられます。これは、macOSやLinuxを含むPython対応プラットフォームで動作し、PowerPointアプリケーションのインストールやライセンスは不要です。

# Langchainとの連携

ChatGPTに教えてもらいながら動かします。`langchainからプレゼンを作る方法`などで、基本的なコードも教えてもらいました。

```py
%pip install -Uq langchain openai python-pptx mlflow langchain-openai
%restart_python
```

```py
import os
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from pptx import Presentation

# APIキー設定
os.environ["OPENAI_API_KEY"] = dbutils.secrets.get("demo-token-takaaki.yayoi", "openai_api_key")
```

```py
import mlflow
# MLflow Tracingの有効化
mlflow.langchain.autolog()
```

マークダウンをそのまま渡してもスライドでは反映されないの、教えてもらったものからプロンプトは少し変更しています。

```py
# モデル設定
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0.7)

# プレゼンのテーマを入力
topic = "エージェントシステムの日本における導入事例"

# プロンプト作成
prompt = ChatPromptTemplate.from_template("""
あなたはプレゼンテーション資料を作成するAIアシスタントです。
以下のトピックについて、プレゼンテーションの構成を作成してください。
トピック：{topic}

構成：
・タイトルスライド（プレゼンのタイトル）
・概要（目的や背景）
・導入事例（3つ程度）
・まとめ

指示：
・マークダウンは使わないでください
・python-pptx への入力を想定してください
""")

# チェーンの構築
chain = prompt | llm
# チェーンの呼び出し
outline = chain.invoke({"topic": topic}).content
```

![Screenshot 2025-03-10 at 13.39.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ce757059-b00b-49fc-82b0-6b1d73ba2ed6.png)

まずは、生成AIにアウトラインを作成してもらうということですね。

```py
outline
```
```
'タイトルスライド\n- タイトル: エージェントシステムの日本における導入事例\n- 副題: 効率化と革新の実現\n- 日付: [プレゼンテーションの日付]\n- 発表者: [発表者の名前]\n\n概要\n- エージェントシステムとは何か\n- 日本におけるエージェントシステムの導入背景\n- 目的: エージェントシステムがもたらす利点と実際の影響を理解する\n\n導入事例\n1. 事例1: 企業Aの顧客サポートエージェント\n   - 概要: 顧客からの問い合わせに自動応答するシステム\n   - 導入の目的: サポート業務の効率化\n   - 結果: 応答時間の短縮と顧客満足度の向上\n\n2. 事例2: 企業Bの製造業向けエージェントシステム\n   - 概要: 生産ラインの監視と最適化を行うエージェント\n   - 導入の目的: 生産効率の向上\n   - 結果: コスト削減と生産性の向上\n\n3. 事例3: 企業Cのマーケティングエージェント\n   - 概要: 顧客データを分析し、ターゲット広告を自動生成するシステム\n   - 導入の目的: マーケティング戦略の最適化\n   - 結果: 広告効果の向上とROIの増加\n\nまとめ\n- エージェントシステムの導入がもたらした効果の総括\n- 今後の展望: 日本におけるエージェントシステムのさらなる普及の可能性\n- 質疑応答の時間を設ける旨の案内'
```

そして、これらをバラして`python-pptx`への入力にすると。

```py
# スライド生成
presentation = Presentation()

for slide_content in outline.split("\n\n"):
    slide = presentation.slides.add_slide(presentation.slide_layouts[1])
    title, *body = slide_content.strip().split("\n")
    slide.shapes.title.text = title
    slide.placeholders[1].text = "\n".join(body)

# 保存
presentation.save("agent_system_presentation.pptx")
```

別のスライドも作ってみます。

```py
topic = "カレーライスの作り方"
outline = chain.invoke({"topic": topic}).content
```
![Screenshot 2025-03-10 at 13.41.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/18d8dfbc-b215-4a72-98e7-4dd47b1e2a8c.png)

```py
# スライド生成
presentation = Presentation()

for slide_content in outline.split("\n\n"):
    slide = presentation.slides.add_slide(presentation.slide_layouts[1])
    title, *body = slide_content.strip().split("\n")
    slide.shapes.title.text = title
    slide.placeholders[1].text = "\n".join(body)

# 保存
presentation.save("curry_rice.pptx")
```

ノートブックと同じパスにPowerPointファイルが作成されるのでダウンロードします(ノートブックでレンダリングする方法を探しましたが見つからず)。

![Screenshot 2025-03-10 at 13.41.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/bf97b109-fb4b-4146-89e4-4c0573717e22.png)


**エージェントシステムの導入事例**

![Screenshot 2025-03-10 at 13.43.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a5dd3bda-8cf6-4289-948b-ff51f8a7c6a3.png)
![Screenshot 2025-03-10 at 13.43.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/eade2e7f-a95c-46ef-9422-77a62425c88f.png)
![Screenshot 2025-03-10 at 13.43.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b698b086-a6a2-4d88-8eb0-8a0f4423df54.png)

**カレーライスの作り方**

プロンプトのテンプレート自体を変えていなかったので、なかなかシュールなプレゼンに。

![Screenshot 2025-03-10 at 13.44.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/37bbf503-81ac-4cf1-b38c-69a577acf9c0.png)
![Screenshot 2025-03-10 at 13.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/57e9ddd6-ee33-4cb6-8d8e-cea1be1bff36.png)
![Screenshot 2025-03-10 at 13.44.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8941f1a0-b2ce-4276-9eb7-9009be1c84db.png)

まあ、元記事の方が苦戦されているように、レイアウトやテイストを洗練させるにはプレースホルダーにテキストなどを埋め込むようにした方が良いのかもしれません。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)