当前位置:   article > 正文

大模型系列:OpenAI使用技巧_使用助手API(GPT-4)和DALL·E-3创建幻灯片_openai写ppt

openai写ppt


本笔记本演示了如何使用新的 助手API(GPT-4)和DALL·E-3来制作信息丰富且视觉吸引力强的幻灯片。

创建幻灯片是许多工作的关键方面,但可能是费力和耗时的。此外,从数据中提取见解并在幻灯片上有效地表达它们可能是具有挑战性的。

本菜谱将演示如何利用新的助手API为您提供端到端的幻灯片创建过程,而无需触摸Microsoft PowerPoint或Google幻灯片,从而节省您宝贵的时间和精力!

0. 设置

# 导入所需的库
from IPython.display import display, Image
from openai import OpenAI
import pandas as pd
import json
import io
from PIL import Image
import requests

# 创建OpenAI客户端对象
client = OpenAI()

# 导入助手的辅助函数,用于显示json和提交消息
def show_json(obj):
    # 将json字符串转换为Python对象并显示
    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,
    }
    # 如果有文件ID,则将其添加到参数字典中
    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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

1. 创建内容

在这个配方中,我们将为我们的公司NotReal Corporation的季度财务审查创建一个简短的虚构演示文稿。我们想要突出一些关键趋势,这些趋势正在影响我们公司的盈利能力。
假设我们有一些财务数据可供使用。让我们加载数据并查看一下…

# 设置financial_data_path变量为'NotRealCorp_financial_data.json'文件的路径
financial_data_path = 'data/NotRealCorp_financial_data.json'

# 使用pd.read_json()函数读取financial_data_path路径下的json文件,并将结果赋值给financial_data变量
financial_data = pd.read_json(financial_data_path)

# 使用financial_data.head(5)函数显示financial_data的前5行数据,以便查看数据的样式和结构
financial_data.head(5)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
YearQuarterDistribution channelRevenue ($M)Costs ($M)Customer countTime
02021Q1Online Sales1.501.3019531502021 Q1
12021Q1Direct Sales1.501.3808091512021 Q1
22021Q1Retail Partners1.501.3482461522021 Q1
32021Q2Online Sales1.521.3086081522021 Q2
42021Q2Direct Sales1.521.4133051532021 Q2

正如您所见,这些数据包括不同分销渠道的季度收入、成本和客户数据。让我们创建一个助手,可以充当个人分析师,并为我们的PowerPoint制作出漂亮的可视化图表!

首先,我们需要上传我们的文件,这样我们的助手才能访问它。

# 创建一个文件对象,打开名为"data/NotRealCorp_financial_data.json"的文件,以二进制模式读取
# 并将其作为参数传递给open()函数,返回一个文件对象
# 将文件对象作为参数传递给client.files.create()函数,创建一个新的文件
# 将新文件的用途设置为'assistants'
file = client.files.create(
  file=open('data/NotRealCorp_financial_data.json',"rb"),
  purpose='assistants',
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

现在,我们准备创建我们的助手。我们可以指示我们的助手充当数据科学家,并接受我们提供的任何查询,并运行必要的代码以输出正确的数据可视化。这里的指令参数类似于ChatCompletions端点中的系统指令,并可以帮助指导助手。我们还可以打开Code Interpreter工具,这样我们的助手就能编码了。最后,我们可以指定任何要使用的文件,这种情况下只是我们上面创建的“financial_data”文件。

# 创建一个名为assistant的变量,用于存储创建的助手对象
# 调用client.beta.assistants.create()方法创建一个助手对象,并传入以下参数:
# instructions:助手的说明信息,即助手的职责和工作内容
# model:助手使用的模型,这里使用的是gpt-4-1106-preview模型
# tools:助手使用的工具,这里使用的是代码解释器
# file_ids:助手需要访问的文件的ID,这里使用的是一个名为file的文件的ID
assistant = client.beta.assistants.create(
  instructions="You are a data scientist assistant. When given data and a query, write the proper code and create the proper visualization",
  model="gpt-4-1106-preview",
  tools=[{"type": "code_interpreter"}],
  file_ids=[file.id]
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

让我们现在创建一个线程,作为我们的第一个请求,请助手计算季度利润,然后按分销渠道随时间绘制利润。助手将自动计算每个季度的利润,并创建一个新的列,将季度和年份组合在一起,而无需直接要求我们。我们还可以指定每条线的颜色。

# 创建一个新的线程,将其赋值给变量thread
# 在线程中创建一个消息列表,包含一个字典
# 字典中包含三个键值对:
#   - role: 用户角色
#   - content: 消息内容,描述了要计算利润(收入减去成本)的方式,并将其可视化为线图,线图显示在不同的分销渠道上,线的颜色为绿色、浅红色和浅蓝色
#   - file_ids: 文件ID列表,包含一个文件的ID,用于附加到消息中
# 将创建的线程赋值给变量thread
thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": "Calculate profit (revenue minus cost) by quarter and year, and visualize as a line plot across the distribution channels, where the colors of the lines are green, light red, and light blue",
      "file_ids": [file.id]
    }
  ]
)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

