使用推理生成例程

2024 年 9 月 12 日
在 Github 中打开

在开发客户服务解决方案时,最初的步骤之一是将知识库文章转换为 LLM 可以理解和遵循的一系列例程。在此上下文中,“例程”指的是为 LLM 有效执行而专门设计的一组逐步说明。每个例程都经过精心构建,以便一个步骤对应一个明确的动作。动作可以包括回复用户、触发函数调用或检索更多相关知识。

大多数内部知识库文章都很复杂,其结构是为了方便人类理解。它们通常包含复杂的图表、多步骤流程和决策树,这些都给基于 LLM 的解决方案带来挑战,使其难以进行有意义的推理。通过将这些文档分解为例程,每个指令都可以得到简化和格式化,从而引导 LLM 完成一系列小的、可管理的任务。这种细粒度的方法减少了歧义,使 LLM 能够有条不紊地处理信息,并降低幻觉或偏离预期路径的风险。

将这些知识库文章转换为例程可能既耗时又具有挑战性,对于试图构建自动化管道的公司而言尤其如此。每个例程都必须考虑各种用户场景,其中需要明确定义动作。例如,当需要函数调用时,例程必须指定要检索的确切信息或要执行的动作——无论是触发 API、检索外部数据还是提取更多上下文。虽然使用传统的 GPT 类模型自动化此过程可以显著减少所涉及的人工工作量,但它通常会引入新的挑战。一些挑战包括设计足够具体以供 LLM 持续遵循的稳健指令、捕获客户交互期间可能出现的独特边缘案例、提供高质量的少样本示例来指导模型的行为,以及在某些情况下,微调模型以实现更可靠或更专业的结果。

o1 已展示出能够零样本高效地解构这些文章并将它们转换为例程集的能力,这意味着 LLM 可以理解和遵循指令,而无需大量的示例或事先对类似任务进行培训。这最大限度地减少了所需的提示工作量,因为例程结构本身为 LLM 完成每个步骤提供了必要的指导。通过将任务分解为具体动作并在需要时集成函数调用,o1 的方法确保即使是复杂的工作流程也可以由 LLM 无缝处理,从而带来更有效和可扩展的客户服务解决方案。

选择知识库文章

在此示例中,我们将使用来自 OpenAI 网站的一组公开可用的帮助中心文章,并将它们转换为 LLM 可以执行的内部例程。除了将策略转换为例程外,我们还将让模型生成函数,使 LLM 能够代表用户执行操作。这对于允许 LLM 执行人工客服代表所拥有的相同操作,并访问可能无法仅从策略文档中立即获得的额外信息是必要的。

我们将首先使用以下帮助中心文章进行例程转换

from openai import OpenAI
from IPython.display import display, HTML
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
import csv

client = OpenAI()
MODEL = 'o1-preview'

我们的文章存储在一个可访问的 csv 文件中。我们将获取这些文章并并行传递给 o1-preview 以生成初始例程。

我们将策略转换为例程的说明包括

  • 将面向外部的策略文档转换为内部 SOP 例程
  • 将策略分解为具体的操作和子操作
  • 概述步骤之间移动的具体条件
  • 确定可能需要外部知识/操作的位置,并定义我们可以用来获取该信息的函数
articles = []

with open('../data/helpcenter_articles.csv', mode='r', encoding='utf-8') as file:
    reader = csv.DictReader(file)
    for row in reader:
        articles.append({
            "policy": row["policy"],
            "content": row["content"]
        })
