FIll_form_demo / app.py
demongodYY
fix key
ea4ca6d
import gradio as gr
from langchain_openai import AzureChatOpenAI
from langchain_core.prompts import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import StrOutputParser
import json
import os
from dotenv import load_dotenv
example1 = """
业务员:您好女士,欢迎光临徐家汇店! 请问您是第一次来我们店吗?
顾客:是的,我是通过广告来的。
业务员: 太好了,欢迎新朋友! 请问您今天是一个人来的吗?
顾客:对,我一个人。
业务员: 很好。您在店里计划逗留多久呢? 是想快速选购,还是想慢慢挑选看看?
顾客:我想大概要逗留30分钟到1小时。
业务员:好的,您有什么特别感兴趣的商品吗? 比如我们的潜水表或者万年历表?
顾客: 我对潜水表很感兴趣,我看到过一些广告,星级的话,我给它3颗星吧
业务员:潜水表确实是我们的明星产品。您想试戴看看吗?
顾客:好的,我想试戴潜水表。
业务员:没问题。试戴之后如果您喜欢,我们有哪些支付方式可以为您服务? 我们支持信用卡、支付宝、微信、会员预充值卡,当然也接受现金
顾客: 我再看看吧。
业务员:明白了。在您挑选商品的过程中,有什么我可以帮助的,或者有什么特别的反馈吗?
顾客: 要是有更多的款式就好了,我过一阵再来看看
业务员:好的,如果有任何问题或需要帮助,请随时告诉我
""".strip()
example2 = """
业务员: 您好,欢迎光临徐家汇店! 请问我可以称呼您为先生吗?
顾客: 是的,你可以这么叫我。
业务员: 很高兴认识您,先生。今天您是第一次来我们店吗?
顾客:不是,我之前来过。
业务员: 好的,欢迎再次光临!您今天想要逛逛还是看到了我们的广告有特别的需求呢?
顾客:我是看到了广告,对你们的潜水表和万年历表都挺感兴趣的。
业务员: 太好了!这两款表都是我们的热销产品。您想先试戴哪一款?
顾客:我想先试戴一下潜水表。
(顾客试戴后)
业务员: 感觉如何,先生? 我们还有万年历表,您也想试试看吗?
顾客:潜水表感觉挺不错的,万年历表我也试试。
(顾客试戴万年历表后)
业务员: 两款表您都试戴了,有没有哪一款特别喜欢的?
顾客: 我还是比较喜欢潜水表,就买这个吧。
业务员:好的,非常精明的选择!请问您打算如何支付呢?
顾客:我用信用卡支付。
业务员:没问题,先生。在完成购买之后,您还有其他需要我帮助的吗?
顾客: 没有了,谢谢!
业务员: 不客气,如果您对我们的产品或服务有任何建议,欢迎随时告诉我们。祝您今天过得愉快!
""".strip()
example3 = """
今天在静安寺店接待了一位新顾客,是位女士,和朋友两人一起来店。\
他是通过我们的广告被吸引来的,对潜水表表现出了浓厚的兴趣,并给了高达3颗星的评价。\
他计划在店里停留大约30分钟到1小时。我为他展示了潜水表,并且他决定试戴。\
最终用户并没有购买。目前他没有提出特别的需求或反馈,但我会保持关注,确保他的购物体验顺利愉快
""".strip()
example4 = """
新天地店今天接待了一位之前来过的男士顾客,他是被我们的广告吸引来的。\
他对潜水表和万年历表都表示了兴趣,最后试戴了这两款表。他特别喜欢潜水表,并决定购买。\
整个过程中,他的停留时间大约是30分钟。顾客最终选择使用信用卡支付。整个沟通过程很顺利,顾客没有提出额外的要求或反馈。
""".strip()
load_dotenv()
demploy_model = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME_GPT4T")
api_version = os.getenv("OPENAI_API_VERSION")
api_key = os.getenv("AZURE_OPENAI_API_KEY")
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
def extract_json(s):
i = s.index("{")
count = 1 # 当前所在嵌套深度,即还没闭合的'{'个数
for j, c in enumerate(s[i + 1 :], start=i + 1):
if c == "}":
count -= 1
elif c == "{":
count += 1
if count == 0:
break
assert count == 0 # 检查是否找到最后一个'}'
return s[i : j + 1]
def process_text_LLM(text):
llm = AzureChatOpenAI(
temperature=0,
deployment_name=demploy_model,
openai_api_version=api_version,
azure_endpoint=endpoint,
openai_api_key=api_key,
)
prompt = ChatPromptTemplate.from_messages(
[
SystemMessagePromptTemplate.from_template(
"""你是一个专业客服人员,需要根据和用户的对话记录,提取出相关的信息,填入对应的表单。
表单填写规则描述: 表单1 为必填,如果顾客有试戴或购物行为,则需要填写表单2。如果没有提取到对应的信息,不要编造,而是填入 null。
====================表单1描述====================
| 表单项 | 类型 | 子选项 |
|------------|--------------|------------------|
| 顾客性别(gender) | 单选🔘 | 男 |
| | | 女 |
| 人数 (number) | 输入框 | - |
| 门店名称 (store_name) | 下拉菜单,单选| 徐家汇店 |
| | | 静安寺店 |
| | | 新天地店 |
| 客流类型 (type) | 下拉菜单,单选| 新用户 - 闲逛 |
| | | 新用户 - 广告引流 |
| | | 老用户 - 闲逛 |
| | | 老用户 - 广告引流 |
| 停留时长 (duration) | 下拉菜单,单选| 10 分钟以内 |
| | | 10 - 30 分钟 |
| | | 30 - 60 分钟 |
| | | 60 分钟以上 |
| 是否购物 (shopping) | 单选🔘 | 是 |
| | | 否 |
============================================================
====================表单2描述:====================
| 表单项 | 类型 | 子选项 | 备注 |
|----------------------|--------------|----------|--------------------------------------------------------|
| 顾客感兴趣的商品 (interested) | 多选 | 潜水表 | |
| | | 万年历表 | |
| 顾客感兴趣的程度 (interest_levels) | 单选(数字) | 1 | |
| | | 2 | |
| | | 3 | |
| 用户试戴的商品 (tried) | 多选 | 潜水表 | |
| | | 万年历表 | |
| 最终成单商品 (final) | 多选 | 潜水表 | 不选择 = 没有成单。每个选项可以选择多次(比如,一次买了两个潜水表) |
| | | 万年历表 | |
| 支付方式 (payment) | 单选 | 信用卡 | |
| | | 支付宝 | |
| | | 微信 | |
| | | 会员预充值卡 | |
| | | 现金 | |
| | | 其它 | |
| 其它沟通内容和顾客反馈 (feedback) | 输入框 | - | |
============================================================
====================输出例子====================
{{
"gender": "女",
"number": 1,
"store_name": "徐家汇店",
"type": "新用户 - 闲逛",
"duration": "10 分钟以内",
"shopping": "否",
"interested": "潜水表",
"interest_levels": 2,
"tried": null,
"final": "万年历表",
"payment": "微信",
"feedback": "哈哈哈哈",
}}
============================================================
必须按照以上输出例子里的 JSON 格式输出。没有提取到的信息填入 null。只有 JSON 本身,不要有其他字符输出。
""".strip()
),
HumanMessagePromptTemplate.from_template("对话记录: ```{input}```"),
]
)
chain = prompt | llm | StrOutputParser()
return chain.invoke({"input": text})
with gr.Blocks() as demo:
with gr.Row():
with gr.Column():
text = gr.Text()
submit_btn = gr.Button(value="Submit")
examples = gr.Examples(
examples=[example1, example2, example3, example4], inputs=[text]
)
with gr.Column():
gender = gr.Radio(
label="顾客性别",
choices=["男", "女"],
interactive=True,
)
number = gr.Number(
label="人数",
interactive=True,
)
store_name = gr.Dropdown(
interactive=True,
label="门店名称",
choices=["徐家汇店", "静安寺店", "新天地店"],
)
type = gr.Dropdown(
label="客流类型",
interactive=True,
choices=[
"新用户 - 闲逛",
"新用户 - 广告引流",
"老用户 - 闲逛",
"老用户 - 广告引流",
],
)
duration = gr.Dropdown(
interactive=True,
label="停留时长",
choices=[
"10 分钟以内",
"10 - 30 分钟",
"30 - 60 分钟",
"60 分钟以上",
],
)
shopping = gr.Radio(
label="是否购物", interactive=True, choices=["是", "否"]
)
with gr.Column():
interested = gr.CheckboxGroup(
label="顾客感兴趣的商品",
interactive=True,
choices=["潜水表", "万年历表"],
)
interest_levels = gr.Radio(
interactive=True,
choices=[("🌟", 1), ("🌟🌟", 2), ("🌟🌟🌟", 3)],
label="感兴趣程度 (为最近选中的商品评级)",
)
tried = gr.CheckboxGroup(
interactive=True, label="用户试戴的商品", choices=["潜水表", "万年历表"]
)
final = gr.CheckboxGroup(
interactive=True, label="最终成单商品", choices=["潜水表", "万年历表"]
)
payment = gr.Radio(
interactive=True,
label="支付方式",
choices=["信用卡", "支付宝", "微信", "会员预充值卡", "现金", "其它"],
)
feedback = gr.Textbox(interactive=True, label="其它沟通内容和顾客反馈")
def process_form(text):
res = process_text_LLM(text)
print(res)
strRes = extract_json(res)
print(strRes)
jsonRes = json.loads(strRes, strict=False)
return {
gender: jsonRes["gender"],
number: jsonRes["number"],
store_name: jsonRes["store_name"],
type: jsonRes["type"],
duration: jsonRes["duration"],
shopping: jsonRes["shopping"],
interested: jsonRes["interested"],
interest_levels: jsonRes["interest_levels"],
tried: jsonRes["tried"],
final: jsonRes["final"],
payment: jsonRes["payment"],
feedback: jsonRes["feedback"],
}
submit_btn.click(
fn=process_form,
inputs=text,
outputs=[
gender,
number,
store_name,
type,
duration,
shopping,
interested,
interest_levels,
tried,
final,
payment,
feedback,
],
)
demo.launch()