一、处理输入—思维链推理
探讨如何处理语言模型的输入,以生成高质量的输出。将详细介绍如何构建思维链推理 Prompt 。
1.思维链提示设计
这是一种引导语言模型进行逐步推理的 Prompt 设计技巧。通过在 Prompt 中设置系统消息,要求语言模型在给出最终结论之前,先明确各个推理步骤。
具体来讲:Prompt可以先请语言模型陈述对问题的初步理解,然后列出需要考虑的方方面面,最后再逐个分析这些因素,给出支持或反对的论据,才得出整体的结论。
1.1 系统消息设计
首先,在系统消息中使用思维链提示:
delimiter = "===="
system_message = f"""
请按照以下步骤回答客户的提问。客户的提问将以{delimiter}分隔。
步骤 1:{delimiter}首先确定用户是否正在询问有关特定产品或产品的问题。产品类别不计入范围。
步骤 2:{delimiter}如果用户询问特定产品,请确认产品是否在以下列表中。所有可用产品:
产品:TechPro 超极本
类别:计算机和笔记本电脑
品牌:TechPro
型号:TP-UB100
保修期:1 年
评分:4.5
特点:13.3 英寸显示屏,8GB RAM,256GB SSD,Intel Core i5 处理器
描述:一款适用于日常使用的时尚轻便的超极本。
价格:$799.99
产品:BlueWave 游戏笔记本电脑
类别:计算机和笔记本电脑
品牌:BlueWave
型号:BW-GL200
保修期:2 年
评分:4.7
特点:15.6 英寸显示屏,16GB RAM,512GB SSD,NVIDIA GeForce RTX 3060
描述:一款高性能的游戏笔记本电脑,提供沉浸式体验。
价格:$1199.99
产品:PowerLite 可转换笔记本电脑
类别:计算机和笔记本电脑
品牌:PowerLite
型号:PL-CV300
保修期:1年
评分:4.3
特点:14 英寸触摸屏,8GB RAM,256GB SSD,360 度铰链
描述:一款多功能可转换笔记本电脑,具有响应触摸屏。
价格:$699.99
产品:TechPro 台式电脑
类别:计算机和笔记本电脑
品牌:TechPro
型号:TP-DT500
保修期:1年
评分:4.4
特点:Intel Core i7 处理器,16GB RAM,1TB HDD,NVIDIA GeForce GTX 1660
描述:一款功能强大的台式电脑,适用于工作和娱乐。
价格:$999.99
产品:BlueWave Chromebook
类别:计算机和笔记本电脑
品牌:BlueWave
型号:BW-CB100
保修期:1 年
评分:4.1
特点:11.6 英寸显示屏,4GB RAM,32GB eMMC,Chrome OS
描述:一款紧凑而价格实惠的 Chromebook,适用于日常任务。
价格:$249.99
步骤 3:{delimiter} 如果消息中包含上述列表中的产品,请列出用户在消息中做出的任何假设,\
例如笔记本电脑 X 比笔记本电脑 Y 大,或者笔记本电脑 Z 有 2 年保修期。
步骤 4:{delimiter} 如果用户做出了任何假设,请根据产品信息确定假设是否正确。
步骤 5:{delimiter} 如果用户有任何错误的假设,请先礼貌地纠正客户的错误假设(如果适用)。\
只提及或引用可用产品列表中的产品,因为这是商店销售的唯一五款产品。以友好的口吻回答客户。
使用以下格式回答问题:
步骤 1: {delimiter} <步骤 1 的推理>
步骤 2: {delimiter} <步骤 2 的推理>
步骤 3: {delimiter} <步骤 3 的推理>
步骤 4: {delimiter} <步骤 4 的推理>
回复客户: {delimiter} <回复客户的内容>
请确保每个步骤上面的回答中中使用 {delimiter} 对步骤和步骤的推理进行分隔。
"""
1.2用户消息测试
接下来,在用户消息中测试在系统消息中设置的思维链提示:
1.2.1更贵的电脑
user_message = f"""BlueWave Chromebook 比 TechPro 台式电脑贵多少?"""
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{user_message}{delimiter}"},
]
response = get_completion_from_messages(messages)
print(response)
1.2.2你有电视吗
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)
2. 内心独白
在某些应用场景下,完整呈现语言模型的推理过程可能会泄露关键信息或答案,这并不可取。例如在教学应用中,我们希望学生通过自己的思考获得结论,而不是直接被告知答案。针对这一问题。“内心独白”技巧可以在一定程度上隐藏语言模型的推理链。
具体做法是,在 Prompt 中指示语言模型以结构化格式存储需要隐藏的中间推理,例如存储为变量。然后在返回结果时,仅呈现对用户有价值的输出,不展示完整的推理过程。这种提示策略只向用户呈现关键信息,避免透露答案。同时语言模型的推理能力也得以保留。
try:
if delimiter in response:
final_response = response.split(delimiter)[-1].strip()
else:
final_response = response.split(":")[-1].strip()
except Exception as e:
final_response = "对不起,我现在有点问题,请尝试问另外一个问题"
print(final_response)
在复杂任务中,我们往往需要语言模型进行多轮交互、逐步推理,才能完成整个流程。
二、处理输入—链式
链式提示是将复杂任务分解为多个简单Prompt的策略。
优点:①分解复杂度,每个 Prompt 仅处理一个具体子任务,避免过于宽泛的要求,提高成功率。
②降低计算成本。过长的 Prompt 使用更多 tokens ,增加成本。
③更容易测试和调试。可以逐步分析每个环节的性能。
④融入外部工具。不同 Prompt 可以调用 API 、数据库等外部资源。
⑤更灵活的工作流程。
1. 提取产品和类别
第一个子任务是,要求 LLM 从用户查询中提取产品和类别。
from tool import get_completion_from_messages
delimiter = "####"
system_message = f"""
您将获得客户服务查询。
客户服务查询将使用{delimiter}字符作为分隔符。
请仅输出一个可解析的Python列表,列表每一个元素是一个JSON对象,每个对象具有以下格式:
'category': <包括以下几个类别:Computers and Laptops、Smartphones and Accessories、Televisions and Home Theater Systems、Gaming Consoles and Accessories、Audio Equipment、Cameras and Camcorders>,
以及
'products': <必须是下面的允许产品列表中找到的产品列表>
类别和产品必须在客户服务查询中找到。
如果提到了某个产品,它必须与允许产品列表中的正确类别关联。
如果未找到任何产品或类别,则输出一个空列表。
除了列表外,不要输出其他任何信息!
允许的产品:
Computers and Laptops category:
TechPro Ultrabook
BlueWave Gaming Laptop
PowerLite Convertible
TechPro Desktop
BlueWave Chromebook
Smartphones and Accessories category:
SmartX ProPhone
MobiTech PowerCase
SmartX MiniPhone
MobiTech Wireless Charger
SmartX EarBuds
Televisions and Home Theater Systems category:
CineView 4K TV
SoundMax Home Theater
CineView 8K TV
SoundMax Soundbar
CineView OLED TV
Gaming Consoles and Accessories category:
GameSphere X
ProGamer Controller
GameSphere Y
ProGamer Racing Wheel
GameSphere VR Headset
Audio Equipment category:
AudioPhonic Noise-Canceling Headphones
WaveSound Bluetooth Speaker
AudioPhonic True Wireless Earbuds
WaveSound Soundbar
AudioPhonic Turntable
Cameras and Camcorders category:
FotoSnap DSLR Camera
ActionCam 4K
FotoSnap Mirrorless Camera
ZoomMaster Camcorder
FotoSnap Instant Camera
只输出对象列表,不包含其他内容。
"""
user_message_1 = f"""
请告诉我关于 smartx pro phone 和 the fotosnap camera 的信息。
另外,请告诉我关于你们的tvs的情况。 """
messages = [{'role':'system', 'content': system_message},
{'role':'user', 'content': f"{delimiter}{user_message_1}{delimiter}"}]
category_and_product_response_1 = get_completion_from_messages(messages)
print(category_and_product_response_1)
user_message_2 = f"""我的路由器不工作了"""
messages = [{'role':'system','content': system_message},
{'role':'user','content': f"{delimiter}{user_message_2}{delimiter}"}]
response = get_completion_from_messages(messages)
print(response)
2. 检索详细信息
我们产品信息存储在 products.json 中
{ "TechPro Ultrabook": { "名称": "TechPro 超极本", "类别": "电脑和笔记本", "品牌": "TechPro", "型号": "TP-UB100", "保修期": "1 year", "评分": 4.5, "特色": ["13.3-inch display", "8GB RAM", "256GB SSD", "Intel Core i5 处理器"], "描述": "一款时尚轻便的超极本,适合日常使用。", "价格": 799.99 }, "BlueWave Gaming Laptop": { "名称": "BlueWave 游戏本", "类别": "电脑和笔记本", "品牌": "BlueWave", "型号": "BW-GL200", "保修期": "2 years", "评分": 4.7, "特色": ["15.6-inch display", "16GB RAM", "512GB SSD", "NVIDIA GeForce RTX 3060"], "描述": "一款高性能的游戏笔记本电脑,提供沉浸式体验。", "价格": 1199.99 }, "PowerLite Convertible": { "名称": "PowerLite Convertible", "类别": "电脑和笔记本", "品牌": "PowerLite", "型号": "PL-CV300", "保修期": "1 year", "评分": 4.3, "特色": ["14-inch touchscreen", "8GB RAM", "256GB SSD", "360-degree hinge"], "描述": "一款多功能的可转换笔记本电脑,具有灵敏的触摸屏。", "价格": 699.99 }, "TechPro Desktop": { "名称": "TechPro Desktop", "类别": "电脑和笔记本", "品牌": "TechPro", "型号": "TP-DT500", "保修期": "1 year", "评分": 4.4, "特色": ["Intel Core i7 processor", "16GB RAM", "1TB HDD", "NVIDIA GeForce GTX 1660"], "描述": "一款功能强大的台式电脑,适用于工作和娱乐。", "价格": 999.99 }, "BlueWave Chromebook": { "名称": "BlueWave Chromebook", "类别": "电脑和笔记本", "品牌": "BlueWave", "型号": "BW-CB100", "保修期": "1 year", "评分": 4.1, "特色": ["11.6-inch display", "4GB RAM", "32GB eMMC", "Chrome OS"], "描述": "一款紧凑而价格实惠的Chromebook,适用于日常任务。", "价格": 249.99 } }
Python 代码读取产品信息,定义 get_product_by_name 函数,是我们能够根据产品名称获取产品,调用 get_product_by_name 函数,输入产品名称
# 读取产品信息
with open("products_zh.json", "r", encoding='utf-8') as file:
products = json.load(file)
def get_product_by_name(name):
"""
根据产品名称获取产品
参数:
name: 产品名称
"""
for product in products.values():
if product["名称"] == name:
return product
return None
def get_products_by_category(category):
"""
根据类别获取产品
参数:
category: 产品类别
"""
return [product for product in products.values() if product["类别"] == category]
print(get_product_by_name("TechPro 超极本"))
print(get_products_by_category("电脑和笔记本"))
3. 生成查询答案
3.1 解析输入的字符串
定义一个 read_string_to_list 函数,将输入的字符串转换为 Python 列表
def read_string_to_list(input_string):
"""
将输入的字符串转换为 Python 列表。
参数:
input_string: 输入的字符串,应为有效的 JSON 格式。
返回:
list 或 None: 如果输入字符串有效,则返回对应的 Python 列表,否则返回 None。
"""
if input_string is None:
return None
try:
# 将输入字符串中的单引号替换为双引号,以满足 JSON 格式的要求
input_string = input_string.replace("'", "\"")
data = json.loads(input_string)
return data
except json.JSONDecodeError:
print("Error: Invalid JSON string")
return None
category_and_product_list = read_string_to_list(category_and_product_response_1)
print(category_and_product_list)
3.2进行检索
定义函数 generate_output_string 函数,根据输入的数据列表生成包含产品或类别信息的字符串:
def generate_output_string(data_list):
"""
根据输入的数据列表生成包含产品或类别信息的字符串。
参数:
data_list: 包含字典的列表,每个字典都应包含 "products" 或 "category" 的键。
返回:
output_string: 包含产品或类别信息的字符串。
"""
output_string = ""
if data_list is None:
return output_string
for data in data_list:
try:
if "products" in data and data["products"]:
products_list = data["products"]
for product_name in products_list:
product = get_product_by_name(product_name)
if product:
output_string += json.dumps(product, indent=4, ensure_ascii=False) + "\n"
else:
print(f"Error: Product '{product_name}' not found")
elif "category" in data:
category_name = data["category"]
category_products = get_products_by_category(category_name)
for product in category_products:
output_string += json.dumps(product, indent=4, ensure_ascii=False) + "\n"
else:
print("Error: Invalid object format")
except Exception as e:
print(f"Error: {e}")
return output_string
product_information_for_user_message_1 = generate_output_string(category_and_product_list)
print(product_information_for_user_message_1)
3.3生成用户查询的答案
system_message = f"""
您是一家大型电子商店的客服助理。
请以友好和乐于助人的口吻回答问题,并尽量简洁明了。
请确保向用户提出相关的后续问题。
"""
user_message_1 = f"""
请告诉我关于 smartx pro phone 和 the fotosnap camera 的信息。
另外,请告诉我关于你们的tvs的情况。
"""
messages = [{'role':'system','content': system_message},
{'role':'user','content': user_message_1},
{'role':'assistant',
'content': f"""相关产品信息:\n\
{product_information_for_user_message_1}"""}]
final_response = get_completion_from_messages(messages)
print(final_response)
三、检查结果
了解如何评估系统生成的输出。学习如何运用审查(Moderation) API 来对输出进行评估,并深入探讨如何通过额外的 Prompt 提升模型在展示输出之前的质量评估。
1.检查有害内容
通过 OpenAI 提供的 Moderation API 来实现对有害内容的检查。
2.检查是否符合产品信息
要求 LLM 作为一个助理检查回复是否充分回答了客户问题,并验证助理引用的事实是否正确。
final_response_to_customer = f"""
SmartX ProPhone 有一个 6.1 英寸的显示屏,128GB 存储、\
1200 万像素的双摄像头,以及 5G。FotoSnap 单反相机\
有一个 2420 万像素的传感器,1080p 视频,3 英寸 LCD 和\
可更换的镜头。我们有各种电视,包括 CineView 4K 电视,\
55 英寸显示屏,4K 分辨率、HDR,以及智能电视功能。\
我们也有 SoundMax 家庭影院系统,具有 5.1 声道,\
1000W 输出,无线重低音扬声器和蓝牙。关于这些产品或\
我们提供的任何其他产品您是否有任何具体问题?
"""
# 这是一段电子产品相关的信息
system_message = f"""
您是一个助理,用于评估客服代理的回复是否充分回答了客户问题,\
并验证助理从产品信息中引用的所有事实是否正确。
产品信息、用户和客服代理的信息将使用三个反引号(即 ```)\
进行分隔。
请以 Y 或 N 的字符形式进行回复,不要包含标点符号:\
Y - 如果输出充分回答了问题并且回复正确地使用了产品信息\
N - 其他情况。
仅输出单个字母。
"""
#这是顾客的提问
customer_message = f"""
告诉我有关 smartx pro 手机\
和 fotosnap 相机(单反相机)的信息。\
还有您电视的信息。
"""
product_information = """{ "name": "SmartX ProPhone", "category": "Smartphones and Accessories", "brand": "SmartX", "model_number": "SX-PP10", "warranty": "1 year", "rating": 4.6, "features": [ "6.1-inch display", "128GB storage", "12MP dual camera", "5G" ], "description": "A powerful smartphone with advanced camera features.", "price": 899.99 } { "name": "FotoSnap DSLR Camera", "category": "Cameras and Camcorders", "brand": "FotoSnap", "model_number": "FS-DSLR200", "warranty": "1 year", "rating": 4.7, "features": [ "24.2MP sensor", "1080p video", "3-inch LCD", "Interchangeable lenses" ], "description": "Capture stunning photos and videos with this versatile DSLR camera.", "price": 599.99 } { "name": "CineView 4K TV", "category": "Televisions and Home Theater Systems", "brand": "CineView", "model_number": "CV-4K55", "warranty": "2 years", "rating": 4.8, "features": [ "55-inch display", "4K resolution", "HDR", "Smart TV" ], "description": "A stunning 4K TV with vibrant colors and smart features.", "price": 599.99 } { "name": "SoundMax Home Theater", "category": "Televisions and Home Theater Systems", "brand": "SoundMax", "model_number": "SM-HT100", "warranty": "1 year", "rating": 4.4, "features": [ "5.1 channel", "1000W output", "Wireless subwoofer", "Bluetooth" ], "description": "A powerful home theater system for an immersive audio experience.", "price": 399.99 } { "name": "CineView 8K TV", "category": "Televisions and Home Theater Systems", "brand": "CineView", "model_number": "CV-8K65", "warranty": "2 years", "rating": 4.9, "features": [ "65-inch display", "8K resolution", "HDR", "Smart TV" ], "description": "Experience the future of television with this stunning 8K TV.", "price": 2999.99 } { "name": "SoundMax Soundbar", "category": "Televisions and Home Theater Systems", "brand": "SoundMax", "model_number": "SM-SB50", "warranty": "1 year", "rating": 4.3, "features": [ "2.1 channel", "300W output", "Wireless subwoofer", "Bluetooth" ], "description": "Upgrade your TV's audio with this sleek and powerful soundbar.", "price": 199.99 } { "name": "CineView OLED TV", "category": "Televisions and Home Theater Systems", "brand": "CineView", "model_number": "CV-OLED55", "warranty": "2 years", "rating": 4.7, "features": [ "55-inch display", "4K resolution", "HDR", "Smart TV" ], "description": "Experience true blacks and vibrant colors with this OLED TV.", "price": 1499.99 }"""
q_a_pair = f"""
顾客的信息: ```{customer_message}```
产品信息: ```{product_information}```
代理的回复: ```{final_response_to_customer}```
回复是否正确使用了检索的信息?
回复是否充分地回答了问题?
输出 Y 或 N
"""
#判断相关性
messages = [
{'role': 'system', 'content': system_message},
{'role': 'user', 'content': q_a_pair}
]
response = get_completion_from_messages(messages)
print(response)
提供一个负例,LLM 同样能够正确判断
another_response = "生活就像一盒巧克力"
q_a_pair = f"""
顾客的信息: ```{customer_message}```
产品信息: ```{product_information}```
代理的回复: ```{another_response}```
回复是否正确使用了检索的信息?
回复是否充分地回答了问题?
输出 Y 或 N
"""
messages = [
{'role': 'system', 'content': system_message},
{'role': 'user', 'content': q_a_pair}
]
response = get_completion_from_messages(messages)
print(response)
实际上,在真实生产环境中,我们并未看到很多人采取这种方式。这种做法也会增加系统的延迟和成本,因为你需要等待额外的 API 调用,并且需要额外的 token 。如果你的应用或产品的错误率仅为0.0000001%,那么你可能可以尝试这种策略。
四、搭建一个待评估的端到端问答系统
构建一个集成评估环节的完整问答系统。这个系统将会融合我们在前几节课中所学到的知识,并且加入了评估步骤。以下是该系统的核心操作流程:
- 对用户的输入进行检验,验证其是否可以通过审核 API 的标准。
- 若输入顺利通过审核,我们将进一步对产品目录进行搜索。
- 若产品搜索成功,我们将继续寻找相关的产品信息。
- 我们使用模型针对用户的问题进行回答。
- 最后,我们会使用审核 API 对生成的回答进行再次的检验。
如果最终答案没有被标记为有害,那么我们将毫无保留地将其呈现给用户。
1.端到端实现问答系统
先从一个函数开始,它的名称是 process_user_message_ch
,该函数主要负责处理用户输入的信息。这个函数接收三个参数,用户的输入、所有的历史信息,以及一个表示是否需要调试的标志。 在函数的内部,我们首先使用 OpenAI 的 Moderation API 来检查用户输入的合规性。如果输入被标记为不合规,我们将返回一个信息,告知用户请求不合规。
接下来,我们利用 utils_zh.find_category_and_product_only
函数(详细请见附录代码)抽取出用户输入中的商品和对应的目录。然后,我们将抽取的信息转化为一个列表。 在获取到商品列表后,我们将查询这些商品的具体信息。
之后,我们生成一个系统消息,设定一些约束,以确保我们的回应符合期望的标准。我们将生成的消息和历史信息一起送入 get_completion_from_messages
函数,得到模型的回应。
接着,我们再次使用 Moderation API 检查模型的输出是否合规。如果输出不合规,我们将返回一个信息,告知无法提供该信息。
最后,我们让模型自我评估是否很好地回答了用户的问题。如果模型认为回答是满足要求的,我们则返回模型的回答;否则,我们会告知用户,他们将会被转接到人工客服进行进一步的帮助。
import openai
import utils_zh
from tool import get_completion_from_messages
'''
注意:限于模型对中文理解能力较弱,中文 Prompt 可能会随机出现不成功,可以多次运行;也非常欢迎同学探究更稳定的中文 Prompt
'''
def process_user_message_ch(user_input, all_messages, debug=True):
"""
对用户信息进行预处理
参数:
user_input : 用户输入
all_messages : 历史信息
debug : 是否开启 DEBUG 模式,默认开启
"""
# 分隔符
delimiter = "```"
# 第一步: 使用 OpenAI 的 Moderation API 检查用户输入是否合规或者是一个注入的 Prompt
response = openai.Moderation.create(input=user_input)
moderation_output = response["results"][0]
# 经过 Moderation API 检查该输入不合规
if moderation_output["flagged"]:
print("第一步:输入被 Moderation 拒绝")
return "抱歉,您的请求不合规"
# 如果开启了 DEBUG 模式,打印实时进度
if debug: print("第一步:输入通过 Moderation 检查")
# 第二步:抽取出商品和对应的目录,类似于之前课程中的方法,做了一个封装
category_and_product_response = utils_zh.find_category_and_product_only(user_input, utils_zh.get_products_and_category())
#print(category_and_product_response)
# 将抽取出来的字符串转化为列表
category_and_product_list = utils_zh.read_string_to_list(category_and_product_response)
#print(category_and_product_list)
if debug: print("第二步:抽取出商品列表")
# 第三步:查找商品对应信息
product_information = utils_zh.generate_output_string(category_and_product_list)
if debug: print("第三步:查找抽取出的商品信息")
# 第四步:根据信息生成回答
system_message = f"""
您是一家大型电子商店的客户服务助理。\
请以友好和乐于助人的语气回答问题,并提供简洁明了的答案。\
请确保向用户提出相关的后续问题。
"""
# 插入 message
messages = [
{'role': 'system', 'content': system_message},
{'role': 'user', 'content': f"{delimiter}{user_input}{delimiter}"},
{'role': 'assistant', 'content': f"相关商品信息:\n{product_information}"}
]
# 获取 GPT3.5 的回答
# 通过附加 all_messages 实现多轮对话
final_response = get_completion_from_messages(all_messages + messages)
if debug:print("第四步:生成用户回答")
# 将该轮信息加入到历史信息中
all_messages = all_messages + messages[1:]
# 第五步:基于 Moderation API 检查输出是否合规
response = openai.Moderation.create(input=final_response)
moderation_output = response["results"][0]
# 输出不合规
if moderation_output["flagged"]:
if debug: print("第五步:输出被 Moderation 拒绝")
return "抱歉,我们不能提供该信息"
if debug: print("第五步:输出经过 Moderation 检查")
# 第六步:模型检查是否很好地回答了用户问题
user_message = f"""
用户信息: {delimiter}{user_input}{delimiter}
代理回复: {delimiter}{final_response}{delimiter}
回复是否足够回答问题
如果足够,回答 Y
如果不足够,回答 N
仅回答上述字母即可
"""
# print(final_response)
messages = [
{'role': 'system', 'content': system_message},
{'role': 'user', 'content': user_message}
]
# 要求模型评估回答
evaluation_response = get_completion_from_messages(messages)
# print(evaluation_response)
if debug: print("第六步:模型评估该回答")
# 第七步:如果评估为 Y,输出回答;如果评估为 N,反馈将由人工修正答案
if "Y" in evaluation_response: # 使用 in 来避免模型可能生成 Yes
if debug: print("第七步:模型赞同了该回答.")
return final_response, all_messages
else:
if debug: print("第七步:模型不赞成该回答.")
neg_str = "很抱歉,我无法提供您所需的信息。我将为您转接到一位人工客服代表以获取进一步帮助。"
return neg_str, all_messages
user_input = "请告诉我关于 smartx pro phone 和 the fotosnap camera 的信息。另外,请告诉我关于你们的tvs的情况。"
response,_ = process_user_message_ch(user_input,[])
print(response)
2.持续收集用户和助手消息
打造了一个友好的可视化界面,以促进用户与助手之间的便捷互动。
# 调用中文 Prompt 版本
def collect_messages_ch(debug=True):
"""
用于收集用户的输入并生成助手的回答
参数:
debug: 用于觉得是否开启调试模式
"""
user_input = inp.value_input
if debug: print(f"User Input = {user_input}")
if user_input == "":
return
inp.value = ''
global context
# 调用 process_user_message 函数
#response, context = process_user_message(user_input, context, utils.get_products_and_category(),debug=True)
response, context = process_user_message_ch(user_input, context, debug=False)
# print(response)
context.append({'role':'assistant', 'content':f"{response}"})
panels.append(
pn.Row('User:', pn.pane.Markdown(user_input, width=600)))
panels.append(
pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'})))
return pn.Column(*panels) # 包含了所有的对话信息
import panel as pn # 用于图形化界面
pn.extension()
panels = [] # collect display
# 系统信息
context = [ {'role':'system', 'content':"You are Service Assistant"} ]
inp = pn.widgets.TextInput( placeholder='Enter text here…')
button_conversation = pn.widgets.Button(name="Service Assistant")
interactive_conversation = pn.bind(collect_messages_ch, button_conversation)
dashboard = pn.Column(
inp,
pn.Row(button_conversation),
pn.panel(interactive_conversation, loading_indicator=True, height=300),
)
dashboard
通过监控该问答系统在更多输入上的回答效果,您可以修改步骤,提高系统的整体性能