使用OpenAI和Langchain的语言电子邮件撰写器Web应用程序

OpenAI和Langchain的语言电子邮件撰写器Web应用程序

介绍

在本文中,我们将看到如何使用OpenAI和Langchain构建一个Web应用程序。这个Web应用程序可以将非结构化的电子邮件转换为格式正确的英文。用户可以输入他们的电子邮件文本,指定所需的语气和语言(正式/非正式和美式/英式英语),应用程序将会提供所选风格的美观格式化的电子邮件。我们不能每次都构建可扩展的应用程序,只是复制粘贴提示和查询;相反,让我们开始构建这个令人惊叹的“专业电子邮件编写工具”。

学习目标

  • 学习如何使用Streamlit构建漂亮的Web应用程序。
  • 了解什么是提示工程以及如何为生成电子邮件创建有效的提示。
  • 学习如何使用Langchain的PromptTemplate查询OpenAI LLM。
  • 学习如何使用Streamlit部署Python应用程序。

本文是Data Science Blogathon的一部分。

Streamlit 设置

首先,我们需要了解Streamlit是什么,它是如何工作的,以及如何为我们的用例进行设置。Streamlit允许我们使用Python创建Web应用程序,并在本地和网络上进行托管。首先,打开终端并使用以下命令安装Streamlit

pip install streamlit

为我们的脚本创建一个空的Python文件,并使用以下命令运行该文件

python -m streamlit run [your_file_name.py]

这将在地址localhost:8501上启动一个空的Streamlit应用程序。打开浏览器并搜索该地址以可视化应用程序。这个应用程序的一个很酷的功能是,您可以对代码进行编辑,它会自动更新浏览器中的应用程序。

构建前端

让我们从为我们的应用程序添加一个标题和页面标题开始编写代码。我将其命名为“专业电子邮件编写工具”

#导入Streamlit库。
import streamlit as st
# 使用标题和标题设置Streamlit应用程序
st.set_page_config(page_title="专业电子邮件编写工具", page_icon=":robot:")
st.header("专业电子邮件编写工具")

输出:

接下来,我们需要从用户那里获取输入,以了解用户想要哪个电子邮件。为此,我们使用streamlit提供的text_area函数。

#获取用户输入的电子邮件文本
def getEmail():
    input_text = st.text_area(label="电子邮件输入", label_visibility='collapsed',
                              placeholder="您的电子邮件...", key="input_text")
    return input_text

input_text = getEmail()

输出:

接下来,我们需要有两个下拉菜单,询问用户对其电子邮件期望的语气,即正式和非正式,以及用户期望的英语方言,即美式英语,英式英语。

#显示用于选择语气和语言的下拉菜单
column1, column2 = st.columns(2)
with column1:
    tone_drop_down = st.selectbox(
        '您希望您的电子邮件具有哪种语气?',
        ('正式', '非正式'))

with column2:
    dialect_drop_down = st.selectbox(
        '您希望使用哪种英语方言?',
        ('美式', '英式'))

以上代码将创建两个包含下拉菜单的列,每个列使用selectbox()函数。

输出:

我们需要强调的是,每次用户更新这些选择时,它都应该重新运行整个应用程序。将其视为每次在下拉菜单中切换某些内容时进行的大刷新。

提示工程

现在我们需要获取用户提供的电子邮件输入,并将其与用户从下拉菜单中选择的配置一起通过Langchain传递。然后我们需要从OpenAI获取格式正确的输出。

为此,我们需要设置一个提示模板。我们需要进行一些提示工程,以在该提示模板中获得优化的输出。提示工程是使用其可以向语言模型提出查询并获取准确结果的提示构造过程。您可以根据需要修改此模板。

1. 提示应清楚描述用户正在提供的输入。例如:

以下是可能是不结构化和措辞不当的电子邮件。

2. 提示应清楚解释语言模型应该给出的输出。例如:

您的目标是:

  • 正确格式化电子邮件
  • 将输入电子邮件转换为花括号中指定的语气。
  • 将输入电子邮件转换为花括号中指定的方言。
  • 如果需要,请在电子邮件开头加上一个热情的介绍。

3. 提示应包含示例,以确保模型了解输出期望。

4. 最后,提示应清楚指示用户输入是什么,每个输入指的是什么。

