😽

Azure上でAssistants APIとDALL·E-3を使用してスライドを作成する

2024/03/22に公開
  • こちらを参考にして実施していきます。
  • 新しいAssistants API(GPT-4)とDALL·E-3を使用して、データから洞察を抽出し魅力的なスライドを迅速に作成するプロセスを探ります。
  • PowerPointやGoogle Slidesを直接操作することなく、Assistants APIを活用することでスライド作成のプロセスをどのように簡素化し、加速するかを解説します。

0.setup

カレントディレクトリにdataとimagesのフォルダを作成しておく。
Jupyter notebook等で操作することを想定してます。

%pip install pandas pyarrow
%pip install pandas
api_endpoint = "https://<YOUR_RESOURCE_NAME>.openai.azure.com"
api_version = "2024-02-15-preview"
api_key = "<AOAI_RESOURCE_API_KEY>"
api_deployment_name = "<DEPLOYMENT_NAME>"
from IPython.display import display, Image
from openai import AzureOpenAI
import os
import pandas as pd
import json
import io
from PIL import Image
import requests
client = AzureOpenAI(api_key=api_key, api_version=api_version, azure_endpoint=api_endpoint)


#Lets import some helper functions for assistants from https://cookbook.openai.com/examples/assistants_api_overview_python
def show_json(obj):
    display(json.loads(obj.model_dump_json()))

def submit_message(assistant_id, thread, user_message,file_ids=None):
    params = {
        'thread_id': thread.id,
        'role': 'user',
        'content': user_message,
    }
    if file_ids:
        params['file_ids']=file_ids

    client.beta.threads.messages.create(
        **params
)
    return client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant_id,
)

def get_response(thread):
    return client.beta.threads.messages.list(thread_id=thread.id)

Azure OpenAIを使用したAssistants APIの利用

Azure OpenAIのクライアントを作成し、Assistants APIを使用してメッセージを送信し、レスポンスを取得するプロセスについて説明します。

  1. Azure OpenAIクライアントの作成
  • 必要な情報: APIキー、APIバージョン、Azureエンドポイント。これらはAzureポータルから取得します。
  • クライアント作成は、上記の情報を用いて行います。
  1. show_json 関数の定義
  • 目的: モデルの出力を人間が読みやすいJSON形式で表示します。
  • 方法: 与えられたオブジェクトのmodel_dump_jsonメソッドを呼び出し、結果を解析して表示します。
  1. submit_message 関数
  • 機能: 指定されたアシスタントID、スレッド、ユーザーメッセージ(および任意のファイルID)を使用してアシスタントにメッセージを送信します。
  • 実装: client.beta.threads.messages.create メソッドを使用し、メッセージ送信後に client.beta.threads.runs.create メソッドで新しいrun(実行)を作成します。
  1. get_response 関数
  • 機能: 指定されたスレッドのすべてのメッセージをリストとして取得し、アシスタントからのレスポンスを取得します。
  • 実装: client.beta.threads.messages.list メソッドを使用します。

1.コンテンツの作成

nyctaxi_data_path = 'https://d37ci6vzurychx.cloudfront.net/trip-data/green_tripdata_2022-12.parquet'
nyctaxi_data = pd.read_parquet(nyctaxi_data_path)
nyctaxi_data.head(5)

出力結果:

VendorID Pickup Datetime Dropoff Datetime Store and Forward Flag RatecodeID PULocationID DOLocationID Passenger Count Trip Distance Fare Amount Extra MTA Tax Tip Amount Tolls Amount Ehail Fee Improvement Surcharge Total Amount Payment Type Trip Type Congestion Surcharge
2 2022-12-01 00:32:58 2022-12-01 00:37:38 N 1.0 166 24 2.0 0.77 5.5 0.5 0.5 1.0 0.0 None 0.3 7.8 1.0 1.0 0.0
1 2022-12-01 00:26:49 2022-12-01 00:31:07 N 1.0 74 41 1.0 0.60 5.0 0.5 0.5 0.0 0.0 None 0.3 6.3 2.0 1.0 0.0
1 2022-12-01 00:20:23 2022-12-01 00:49:36 N 1.0 260 17 1.0 0.00 22.2 0.0 0.5 0.0 0.0 None 0.3 23.0 1.0 1.0 0.0
2 2022-12-01 00:20:23 2022-12-01 00:28:46 N 1.0 80 256 1.0 1.71 8.0 0.5 0.5 0.0 0.0 None 0.3 9.3 2.0 1.0 0.0
2 2022-12-01 00:09:12 2022-12-01 00:13:39 N 1.0 179 179 1.0 0.62 5.0 0.5 0.5 4.0 0.0 None 0.3 10.3 1.0 1.0 0.0
csv_file_path = 'data/green_tripdata_2022-12.csv'
nyctaxi_data.to_csv(csv_file_path, index=False)
print(f"CSVファイルが保存されました: {csv_file_path}")

出力結果:
CSVファイルが保存されました: data/green_tripdata_2022-12.csv

file = client.files.create(
  file=open('data/green_tripdata_2022-12.csv',"rb"),
  purpose='assistants',
)
print(file.id)

ファイルのアップロード

  • https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.pageから2022年12月のニューヨーク市のタクシーデータを取得します。
  • Parquetファイルがサポートされていないので、CSVファイル(green_tripdata_2022-12.csv)に変換しDataフォルダに格納します。
  • CSVファイルをAzure OpenAIのデータファイルにアップロードしファイルIDを取得します。
  • Azure OpenAI Studio上からもファイルを確認できます。

assistant = client.beta.assistants.create(
  name="NYC Taxi Assistant",
  instructions="あなたはデータサイエンティストのアシスタントです。データとクエリが与えられたとき、適切なコードを書き、適切な可視化を作成します",
  model=api_deployment_name,
  tools=[{"type": "code_interpreter"}],
  file_ids=[file.id]
)
show_json(assistant)

NYC Taxi Assistantの作成

このコードスニペットは、client.beta.assistants.createメソッドを使用して、"NYC Taxi Assistant"という名前の新しいアシスタントを作成する方法を示しています。このアシスタントは、データサイエンティストの補助として機能し、与えられたデータとクエリに基づいて適切なコードを記述し、適切な可視化を作成します。

コード解説

  • name: アシスタントの名前を指定します。この例では、"NYC Taxi Assistant"という名前が使われています。
  • instructions: アシスタントの指示または役割を説明するテキストです。ここでは、アシスタントがデータサイエンティストの助けとして機能し、データとクエリに応じてコードを書き、可視化を行うことが期待されています。
  • model: 使用するモデルを指定するapi_deployment_nameを含みます。この名前は、アシスタントがどのモデルまたはAPIデプロイメントに基づいて構築されるかを示します。
  • tools: アシスタントが利用するツールのリストです。この例では、{"type": "code_interpreter"}が指定されており、アシスタントがコードを解釈する能力を持つことを意味します。
  • file_ids: アシスタントが参照するファイルのIDのリストです。ここでは[file.id]が指定されており、アシスタントが特定のファイルにアクセスできるようになっています。

最後に、show_json(assistant)関数を使用して、作成されたアシスタントの詳細をJSON形式で表示します。これにより、アシスタントのプロパティと設定を簡単に確認できます。

thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": "24時間ごとに乗客数を表示してください。縦軸を乗客数、横軸を0-23時間で表示。乗客数によって色分け。",
      "file_ids": [file.id]
    }
  ]
)


run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
)

messages = client.beta.threads.messages.list(thread_id=thread.id)

Azure OpenAIアシスタントAPIを使用した質問への回答の取得