现在我们可以执行线程的运行。

# 创建一个运行实例,将其赋值给变量run
run = client.beta.threads.runs.create(
    # 指定线程ID,即要在哪个线程中运行
    thread_id=thread.id,
    # 指定助手ID,即要使用哪个助手来运行
    assistant_id=assistant.id,
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

我们现在可以开始一个循环,检查图像是否已经创建。注意:这可能需要几分钟。


messages = client.beta.threads.messages.list(thread_id=thread_id)  # 获取线程ID对应的所有消息列表
  • 1
  • 2
# 导入time模块
import time

# 进入循环
while True:
    # 获取消息列表
    messages = client.beta.threads.messages.list(thread_id=thread.id)
    try:
        # 判断是否已经创建了图片
        messages.data[0].content[0].image_file
        # 等待5秒,确保程序运行完成
        time.sleep(5)
        # 输出提示信息
        print('Plot created!')
        # 跳出循环
        break
    except:
        # 等待10秒,继续等待程序运行
        time.sleep(10)
        # 输出提示信息
        print('Assistant still working...')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Assistant still working...
Plot created!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

让我们看看助手添加的消息。

# 获取指定线程的所有消息
messages = client.beta.threads.messages.list(thread_id=thread.id)

# 提取每条消息的第一个内容,并存储在列表中
content_list = [message.content[0] for message in messages.data]
  • 1
  • 2
  • 3
  • 4
  • 5
[MessageContentImageFile(image_file=ImageFile(file_id='file-0rKABLygI02MgwwhpgWdRFY1'), type='image_file'),
 MessageContentText(text=Text(annotations=[], value="The profit has been calculated for each distribution channel by quarter and year. Next, I'll create a line plot to visualize these profits. As specified, I will use green for the 'Online Sales', light red for 'Direct Sales', and light blue for 'Retail Partners' channels. Let's create the plot."), type='text'),
 MessageContentText(text=Text(annotations=[], value="The JSON data has been successfully restructured into a tabular dataframe format. It includes the year, quarter, distribution channel, revenue, costs, customer count, and a combined 'Time' representation of 'Year Quarter'. Now, we have the necessary information to calculate the profit (revenue minus cost) by quarter and year.\n\nTo visualize the profit across the different distribution channels with a line plot, we will proceed with the following steps:\n\n1. Calculate the profit for each row in the dataframe.\n2. Group the data by 'Time' (which is a combination of Year and Quarter) and 'Distribution channel'.\n3. Aggregate the profit for each group.\n4. Plot the aggregated profits as a line plot with the distribution channels represented in different colors as requested.\n\nLet's calculate the profit for each row and then continue with the visualization."), type='text'),
 MessageContentText(text=Text(annotations=[], value='The structure of the JSON data shows that it is a dictionary with "Year", "Quarter", "Distribution channel", and potentially other keys that map to dictionaries containing the data. The keys of the inner dictionaries are indices, indicating that the data is tabular but has been converted into a JSON object.\n\nTo properly convert this data into a DataFrame, I will restructure the JSON data into a more typical list of dictionaries, where each dictionary represents a row in our target DataFrame. Subsequent to this restructuring, I can then load the data into a Pandas DataFrame. Let\'s restructure and load the data.'), type='text'),
 MessageContentText(text=Text(annotations=[], value="The JSON data has been incorrectly loaded into a single-row DataFrame with numerous columns representing each data point. This implies the JSON structure is not as straightforward as expected, and a direct conversion to a flat table is not possible without further processing.\n\nTo better understand the JSON structure and figure out how to properly normalize it into a table format, I will print out the raw JSON data structure. We will analyze its format and then determine the correct approach to extract the profit by quarter and year, as well as the distribution channel information. Let's take a look at the JSON structure."), type='text'),
 MessageContentText(text=Text(annotations=[], value="It seems that the file content was successfully parsed as JSON, and thus, there was no exception raised. The variable `error_message` is not defined because the `except` block was not executed.\n\nI'll proceed with displaying the data that was parsed from JSON."), type='text'),
 MessageContentText(text=Text(annotations=[], value="It appears that the content of the dataframe has been incorrectly parsed, resulting in an empty dataframe with a very long column name that seems to contain JSON data rather than typical CSV columns and rows.\n\nTo address this issue, I will take a different approach to reading the file. I will attempt to parse the content as JSON. If this is not successful, I'll adjust the loading strategy accordingly. Let's try to read the contents as JSON data first."), type='text'),
 MessageContentText(text=Text(annotations=[], value="Before we can calculate profits and visualize the data as requested, I need to first examine the contents of the file that you have uploaded. Let's go ahead and read the file to understand its structure and the kind of data it contains. Once I have a clearer picture of the dataset, we can proceed with the profit calculations. I'll begin by loading the file into a dataframe and displaying the first few entries to see the data schema."), type='text'),
 MessageContentText(text=Text(annotations=[], value='Calculate profit (revenue minus cost) by quarter and year, and visualize as a line plot across the distribution channels, where the colors of the lines are green, light red, and light blue'), type='text')]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我们可以看到,助手的最后一条消息(最新的消息显示在前面)包含了我们正在寻找的图像文件。有趣的是,这里的一个注释是,由于第一次解析不成功,助手能够尝试多次解析JSON数据,展示了助手的适应性。

# 定义一个快速的帮助函数,将输出文件转换成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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
# 获取图片文件的file_id
plot_file_id = messages.data[0].content[0].image_file.file_id

# 设置图片文件的保存路径
image_path = "../images/NotRealCorp_chart.png"

# 将文件转换为png格式并保存到指定路径
convert_file_to_png(plot_file_id, image_path)

# 上传图片文件到客户端
plot_file = client.files.create(
  file=open(image_path, "rb"),
  purpose='assistants'
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

让我们加载剧情!

很好!所以,只用一句话,我们就能让助手使用代码解释器来计算盈利能力,并绘制各个分销渠道的三条线图。

现在我们有了一个漂亮的可视化图表,但我们希望还有一些见解与之相伴。

2. 生成洞见

要从我们的图像中获得见解,我们只需要在我们的线程中添加一条新消息。我们的助手将知道使用消息历史记录,为我们提供一些简洁的视觉总结。

# 调用submit_message函数,向助手发送消息
# 参数1:assistant.id,助手的id
# 参数2:thread,消息的主题
# 参数3:消息内容,要求提供两个中等长度的句子(每个句子大约20-30个单词),描述刚刚创建的情节中最重要的见解
# 这些句子将用于幻灯片,应该涉及数据背后的“所以”
submit_message(assistant.id,thread,"Give me two medium length sentences (~20-30 words per sentence) of the \
      most important insights from the plot you just created.\
             These will be used for a slide deck, and they should be about the\
                     'so what' behind the data."
)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
Run(id='run_NWoygMcBfHUr58fCE4Cn6rxN', assistant_id='asst_3T362kLlTyAq0FUnkvjjQczO', cancelled_at=None, completed_at=None, created_at=1701827074, expires_at=1701827674, failed_at=None, file_ids=['file-piTokyHGllwGITzIpoG8dok3'], instructions='You are a data scientist assistant. When given data and a query, write the proper code and create the proper visualization', last_error=None, metadata={}, model='gpt-4-1106-preview', object='thread.run', required_action=None, started_at=None, status='queued', thread_id='thread_73TgtFoJMlEJvb13ngjTnAo3', tools=[ToolAssistantToolsCode(type='code_interpreter')])
  • 1

现在,一旦运行完成,我们就可以看到最新的消息。

# 等待10秒钟,以确保助手完成迭代
time.sleep(10)

# 调用get_response函数,获取助手的回复
response = get_response(thread)

# 从回复中获取第一个数据的内容
bullet_points = response.data[0].content[0].text.value

# 打印bullet_points
print(bullet_points)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
The plot reveals a consistent upward trend in profits for all distribution channels, indicating successful business growth over time. Particularly, 'Online Sales' shows a notable increase, underscoring the importance of digital presence in revenue generation.
  • 1

酷!所以我们的助手能够识别出在线销售利润的显著增长,并推断出这显示了数字化存在的重要性。现在让我们为幻灯片取一个引人注目的标题。

# 给助手发送消息,让其在当前线程中创建一个幻灯片标题
submit_message(assistant.id, thread, "Given the plot and bullet points you created, come up with a very brief title for a slide. It should reflect just the main insights you came up with.")
  • 1
  • 2
Run(id='run_q6E85J31jCw3QkHpjJKl969P', assistant_id='asst_3T362kLlTyAq0FUnkvjjQczO', cancelled_at=None, completed_at=None, created_at=1701827084, expires_at=1701827684, failed_at=None, file_ids=['file-piTokyHGllwGITzIpoG8dok3'], instructions='You are a data scientist assistant. When given data and a query, write the proper code and create the proper visualization', last_error=None, metadata={}, model='gpt-4-1106-preview', object='thread.run', required_action=None, started_at=None, status='queued', thread_id='thread_73TgtFoJMlEJvb13ngjTnAo3', tools=[ToolAssistantToolsCode(type='code_interpreter')])
  • 1

而且标题是:

# 等待一段时间,因为助手可能需要进行一些步骤
time.sleep(10)

# 调用get_response函数,获取响应
response = get_response(thread)

# 从响应中获取数据,并取出第一个内容的标题
title = response.data[0].content[0].text.value

# 打印标题
print(title)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
"Ascending Profits & Digital Dominance"
  • 1

3. DALL·E-3 标题图片

很好,现在我们有了一个标题、一个情节和两个项目符号。我们几乎可以把这些都放在幻灯片上了,但作为最后一步,让我们让DALL·E-3想出一张图片作为演示文稿的标题幻灯片。


注意: DALL·E-3目前还不在助手API中可用,但即将推出!


我们将提供我们公司(NotRealCorp)的简要描述,然后让DALL·E-3来完成剩下的工作!

# 定义一个字符串变量company_summary,用于存储公司的简介信息
company_summary = "NotReal Corp is a prominent hardware company that manufactures and sells processors, graphics cards and other essential computer hardware."
  • 1
  • 2
# 调用client的images.generate方法生成图片
response = client.images.generate(
  model='dall-e-3',  # 使用的模型为'dall-e-3'
  prompt=f"given this company summary {company_summary}, create an inspirational \
    photo showing the growth and path forward. This will be used at a quarterly\
       financial planning meeting",  # 提示信息,描述了生成图片的要求
  size="1024x1024",  # 图片尺寸为1024x1024
  quality="hd",  # 图片质量为高清
  n=1  # 生成一张图片
)

# 获取生成的图片的URL
image_url = response.data[0].url
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

酷,现在我们可以将这个图像添加到我们的线程中。首先,我们可以将图像保存在本地,然后使用“文件”上传端点将其上传到助手API。让我们也看一下我们的图像。

# 定义变量dalle_img_path,指定保存图片的路径
dalle_img_path = '../images/dalle_image.png'

# 通过requests库获取图片的二进制数据
img = requests.get(image_url)

# 将获取到的图片二进制数据写入本地文件
with open(dalle_img_path,'wb') as file:
  file.write(img.content)

# 将本地文件上传至指定的云存储服务
dalle_file = client.files.create(
  file=open(dalle_img_path, "rb"),
  purpose='assistants'
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

4. 创建幻灯片

我们现在已经拥有了创建幻灯片所需的所有内容。虽然我们可以简单地添加一条消息来要求幻灯片,但是让我们给助手提供一个幻灯片模板,使用python-pptx库来使用。这将确保我们获得我们想要的风格的幻灯片组。有关创建模板的说明,请参见笔记本末尾的扩展部分。

# 第一个代码段

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

# 创建一个新的演示文稿对象
prs = Presentation()

# 添加一个空白幻灯片布局
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# 将幻灯片的背景颜色设置为黑色
background = slide.background
fill = background.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0, 0, 0)

# 在幻灯片的左侧添加图片,并在顶部和底部留有边距
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)

# 在更高的位置添加标题文本框
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

# 添加副标题文本框
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

# 创建一个新的演示文稿对象
prs = Presentation()

# 添加一个空白幻灯片布局
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# 将幻灯片的背景颜色设置为黑色
background = slide.background
fill = background.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0, 0, 0)

