第三章 评估输入——分类¶
在本章中,我们将重点讨论评估输入任务,这对于确保系统的质量和安全性至关重要。
对于需要处理不同情况下的许多独立指令集的任务,首先对查询类型进行分类,并以此为基础确定要使用哪些指令,具有诸多益处。
这可以通过定义固定的类别和 hard-coding 与处理给定类别任务相关的指令来实现。
例如,在构建客户服务助手时,首先对查询类型进行分类,然后根据该分类确定要使用哪些指令,这一点可能非常重要。
举个具体的例子,如果用户要求关闭其帐户,那么二级指令可能是添加有关如何关闭账户的额外说明;而如果用户询问特定产品的信息,则二级指令可能会添加更多的产品信息。
一、环境配置¶
同上一章,我们首先需要配置使用 OpenAI API 的环境
import openai
# 导入第三方库
openai.api_key = "sk-..."
# 设置 API_KEY, 请替换成您自己的 API_KEY
# 以下为基于环境变量的配置方法示例,这样更加安全。仅供参考,后续将不再涉及。
# import openai
# import os
# OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
# openai.api_key = OPENAI_API_KEY
def get_completion_from_messages(messages,
model="gpt-3.5-turbo",
temperature=0,
max_tokens=500):
'''
封装一个访问 OpenAI GPT3.5 的函数
参数:
messages: 这是一个消息列表,每个消息都是一个字典,包含 role(角色)和 content(内容)。角色可以是'system'、'user' 或 'assistant’,内容是角色的消息。
model: 调用的模型,默认为 gpt-3.5-turbo(ChatGPT),有内测资格的用户可以选择 gpt-4
temperature: 这决定模型输出的随机程度,默认为0,表示输出将非常确定。增加温度会使输出更随机。
max_tokens: 这决定模型输出的最大的 token 数。
'''
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=temperature, # 这决定模型输出的随机程度
max_tokens=max_tokens, # 这决定模型输出的最大的 token 数
)
return response.choices[0].message["content"]
二、对用户指令进行分类¶
在这里,我们使用系统消息 (system_message) 作为系统的全局指导,并选用 # 作为分隔符。
分隔符是一种用于区分指令或输出中不同部分的工具,它能帮助模型识别各个部分,从而提高系统在执行特定任务时的准确性和效率。
在这个例子中,我们选择使用 # 作为分隔符。
# 是一个理想的分隔符,因为它可以被视为一个独立的 token。
delimiter = "####"
这是我们的 system message,我们正在以下面的方式询问模型。
system_message = f"""
You will be provided with customer service queries. \
The customer service query will be delimited with \
{delimiter} characters.
Classify each query into a primary category \
and a secondary category.
Provide your output in json format with the \
keys: primary and secondary.
Primary categories: Billing, Technical Support, \
Account Management, or General Inquiry.
Billing secondary categories:
Unsubscribe or upgrade
Add a payment method
Explanation for charge
Dispute a charge
Technical Support secondary categories:
General troubleshooting
Device compatibility
Software updates
Account Management secondary categories:
Password reset
Update personal information
Close account
Account security
General Inquiry secondary categories:
Product information
Pricing
Feedback
Speak to a human
"""
system_message = f"""
你将获得客户服务查询。
每个客户服务查询都将用{delimiter}字符分隔。
将每个查询分类到一个主要类别和一个次要类别中。
以 JSON 格式提供你的输出,包含以下键:primary 和 secondary。
主要类别:计费(Billing)、技术支持(Technical Support)、账户管理(Account Management)或一般咨询(General Inquiry)。
计费次要类别:
取消订阅或升级(Unsubscribe or upgrade)
添加付款方式(Add a payment method)
收费解释(Explanation for charge)
争议费用(Dispute a charge)
技术支持次要类别:
常规故障排除(General troubleshooting)
设备兼容性(Device compatibility)
软件更新(Software updates)
账户管理次要类别:
重置密码(Password reset)
更新个人信息(Update personal information)
关闭账户(Close account)
账户安全(Account security)
一般咨询次要类别:
产品信息(Product information)
定价(Pricing)
反馈(Feedback)
与人工对话(Speak to a human)
"""
现在我们来看一个用户消息(user message)的例子。
user_message = f"""\
I want you to delete my profile and all of my user data"""
user_message = f"""\
我希望你删除我的个人资料和所有用户数据。"""
将这个消息格式化为一个消息列表,系统消息和用户消息使用"####"进行分隔。
我们思考一下,作为人类,这句话属于哪个类别:"我想让您删除我的个人资料。"
这句话看上去属于"Account Management",或者属于"Close account"。
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{user_message}{delimiter}"},
]
让我们看看模型是如何思考的
模型的分类是将"Account Management"作为"primary","Close account"作为"secondary"。
请求结构化输出(如 JSON)的好处是,您可以轻松地将其读入某个对象中,例如 Python 中的字典。如果您使用其他语言,也可以转换为其他对象,然后输入到后续步骤中。
response = get_completion_from_messages(messages)
print(response)
{
"primary": "账户管理",
"secondary": "关闭账户"
}
这是另一个用户消息: "告诉我更多关于你们的平板电视的信息"
我们运用相同的消息列表来获取模型的响应,然后打印出来。
这里返回了另一个分类结果,并且看起来应该是正确的。
user_message = f"""\
Tell me more about your flat screen tvs"""
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{user_message}{delimiter}"},
]
response = get_completion_from_messages(messages)
print(response)
{
"primary": "General Inquiry",
"secondary": "Product information"
}
user_message = f"""\
告诉我更多有关你们的平板电脑的信息"""
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{user_message}{delimiter}"},
]
response = get_completion_from_messages(messages)
print(response)
以下是针对平板电脑的一般咨询:
{
"primary": "General Inquiry",
"secondary": "Product information"
}
如果您有任何特定的问题或需要更详细的信息,请告诉我,我会尽力回答。
因此,根据客户咨询的分类,我们现在可以提供一套更具体的指令来处理后续步骤。
在这种情况下,我们可能会添加关于电视的额外信息,而在其他情况下,我们可能希望提供关闭账户的链接或类似的内容。
在接下来的章节中,我们将进一步了解处理输入的不同方法
在下一章中,我们将探讨更多关于评估输入的方法,特别是如何确保用户以负责任的方式使用系统。