CONVERSION_PROMPT = """
You are a helpful assistant tasked with taking an external facing help center article and converting it into a internal-facing programmatically executable routine optimized for an LLM. 
The LLM using this routine will be tasked with reading the policy, answering incoming questions from customers, and helping drive the case toward resolution.

Please follow these instructions:
1. **Review the customer service policy carefully** to ensure every step is accounted for. It is crucial not to skip any steps or policies.
2. **Organize the instructions into a logical, step-by-step order**, using the specified format.
3. **Use the following format**:
   - **Main actions are numbered** (e.g., 1, 2, 3).
   - **Sub-actions are lettered** under their relevant main actions (e.g., 1a, 1b).
      **Sub-actions should start on new lines**
   - **Specify conditions using clear 'if...then...else' statements** (e.g., 'If the product was purchased within 30 days, then...').
   - **For instructions that require more information from the customer**, provide polite and professional prompts to ask for additional information.
   - **For actions that require data from external systems**, write a step to call a function using backticks for the function name (e.g., `call the check_delivery_date function`).
      - **If a step requires the customer service agent to take an action** (e.g., process a refund), generate a function call for this action (e.g., `call the process_refund function`).
      - **Define any new functions** by providing a brief description of their purpose and required parameters.
   - **If there is an action an assistant can performon behalf of the user**, include a function call for this action (e.g., `call the change_email_address function`), and ensure the function is defined with its purpose and required parameters.
      - This action may not be explicitly defined in the help center article, but can be done to help the user resolve their inquiry faster
   - **The step prior to case resolution should always be to ask if there is anything more you can assist with**.
   - **End with a final action for case resolution**: calling the `case_resolution` function should always be the final step.
4. **Ensure compliance** by making sure all steps adhere to company policies, privacy regulations, and legal requirements.
5. **Handle exceptions or escalations** by specifying steps for scenarios that fall outside the standard policy.

**Important**: If at any point you are uncertain, respond with "I don't know."

Please convert the customer service policy into the formatted routine, ensuring it is easy to follow and execute programmatically.

"""
def generate_routine(policy):
    try:
        messages = [
            {
                "role": "user",
                "content": f"""
                    {CONVERSION_PROMPT}

                    POLICY:
                    {policy}
                """
            }
        ]

        response = client.chat.completions.create(
            model=MODEL,
            messages=messages
        )
        

        return response.choices[0].message.content 
    except Exception as e:
        print(f"An error occurred: {e}")
def process_article(article):
    routine = generate_routine(article['content'])
    return {"policy": article['policy'], "content": article['content'], "routine": routine}


with ThreadPoolExecutor() as executor:
    results = list(executor.map(process_article, articles))

我们将例程的结果存储在数据帧中并打印出来,以便我们可以初步了解一下。

df = pd.DataFrame(results)

# Set display options to show all text in the dataframe cells
pd.set_option('display.max_colwidth', None)

# Function to display formatted text in HTML
def display_formatted_dataframe(df):
    def format_text(text):
        return text.replace('\n', '<br>')

    df_formatted = df.copy()
    df_formatted['content'] = df_formatted['content'].apply(format_text)
    df_formatted['routine'] = df_formatted['routine'].apply(format_text)
    
    display(HTML(df_formatted.to_html(escape=False, justify='left')))

display_formatted_dataframe(df)
策略 内容 例程
0 删除付款方式 如何删除我的付款方式?
一周前更新
我们会保留您的付款方式,以支付您帐户上的任何未结费用。要停止向您的付款方式收费,请按照以下步骤操作。

## ChatGPT
您可以随时取消您的 ChatGPT Plus 订阅以停止进一步收费
点击 ChatGPT 侧边栏中的“我的计划”。
点击弹出窗口中的“管理我的订阅”。
选择“取消计划”。
请注意,您的取消将在下一个账单日期的第二天生效,在此之前您可以继续使用我们的服务。为避免在下一个账单周期被收费,请在下一个账单日期前至少 24 小时取消您的订阅。

## API
我们需要保留一种付款方式,以结算任何未结的使用成本。欢迎您取消您的按需付费服务,方法是点击您的账单概览中的“取消付费帐户”。在本月发票开出后,当前卡将不再收费。
如果您想继续使用该服务,请在账单概览页面中添加新的付款方式,然后选择“设置为默认”。然后您就可以删除旧的付款方式。
1. 验证客户的帐户。
a. 礼貌地询问客户他们的电子邮件地址或帐户 ID 以查找他们的帐户。
b. `调用 verify_customer_account(email_or_account_id)`。

