🔥博客主页:西瓜WiFi
🎥系列专栏:《大语言模型》
很多非常有趣的模型,值得收藏,满足大家的收集癖! 如果觉得有用,请三连👍⭐❤️,谢谢!
长期不定时更新,欢迎watch和fork!❤️❤️❤️
❤️感谢大家点赞👍 收藏⭐ 评论⭐
🎥大语言模型LLM基础-系列文章:
【大语言模型LLM】- AI工具收录集合,一篇就够了!
【大语言模型LLM】-大语言模型如何编写Prompt?
【大语言模型LLM】-如何使用大语言模型提高工作效率?
【大语言模型LLM】-使用大语言模型搭建点餐机器人
【大语言模型LLM】-基础语言模型和指令微调的语言模型
【大语言模型LLM】-基于ChatGPT搭建客服助手(1)
⭐持续更新中…
接上一篇【大语言模型LLM】-基于ChatGPT搭建客服助手(1),本篇我们将不局限于使用ChatGPT的API,还将调用使用Ollama+LLM部署在本地的大语言模型,实现机器人助手的私有化搭建。这部分内容融合了我们前面几篇的全部内容。并且加入了评估步骤。以下是该系统的核心操作流程:
- 根据用户输入,获取相关产品信息。
- 若产品搜索成功,我们将继续寻找相关的详细产品信息。
- 我们使用模型针对用户的问题进行回答。
- 最后,让模型自己评估回答是否符合用户需求。
最终,将审核通过的答案呈现给用户。
第一部分 根据用户的输入获取产品列表
import json
from collections import defaultdict
# 获取商品和目录
def get_products_and_category(products_file):
try:
with open(products_file, 'r') as file:
products = json.load(file)
except FileNotFoundError:
print('产品文件不存在!')
return None
except json.JSONDecodeError:
print('产品文件格式错误!')
return None
# 利用 defaultdict 创建一个空列表,用于存放不同类别的产品信息
products_by_category = defaultdict(list)
# 循环遍历产品信息
for product_name, product_info in products.items():
# 获取产品类别的信息
category = product_info.get('category')
# 如果产品类别存在,则将产品名称添加到对应的列表中
if category:
products_by_category[category].append(product_info.get('name'))
# 返回产品按类别分组的信息
return dict(products_by_category)
# 将字符串转换为列表
def read_string_to_list(input_string):
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(input_string)
print("错误:非法的 Json 格式")
return None
# 获取目录和产品
def find_category_and_product_only(user_input,products_and_category):
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
只输出对象列表,不包含其他内容。
"""
messages = [
{'role':'system', 'content': system_message},
{'role':'user', 'content': f"{delimiter}{user_input}{delimiter}"},
]
return get_gemma_response(messages)
# 商品和目录的数据文件
products_file = 'products.json'
categories_file = 'categories.json'
# 获取目录和产品
category_and_product_response = find_category_and_product_only('你好,有电视机嘛?',products_and_category)
# 将字符串转换为列表
category_and_product_list = read_string_to_list(category_and_product_response)
print("第一步:抽取出商品列表")
print('- '*65)
print(category_and_product_list)
输出结果:
第一步:抽取出商品列表
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[{'category': 'Televisions and Home Theater Systems', 'products': ['CineView 4K TV', 'CineView 8K TV', 'CineView OLED TV']}]
第二部分 根据商品列表抽取商品信息
# 商品信息的搜索
def get_product_by_name(name):
products = get_products()
return products.get(name, None)
# 根据商品列表抽取商品信息
def generate_output_string(data_list):
"""
根据商品列表抽取商品信息并生成输出字符串。
参数:
data_list:包含商品信息的列表。
返回:
输出字符串。
"""
output_string = ""
# 如果输入列表为 None,则返回空字符串。
if data_list is None:
return output_string
# 循环遍历数据列表中的每个项目。
for data in data_list:
try:
# 如果项目包含 "products" 字段,则获取产品列表并循环遍历产品名称。
if "products" in data:
products_list = data["products"]
for product_name in products_list:
# 获取产品名称对应的产品对象。
product = get_product_by_name(product_name)
# 如果产品存在,则将其转换为 JSON 字符串并将其追加到输出字符串中。
if product:
output_string += json.dumps(product, indent=4) + "\n"
# 如果产品不存在,则打印错误信息。
else:
print(f"错误: 商品 '{product_name}' 没有找到")
# 如果项目包含 "category" 字段,则获取该类别的产品列表并循环遍历产品。
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) + "\n"
# 如果数据格式不正确,则打印错误信息。
else:
print("错误:非法的商品格式")
# 捕获所有异常并打印错误信息。
except Exception as e:
print(f"Error: {e}")
return output_string
product_information = generate_output_string(category_and_product_list)
print("第二步:抽取商品信息")
print('- '*65)
print(product_information)
输出结果:
第二步:抽取商品信息
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{
"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": "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": "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
}
第三部分 根据信息生成回答
def get_assistant_response(user_input,all_messages):
# 分隔符
delimiter = '''```'''
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}"}
]
# print(messages)
# 获取 LLM 的回答
# 通过附加 all_messages 实现多轮对话
final_response = get_gemma_response(all_messages + messages)
# 将该轮信息加入到历史信息中
all_messages = all_messages + messages[1:]
return final_response
final_response = get_assistant_response('你好,有电视机嘛?',[])
print("第三步:获取助手回答")
print('- '*65)
print(final_response)
第四部分 检查模型是否很好的回答了问题
def check_assistant_reponse(final_response,all_messages,debug = True):
# 分隔符
delimiter = '''```'''
system_message = f"""
您是一家大型电子商店的客户服务助理。\
请以友好和乐于助人的语气回答问题,并提供简洁明了的答案。\
请确保向用户提出相关的后续问题。
"""
user_message = f"""
用户信息: {delimiter}{user_input}{delimiter}
代理回复: {delimiter}{final_response}{delimiter}
回复是否足够回答问题
如果足够,回答 Y
如果不足够,回答 N
仅回答上述字母即可
"""
print(user_message)
messages = [
{'role': 'system', 'content': system_message},
{'role': 'user', 'content': user_message}
]
# 要求模型评估回答
evaluation_response = get_gemma_response(messages)
print(evaluation_response)
if debug: print("第四步:模型评估该回答")
# 第七步:如果评估为 Y,输出回答;如果评估为 N,反馈将由人工修正答案
# 使用 in 来避免模型可能生成 Yes
if "Y" in evaluation_response:
if debug: print("第五步:模型赞同了该回答.")
return final_response, all_messages
else:
if debug: print("第六步:模型不赞成该回答.")
neg_str = "很抱歉,我无法提供您所需的信息。我将为您转接到一位人工客服代表以获取进一步帮助。"
return neg_str, all_messages
check_response_result = check_assistant_reponse(final_response,[])
print(check_response_result )
输出结果:
用户信息: ```请告诉我关于 smartx pro phone 和 the fotosnap camera 的信息。另外,请告诉我关于你们的tvs的情况。```
代理回复: ```...
请问您对哪种电视机感兴趣?```
回复是否足够回答问题
如果足够,回答 Y
如果不足够,回答 N
仅回答上述字母即可
N
第四步:模型评估该回答
第六步:模型不赞成该回答.
('很抱歉,我无法提供您所需的信息。我将为您转接到一位人工客服代表以获取进一步帮助。', [])
这里模型的回答没有通过自己的检查,我们需要注意到,在中文的理解和处理方面,由于模型的特性,我们可能会偶尔遇到不理想的结果。在这种情况下,可以多尝试几次,或者进行深入的研究,以找到更稳定的方法。
第五部分 客服助手全部代码
import json
import requests
from collections import defaultdict
# 商品和目录的数据文件
products_file = 'products.json'
categories_file = 'categories.json'
# 分隔符
delimiter = "####"
# 第二步(抽取商品)系统信息文本
step_2_system_message_content = f"""
您将获得一次客户服务对话。最近的用户查询将使用{delimiter}字符进行分隔。
输出一个Python对象列表,其中每个对象具有以下格式:
'category': <包括以下几个类别:Computers and Laptops、martphones and Accessories、elevisions and Home Theater Systems、elevisions and Home Theater Systems、elevisions and Home Theater Systems、'category': <包括以下几个类别:Computers and Laptops、martphones and Accessories、elevisions and Home Theater Systems、elevisions and Home Theater Systems、elevisions and Home Theater Systems、相机和摄像机>,
或者
'products': <必须是下面的允许产品列表中找到的产品>
类别和产品必须在客户服务查询中找到。
如果提到了产品,它必须与下面的允许产品列表中的正确类别相关联。
如果未找到任何产品或类别,请输出一个空列表。
只列出之前对话的早期部分未提及和讨论的产品和类别。
允许的产品:
Computers and Laptops类别:
TechPro Ultrabook
BlueWave Gaming Laptop
PowerLite Convertible
TechPro Desktop
BlueWave Chromebook
Smartphones and Accessories类别:
SmartX ProPhone
MobiTech PowerCase
SmartX MiniPhone
MobiTech Wireless Charger
SmartX EarBuds
Televisions and Home Theater Systems类别:
CineView 4K TV
SoundMax Home Theater
CineView 8K TV
SoundMax Soundbar
CineView OLED TV
Gaming Consoles and Accessories类别:
GameSphere X
ProGamer Controller
GameSphere Y
ProGamer Racing Wheel
GameSphere VR Headset
Audio Equipment类别:
AudioPhonic Noise-Canceling Headphones
WaveSound Bluetooth Speaker
AudioPhonic True Wireless Earbuds
WaveSound Soundbar
AudioPhonic Turntable
Cameras and Camcorders类别:
FotoSnap DSLR Camera
ActionCam 4K
FotoSnap Mirrorless Camera
ZoomMaster Camcorder
FotoSnap Instant Camera
只输出对象列表,不包含其他内容。
"""
step_2_system_message = {'role':'system', 'content': step_2_system_message_content}
# 第四步(生成用户回答)的系统信息
step_4_system_message_content = f"""
你是一家大型电子商店的客户服务助理。
以友好和乐于助人的语气回答,回答保持简洁明了。
确保让用户提出相关的后续问题。
"""
step_4_system_message = {'role':'system', 'content': step_4_system_message_content}
# 第六步(验证模型回答)的系统信息
step_6_system_message_content = f"""
你是一个助手,评估客户服务代理的回答是否足够回答客户的问题,并验证助手从产品信息中引用的所有事实是否正确。
对话历史、产品信息、用户和客户服务代理的消息将用```进行分隔。
请用一个字母回答,不带标点符号:
Y - 如果输出足够回答问题,并且回答正确使用了产品信息
N - 输出不足够回答问题,或者没有正确使用产品信息
只输出一个字母。
"""
step_6_system_message = {'role':'system', 'content': step_6_system_message_content}
def get_gemma_response(messages,model='llama3'):
'''
prompt: 对应的提示词
Data 参数:
model:(必需)模型名称
messages:聊天消息,这可用于保持聊天记忆
消息对象具有以下字段:
role:消息的角色,可以是system、user或assistant
content:消息的内容
images(可选):要包含在消息中的图像列表(用于多模态模型,如llava)
高级参数(可选):
format:返回响应的格式。当前唯一接受的值是json
options:在Modelfile文档中列出的额外模型参数,如temperature
stream:如果为false,则响应将作为单个响应对象返回,而不是对象流
keep_alive:控制模型在请求后保持加载到内存中的时间(默认值:5m)
'''
# Ollama 本地 API 接口
url = 'http://localhost:11434/api/chat'
# 定义请求的数据
data = {
"model": model,
"messages": messages,
"stream": False
}
# 发送 POST 请求
response = requests.post(url, json=data)
response_data = response.json()
return response_data['message']['content']
# 创建目录(如果没有本地目录文件,需要创建一份)
def create_categories():
categories_dict = {
'Billing': [
'Unsubscribe or upgrade',
'Add a payment method',
'Explanation for charge',
'Dispute a charge'],
'Technical Support':[
'General troubleshooting',
'Device compatibility',
'Software updates'],
'Account Management':[
'Password reset',
'Update personal information',
'Close account',
'Account security'],
'General Inquiry':[
'Product information',
'Pricing',
'Feedback',
'Speak to a human']
}
with open(categories_file, 'w') as file:
json.dump(categories_dict, file)
return categories_dict
# 获取目录数据
def get_categories():
with open(categories_file, 'r') as file:
categories = json.load(file)
return categories
# 获取商品列表
def get_product_list():
products = get_products()
product_list = []
for product in products.keys():
product_list.append(product)
return product_list
# 获取商品和目录
def get_products_and_category():
# 获取所有商品
products = get_products()
# 使用 defaultdict初始化一个空字典,用于将商品分组到目录中
products_by_category = defaultdict(list)
# 遍历所有商品
for product_name, product_info in products.items():
# 获取商品的目录
category = product_info.get('category')
# 如果目录存在,则将商品名称添加到该目录的列表中
if category:
products_by_category[category].append(product_info.get('name'))
# 返回商品按目录分组的字典
return dict(products_by_category)
# 从商品数据中获取
def get_products():
with open(products_file, 'r') as file:
products = json.load(file)
return products
# 从用户问题中抽取商品和类别
def find_category_and_product(user_input,products_and_category):
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': <必须是下面的允许产品列表中找到的产品列表>
其中类别和产品必须在客户服务查询中找到。
如果提到了产品,则必须将其与允许产品列表中的正确类别关联。
如果未找到任何产品或类别,则输出一个空列表。
除了列表外,不要输出其他任何信息!
允许的产品以JSON格式提供。
每个项的键表示类别。
每个项的值是该类别中的产品列表。
允许的产品:{products_and_category}
"""
messages = [
{'role':'system', 'content': system_message},
{'role':'user', 'content': f"{delimiter}{user_input}{delimiter}"},
]
return get_gemma_response(messages)
# 相比上一个函数,可获取的商品直接在 template 中限定
def find_category_and_product_only(user_input,products_and_category):
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
只输出对象列表,不包含其他内容。
"""
messages = [
{'role':'system', 'content': system_message},
{'role':'user', 'content': f"{delimiter}{user_input}{delimiter}"},
]
return get_gemma_response(messages)
# 从问题中抽取商品
def get_products_from_query(user_msg):
products_and_category = get_products_and_category()
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': <必须是下面的允许产品列表中找到的产品列表>
类别和产品必须在客户服务查询中找到。
如果提到了某个产品,它必须与允许产品列表中的正确类别关联。
如果未找到任何产品或类别,则输出一个空列表。
除了列表外,不要输出其他任何信息!
允许的产品以JSON格式提供。
每个项目的键表示类别。
每个项目的值是该类别中的产品列表。
以下是允许的产品:{products_and_category}
"""
messages = [
{'role':'system', 'content': system_message},
{'role':'user', 'content': f"{delimiter}{user_msg}{delimiter}"},
]
category_and_product_response = get_gemma_response(messages)
return category_and_product_response
# 商品信息的搜索
def get_product_by_name(name):
products = get_products()
return products.get(name, None)
def get_products_by_category(category):
products = get_products()
return [product for product in products.values() if product["category"] == category]
# 获取提及的商品信息
def get_mentioned_product_info(data_list):
# 初始化一个空列表来保存商品信息
product_info_l = []
# 如果输入列表为空,则返回空列表
if data_list is None:
return product_info_l
# 遍历数据列表
for data in data_list:
try:
# 检查数据中是否存在 "products" 字段,如果是则获取商品列表
if "products" in data:
products_list = data["products"]
# 遍历商品列表
for product_name in products_list:
# 获取商品信息,并将其添加到商品信息列表中
product = get_product_by_name(product_name)
if product:
product_info_l.append(product)
# 如果商品未找到,则打印错误信息
else:
print(f"错误: 商品 '{product_name}' 未找到")
# 检查数据中是否存在 "category" 字段,如果是则获取该类别的商品信息
elif "category" in data:
category_name = data["category"]
# 获取该类别的商品信息
category_products = get_products_by_category(category_name)
# 遍历商品信息列表并将其添加到商品信息列表中
for product in category_products:
product_info_l.append(product)
# 如果数据格式非法,则打印错误信息
else:
print("错误:非法的商品格式")
# 捕获任何异常并打印错误信息
except Exception as e:
print(f"Error: {e}")
# 返回商品信息列表
return product_info_l
def read_string_to_list(input_string):
if input_string is None:
return None
try:
input_string = input_string.replace("'", "\"") # Replace single quotes with double quotes for valid JSON
data = json.loads(input_string)
return data
except json.JSONDecodeError:
print(input_string)
print("错误:非法的 Json 格式")
return None
# 生成输出字符串
def generate_output_string(data_list):
"""
从数据列表中生成输出字符串。
参数:
data_list:包含商品或目录信息的列表。
返回:
输出字符串。
"""
output_string = ""
# 如果数据列表为空,则返回空字符串。
if data_list is None:
return output_string
# 遍历数据列表。
for data in data_list:
try:
# 检查数据是否包含 "products" 或 "category" 字段。
if "products" in data:
# 获取产品列表。
products_list = data["products"]
# 遍历产品列表。
for product_name in products_list:
# 获取商品信息。
product = get_product_by_name(product_name)
# 如果商品存在,则将其转换为 JSON 字符串并添加到输出字符串中。
if product:
output_string += json.dumps(product, indent=4) + "\n"
else:
# 如果商品不存在,则打印错误信息。
print(f"错误: 商品 '{product_name}' 没有找到")
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) + "\n"
else:
# 打印错误信息。
print("错误:非法的商品格式")
except Exception as e:
# 打印错误信息。
print(f"Error: {e}")
# 返回输出字符串。
return output_string
# Example usage:
#product_information_for_user_message_1 = generate_output_string(category_and_product_list)
#print(product_information_for_user_message_1)
# 回答用户问题
def answer_user_msg(user_msg,product_info):
"""
代码参见第五节课
"""
delimiter = "####"
system_message = f"""
您是一家大型电子商店的客户服务助理。\
请用友好和乐于助人的口吻回答问题,提供简洁明了的答案。\
确保向用户提出相关的后续问题。
"""
# user_msg = f"""
# tell me about the smartx pro phone and the fotosnap camera, the dslr one. Also what tell me about your tvs"""
messages = [
{'role':'system', 'content': system_message},
{'role':'user', 'content': f"{delimiter}{user_msg}{delimiter}"},
{'role':'assistant', 'content': f"相关产品信息:\n{product_info}"},
]
response = get_gemma_response(messages)
return response
# 创建并存入商品数据
def create_products():
# product information
# fun fact: all these products are fake and were generated by a language model
products = {
"TechPro Ultrabook": {
"name": "TechPro Ultrabook",
"category": "Computers and Laptops",
"brand": "TechPro",
"model_number": "TP-UB100",
"warranty": "1 year",
"rating": 4.5,
"features": ["13.3-inch display", "8GB RAM", "256GB SSD", "Intel Core i5 processor"],
"description": "A sleek and lightweight ultrabook for everyday use.",
"price": 799.99
},
"BlueWave Gaming Laptop": {
"name": "BlueWave Gaming Laptop",
"category": "Computers and Laptops",
"brand": "BlueWave",
"model_number": "BW-GL200",
"warranty": "2 years",
"rating": 4.7,
"features": ["15.6-inch display", "16GB RAM", "512GB SSD", "NVIDIA GeForce RTX 3060"],
"description": "A high-performance gaming laptop for an immersive experience.",
"price": 1199.99
},
"PowerLite Convertible": {
"name": "PowerLite Convertible",
"category": "Computers and Laptops",
"brand": "PowerLite",
"model_number": "PL-CV300",
"warranty": "1 year",
"rating": 4.3,
"features": ["14-inch touchscreen", "8GB RAM", "256GB SSD", "360-degree hinge"],
"description": "A versatile convertible laptop with a responsive touchscreen.",
"price": 699.99
},
"TechPro Desktop": {
"name": "TechPro Desktop",
"category": "Computers and Laptops",
"brand": "TechPro",
"model_number": "TP-DT500",
"warranty": "1 year",
"rating": 4.4,
"features": ["Intel Core i7 processor", "16GB RAM", "1TB HDD", "NVIDIA GeForce GTX 1660"],
"description": "A powerful desktop computer for work and play.",
"price": 999.99
},
"BlueWave Chromebook": {
"name": "BlueWave Chromebook",
"category": "Computers and Laptops",
"brand": "BlueWave",
"model_number": "BW-CB100",
"warranty": "1 year",
"rating": 4.1,
"features": ["11.6-inch display", "4GB RAM", "32GB eMMC", "Chrome OS"],
"description": "A compact and affordable Chromebook for everyday tasks.",
"price": 249.99
},
"SmartX ProPhone": {
"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
},
"MobiTech PowerCase": {
"name": "MobiTech PowerCase",
"category": "Smartphones and Accessories",
"brand": "MobiTech",
"model_number": "MT-PC20",
"warranty": "1 year",
"rating": 4.3,
"features": ["5000mAh battery", "Wireless charging", "Compatible with SmartX ProPhone"],
"description": "A protective case with built-in battery for extended usage.",
"price": 59.99
},
"SmartX MiniPhone": {
"name": "SmartX MiniPhone",
"category": "Smartphones and Accessories",
"brand": "SmartX",
"model_number": "SX-MP5",
"warranty": "1 year",
"rating": 4.2,
"features": ["4.7-inch display", "64GB storage", "8MP camera", "4G"],
"description": "A compact and affordable smartphone for basic tasks.",
"price": 399.99
},
"MobiTech Wireless Charger": {
"name": "MobiTech Wireless Charger",
"category": "Smartphones and Accessories",
"brand": "MobiTech",
"model_number": "MT-WC10",
"warranty": "1 year",
"rating": 4.5,
"features": ["10W fast charging", "Qi-compatible", "LED indicator", "Compact design"],
"description": "A convenient wireless charger for a clutter-free workspace.",
"price": 29.99
},
"SmartX EarBuds": {
"name": "SmartX EarBuds",
"category": "Smartphones and Accessories",
"brand": "SmartX",
"model_number": "SX-EB20",
"warranty": "1 year",
"rating": 4.4,
"features": ["True wireless", "Bluetooth 5.0", "Touch controls", "24-hour battery life"],
"description": "Experience true wireless freedom with these comfortable earbuds.",
"price": 99.99
},
"CineView 4K TV": {
"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
},
"SoundMax Home Theater": {
"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
},
"CineView 8K TV": {
"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
},
"SoundMax Soundbar": {
"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
},
"CineView OLED TV": {
"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
},
"GameSphere X": {
"name": "GameSphere X",
"category": "Gaming Consoles and Accessories",
"brand": "GameSphere",
"model_number": "GS-X",
"warranty": "1 year",
"rating": 4.9,
"features": ["4K gaming", "1TB storage", "Backward compatibility", "Online multiplayer"],
"description": "A next-generation gaming console for the ultimate gaming experience.",
"price": 499.99
},
"ProGamer Controller": {
"name": "ProGamer Controller",
"category": "Gaming Consoles and Accessories",
"brand": "ProGamer",
"model_number": "PG-C100",
"warranty": "1 year",
"rating": 4.2,
"features": ["Ergonomic design", "Customizable buttons", "Wireless", "Rechargeable battery"],
"description": "A high-quality gaming controller for precision and comfort.",
"price": 59.99
},
"GameSphere Y": {
"name": "GameSphere Y",
"category": "Gaming Consoles and Accessories",
"brand": "GameSphere",
"model_number": "GS-Y",
"warranty": "1 year",
"rating": 4.8,
"features": ["4K gaming", "500GB storage", "Backward compatibility", "Online multiplayer"],
"description": "A compact gaming console with powerful performance.",
"price": 399.99
},
"ProGamer Racing Wheel": {
"name": "ProGamer Racing Wheel",
"category": "Gaming Consoles and Accessories",
"brand": "ProGamer",
"model_number": "PG-RW200",
"warranty": "1 year",
"rating": 4.5,
"features": ["Force feedback", "Adjustable pedals", "Paddle shifters", "Compatible with GameSphere X"],
"description": "Enhance your racing games with this realistic racing wheel.",
"price": 249.99
},
"GameSphere VR Headset": {
"name": "GameSphere VR Headset",
"category": "Gaming Consoles and Accessories",
"brand": "GameSphere",
"model_number": "GS-VR",
"warranty": "1 year",
"rating": 4.6,
"features": ["Immersive VR experience", "Built-in headphones", "Adjustable headband", "Compatible with GameSphere X"],
"description": "Step into the world of virtual reality with this comfortable VR headset.",
"price": 299.99
},
"AudioPhonic Noise-Canceling Headphones": {
"name": "AudioPhonic Noise-Canceling Headphones",
"category": "Audio Equipment",
"brand": "AudioPhonic",
"model_number": "AP-NC100",
"warranty": "1 year",
"rating": 4.6,
"features": ["Active noise-canceling", "Bluetooth", "20-hour battery life", "Comfortable fit"],
"description": "Experience immersive sound with these noise-canceling headphones.",
"price": 199.99
},
"WaveSound Bluetooth Speaker": {
"name": "WaveSound Bluetooth Speaker",
"category": "Audio Equipment",
"brand": "WaveSound",
"model_number": "WS-BS50",
"warranty": "1 year",
"rating": 4.5,
"features": ["Portable", "10-hour battery life", "Water-resistant", "Built-in microphone"],
"description": "A compact and versatile Bluetooth speaker for music on the go.",
"price": 49.99
},
"AudioPhonic True Wireless Earbuds": {
"name": "AudioPhonic True Wireless Earbuds",
"category": "Audio Equipment",
"brand": "AudioPhonic",
"model_number": "AP-TW20",
"warranty": "1 year",
"rating": 4.4,
"features": ["True wireless", "Bluetooth 5.0", "Touch controls", "18-hour battery life"],
"description": "Enjoy music without wires with these comfortable true wireless earbuds.",
"price": 79.99
},
"WaveSound Soundbar": {
"name": "WaveSound Soundbar",
"category": "Audio Equipment",
"brand": "WaveSound",
"model_number": "WS-SB40",
"warranty": "1 year",
"rating": 4.3,
"features": ["2.0 channel", "80W output", "Bluetooth", "Wall-mountable"],
"description": "Upgrade your TV's audio with this slim and powerful soundbar.",
"price": 99.99
},
"AudioPhonic Turntable": {
"name": "AudioPhonic Turntable",
"category": "Audio Equipment",
"brand": "AudioPhonic",
"model_number": "AP-TT10",
"warranty": "1 year",
"rating": 4.2,
"features": ["3-speed", "Built-in speakers", "Bluetooth", "USB recording"],
"description": "Rediscover your vinyl collection with this modern turntable.",
"price": 149.99
},
"FotoSnap DSLR Camera": {
"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
},
"ActionCam 4K": {
"name": "ActionCam 4K",
"category": "Cameras and Camcorders",
"brand": "ActionCam",
"model_number": "AC-4K",
"warranty": "1 year",
"rating": 4.4,
"features": ["4K video", "Waterproof", "Image stabilization", "Wi-Fi"],
"description": "Record your adventures with this rugged and compact 4K action camera.",
"price": 299.99
},
"FotoSnap Mirrorless Camera": {
"name": "FotoSnap Mirrorless Camera",
"category": "Cameras and Camcorders",
"brand": "FotoSnap",
"model_number": "FS-ML100",
"warranty": "1 year",
"rating": 4.6,
"features": ["20.1MP sensor", "4K video", "3-inch touchscreen", "Interchangeable lenses"],
"description": "A compact and lightweight mirrorless camera with advanced features.",
"price": 799.99
},
"ZoomMaster Camcorder": {
"name": "ZoomMaster Camcorder",
"category": "Cameras and Camcorders",
"brand": "ZoomMaster",
"model_number": "ZM-CM50",
"warranty": "1 year",
"rating": 4.3,
"features": ["1080p video", "30x optical zoom", "3-inch LCD", "Image stabilization"],
"description": "Capture life's moments with this easy-to-use camcorder.",
"price": 249.99
},
"FotoSnap Instant Camera": {
"name": "FotoSnap Instant Camera",
"category": "Cameras and Camcorders",
"brand": "FotoSnap",
"model_number": "FS-IC10",
"warranty": "1 year",
"rating": 4.1,
"features": ["Instant prints", "Built-in flash", "Selfie mirror", "Battery-powered"],
"description": "Create instant memories with this fun and portable instant camera.",
"price": 69.99
}
}
products_file = 'products.json'
with open(products_file, 'w') as file:
json.dump(products, file)
return products
'''
注意:限于模型对中文理解能力较弱,中文 Prompt 可能会随机出现不成功,可以多次运行;也非常欢迎同学探究更稳定的中文 Prompt
'''
def process_user_message_ch(user_input, all_messages, debug=True):
"""
对用户信息进行预处理
参数:
user_input : 用户输入
all_messages : 历史信息
debug : 是否开启 DEBUG 模式,默认开启
"""
# 分隔符
delimiter = "```"
# 第一步:抽取出商品和对应的目录,类似于之前课程中的方法,做了一个封装
category_and_product_response = find_category_and_product_only(user_input, get_products_and_category())
# 将抽取出来的字符串转化为列表
category_and_product_list = read_string_to_list(category_and_product_response)
# print(category_and_product_list)
if debug: print("第一步:抽取出商品列表")
# 第三步:查找商品对应信息
product_information = generate_output_string(category_and_product_list)
if debug: print("第二步:查找抽取出的商品信息")
# print('商品信息:',product_information)
# 第四步:根据信息生成回答
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}"}
]
# 获取 LLM 的回答
# 通过附加 all_messages 实现多轮对话
final_response = get_gemma_response(all_messages + messages)
# print(messages)
# print(final_response)
if debug:print("第三步:生成用户回答")
# 将该轮信息加入到历史信息中
all_messages = all_messages + messages[1:]
# 第四步:模型检查是否很好地回答了用户问题
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_gemma_response(messages)
# print(evaluation_response)
if debug: print("第六步:模型评估该回答")
# 第七步:如果评估为 Y,输出回答;如果评估为 N,反馈将由人工修正答案
# 使用 in 来避免模型可能生成 Yes
if "Y" in evaluation_response:
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,[],debug=False)
print(response)
输出结果:
####
Customer Service Query:
####
category: Smartphones and Accessories
products: ["SmartX ProPhone", "MobiTech PowerCase"]
category: Cameras and Camcorders
products: ["FotoSnap DSLR Camera", "ActionCam 4K"]
category: Televisions and Home Theater Systems
products: ["CineView 4K TV", "SoundMax Home Theater"]
####
错误:非法的 Json 格式
1. SmartX Pro Phone:
SmartX Pro Phone 是我们公司最新推出的智能手机产品。它具有高级的照相摄像技术、高速数据处理和智能化功能等特点。这款手机适用于日常生活和工作,能够满足您的多样需求。
2. FotoSnap Camera:
FotoSnap Camera 是我们的新一代相机产品。它拥有超高像素、高感光度和快速拍摄速度等特点。相机可以拍摄高清照片、视频,且具有智能化功能,可以自动调整拍摄参数、修复照相结果等功能。
3. TV:
关于我们公司的电视产品,我可以告诉您,我们提供了一系列的液晶电视、LED电视和OLED电视等多样化的选择。我们的电视具备高清显示、高对比度和智能化功能等特点,可以满足您的家庭娱乐需求。
额外信息:
您是否想了解更多关于 SmartX Pro Phone 和 FotoSnap Camera 的详细信息?或者您也想了解关于我们公司的电视产品有什么优缺点?
请随时提出您的问题,我们将尽快为您解答!