# 定义占位符
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."

# 在幻灯片的左侧添加图片占位符
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)

# 添加标题文本框,跨越整个宽度
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

# 添加硬编码的“关键见解”文本和项目符号
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
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123

让我们为幻灯片设置一些快速变量。我们希望公司名称NotRealCorp出现在标题幻灯片上,演示文稿的标题应为“2023年第三季度季度财务规划会议”。

# 设置标题文本为"NotRealCorp"
title_text = "NotRealCorp"

# 设置副标题文本为"Quarterly financial planning meeting, Q3 2023"
subtitle_text = "Quarterly financial planning meeting, Q3 2023"
  • 1
  • 2
  • 3
  • 4
  • 5

而对于数据幻灯片,我们有:

在这里,我们有一个创建标题幻灯片的模板。下面的模板是通过将一个理想的标题幻灯片的图像上传到GPT-V,并要求生成用于创建该模板的python-pptx代码来创建的。模板的输入是image_path、title_text和subtitle_text。

# 请使用提供的代码模板创建一个PPTX幻灯片,该幻灯片遵循模板格式,但使用了包含的图像、公司名称/标题和文档名称/副标题:
# {title_template}。重要提示:在第一张幻灯片中使用此消息中包含的图像文件作为image_path图像,并使用公司名称{title_text}作为title_text变量,
# 并使用subtitle_text {subtitle_text}作为subtitle_text变量。