このブログ記事では、Azure OpenAIのAssistants APIを利用して特定の質問に対する回答を取得する方法を説明します。このプロセスは、新しいスレッドの作成、アシスタントの実行、および回答の取得の3つの主要なステップに分けられます。

  1. 新しいスレッドの作成
  • 使用メソッド: client.beta.threads.create
  • 機能: ユーザーからの質問や命令を含むメッセージリストを引数として、新しいスレッドを作成します。各メッセージはrole("user")、content(質問や命令のテキスト)、およびfile_ids(関連ファイルのIDリスト)を持つ辞書形式です。
  1. アシスタントの実行
  • 使用メソッド: client.beta.threads.runs.create
  • 機能: スレッドIDとアシスタントIDを引数として、新しいrun(アシスタントの実行)を作成します。
  1. 回答の取得
  • 使用メソッド: client.beta.threads.messages.list
  • 機能: 指定されたスレッドのすべてのメッセージをリストとして取得し、アシスタントからのレスポンスを得ることができます。

この方法を使用することで、特定の質問をAzure OpenAIのアシスタントに投げ、得られた回答を確認することができます。

import time
#数分かかります。しばらくお待ちください。                           
while True:
    messages = client.beta.threads.messages.list(thread_id=thread.id)
    try:
        #See if image has been created
        messages.data[0].content[0].image_file
        #Sleep to make sure run has completed
        time.sleep(5)
        print('Plot created!')
        break
    except:
        time.sleep(10)
        print('Assistant still working...')

アシスタントによるプロット作成の監視

このコードは、Azure OpenAIアシスタントが生成したプロット(画像)が利用可能になるまで待機し、利用可能になった際に通知することを目的としています。

処理フロー

  1. 無限ループの開始: プロットが利用可能になるまで継続されます。
  2. メッセージの取得: client.beta.threads.messages.listメソッドを使用して、指定されたスレッドのすべてのメッセージを取得し、アシスタントからのレスポンスを全て確認します。
  3. プロットの確認: tryブロック内で最新のメッセージに画像ファイルが含まれているかを確認します。画像ファイルがあれば、'Plot created!'と表示し、5秒後にループを終了します。これは、プロットが利用可能になったことを意味します。
  4. 待機とループの継続: 画像ファイルがない場合、エラーが発生し、exceptブロックが実行されます。'Assistant still working...'と表示し、10秒間待機後にループを継続します。これはアシスタントがプロット作成中であることを示します。

アシスタントのプロット作成プロセスを効率的に監視し、作成完了時に通知を受け取ることができます。

messages = client.beta.threads.messages.list(thread_id=thread.id)
[message.content[0] for message in messages.data]

指定されたスレッドからすべてのメッセージを取得し、それらの内容をリストとして抽出する方法を説明します。

  1. メッセージの取得: client.beta.threads.messages.listメソッドを用いて、指定されたスレッドIDに関連するすべてのメッセージを取得します。このメソッドからはメッセージのリストが返されます。

  2. 内容の抽出: リスト内包表記を活用して、取得した各メッセージから内容(message.content[0])を抽出します。結果として、メッセージ内容のみを含む新たなリストが生成されます。

このプロセスにより、指定されたスレッド内の全メッセージの内容を簡単にリスト形式で抽出することができます。

# Quick helper function to convert our output file to a png
def convert_file_to_png(file_id, write_path):
    data = client.files.content(file_id)
    data_bytes = data.read()
    with open(write_path, "wb") as file:
        file.write(data_bytes)

ファイル内容のPNG形式での保存

指定されたファイルIDの内容を取得し、PNGファイルとして指定されたパスに書き込むヘルパー関数convert_file_to_pngの定義方法を説明します。

処理の流れ

  1. ファイル内容の取得: client.files.contentメソッドを使用して指定されたファイルIDの内容を取得します。このメソッドからはファイル内容を表すオブジェクトが返されます。

  2. バイト列の読み込み: 取得したオブジェクトのreadメソッドを呼び出し、ファイルの内容をバイト列として読み込みます。このバイト列はdata_bytesという変数に格納されます。

  3. PNGファイルとしての書き込み: open関数を使用して指定されたパスでバイナリ書き込みモード("wb")でファイルを開き、writeメソッドを使用して読み込んだバイト列をファイルに書き込みます。

この関数を通じて、指定されたファイルIDの内容をPNGファイルとして簡単に保存することができます。

plot_file_id = messages.data[0].content[0].image_file.file_id
image_path = "images/nyctaxi_chart.png"
convert_file_to_png(plot_file_id,image_path)