2. 验证客户的身份。
a. 礼貌地要求客户提供安全信息以确认其身份(例如,备案付款方式的后四位数字)。
b. `调用 verify_customer_identity(account_id, security_information)`。
c. 如果无法验证客户的身份,则
- 通知客户,出于安全原因,在未进行身份验证的情况下,我们无法继续操作。
- 提供有关他们如何验证身份的指导。
- 继续执行步骤 6。

3. 确定客户的帐户类型。
a. `调用 check_account_type(account_id)`。

4. 如果客户是 ChatGPT Plus 订阅者,则
a. 询问客户是否需要帮助取消他们的 ChatGPT Plus 订阅。
b. 如果客户同意,则
- `调用 cancel_subscription(account_id)`。
- 通知客户他们的订阅已取消,取消将在下一个账单日期的第二天生效。
- 提醒客户他们可以继续使用我们的服务直到那时。
c. 否则
- 向客户提供以下取消订阅的步骤
- 点击 ChatGPT 侧边栏中的 **“我的计划”**。
- 点击弹出窗口中的 **“管理我的订阅”**。
- 选择 **“取消计划”**。
- 通知客户取消生效日期以及在此之前可以继续访问。
- 建议客户在下一个账单日期前至少 24 小时取消,以避免在下一个账单周期被收费。

5. 否则,如果客户是 API 用户,则
a. 通知客户我们需要保留一种付款方式,以结算任何未结的使用成本。
b. 询问客户是否需要帮助取消他们的按需付费服务。
c. 如果客户同意,则
- `调用 cancel_paid_account(account_id)`。
- 通知客户,在本月发票开出后,当前卡将不再收费。
d. 否则
- 向客户提供以下取消按需付费服务的步骤
- 转到 **账单概览** 页面。
- 点击 **“取消付费帐户”**。
- 通知客户,在本月发票开出后,当前卡将不再收费。
e. 如果客户想继续使用该服务但更改付款方式
- 询问客户是否需要帮助添加新的付款方式并将其设置为默认。
- 如果客户同意
- 礼貌地索取新的付款方式详细信息。
- `调用 add_payment_method(account_id, payment_details)`。
- `调用 set_default_payment_method(account_id, new_payment_method_id)`。
- `调用 delete_payment_method(account_id, old_payment_method_id)`。
- 通知客户旧的付款方式已被删除,新的付款方式已设置为默认。
- 否则
- 指示客户在账单概览页面中添加新的付款方式。
- 要求他们为新的付款方式选择 **“设置为默认”**。
- 通知他们然后他们可以删除旧的付款方式。

6. 询问客户是否还有其他可以帮助他们的地方。

7. `调用 case_resolution()`。

---

**函数定义:**

- `verify_customer_account(email_or_account_id)`:使用客户的电子邮件地址或帐户 ID 验证客户的帐户。
**参数:** `email_or_account_id`

- `verify_customer_identity(account_id, security_information)`:使用安全信息确认客户的身份。
**参数:** `account_id`,`security_information`

- `check_account_type(account_id)`:检索客户的帐户类型(ChatGPT Plus 订阅者或 API 用户)。
**参数:** `account_id`

- `cancel_subscription(account_id)`:取消客户的 ChatGPT Plus 订阅。
**参数:** `account_id`

- `cancel_paid_account(account_id)`:取消客户的 API 按需付费服务。
**参数:** `account_id`

- `add_payment_method(account_id, payment_details)`:向客户的帐户添加新的付款方式。
**参数:** `account_id`,`payment_details`

- `set_default_payment_method(account_id, payment_method_id)`:将付款方式设置为客户的默认方式。
**参数:** `account_id`,`payment_method_id`

- `delete_payment_method(account_id, payment_method_id)`:从客户的帐户中删除付款方式。
**参数:** `account_id`,`payment_method_id`

- `case_resolution()`:解决案例并将其标记为已完成。
1 商业伙伴协议 如何与 OpenAI 签订商业伙伴协议 (BAA)?
关于医疗保健公司 HIPAA 合规性的信息