# 接下来,使用以下代码模板创建第二张幻灯片:{data_vis_template},该幻灯片遵循模板格式,但使用了公司名称/标题和文档名称/副标题:
# {data_vis_template}。重要提示:使用之前在线程中创建的第二个附加图像作为data_vis_img图像,并使用之前创建的数据可视化标题作为title_text变量,
# 并使用之前创建的洞察力的项目符号作为bullet_points变量。

# 将这两张幻灯片输出为.pptx文件。确保输出是两张幻灯片,每张幻灯片与此消息中给出的相应模板相匹配。
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]
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
Run(id='run_taLrnOnlDhoywgQFFBOLPlg0', assistant_id='asst_3T362kLlTyAq0FUnkvjjQczO', cancelled_at=None, completed_at=None, created_at=1701827118, expires_at=1701827718, failed_at=None, file_ids=['file-piTokyHGllwGITzIpoG8dok3'], instructions='You are a data scientist assistant. When given data and a query, write the proper code and create the proper visualization', last_error=None, metadata={}, model='gpt-4-1106-preview', object='thread.run', required_action=None, started_at=None, status='queued', thread_id='thread_73TgtFoJMlEJvb13ngjTnAo3', tools=[ToolAssistantToolsCode(type='code_interpreter')])
  • 1