#Upload
plot_file = client.files.create(
  file=open(image_path, "rb"),
  purpose='assistants'
)

プロットの保存とアップロード

このPythonコードは、アシスタントから取得したプロット(画像)をローカルにPNGファイルとして保存し、その後、OpenAIのサーバーにアップロードするプロセスを説明します。

処理の流れ

  1. プロットのファイルID取得: 最新のメッセージからプロットのファイルIDをmessages.data[0].content[0].image_file.file_idを使用して取得し、plot_file_id変数に格納します。

  2. 保存パスの指定: ローカルでプロットを保存するパスを"images/nyctaxi_chart.png"と指定し、image_path変数に格納します。

  3. PNGファイルとしての保存: convert_file_to_png関数を呼び出して、取得したファイルIDのプロットを指定されたパスにPNGファイルとして保存します。この関数は、ファイルIDと保存パスを引数に取ります。

  4. サーバーへのアップロード: client.files.createメソッドを使用して、保存したPNGファイルをサーバーにアップロードします。このメソッドは、ファイルオブジェクト(open(image_path, "rb")で開かれたファイル)と目的('assistants')を引数に取ります。成功すると、作成されたファイルの情報を含むオブジェクトを返し、これをplot_file変数に格納します。

Azure OpenAIのアシスタントから取得したプロットを効率的にローカルに保存し、必要に応じてサーバーにアップロードすることができます。

from IPython.display import Image

display(Image(image_path))

2.作成したプロット図のインサイトを考察

submit_message(assistant.id,thread,"作成したプロットからの最も重要な洞察を3つの中程度の長さの文(1文あたり約20-30語)で提供します。これらはスライドに使用される予定です。なぜそのような結果になるか示してください。")
time.sleep(10)
response = get_response(thread)
bullet_points = response.data[0].content[0].text.value
print(bullet_points)

出力結果:

  1. 夜間から早朝にかけての時間帯、特に午前0時から午前6時ごろまでは、乗客数が著しく減少しており、これは人々が就寝していることが一般的であるためです。
  2. 午後の遅い時間に乗客数がピークに達していることが見られ、これは通勤時間、社交活動、または夕方の予定のためにタクシーの需要が増加するからでしょう。
  3. 早朝の時間帯に乗客数が急速に増加していることは、出勤や学校への移動が開始されるため、タクシーを利用する人が多くなることを示しています。

アシスタントからの回答の取得と表示

このPythonコードは、アシスタントに特定の質問を投げその回答を取得して表示するものです。

処理の流れ

  1. メッセージの送信: submit_message関数を用いて、アシスタントに「作成したプロットからの最も重要な洞察を3つの中程度の長さの文で提供します。これらはスライドに使用される予定です。なぜそのような結果になるか示してください。」という質問を送信します。

  2. 回答の準備待ち: time.sleep(10)を使用して、アシスタントが回答を準備するのを10秒間待ちます。

  3. 回答の取得: get_response関数を使用して、アシスタントからの回答を含むメッセージを取得します。最新のメッセージの内容が、求められた回答です。

  4. 回答の表示: print関数を使用して、取得した回答を表示します。

作成したプロットから洞察を簡潔に取得し、表示することができます。
ここまでで既存のデータから図を作成し、簡単にインサイトを得ることが出来ます。

submit_message(assistant.id,thread,"作成したプロットと箇条書きをもとに、スライドのタイトルを簡潔に考えましょう。\
               スライドにつけるごく簡単なタイトルを考えましょう。それは、あなたが思いついた主要な洞察だけを反映したものでなければなりません。"
)
time.sleep(10)
response = get_response(thread)
title = response.data[0].content[0].text.value
print(title)

出力結果:
"一日の乗客数ピークと低迷時間帯の明確なトレンド"

スライドのタイトルを考案

このPythonコードは、特定の質問をアシスタントに投げかけ、その回答を取得して表示するものです。