《健康保险流通与责任法案》(HIPAA) 是一项美国联邦法律,要求对受保护的健康信息 (PHI) 进行隐私和安全保护。我们的 API 平台非常适合任何希望处理受保护健康信息的承保实体或业务伙伴,我们很乐意协助您履行 HIPAA 合规性。要使用我们的 API 平台,您首先需要与 OpenAI 签订 BAA。


如何开始?
如果您在使用我们的 API 之前需要 BAA,请发送电子邮件至 baa@openai.com,详细说明您的公司和用例。

我们的团队将在 1-2 个工作日内回复。我们会根据具体情况审核每个 BAA 请求,并且可能需要更多信息。此过程通常在几个工作日内完成。


我可以为 ChatGPT 获取 BAA 吗?
如果您有兴趣为 ChatGPT 企业版探索 BAA,请联系销售部门。


如果我未获批准会怎样?
我们能够批准大多数请求 BAA 的客户,但有时用例无法通过我们团队的评估。在这种情况下,我们将提供反馈和背景信息,说明原因,并让您有机会更新您对我们 API 的预期用途并重新申请。


所有 API 服务都包含在 BAA 中吗?
否,只有符合零保留条件的端点才包含在 BAA 中。您可以查看这些端点的列表。


签署 BAA 是否需要企业协议?
否,签署 BAA 不需要企业协议。
1. 感谢客户并要求澄清
a. “感谢您联系我们!请问您是否需要商业伙伴协议 (BAA) 以使用我们的 API 或 ChatGPT 企业版?”

2. 如果客户需要 API 的 BAA,则
a. 通知客户:“要获得我们 API 的 BAA,请发送电子邮件至 baa@openai.com,详细说明您的公司和用例。”
b. 通知客户:“我们的团队将在 1-2 个工作日内回复。”
c. 通知客户:“我们会根据具体情况审核每个 BAA 请求,并且可能需要更多信息。”
d. 通知客户:“此过程通常在几个工作日内完成。”
e. 通知客户:“请注意,只有符合零数据保留条件的端点才包含在 BAA 中。”
i. 调用 `provide_list_of_zero_retention_endpoints` 函数。
f. 通知客户:“签署 BAA 不需要企业协议。”

3. 如果客户需要 ChatGPT 企业版的 BAA,则
a. 通知客户:“要探索 ChatGPT 企业版的 BAA,请联系我们的销售团队。”
i. 调用 `provide_sales_contact_information` 函数。

4. 如果客户未获批准,则
a. 通知客户:“我们能够批准大多数请求 BAA 的客户,但有时用例无法通过我们团队的评估。”
b. 通知客户:“在这种情况下,我们将提供反馈和背景信息,说明原因,并让您有机会更新您对我们 API 的预期用途并重新申请。”

5. 询问客户是否还有其他可以帮助他们的地方
a. “今天还有什么可以帮您吗?”

6. 调用 `case_resolution` 函数。

---

**函数定义:**

- `provide_list_of_zero_retention_endpoints`
- **目的**:向客户提供符合 BAA 零数据保留条件的 API 端点列表。
- **参数**:无。

- `provide_sales_contact_information`
- **目的**:向客户提供联系信息,以便他们联系我们的销售团队,咨询 ChatGPT 企业版。
- **参数**:无。

- `case_resolution`
- **目的**:完成案例并将其标记为已解决。
- **参数**:无。
2 设置预付账单 如何设置预付账单?

工作原理
预付账单允许 API 用户预先购买使用量。您购买的积分将应用于您的月度发票。这意味着您产生的任何 API 使用量将首先从预付积分中扣除。如果您的使用量超过您购买的积分,您将需要为超出部分付费。
预付账单帮助开发人员了解他们的前期承诺,从而为预算和支出管理提供更高的可预测性。