# 循环执行以下代码,直到成功获取pptx_id
while True:
    try:
        # 调用get_response函数获取响应
        response = get_response(thread)
        # 从响应中获取pptx_id
        pptx_id = response.data[0].content[0].text.annotations[0].file_path.file_id
        # 打印成功获取的pptx_id
        print("成功获取pptx_id:", pptx_id)
        # 跳出循环
        break
    except Exception as e:
        # 如果出现异常,打印提示信息
        print("助手正在处理PPTX...")
        # 等待10秒
        time.sleep(10)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Assistant still working on PPTX...
Successfully retrieved pptx_id: file-oa0i63qPH4IaJXYj90aA6L4Q
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
# 获取pptx文件的ID
pptx_id = response.data[0].content[0].text.annotations[0].file_path.file_id

# 通过文件ID从客户端获取ppt文件
ppt_file = client.files.content(pptx_id)

# 创建一个字节流对象
file_obj = io.BytesIO(ppt_file.read())

# 将字节流对象写入到指定路径下的文件中
with open("data/created_slides.pptx", "wb") as f:
    f.write(file_obj.getbuffer())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

现在,我们已经保存了一个包含所有创建内容的PPTX文件!。

让我们看一下刚刚使用辅助API和DALL·E-3创建的.pptx的屏幕截图。在助手API中,我们还没有“种子”参数,因此由于LLM的非确定性,DALL·E-3图像和措辞将与运行此笔记本时看到的略有不同,但输出应该在方向上相同。

标题幻灯片:

而且数据幻灯片:

5. 结论

哇!虽然这些幻灯片需要一些格式调整,但我们使用助手API、GPT-4和DALL·E-3制作了一些很棒的内容。我们能够使用助手计算分销渠道的季度利润、绘制结果、识别可视化的见解和关键要点,并创建一个总结性的标题,只需一个包含财务数据的.csv文件。而且,仅仅通过我们公司NotRealCorp的描述,我们就使用DALL·E-3制作了一个很棒的标题图片。

虽然我们离完全自动化这个过程还有一段路要走,但希望这个笔记本可以让您的幻灯片制作过程变得更容易。更重要的是,这个笔记本可以让您看到助手API的潜力!我们很兴奋地看到您的构建。

6. 扩展功能

  • 当DALL·E-3被纳入助手API时,我们将能够在线程内请求生成的标题图像。
  • Assistants API尚不支持GPT-4-Vision,但可以用于从线图像中收集见解。
  • GPT-4-Vision被用于生成包含在此配方中的python-pptx模板,因此一个潜在的扩展项目可以展示将图像转换为幻灯片模板的最佳实践。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/464370
推荐阅读
相关标签
  

闽ICP备14008679号