以下是我们根据上述规则创建的提示:

# 定义电子邮件转换任务的模板
template = """
    以下是可能是不结构化和措辞不当的电子邮件。
    您的目标是:
    - 正确格式化电子邮件
    - 将输入电子邮件转换为花括号中指定的语气。
    - 将输入电子邮件转换为花括号中指定的方言。

    以下是不同语气的示例:
    - 正式:我们去了海德拉巴度周末。我们有很多事要告诉你。
    - 非正式:去了海德拉巴度周末。有很多事要告诉你。

    以下是不同方言中的一些单词示例:
    - 美式英语:Garbage, cookie, green thumb, parking lot, pants, windshield, 
      French Fries, cotton candy, apartment
    - 英式英语:Green fingers, car park, trousers, windscreen, chips, candyfloss, 
      flag, rubbish, biscuit

    每个方言的示例句子:
    - 美式英语:当他们漫步在多彩的街区时,莎拉问她的朋友是否想在附近的咖啡馆喝杯咖啡。秋天的
                叶子令人叹为观止,他们享受着宜人的天气,聊着周末的计划。
    - 英式英语:当他们漫步在风景如画的街区时,莎拉问她的朋友是否喜欢在附近的咖啡馆喝杯咖啡。秋天的
                叶子令人惊叹,他们品味着宜人的天气,聊着周末的计划。

    请在电子邮件开头加上一个热情的介绍。如果需要,请添加介绍。
    
    以下是电子邮件、语气和方言:
    语气:{tone}
    方言:{dialect}
    电子邮件:{email}
    
    您的{dialect}回复:
"""

现在使用Langchain的PromptTemplate类创建提示,通过它我们可以将用户输入注入到提示中。

# 导入PromptTemplate类
from langchain import PromptTemplate
# 创建一个PromptTemplate实例来管理输入变量和模板
prompt = PromptTemplate(
    input_variables=["tone", "dialect", "email"],
    template=query_template,
)

加载语言模型

请确保您已经准备好OpenAI API密钥。如果没有,请按照以下步骤操作。

  • 访问“https://openai.com/”并创建您的账户。
  • 登录到您的账户,在仪表板上选择“API”。
  • 现在点击您的个人资料图标,然后选择“查看API密钥”。
  • 选择“创建新的密钥”,复制并保存它。

OpenAI API密钥代码

以下是一个函数的代码,它使用text_input()函数从用户那里获取OpenAI API密钥,并将示例API密钥显示为占位符。

# 显示用于OpenAI API密钥的文本输入
def fetchAPIKey():
    input_text = st.text_input(
        label="OpenAI API密钥",  placeholder="例如:vk-Cb8un42twmA8tf...", key="openai_api_key_input")
    return input_text

# 从用户获取OpenAI API密钥
openai_api_key = fetchAPIKey()

输出:

我们需要确保API密钥要么在我们的脚本中,但这并不推荐,因为我们不希望在任何地方硬编码它,要么在我们的环境变量中,这样我们的代码就可以从中获取。创建环境变量的一种方法是使用一个单独的.env文件。

设置环境变量的步骤

按照以下步骤创建环境变量:

1:打开终端,并使用命令“pip install python dotenv”安装python-dotenv包。

2:创建一个名为“.env”的文件。

3:以下格式存储您的API密钥

API_KEY=您的API密钥

4:加载dotenv包,并使用该包获取您的环境变量

from dotenv import load_dotenv
import os

# 从.env文件加载环境变量
load_dotenv()

# 使用os.environ访问API密钥
openai_api_key = os.environ.get("API_KEY")

这种方法可以防止意外暴露API密钥直接在代码中。请将此文件保密,而不是公开共享。

然而,由于OpenAI API允许有限数量的API请求,我们将要求用户输入他们的API密钥而不是提供我们的密钥。在这种情况下,我们将使用温度等于0.7加载OpenAI,这意味着它会有创造性。如果我们传递无效的OpenAI API密钥,下面的代码将抛出错误。此外,如果用户输入无效的密钥,我们必须显示适当的警告。

# 导入OpenAI库
from langchain.llms import OpenAI
# 加载语言模型的函数
def loadLanguageModel(api_key_openai):
    llm = OpenAI(temperature=.7, openai_api_key=api_key_openai)
    return llm

