demongodYY commited on
Commit
25b44a6
·
1 Parent(s): 461f776
Files changed (3) hide show
  1. .gitignore +151 -0
  2. app.py +275 -0
  3. requirements.txt +4 -0
.gitignore ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Azure az webapp deployment details
2
+ .azure
3
+ *_env
4
+
5
+ # Byte-compiled / optimized / DLL files
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+
10
+ # C extensions
11
+ *.so
12
+
13
+ # Distribution / packaging
14
+ .Python
15
+ build/
16
+ develop-eggs/
17
+ dist/
18
+ downloads/
19
+ eggs/
20
+ .eggs/
21
+ lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ share/python-wheels/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+ MANIFEST
32
+
33
+ # PyInstaller
34
+ # Usually these files are written by a python script from a template
35
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
36
+ *.manifest
37
+ *.spec
38
+
39
+ # Installer logs
40
+ pip-log.txt
41
+ pip-delete-this-directory.txt
42
+
43
+ # Unit test / coverage reports
44
+ htmlcov/
45
+ .tox/
46
+ .nox/
47
+ .coverage
48
+ .coverage.*
49
+ .cache
50
+ nosetests.xml
51
+ coverage.xml
52
+ *.cover
53
+ *.py,cover
54
+ .hypothesis/
55
+ .pytest_cache/
56
+ cover/
57
+
58
+ # Translations
59
+ *.mo
60
+ *.pot
61
+
62
+ # Django stuff:
63
+ *.log
64
+ local_settings.py
65
+ db.sqlite3
66
+ db.sqlite3-journal
67
+
68
+ # Flask stuff:
69
+ instance/
70
+ .webassets-cache
71
+
72
+ # Scrapy stuff:
73
+ .scrapy
74
+
75
+ # Sphinx documentation
76
+ docs/_build/
77
+
78
+ # PyBuilder
79
+ .pybuilder/
80
+ target/
81
+
82
+ # Jupyter Notebook
83
+ .ipynb_checkpoints
84
+
85
+ # IPython
86
+ profile_default/
87
+ ipython_config.py
88
+
89
+ # pyenv
90
+ # For a library or package, you might want to ignore these files since the code is
91
+ # intended to run in multiple environments; otherwise, check them in:
92
+ # .python-version
93
+
94
+ # pipenv
95
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
96
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
97
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
98
+ # install all needed dependencies.
99
+ #Pipfile.lock
100
+
101
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
102
+ __pypackages__/
103
+
104
+ # Celery stuff
105
+ celerybeat-schedule
106
+ celerybeat.pid
107
+
108
+ # SageMath parsed files
109
+ *.sage.py
110
+
111
+ # Environments
112
+ .env
113
+ .venv
114
+ env/
115
+ venv/
116
+ ENV/
117
+ env.bak/
118
+ venv.bak/
119
+
120
+ # Spyder project settings
121
+ .spyderproject
122
+ .spyproject
123
+
124
+ # Rope project settings
125
+ .ropeproject
126
+
127
+ # mkdocs documentation
128
+ /site
129
+
130
+ # mypy
131
+ .mypy_cache/
132
+ .dmypy.json
133
+ dmypy.json
134
+
135
+ # Pyre type checker
136
+ .pyre/
137
+
138
+ # pytype static type analyzer
139
+ .pytype/
140
+
141
+ # Cython debug symbols
142
+ cython_debug/
143
+
144
+ # NPM
145
+ npm-debug.log*
146
+ node_modules
147
+ static/
148
+
149
+ .DS_Store
150
+ wandb/
151
+ codebase/
app.py ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from langchain_openai import AzureChatOpenAI
3
+ from langchain_core.prompts import (
4
+ ChatPromptTemplate,
5
+ SystemMessagePromptTemplate,
6
+ HumanMessagePromptTemplate,
7
+ )
8
+ from langchain.schema import StrOutputParser
9
+ import json
10
+ import os
11
+ from dotenv import load_dotenv
12
+
13
+
14
+ example1 = """
15
+ 业务员:您好女士,欢迎光临徐家汇店! 请问您是第一次来我们店吗?
16
+ 顾客:是的,我是通过广告来的。
17
+ 业务员: 太好了,欢迎新朋友! 请问您今天是一个人来的吗?
18
+ 顾客:对,我一个人。
19
+ 业务员: 很好。您在店里计划逗留多久呢? 是想快速选购,还是想慢慢挑选看看?
20
+ 顾客:我想大概要逗留30分钟到1小时。
21
+ 业务员:好的,您有什么特别感兴趣的商品吗? 比如我们的潜水表或者万年历表?
22
+ 顾客: 我对潜水表很感兴趣,我看到过一些广告,星级的话,我给它3颗星吧
23
+ 业务员:潜水表确实是我们的明星产品。您想试戴看看吗?
24
+ 顾客:好的,我想试戴潜水表。
25
+ 业务员:没问题。试戴之后如果您喜欢,我们有哪些支付方式可以为您服务? 我们支持信用卡、支付宝、微信、会员预充值卡,当然也接受现金
26
+ 顾客: 我再看看吧。
27
+ 业务员:明白了。在您挑选商品的过程中,有什么我可以帮助的,或者有什么特别的反馈吗?
28
+ 顾客: 要是有更多的款式就好了,我过一阵再来看看
29
+ 业务员:好的,如果有任何问题或需要帮助,请随时告诉我
30
+ """.strip()
31
+
32
+
33
+ example2 = """
34
+ 业务员: 您好,欢迎光临徐家汇店! 请问我可以称呼您为先生吗?
35
+ 顾客: 是的,你可以这么叫我。
36
+ 业务员: 很高兴认识您,先生。今天您是第一次来我们店吗?
37
+ 顾客:不是,我之前来过。
38
+ 业务员: 好的,欢迎再次光临!您今天想要逛逛还是看到了我们的广告有特别的需求呢?
39
+ 顾客:我是看到了广告,对你们的潜水表和万年历表都挺感兴趣的。
40
+ 业务员: 太好了!这两款表都是我们的热销产品。您想先试戴哪一款?
41
+ 顾客:我想先试戴一下潜水表。
42
+ (顾客试戴后)
43
+ 业务员: 感觉如何,先生? 我们还有万年历表,您也想试试看吗?
44
+ 顾客:潜水表感觉挺不错的,万年历表我也试试。
45
+ (顾客试戴万年历表后)
46
+ 业务员: 两款表您都试戴了,有没有哪一款特别喜欢的?
47
+ 顾客: 我还是比较喜欢潜水表,就买这个吧。
48
+ 业务员:好的,非常精明的选择!请问您打算如何支付呢?
49
+ 顾客:我用信用卡支付。
50
+ 业务员:没问题,先生。在完成购买之后,您还有其他需要我帮助的吗?
51
+ 顾客: 没有了,谢谢!
52
+ 业务员: 不客气,如果您对我们的产品或服务有任何建议,欢迎随时告诉我们。祝您今天过得愉快!
53
+ """.strip()
54
+
55
+ example3 = """
56
+ 今天在静安寺店接待了一位新顾客,是位女士,和朋友两人一起来店。\
57
+ 他是通过我们的广告被吸引来的,对潜水表表现出了浓厚的兴趣,并给了高达3颗星的评价。\
58
+ 他计划在店里停留大约30分钟到1小时。我为他展示了潜水表,并且他决定试戴。\
59
+ 最终用户并没有购买。目前他没有提出特别的需求或反馈,但我会保持关注,确保他的购物体验顺利愉快
60
+ """.strip()
61
+
62
+ example4 = """
63
+ 新天地店今天接待了一位之前来过的男士顾客,他是被我们的广告吸引来的。\
64
+ 他对潜水表和万年历表都表示了兴趣,最后试戴了这两款表。他特别喜欢潜水表,并决定购买。\
65
+ 整个过程中,他的停留时间大约是30分钟。顾客最终选择使用信用卡支付。整个沟通过程很顺利,顾客没有提出额外的要求或反馈。
66
+ """.strip()
67
+
68
+ load_dotenv()
69
+
70
+ demploy_model = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME_GPT4T")
71
+ api_version = os.getenv("OPENAI_API_VERSION")
72
+ api_key = os.getenv("OPENAI_API_KEY")
73
+ endpoint = os.getenv("OPENAI_API_BASE")
74
+
75
+ print(demploy_model, api_version, api_key, endpoint)
76
+
77
+
78
+ def extract_json(s):
79
+ i = s.index("{")
80
+ count = 1 # 当前所在嵌套深度,即还没闭合的'{'个数
81
+ for j, c in enumerate(s[i + 1 :], start=i + 1):
82
+ if c == "}":
83
+ count -= 1
84
+ elif c == "{":
85
+ count += 1
86
+ if count == 0:
87
+ break
88
+ assert count == 0 # 检查是否找到最后一个'}'
89
+ return s[i : j + 1]
90
+
91
+
92
+ def process_text_LLM(text):
93
+ llm = AzureChatOpenAI(
94
+ temperature=0,
95
+ deployment_name="testgpt4turbo",
96
+ openai_api_version="2023-05-15",
97
+ azure_endpoint="https://testbotgpt4.openai.azure.com/",
98
+ api_key="89bda4e620a348858c24dd985598fa99",
99
+ )
100
+
101
+ prompt = ChatPromptTemplate.from_messages(
102
+ [
103
+ SystemMessagePromptTemplate.from_template(
104
+ """你是一个专业客服人员,需要根据和用户的对话记录,提取出相关的信息,填入对应的表单。
105
+ 表单填写规则描述: 表单1 为必填,如果顾客有试戴或购物行为,则���要填写表单2。如果没有提取到对应的信息,不要编造,而是填入 null。
106
+
107
+ ====================表单1描述====================
108
+ | 表单项 | 类型 | 子选项 |
109
+ |------------|--------------|------------------|
110
+ | 顾客性别(gender) | 单选🔘 | 男 |
111
+ | | | 女 |
112
+ | 人数 (number) | 输入框 | - |
113
+ | 门店名称 (store_name) | 下拉菜单,单选| 徐家汇店 |
114
+ | | | 静安寺店 |
115
+ | | | 新天地店 |
116
+ | 客流类型 (type) | 下拉菜单,单选| 新用户 - 闲逛 |
117
+ | | | 新用户 - 广告引流 |
118
+ | | | 老用户 - 闲逛 |
119
+ | | | 老用户 - 广告引流 |
120
+ | 停留时长 (duration) | 下拉菜单,单选| 10 分钟以内 |
121
+ | | | 10 - 30 分钟 |
122
+ | | | 30 - 60 分钟 |
123
+ | | | 60 分钟以上 |
124
+ | 是否购物 (shopping) | 单选🔘 | 是 |
125
+ | | | 否 |
126
+ ============================================================
127
+
128
+ ====================表单2描述:====================
129
+ | 表单项 | 类型 | 子选项 | 备注 |
130
+ |----------------------|--------------|----------|--------------------------------------------------------|
131
+ | 顾客感兴趣的商品 (interested) | 多选 | 潜水表 | |
132
+ | | | 万年历表 | |
133
+ | 顾客感兴趣的程度 (interest_levels) | 单选(数字) | 1 | |
134
+ | | | 2 | |
135
+ | | | 3 | |
136
+ | 用户试戴的商品 (tried) | 多选 | 潜水表 | |
137
+ | | | 万年历表 | |
138
+ | 最终成单商品 (final) | 多选 | 潜水表 | 不选择 = 没有成单。每个选项可以选择多次(比如,一次买了两个潜水表) |
139
+ | | | 万年历表 | |
140
+ | 支付方式 (payment) | 单选 | 信用卡 | |
141
+ | | | 支付宝 | |
142
+ | | | 微信 | |
143
+ | | | 会员预充值卡 | |
144
+ | | | 现金 | |
145
+ | | | 其它 | |
146
+ | 其它沟通内容和顾客反馈 (feedback) | 输入框 | - | |
147
+ ============================================================
148
+
149
+ ====================输出例子====================
150
+ {{
151
+ "gender": "女",
152
+ "number": 1,
153
+ "store_name": "徐家汇店",
154
+ "type": "新用户 - 闲逛",
155
+ "duration": "10 分钟以内",
156
+ "shopping": "否",
157
+ "interested": "潜水表",
158
+ "interest_levels": 2,
159
+ "tried": null,
160
+ "final": "万年历表",
161
+ "payment": "微信",
162
+ "feedback": "哈哈哈哈",
163
+ }}
164
+ ============================================================
165
+
166
+ 必须按照以上输出例子里的 JSON 格式输出。没有提取到的信息填入 null。只有 JSON 本身,不要有其他字符输出。
167
+ """.strip()
168
+ ),
169
+ HumanMessagePromptTemplate.from_template("对话记录: ```{input}```"),
170
+ ]
171
+ )
172
+
173
+ chain = prompt | llm | StrOutputParser()
174
+ return chain.invoke({"input": text})
175
+
176
+
177
+ with gr.Blocks() as demo:
178
+ with gr.Row():
179
+
180
+ with gr.Column():
181
+ text = gr.Text()
182
+ submit_btn = gr.Button(value="Submit")
183
+ examples = gr.Examples(
184
+ examples=[example1, example2, example3, example4], inputs=[text]
185
+ )
186
+
187
+ with gr.Column():
188
+ gender = gr.Radio(label="顾客性别", choices=["男", "女"])
189
+ number = gr.Number(label="人数")
190
+ store_name = gr.Dropdown(
191
+ label="门店名称", choices=["徐家汇店", "静安寺店", "新天地店"]
192
+ )
193
+ type = gr.Dropdown(
194
+ label="客流类型",
195
+ choices=[
196
+ "新用户 - 闲逛",
197
+ "新用户 - 广告引流",
198
+ "老用户 - 闲���",
199
+ "老用户 - 广告引流",
200
+ ],
201
+ )
202
+ duration = gr.Dropdown(
203
+ label="停留时长",
204
+ choices=[
205
+ "10 分钟以内",
206
+ "10 - 30 分钟",
207
+ "30 - 60 分钟",
208
+ "60 分钟以上",
209
+ ],
210
+ )
211
+ shopping = gr.Radio(label="是否购物", choices=["是", "否"])
212
+
213
+ with gr.Column():
214
+ interested = gr.CheckboxGroup(
215
+ label="顾客感兴趣的商品", choices=["潜水表", "万年历表"]
216
+ )
217
+ interest_levels = gr.Radio(
218
+ choices=[("🌟", 1), ("🌟🌟", 2), ("🌟🌟🌟", 3)],
219
+ label="感兴趣程度 (为最近选中的商品评级)",
220
+ )
221
+ tried = gr.CheckboxGroup(
222
+ label="用户试戴的商品", choices=["潜水表", "万年历表"]
223
+ )
224
+ final = gr.CheckboxGroup(
225
+ label="最终成单商品", choices=["潜水表", "万年历表"]
226
+ )
227
+ payment = gr.Radio(
228
+ label="支付方式",
229
+ choices=["信用卡", "支付宝", "微信", "会员预充值卡", "现金", "其它"],
230
+ )
231
+ feedback = gr.Textbox(label="其它沟通内容和顾客反馈")
232
+
233
+ def process_form(text):
234
+
235
+ res = process_text_LLM(text)
236
+ print(res)
237
+ strRes = extract_json(res)
238
+ print(strRes)
239
+ jsonRes = json.loads(strRes, strict=False)
240
+
241
+ return {
242
+ gender: jsonRes["gender"],
243
+ number: jsonRes["number"],
244
+ store_name: jsonRes["store_name"],
245
+ type: jsonRes["type"],
246
+ duration: jsonRes["duration"],
247
+ shopping: jsonRes["shopping"],
248
+ interested: jsonRes["interested"],
249
+ interest_levels: jsonRes["interest_levels"],
250
+ tried: jsonRes["tried"],
251
+ final: jsonRes["final"],
252
+ payment: jsonRes["payment"],
253
+ feedback: jsonRes["feedback"],
254
+ }
255
+
256
+ submit_btn.click(
257
+ fn=process_form,
258
+ inputs=text,
259
+ outputs=[
260
+ gender,
261
+ number,
262
+ store_name,
263
+ type,
264
+ duration,
265
+ shopping,
266
+ interested,
267
+ interest_levels,
268
+ tried,
269
+ final,
270
+ payment,
271
+ feedback,
272
+ ],
273
+ )
274
+
275
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio==4.14.0
2
+ langchain==0.1.10
3
+ langchain-openai==0.0.8
4
+ python-dotenv==1.0.1