设置预付账单
如果您使用的是月度账单计划,您也可以选择切换到预付账单并预先购买 API 使用积分。
- 转到您帐户设置中的账单概览
- 点击“开始付款计划”(您可能会看到诸如“购买积分”之类的变体)
注意:如果您之前有应付账款账单计划,您需要先取消此现有付款计划。
- 选择您要购买的初始积分金额。最低购买金额为 5 美元。最高购买金额将根据您的信任等级而定。
- 确认并购买您的初始积分金额。
- 使用自动充值设置自动充值金额,即当您的余额低于设定的阈值时,将添加到您帐户的积分金额。

请注意,任何购买的积分将在 1 年后过期,且不可退款。
购买积分后,您应该可以开始使用 API。请注意,我们的系统更新以反映您的积分余额可能需要几分钟的延迟。


购买更多积分
一旦您用完所有积分,您的 API 请求将开始返回错误,告知您已达到账单配额。如果您想继续使用 API,您可以返回账单门户并使用“添加到余额”按钮购买更多积分。


延迟账单
由于我们的账单和处理系统的复杂性,在您用完所有积分后,我们可能在切断访问权限方面存在延迟。这种超额使用量可能会在您的账单仪表板中显示为负积分余额,并将从您下次购买积分中扣除。
1. `调用 check_billing_plan(user_id)`
- **函数:** `check_billing_plan(user_id)`
- **目的:** 检索用户当前的账单计划(例如,月度账单、预付账单或应付账款账单)。
- **参数:**
- `user_id`:用户的唯一标识符。

2. 如果用户有应付账款账单计划
2a. 通知用户:“请注意,由于您有应付账款账单计划,您需要先取消您现有的付款计划,然后才能切换到预付账单。您需要帮助取消您当前的计划吗?”
2b. 如果用户同意,`调用 cancel_payment_plan(user_id)`
- **函数:** `cancel_payment_plan(user_id)`
- **目的:** 取消用户当前的应付账款账单计划。
- **参数:**
- `user_id`:用户的唯一标识符。

3. 指导用户设置预付账单
3a. 指示用户:“请转到您帐户设置中的账单概览。”
3b. 指示用户:“点击“开始付款计划”(您可能会看到诸如“购买积分”之类的变体)。”
3c. 通知用户:“选择您要购买的初始积分金额。最低购买金额为 5 美元,最高购买金额将根据您的信任等级而定。”
3d. 指示用户:“确认并购买您的初始积分金额。”
3e. 建议用户:“您可以设置自动充值,以便在您的余额低于设定的阈值时自动向您的帐户添加积分。”

4. 通知用户有关积分过期和退款政策
4a. 通知用户:“请注意,任何购买的积分将在 1 年后过期,且不可退款。”

5. 通知用户有关激活时间
5a. 通知用户:“购买积分后,您应该可以开始使用 API。请注意,我们的系统更新以反映您的积分余额可能需要几分钟的延迟。”

6. 询问用户:“今天还有什么可以帮您吗?”

7. 如果用户没有其他问题,`调用 case_resolution()`
- **函数:** `case_resolution()`
- **目的:** 将案例标记为已解决并结束交互。
3 增值税豁免申请 如何提交增值税豁免申请?
一周前更新
如果您符合免税资格并希望将其应用于您的帐户,请按照以下步骤操作

取决于州和是否需要
1. 从您所在的州或当地政府获取最新的免税证明和/或您完全填写的非营利组织销售税免税表格。证明/表格应包括
您的姓名和地址
免税编号
签名和日期等。
2. 使用右下角的聊天小部件向我们发送您的证明副本。请包括您的组织 ID、发票编号或与帐户关联的电子邮件地址,以便我们轻松找到您。有关如何查找这些项目的说明如下。

3. 收到您的证明/表格后,我们将对其进行审核并将免税应用于您的帐户。免税应用后,您将收到确认电子邮件。

请注意,免税仅适用于未来的购买。我们无法追溯应用增值税豁免。



在哪里查找您的帐户数据
为了提交增值税(“VAT”)豁免申请,您将需要您组织的账单偏好中的以下信息
1. 公司名称
2. 账单电子邮件
3. 主要营业地址
4. 营业税 ID
1. 问候客户并确认他们的请求。
1a. 说:“当然,我很乐意帮助您提交增值税豁免申请。”