示例

让我们给用户一个示例,以便用户可以了解他应该输入什么,并可以期望得到什么。让我们在前端创建一个“显示示例”按钮。以下函数使用一个示例的非结构化和用词不当的电子邮件查询更新文本框。

# 使用示例电子邮件更新文本框的函数
def textBoxUpdateWithExample():
    print("在更新中")
    st.session_state.input_text = "Vinay,我从周一开始在你的办公室工作"

# 显示示例电子邮件的按钮
st.button("*显示示例*", type='secondary',
          help="单击以查看您将要转换的电子邮件的示例。", on_click=textBoxUpdateWithExample)
st.markdown("### 您的电子邮件:")

输出:

接下来,我们需要确保用户已经输入了他的API密钥,并且在调用语言模型之前,他应该在文本框中输入了一些查询。如果他在没有API密钥或无效API的情况下调用模型,我们需要向用户显示正确获取密钥的说明。

# 如果用户已经提供了input_text,则进行电子邮件转换
if input_text:
    if not openai_api_key:
        # 如果未提供API密钥,则显示警告
        st.warning(
            '请插入OpenAI API密钥。 [点击此处查看说明](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key)', icon="⚠️")
        st.stop()
    # 使用提供的API密钥加载语言模型
    llm = loadLanguageModel(api_key_openai=openai_api_key)
    # 使用PromptTemplate和语言模型格式化电子邮件
    prompt_with_email = prompt.format(
        tone=tone_drop_down, dialect=dialect_drop_down, email=input_text)
    formatted_email = llm(prompt_with_email)
    # 显示格式化的电子邮件
    st.write(formatted_email)

输出:

如果用户在文本框中输入了正确的 API 密钥和适当的电子邮件文本,我们将使用用户输入的电子邮件文本和配置格式化提示,即语气和方言。然后,我们将将此提示传递给我们的语言模型,语言模型将以正确格式的电子邮件作为响应返回,我们将使用 streamlit write() 函数在“您的电子邮件”选项卡下向用户显示该电子邮件。

部署应用程序

按照以下步骤部署应用程序:

1:首先,我们必须将代码推送到 GitHub 存储库中。在推送之前,创建一个包含我们代码所有依赖项的 requirements.txt 文件。

  • langchain
  • openai
  • streamlit

2:前往 streamlit.io 并通过授权 GitHub 创建一个帐户。

3:登录到您的 streamlit 帐户。

4:点击创建一个新应用程序,并传递 GitHub 存储库的所有详细信息。在主文件路径下,给出包含 Python 脚本的文件名。最后,点击部署。

5:保存应用程序 URL。几分钟后,您可以使用该 URL 在网络上看到您的应用程序。

完整实现

# 导入所需库
from langchain import PromptTemplate
import streamlit as st
from langchain.llms import OpenAI

# 定义电子邮件转换任务的模板
query_template = query_template = """
    下面是一封可能结构混乱、措辞不当的电子邮件。
    您的目标是:
    - 适当格式化电子邮件
    - 将输入的电子邮件转换为花括号中指定的语气。
    - 将输入的电子邮件转换为花括号中指定的方言。

    以下是不同语气的参考示例:
    - 正式:我们去海得拉巴度周末。我们有很多事情要告诉你。
    - 非正式:去海得拉巴度周末。有很多事情要告诉你。

    以下是不同方言的一些单词示例:
    - 美式英语:垃圾,饼干,绿手指,停车场,裤子,挡风玻璃,
                炸薯条,棉花糖,公寓
    - 英式英语:绿手指,停车场,裤子,挡风玻璃,薯条,棉花糖,
               旗帜,垃圾,饼干

    每种方言的示例句子:
    - 美式英语:当他们漫步穿过色彩斑斓的社区时,萨拉问她的朋友是否想在附近的咖啡馆喝杯咖啡。秋天的
                枫叶令人叹为观止,他们享受着宜人的天气,闲聊着周末计划。
    - 英式英语:当他们漫步穿过风景如画的社区时,萨拉问她的朋友是否想在附近的咖啡馆喝杯咖啡。秋天的
               树叶令人惊叹,他们品味着宜人的天气,闲谈着周末计划。

    如果需要,可以以热情的介绍开始电子邮件。添加介绍如果需要。

    以下是电子邮件、语气和方言:
    语气:{tone}
    方言:{dialect}
    电子邮件:{email}
    
    您的{dialect}回复:
"""