処理の流れ

  1. メッセージの送信: submit_message関数を使い、アシスタントに「作成したプロットと箇条書きをもとに、スライドのタイトルを簡潔に考えましょう。」というメッセージを送信します。送信するメッセージは、主要な洞察を反映した簡単なスライドのタイトルの提案を依頼します。

  2. 回答の準備待ち: time.sleep(10)を用いてアシスタントが回答を準備するのを10秒待ちます。

  3. 回答の取得: get_response関数により、アシスタントからの回答を含むメッセージを取得します。取得した最新のメッセージの内容が、要求された回答です。

  4. 回答の表示: print関数を使って取得した回答を表示します。

スライドのタイトルを考案し、表示することができます。

3.DALL·E-3 を使用してスライドに使用する図を作成

company_summary = "ニューヨーク市のGreen Taxi(緑のタクシー)は、公式にはBoro Taxiと呼ばれ、特にマンハッタンの中心部以外の地域や空港で乗客を拾うことが許可されているタクシー。これらのタクシーは、ニューヨーク市のタクシー・リムジン委員会(TLC)によって2013年に導入された。"
response = client.images.generate(
  model='Dalle3',
  prompt=f"会社概要 {company_summary}, 成長と前進を示す感動的な写真を作成する。\
    これは四半期ごとの財務計画会議で使用します。",
       size="1024x1024",
       quality="hd",
       n=1
)
image_url = response.data[0].url

画像生成APIを使用した画像の生成とURLの取得

このPythonコードは、画像生成APIを利用して指定プロンプトに基づく画像を生成し、その画像のURLを取得する流れを示しています。

処理の流れ

  1. 画像の生成: client.images.generateメソッドを使い、モデル名('Dalle3')、プロンプト、画像サイズ("1024x1024")、画像品質("hd")、生成する画像の数(1)を引数に画像を生成します。

  2. URLの取得: response.data[0].urlを用いて生成された画像のURLを取得し、image_url変数に格納します。

このコードにより、特定のプロンプトに基づいて画像が生成され、その画像のURLが得られます。

dalle_img_path = 'images/nyc_dalle_image.png'
img = requests.get(image_url)

#Save locally
with open(dalle_img_path,'wb') as file:
  file.write(img.content)

#Upload
dalle_file = client.files.create(
  file=open(dalle_img_path, "rb"),
  purpose='assistants'
)
display(Image(dalle_img_path))

指定URLからの画像ダウンロードとサーバーへのアップロード

特定のURLから画像をダウンロードし、ローカルに保存した後、サーバーにアップロードする手順を実行します。

  1. 画像のダウンロード: requests.get(image_url)を使用して、指定されたURLから画像をダウンロードします。取得したレスポンスはimg変数に格納されます。

  2. ローカルへの保存: ダウンロードした画像を'images/nyc_dalle_image.png'のパスに保存します。このパスはdalle_img_path変数に格納されます。

  3. ファイル書き込み: open関数とwithステートメントを使用し、'wb'モードで画像内容(img.content)をファイルに書き込みます。

  4. Azure OpenAIサーバーへのアップロード: client.files.createメソッドにより、ローカルに保存した画像をサーバーにアップロードします。このメソッドはファイルの情報を含むオブジェクトを返し、これをdalle_file変数に格納します。

このプロセスにより、特定のURLから画像をダウンロードし、ローカルに保存後、サーバーにアップロードします。

4.スライドの作成

title_template = """
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT
from pptx.dml.color import RGBColor

# Create a new presentation object
prs = Presentation()

# Add a blank slide layout
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# Set the background color of the slide to black
background = slide.background
fill = background.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0, 0, 0)

# Add image to the left side of the slide with a margin at the top and bottom
left = Inches(0)
top = Inches(0)
height = prs.slide_height
width = prs.slide_width * 3/5
pic = slide.shapes.add_picture(image_path, left, top, width=width, height=height)

# Add title text box positioned higher
left = prs.slide_width * 3/5
top = Inches(2)
width = prs.slide_width * 2/5
height = Inches(1)
title_box = slide.shapes.add_textbox(left, top, width, height)
title_frame = title_box.text_frame
title_p = title_frame.add_paragraph()
title_p.text = title_text
title_p.font.bold = True
title_p.font.size = Pt(38)
title_p.font.color.rgb = RGBColor(255, 255, 255)
title_p.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER

# Add subtitle text box
left = prs.slide_width * 3/5
top = Inches(3)
width = prs.slide_width * 2/5
height = Inches(1)
subtitle_box = slide.shapes.add_textbox(left, top, width, height)
subtitle_frame = subtitle_box.text_frame
subtitle_p = subtitle_frame.add_paragraph()
subtitle_p.text = subtitle_text
subtitle_p.font.size = Pt(22)
subtitle_p.font.color.rgb = RGBColor(255, 255, 255)
subtitle_p.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
"""

