Spaces:
Sleeping
Sleeping
| 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() | |