Spaces:
Sleeping
Sleeping
File size: 13,039 Bytes
25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 ea4ca6d 25b44a6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
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()
|