data_vis_template = """
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT
from pptx.dml.color import RGBColor

# Create a new presentation object
prs = Presentation()

# Add a blank slide layout
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# Set the background color of the slide to black
background = slide.background
fill = background.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0, 0, 0)

# Define placeholders
image_path = data_vis_img
title_text = "Maximizing Profits: The Dominance of Online Sales & Direct Sales Optimization"
bullet_points = "• Online Sales consistently lead in profitability across quarters, indicating a strong digital market presence.\n• Direct Sales show fluctuations, suggesting variable performance and the need for targeted improvements in that channel."

# Add image placeholder on the left side of the slide
left = Inches(0.2)
top = Inches(1.8)
height = prs.slide_height - Inches(3)
width = prs.slide_width * 3/5
pic = slide.shapes.add_picture(image_path, left, top, width=width, height=height)

# Add title text spanning the whole width
left = Inches(0)
top = Inches(0)
width = prs.slide_width
height = Inches(1)
title_box = slide.shapes.add_textbox(left, top, width, height)
title_frame = title_box.text_frame
title_frame.margin_top = Inches(0.1)
title_p = title_frame.add_paragraph()
title_p.text = title_text
title_p.font.bold = True
title_p.font.size = Pt(28)
title_p.font.color.rgb = RGBColor(255, 255, 255)
title_p.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER

# Add hardcoded "Key Insights" text and bullet points
left = prs.slide_width * 2/3
top = Inches(1.5)
width = prs.slide_width * 1/3
height = Inches(4.5)
insights_box = slide.shapes.add_textbox(left, top, width, height)
insights_frame = insights_box.text_frame
insights_p = insights_frame.add_paragraph()
insights_p.text = "Key Insights:"
insights_p.font.bold = True
insights_p.font.size = Pt(24)
insights_p.font.color.rgb = RGBColor(0, 128, 100)
insights_p.alignment = PP_PARAGRAPH_ALIGNMENT.LEFT
insights_frame.add_paragraph()


bullet_p = insights_frame.add_paragraph()
bullet_p.text = bullet_points
bullet_p.font.size = Pt(12)
bullet_p.font.color.rgb = RGBColor(255, 255, 255)
bullet_p.line_spacing = 1.5
"""

python-pptxを使用したPowerPointプレゼンテーションの生成

このPythonコードでは、python-pptxライブラリを使用してPowerPointプレゼンテーションを生成し、その中で2種類のテンプレートtitle_templatedata_vis_templateを提供します。

title_template

  • 機能: タイトルとサブタイトルを含むスライドの作成。
  • 手順:
    1. 新しいプレゼンテーションオブジェクトを作成し、空のスライドレイアウトを追加。
    2. スライドの背景色を黒に設定。
    3. 左側に画像を、右側にタイトル(title_text)とサブタイトル(subtitle_text)のテキストボックスを追加。

data_vis_template

  • 機能: タイトル、画像、および「Key Insights」のテキストと箇条書きを含むスライドの作成。
  • 手順:
    1. 新しいプレゼンテーションオブジェクトを作成し、空のスライドレイアウトを追加。
    2. スライドの背景色を黒に設定。
    3. 左側に画像を、上部にタイトル(title_text)のテキストボックスを追加。
    4. 右側に「Key Insights」のテキスト(ハードコード)と箇条書き(bullet_points)のテキストボックスを追加。