2. 向客户请求必要的信息。
2a. 礼貌地询问以下内容
- “请问您能提供您的**公司名称**吗?”
- “我可以获取与您的帐户关联的**账单电子邮件**吗?”
- “请问您能提供您的**主要营业地址**吗?”
- “请提供您的**营业税 ID**。”
2b. 如果客户需要帮助查找此信息,请提供指导。
- 说:“您可以在您组织的账单偏好中找到此信息。”

3. 请求客户提供其最新的免税证明副本。
3a. 说:“请问您能向我们发送一份您最新的**免税证明**副本吗?它应包括您的姓名和地址、免税编号、签名和日期。”

4. 指导客户如何发送证明。
4a. 说:“您可以使用**右下角的聊天小部件**向我们发送您的证明副本。”
4b. 说:“请包括您的**组织 ID**、**发票编号**或与您**帐户关联的电子邮件地址**,以便我们轻松找到您。”

5. 一旦客户提供了所需的信息和证明
5a. 使用参数:company_name、billing_email、business_address、business_tax_id、tax_exemption_certificate、account_identifier `调用 process_vat_exemption_request 函数`。
5b. **定义 `process_vat_exemption_request 函数`**
- **目的**:根据提供的信息和证明审核并将增值税豁免应用于客户的帐户。
- **参数**
- company_name
- billing_email
- business_address
- business_tax_id
- tax_exemption_certificate
- account_identifier(组织 ID/发票编号/电子邮件地址)

6. 通知客户
6a. 说:“谢谢。审核您的证明后,我们会将增值税豁免应用于您的帐户。”
6b. 说:“免税应用后,您将收到确认电子邮件。”
6c. 说:“请注意,免税仅适用于未来的购买。我们无法追溯应用增值税豁免。”
6d. 如果客户请求将增值税豁免应用于过去的购买
- 说:“很抱歉,我们无法将增值税豁免应用于过去的购买。增值税豁免一旦应用于您的帐户,将仅适用于未来的购买。”

7. 询问是否还有其他可以帮助您的地方。
7a. 说:“今天还有什么可以帮您吗?”

8. `调用 case_resolution 函数`

结果

在查看生成的例程后,我们可以得出以下几点见解

  • 示例响应:该模型有效地生成了示例响应,LLM 可以在执行策略时使用这些响应(例如,“指示用户:“确认并购买您的初始积分金额。””)。
  • 离散步骤:该模型擅长将问题分解为 LLM 需要执行的离散操作。每个指令都定义明确且易于理解。
  • 函数定义:例程的输出包括明确定义的函数,用于检索外部信息或触发操作(例如,review_and_apply_tax_exemptionget_billing_planupdate_payment_method)。
    • 这对于任何成功的例程都至关重要,因为 LLM 通常需要与外部系统交互。利用函数调用是与这些系统交互和执行操作的有效方法。
  • IFTTT 逻辑:该模型有效地采用了 IFTTT(If This, Then That)逻辑,这对于 LLM 来说是理想的(例如,“如果客户请求帮助,则继续执行步骤 3f。”)。
    • 当原始知识库文章包含复杂的工作流程和图表时,这种类型的翻译变得极其有价值。人类可能不容易理解这种复杂性,LLM 就更不用说了。IFTTT 逻辑易于理解,并且非常适合客户服务解决方案

我们接下来要往哪里去?

这些例程现在可以集成到代理系统中,以解决特定的客户问题。当客户请求帮助执行设置预付账单等任务时,我们可以使用分类器来确定要检索的适当例程,并将其提供给 LLM 以直接与客户交互。除了向用户提供关于如何设置账单的说明之外,系统还可以代表他们执行操作。

在将这些例程部署到生产环境之前,我们应该开发全面的评估来测试和验证模型响应的质量。此过程可能需要调整例程以确保合规性和有效性。