# 创建 PromptTemplate 实例来管理输入变量和模板
prompt = PromptTemplate(
    input_variables=["tone", "dialect", "email"],
    template=query_template,
)

# 加载语言模型的函数
def loadLanguageModel(api_key_openai):
    llm = OpenAI(temperature=.7, openai_api_key=api_key_openai)
    return llm

# 使用标题和标题设置 Streamlit 应用程序
st.set_page_config(page_title="专业电子邮件写作", page_icon=":robot:")
st.header("专业电子邮件写作")

# 为 Streamlit 布局创建列
column1, column2 = st.columns(2)

# 显示 OpenAI API 密钥的文本输入
def fetchAPIKey():
    input_text = st.text_input(
        label="OpenAI API 密钥",  placeholder="例如:vk-Cb8un42twmA8tf...", key="openai_api_key_input")
    return input_text

# 从用户获取 OpenAI API 密钥
openai_api_key = fetchAPIKey()

# 显示下拉框以选择语气和方言
column1, column2 = st.columns(2)
with column1:
    tone_drop_down = st.selectbox(
        '您希望电子邮件具有哪种语气?',
        ('正式', '非正式'))

with column2:
    dialect_drop_down = st.selectbox(
        '您希望使用哪种英语方言?',
        ('美式英语', '英式英语'))

# 获取用户输入的电子邮件文本
def getEmail():
    input_text = st.text_area(label="电子邮件输入", label_visibility='collapsed',
                              placeholder="您的电子邮件...", key="input_text")
    return input_text

input_text = getEmail()

# 检查电子邮件是否超过字数限制
if len(input_text.split(" ")) > 700:
    st.write("最大限制为 700 个单词。请输入较短的电子邮件")
    st.stop()

# 更新文本框以显示示例电子邮件的函数
def textBoxUpdateWithExample():
    print("in updated")
    st.session_state.input_text = "Vinay I am starts work at yours office from monday"

# 按钮以显示示例电子邮件
st.button("*显示示例*", type='secondary',
          help="点击以查看要转换的电子邮件的示例。", on_click=textBoxUpdateWithExample)
st.markdown("### 您的电子邮件:")

# 如果用户提供了 input_text,则进行电子邮件转换
if input_text:
    if not openai_api_key:
        # 如果未提供 API 密钥,则显示警告
        st.warning(
            '请插入 OpenAI API 密钥。详细说明[在此处](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key)', icon="⚠️")
        st.stop()
    # 使用提供的 API 密钥加载语言模型
    llm = loadLanguageModel(api_key_openai=openai_api_key)
    # 使用 PromptTemplate 和语言模型格式化电子邮件
    prompt_with_email = prompt.format(
        tone=tone_drop_down, dialect=dialect_drop_down, email=input_text)
    formatted_email = llm(prompt_with_email)
    # 显示格式化的电子邮件
    st.write(formatted_email)

结论

在本文中,我们看到了如何使用OpenAI LLM和Langchain创建一个美观的Web应用程序。我们从安装和设置Streamlit开始。然后,我们创建了一个前端界面,用于接收用户输入,如语调、方言和电子邮件文本。之后,我们创建了一个有效的提示来查询语言模型,使用了这些输入。接下来,我们使用API密钥初始化OpenAI模型,通过Langchain传递我们创建的提示。最后,我们使用Streamlit将应用程序部署到Web中。

主要观点

  • 使用Python中的Streamlit库,我们可以构建交互式Web应用程序。
  • 提示工程在从语言模型中获取优化结果方面起着关键作用。
  • 使用OpenAI库及其密钥,可以轻松在Python应用程序中使用OpenAI LLM。
  • 使用Langchain的PromptTemplate,我们可以根据用户输入正确格式化提示,进而在查询LLM时使用。
  • 使用Streamlit Share,我们可以将Python应用程序托管到实时URL中。

常见问题

本文中显示的媒体不归Analytics Vidhya所有,仅供作者自行决定使用。