これらのテンプレートを使用することで、プレゼンテーションの異なるセクションを生成し、それぞれに特定のレイアウトとスタイルを適用することができます。

title_text = "NYC Taxi Corp"
subtitle_text = "by hourly passenger count"
submit_message(assistant.id,thread,f"Use the included code template to create a PPTX slide that follows the template format, but uses the image, company name/title, and document name/subtitle included:\
{title_template}. IMPORTANT: Use the image file included in this message as the image_path image in this first slide, and use the Company Name {title_text} as the title_text variable, and \
  use the subtitle_text {subtitle_text} a the subtitle_text variable. \
    NEST, create a SECOND slide using the following code template: {data_vis_template} to create a PPTX slide that follows the template format, but uses the company name/title, and document name/subtitle included:\
{data_vis_template}. IMPORTANT: Use the line plot image, that is the second attached image in this message, that you created earlier in the thread as the data_vis_img image, and use the data visualization title that you created earlier for the variable title_text, and\
  the bullet points of insights you created earlier for the bullet_points variable. Output these TWO SLIDES as a .pptx file. Make sure the output is two slides, with each slide matching the respective template given in this message.",
              file_ids=[dalle_file.id, plot_file.id]
)

アシスタントを使用したPPTXスライドの作成指示

このPythonコードは、アシスタントに2つの特定のPPTXスライドを作成するための指示を送信します。各スライドは特定のテンプレートに従っています。

処理の流れ

  1. 最初のスライド: title_templateを使用してスライドを作成。メッセージに含まれる画像ファイルをimage_path画像として、Company Name {title_text}をタイトルとして、subtitle_text {subtitle_text}をサブタイトルとして使用。

  2. 二番目のスライド: data_vis_templateを使用してスライドを作成。メッセージに含まれる2番目の画像(折れ線グラフの画像)をdata_vis_img画像として、データ可視化のタイトルをtitle_textとして、洞察の箇条書きをbullet_pointsとして使用。

実装詳細

  • submit_message関数を使用してアシスタントにメッセージを送信。アシスタントID、スレッド、およびユーザーメッセージ(2つのスライド作成に関する詳細な指示)を引数として受け取る。
  • また、file_ids引数をオプションで受け取り、メッセージに添付するファイルIDのリスト(この場合はdalle_file.idplot_file.id)を含む。

このコードは、特定のテンプレートに従って2つのPPTXスライドを作成し、それらを.pptxファイルとして出力するようアシスタントに指示します。

#数分かかります
while True:
    try:
        response = get_response(thread)
        pptx_id = response.data[0].content[0].text.annotations[0].file_path.file_id
        print("Successfully retrieved pptx_id:", pptx_id)
        break
    except Exception as e:
        print("Assistant still working on PPTX...")
        time.sleep(10)

出力結果:
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Successfully retrieved pptx_id: assistant-ilM6dlpb0kuq9jEqE8QqZVCw

pptx_id = response.data[0].content[0].text.annotations[0].file_path.file_id
ppt_file= client.files.content(pptx_id)
file_obj = io.BytesIO(ppt_file.read())
with open("data/nyc_taxi_created_slides.pptx", "wb") as f:
    f.write(file_obj.getbuffer())

以下のようなスライドが作成されます。
サンプル編集することでスライドのデザインや数を増やすことが出来ます。
文字の背景少し修正いたしました。

5.まとめ

  • これらのスライドはいくつかのフォーマットの調整が必要かもしれませんが、Assistants API、DALL·E-3を使用してコンテンツを作成することができました。
  • NYC Taxi Dataのcsvファイルを受け取り、Assistants APIを使用して時間ごとの乗客数を計算し、結果をプロットします。可視化からの洞察と重要なポイントを特定し、要約するタイトルを作成しました。
  • NYC Taxi Dataの説明だけを与えられて、DALL·E-3を使用してタイトル画像を作成しました。
  • 完全に人間なしでこのプロセスを自動化するには程遠いですが、このノートブックがあなたのスライド作成プロセスを少しでも簡単にすることを願っています。
  • このノートブックがAssistants APIの可能性を示すことができれば幸いです。

Discussion