allinaigc commited on
Commit
85588ef
1 Parent(s): 460b18c

Upload 12 files

Browse files
agent_icon.png ADDED
analysis_icon.png ADDED
app.py ADDED
@@ -0,0 +1,518 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ 1. 支持所有多个文件类型的大模型批处理功能,可以清洗文本数据,提取关键信息,并生成标准格式的输出文件。
3
+ 1. 支持多种文件类型的上传,包括pdf, docx, xlsx, csv, json等。
4
+ 1. Streamlit不支持上传一个文件夹,可以用ctrl+A上传所有文件。会自动显示上传的文件名字。
5
+
6
+ 错误信息:
7
+ 1. 如果上传的单个文件中的内容超过大模型的上下文,可能会报错。需要确认文件内容,或者需要更换长文大模型。
8
+
9
+ """
10
+
11
+ ##TODO: 1. 每次调用新的csv文件。
12
+
13
+ # -*- coding: utf-8 -*-
14
+ import streamlit as st
15
+ import openai
16
+ import os
17
+ import numpy as np
18
+ import pandas as pd
19
+ import json
20
+ import csv
21
+ import tempfile
22
+ from tempfile import NamedTemporaryFile
23
+ import pathlib
24
+ from pathlib import Path
25
+ import re
26
+ from re import sub
27
+ from itertools import product
28
+ import time
29
+ from time import sleep
30
+ from datetime import datetime
31
+ import streamlit_authenticator as stauth
32
+ # from langchain_community.vectorstores import FAISS
33
+ # from langchain.embeddings.huggingface import HuggingFaceEmbeddings
34
+ # from langchain_core.output_parsers import StrOutputParser
35
+ # from langchain_core.runnables import RunnablePassthrough
36
+ from langchain.llms.base import LLM
37
+ from langchain.llms.utils import enforce_stop_tokens
38
+ from typing import Dict, List, Optional, Tuple, Union
39
+ import requests
40
+ import streamlit as st
41
+ # import rag_reponse_002
42
+ import dashscope
43
+ from dotenv import load_dotenv
44
+ from datetime import datetime
45
+ import pytz
46
+ from pytz import timezone
47
+ from datetime import date
48
+ import qwen_response
49
+ from save_info import save_csv_info
50
+ import streamlit_ext as ste ##TODO: 为了点击download button后保持页面。
51
+ import create_newfile
52
+
53
+ ## 获得程序运行的当前时间
54
+ def get_current_time():
55
+ beijing_tz = timezone('Asia/Shanghai')
56
+ beijing_time = datetime.now(beijing_tz)
57
+ current_time = beijing_time.strftime('%H:%M:%S')
58
+ return current_time
59
+
60
+ load_dotenv()
61
+ ### 设置openai的API key
62
+ os.environ["OPENAI_API_KEY"] = os.environ['user_token']
63
+ openai.api_key = os.environ['user_token']
64
+ bing_search_api_key = os.environ['bing_api_key']
65
+ dashscope.api_key = os.environ['dashscope_api_key']
66
+
67
+ ### Streamlit页面设定。
68
+ st.set_page_config(layout="wide", page_icon="🌀", page_title="人工智能大模型的智能信息探索平台")
69
+ st.title("人工智能大模型文本清洗与挖掘平台(可内网部署)")
70
+ # st.subheader("Large Language Model-based Knowledge Base QA System")
71
+ # st.warning("_声明:内容由人工智能生成,仅供参考。如果您本人使用或对外传播本服务生成的输出,您应当主动核查输出内容的真实性、准确性,避免传播虚假信息。_")
72
+ # st.info("_声明:内容由人工智能生成,仅供参考。如果您本人使用或对外传播本服务生成的输出,您应当主动核查输出内容的真实性、准确性,避免传播虚假信息。_")
73
+ st.write("_声明:内容由人工智能生成,仅供参考。如果您本人使用或对外传播本服务生成的输出,您应当主动核查输出内容的真实性、准确性,避免传播虚假信息。_")
74
+ # st.divider()
75
+
76
+
77
+
78
+ ### authentication with a local yaml file.
79
+ import yaml
80
+ from yaml.loader import SafeLoader
81
+ with open('./config.yaml') as file:
82
+ config = yaml.load(file, Loader=SafeLoader)
83
+ authenticator = stauth.Authenticate(
84
+ config['credentials'],
85
+ config['cookie']['name'],
86
+ config['cookie']['key'],
87
+ config['cookie']['expiry_days'],
88
+ config['preauthorized']
89
+ )
90
+
91
+ user, authentication_status, username = authenticator.login('main')
92
+ # user, authentication_status, username = authenticator.login('用户登录', 'main')
93
+
94
+ ## 清楚所有对话记录。
95
+ def clear_all():
96
+ st.session_state.conversation = None
97
+ st.session_state.chat_history = None
98
+ st.session_state.messages = []
99
+ message_placeholder = st.empty()
100
+
101
+ ## 只用这一个就可以了。
102
+ # st.rerun()
103
+
104
+ return None
105
+
106
+ if authentication_status:
107
+ with st.sidebar:
108
+ st.markdown(
109
+ """
110
+ <style>
111
+ [data-testid="stSidebar"][aria-expanded="true"]{
112
+ min-width: 400px;
113
+ max-width: 400px;
114
+ }
115
+ """,
116
+ unsafe_allow_html=True,
117
+ )
118
+ ### siderbar的题目。
119
+ ### siderbar的题目。
120
+ # st.header(f'**大语言模型专家系统工作设定区**')
121
+ st.header(f'**欢迎 **{username}** 使用本系统** ')
122
+ st.write(f'_Large Language Model Expert System Environment_')
123
+ # st.write(f'_Welcome and Hope U Enjoy Staying Here_')
124
+ authenticator.logout('登出', 'sidebar')
125
+
126
+ ### 提交请求
127
+ submit_btn = st.sidebar.button("开始执行操作", use_container_width=True, type='primary')
128
+
129
+ ### 清除记录,重启一轮新对话。
130
+ st.sidebar.button("清除记录,重启一个新任务", on_click=clear_all, use_container_width=True, type='secondary')
131
+
132
+ ### 定义任务目标
133
+ task_goal = st.selectbox(label="**任务目标**", options=['文本内容清洗', '人才资料甄选', '销售机会挖掘', '日志文件分析', '舆情内容分析', '潜在投诉挖掘', '合规稽核纠偏'], index=0)
134
+
135
+ match task_goal:
136
+ case '文本内容清洗':
137
+ prompt_sys = """你是一个文本内容清洗专家。你需要完成我给你的任务。"""
138
+ case '人才资料甄选':
139
+ prompt_sys = """你是一个人才资料甄选专家。你需要完成我给你的任务。"""
140
+ case '销售机会挖掘':
141
+ prompt_sys = """你是一个销售机会挖掘专家。你需要完成我给你的任务。"""
142
+ case '日志文件分析':
143
+ prompt_sys = """你是一个日志文件分析专家。你需要完成我给你的任务。"""
144
+ case '舆情内容分析':
145
+ prompt_sys = """你是一个舆情内容分析专家。你需要完成我给你的任务。"""
146
+ case '潜在投诉挖掘':
147
+ prompt_sys = """你是一个潜在投诉挖掘专家。你需要完成我给你的任务。"""
148
+ case '合规稽核纠偏':
149
+ prompt_sys = """你是一个合规稽核纠偏专家。你需要完成我给你的任务。"""
150
+
151
+
152
+
153
+ ## 在sidebar上的三个分页显示,用st.tabs实现。
154
+ tab_1, tab_2, tab_4 = st.tabs(['使用须知', '模型参数', '系统角色设定'])
155
+ # tab_1, tab_2, tab_3, tab_4 = st.tabs(['使用须知', '模型参数', '提示词模板', '系统角色设定'])
156
+
157
+ # with st.expander(label='**使用须知**', expanded=False):
158
+ with tab_1:
159
+ # st.markdown("#### 快速上手指南")
160
+ with st.text(body="说明"):
161
+ st.markdown("* 重启一个新任务时,只需要刷新页面(按Ctrl/Command + R)即可。")
162
+ with st.text(body="说明"):
163
+ st.markdown("* 为了保护数据与隐私,所有对话均不会被保存,刷新页面立即删除。敬请放心。")
164
+ # with st.text(body="说明"):
165
+ # st.markdown("* “GPT-4”回答质量极佳,但速度缓慢,建议适当使用。")
166
+ with st.text(body="说明"):
167
+ st.markdown("* 现有仅限一次任务执行,将不会保持之前的任务结果记录。")
168
+ with st.text(body="说明"):
169
+ st.markdown("""* 系统的工作流程如下:
170
+ 1. 用户提交待处理的文件。
171
+ 1. 系统将问题转换为机器可理解的格式。
172
+ 1. 系统使用大语言模型来进行全量信息探索。
173
+ 1. 系统使用内置的智能系统来进行基于文本高维特征的探索。
174
+ 1. 系统返回完整且准确的答案。""")
175
+
176
+ ## 大模型参数
177
+ # with st.expander(label='**大语言模型参数**', expanded=True):
178
+ with tab_2:
179
+ max_tokens = st.slider(label='Max_Token(生成结果时最大字数)', min_value=100, max_value=8096, value=4096,step=100)
180
+ temperature = st.slider(label='Temperature (温度)', min_value=0.0, max_value=1.0, value=0.8, step=0.1)
181
+ top_p = st.slider(label='Top_P (核采样)', min_value=0.0, max_value=1.0, value=0.6, step=0.1)
182
+ frequency_penalty = st.slider(label='Frequency Penalty (重复度惩罚因子)', min_value=-2.0, max_value=2.0, value=1.0, step=0.1)
183
+ presence_penalty = st.slider(label='Presence Penalty (控制主题的重复度)', min_value=-2.0, max_value=2.0, value=1.0, step=0.1)
184
+
185
+ # with tab_3:
186
+ # # st.markdown("#### Prompt提示词参考资料")
187
+ # # with st.expander(label="**大语言模型基础提示词Prompt示例**", expanded=False):
188
+ # st.code(
189
+ # body="我是一个企业主,我需要关注哪些“存货”相关的数据资源规则?", language='plaintext')
190
+ # st.code(
191
+ # body="作为零售商,了解哪些关键的库存管理指标对我至关重要?", language='plaintext')
192
+ # st.code(body="企业主在监控库存时,应如何确保遵守行业法规和最佳实践?",
193
+ # language='plaintext')
194
+ # st.code(body="在数字化时代,我应该关注哪些技术工具或平台来优化我的库存数据流程?", language='plaintext')
195
+ # st.code(body="我应该如何定期审查和分析这些库存数据以提高运营效率?", language='plaintext')
196
+ # st.code(body="如何设置预警系统来避免过度库存或缺货情况?", language='plaintext')
197
+
198
+ with tab_4:
199
+ st.text_area(label='系统角色设定', value='你是一个人工智能,你需要回答我提出的问题,或者完成我交代的任务。你需要使用我提问的语言(如中文、英文)来回答。', height=200, label_visibility='hidden')
200
+
201
+
202
+ elif authentication_status == False:
203
+ st.error('⛔ 用户名或密码错误!')
204
+ elif authentication_status == None:
205
+ st.warning('⬆ 请先登录!')
206
+
207
+ ### 上传文件的模块
208
+ def upload_file(uploaded_file):
209
+ if uploaded_file is not None:
210
+ # filename = uploaded_file.name
211
+ # st.write(filename) # print out the whole file name to validate. not to show in the final version.
212
+ try:
213
+ # if '.pdf' in filename: ### original code here.
214
+ if '.pdf' in uploaded_file.name:
215
+ pdf_filename = uploaded_file.name ### original code here.
216
+ # print('PDF file:', pdf_filename)
217
+ # with st.status('正在为您解析新知识库...', expanded=False, state='running') as status:
218
+ spinner = st.spinner('正在为您解析新知识库...请耐心等待')
219
+ with spinner:
220
+ uploaded_file_name = "File_provided"
221
+ temp_dir = tempfile.TemporaryDirectory()
222
+ # ! working.
223
+ uploaded_file_path = pathlib.Path(temp_dir.name) / uploaded_file_name
224
+ with open(pdf_filename, 'wb') as output_temporary_file:
225
+ # with open(f'./{username}_upload.pdf', 'wb') as output_temporary_file: ### original code here. 可能会造成在引用信息来源时文件名不对的问题。
226
+ # ! 必须用这种格式读入内容,然后才可以写入temporary文件夹中。
227
+ # output_temporary_file.write(uploaded_file.getvalue())
228
+ output_temporary_file.write(uploaded_file.getvalue())
229
+
230
+ return pdf_filename
231
+
232
+ else:
233
+ # if '.csv' in filename: ### original code here.
234
+ if '.csv' in uploaded_file.name:
235
+ print('start the csv file processing...')
236
+ csv_filename = uploaded_file.name
237
+ filename = uploaded_file.name
238
+
239
+ csv_file = pd.read_csv(uploaded_file)
240
+ csv_file.to_csv(f'./{username}/{username}_upload.csv', encoding='utf-8', index=False)
241
+ st.write(csv_file[:3]) # 这里只是显示文件,后面需要定位文件所在的绝对路径。
242
+ elif '.txt' in uploaded_file.name:
243
+ print('start the txt file processing...')
244
+ txt_filename = uploaded_file.name
245
+ filename = uploaded_file.name
246
+ txt_file = uploaded_file.getvalue()
247
+ file = open(f"{txt_filename}", 'rb')
248
+ content = file.read()
249
+ content = file.split(b'\n')
250
+
251
+ # with open(file=f'./{username}/{username}_upload.txt', mode='rb', encoding='utf-8') as output_temporary_file:
252
+ # output_temporary_file.write(txt_file)
253
+ st.write(file)
254
+
255
+ ### json格式文件
256
+ elif '.json' in uploaded_file.name:
257
+ print('start the json file processing...')
258
+ json_filename = uploaded_file.name
259
+ json_file = uploaded_file.getvalue()
260
+ # file = open(f"{txt_filename}", 'rb')
261
+ # content = file.read()
262
+ # content = file.split(b'\n')
263
+
264
+ # with open(file=f'./{username}/{username}_upload.txt', mode='rb', encoding='utf-8') as output_temporary_file:
265
+ # output_temporary_file.write(txt_file)
266
+ # st.write(json_filename)
267
+
268
+ # else:
269
+ # xls_file = pd.read_excel(uploaded_file)
270
+ # xls_file.to_csv(f'./{username}_upload.csv', index=False)
271
+ # st.write(xls_file[:3])
272
+
273
+ print('end the file processing...')
274
+
275
+ # uploaded_file_name = "File_provided"
276
+ # temp_dir = tempfile.TemporaryDirectory()
277
+ # ! working.
278
+ # uploaded_file_path = pathlib.Path(temp_dir.name) / uploaded_file_name
279
+ # with open('./upload.csv', 'wb') as output_temporary_file:
280
+ # with open(f'./{username}_upload.csv', 'wb') as output_temporary_file:
281
+ # print(f'./{name}_upload.csv')
282
+ # ! 必须用这种格式读入内容,然后才可以写入temporary文件夹中。
283
+ # output_temporary_file.write(uploaded_file.getvalue())
284
+ # st.write(uploaded_file_path) #* 可以查看文件是否真实存在,然后是否可以
285
+
286
+ except Exception as e:
287
+ # st.write(e)
288
+ pass
289
+
290
+ ## 以下代码是为了解决上传文件后,文件路径和文件名不对的问题。
291
+ # uploaded_file_name = "File_provided"
292
+ # temp_dir = tempfile.TemporaryDirectory()
293
+ # # ! working.
294
+ # uploaded_file_path = pathlib.Path(temp_dir.name) / uploaded_file_name
295
+ # # with open('./upload.csv', 'wb') as output_temporary_file:
296
+ # with open(f'./{name}_upload.csv', 'wb') as output_temporary_file:
297
+ # # print(f'./{name}_upload.csv')
298
+ # # ! 必须用这种格式读入内容,然后才可以写入temporary文件夹中。
299
+ # # output_temporary_file.write(uploaded_file.getvalue())
300
+ # output_temporary_file.write(uploaded_file.getvalue())
301
+ # # st.write(uploaded_file_path) # * 可以查看文件是否真实存在,然后是否可以
302
+ # # st.write('Now file saved successfully.')
303
+
304
+ # return pdf_filename, csv_filename
305
+ return None
306
+
307
+
308
+ ## streamlit中显示上传文件的模块
309
+ try:
310
+ uploaded_file = st.file_uploader(
311
+ "选择需要处理的文件(注:可一次选择多个文件)", type=(["txt", "docx", "PDF", "CSV", "xlsx","xls","json"]), accept_multiple_files=True)
312
+
313
+ ## 获得上传所有文件的大小。
314
+ uploaded_filesize = round(sum(file.size for file in uploaded_file) / 1000, 2)
315
+ #总共上传了{}个文件。'.format(len(uploaded_file))) ### 显示上传了多少文件。
316
+
317
+ # 默认状态下没有上传文件,None,会报错。需要判断。
318
+ if uploaded_file:
319
+ ## 显示上传文件的信息。
320
+ metric_col1, metric_col2, metric_col3, metric_col4 = st.columns(4)
321
+ metric_col1.metric(label='上传的文件数', value=f"{len(uploaded_file)}个", delta=None)
322
+ metric_col2.metric(label='上传文件的大小', value=f"{uploaded_filesize} KB", delta=None)
323
+ metric_col3.metric(label='上传文件的时间', value=f"{get_current_time()}", delta=None)
324
+ metric_col4.metric(label='当前日期', value=f"{str(date.today())}", delta=None)
325
+
326
+ # # uploaded_file_path = upload_file(uploaded_file)
327
+ # upload_file(uploaded_file)
328
+ except Exception as e:
329
+ print(e)
330
+ pass
331
+
332
+ st.divider()
333
+ ### 提示词部分。
334
+ with st.expander(label='**标准模块**', expanded=True):
335
+ col_1, col_2, col_3, col_4 = st.columns(4)
336
+ with col_1:
337
+ prompt_input = st.text_area(label='**原始文件的说明**', value=""" 1. "input"和“instruction”都代表了用户的问题,可以忽略“instruction”部分的内容。
338
+
339
+ 2. “output”是法律顾问的回答内容。""", height=200, label_visibility='visible')
340
+ with col_2:
341
+ prompt_caution = st.text_area(label='**注意事项**', value='忽略所有语法错误和错别字。',height=200, label_visibility='visible')
342
+ with col_3:
343
+ prompt_rule = st.text_area(label='**规则定义**', value='无特定规则要求。',height=200, label_visibility='visible')
344
+ with col_4:
345
+ prompt_output = st.text_area(label='**输出结果的要求**', value=
346
+ """【用户问题】用一段话来总结用户的核心问题。
347
+ 【法律顾问回答】用一段话来总结法律顾问的回答要点。
348
+ 【整体情况】用一句话来简单概述判断这一通话的整体情况。
349
+ 【是否解决】判断问题是否解决。
350
+ """, height=200, label_visibility='visible')
351
+
352
+ # st.write(f"{prompt_explain} {prompt_notice} {prompt_rule} {prompt_ouput}")
353
+
354
+ ### 专业模式部分。
355
+ with st.expander(label='**定制模块**', expanded=False):
356
+ # settings_col_1, settings_col_2, settings_col_3, settings_col_4, settings_col_5 = st.columns(5)
357
+ settings_col_1, settings_col_2, settings_col_3 = st.columns(3)
358
+ settings_col_1.toggle('高质量模式', value=False, key='high_end_mode')
359
+ settings_col_2.toggle('长文模式', value=False, key='length_context_mode')
360
+ settings_col_3.toggle('强力模式', value=False, key='powerful_mode')
361
+
362
+ # with settings_col_1:
363
+ # settings_col_1.toggle('高质量模式', value=False, key='high_end_mode')
364
+ # with settings_col_2:
365
+ # settings_col_2.toggle('长文模式', value=False, key='length_context_mode')
366
+ # with settings_col_3:
367
+ # settings_col_3.toggle('强力模式', value=False, key='powerful_mode')
368
+
369
+ ### rag设定
370
+ rag_col_1, rag_col_2 = st.columns(2)
371
+ ### 爬虫网站
372
+ target_url = rag_col_1.text_input('目标网址', value='https://www.123abc.com', label_visibility='visible', disabled=True)
373
+
374
+ ### 加载知识来源
375
+ target_database = rag_col_2.multiselect(label='信息增强', options=['互联网', '知识库', '规则库', '案例库'], default=['规则库'], disabled=True)
376
+
377
+ ### 各类高级设定
378
+ advance_col_1, advance_col_2, advance_col_3, advance_col_4, advance_col_5 = st.columns(5)
379
+ with advance_col_1:
380
+ prompt_explain = st.text_area(label='筛选规则定制', value='', height=200, label_visibility='visible', disabled=True)
381
+ with advance_col_2:
382
+ prompt_notice = st.text_area(label='敏感词制定', value='',height=200, label_visibility='visible', disabled=True)
383
+ with advance_col_3:
384
+ prompt_rule = st.text_area(label='过滤名单', value='',height=200, label_visibility='visible', disabled=True)
385
+ with advance_col_4:
386
+ prompt_ouput = st.text_area(label='词云频率设定', value='',height=200, label_visibility='visible', disabled=True)
387
+ with advance_col_5:
388
+ prompt_ouput = st.text_area(label='其他设定', value='',height=200, label_visibility='visible', disabled=True)
389
+
390
+ # st.write(f"{prompt_explain} {prompt_notice} {prompt_rule} {prompt_ouput}")
391
+
392
+ ### 以下是工作区,包括进度等。
393
+ st.divider()
394
+
395
+
396
+ ### prompt区
397
+
398
+ # prompt_sys = """你是一个法律专家。你需要完成我给你的任务。"""
399
+ # prompt_input = """我给你的数据中包括了一通完整的法律援助中心的电话记录,其中的数据格式说明如下:
400
+ # 1. "input"和“instruction”都代表了用户的问题,可以忽略“instruction”部分的内容。
401
+ # 2. “output”是法律顾问的回答内容。"""
402
+ # prompt_caution = """你忽略所有语法错误和错别字。"""
403
+ # prompt_output = """现在,我需要你帮忙我整理这通电话的内容,用如下格式(你只需要提供以下格式要求的内容,不需要输出任何其他说明或者解释。):
404
+ # 【用户问题】用一段话来总结用户的核心问题。
405
+ # 【法律顾问回答】用一段话来总结法律顾问的回答要点。
406
+ # 【整体情况】用一句话来简单概述判断这一通话的整体情况。
407
+ # 【是否解决】判断问题是否解决。
408
+
409
+ import st_data_parser
410
+
411
+ ### 用LLM总结语料的函数 , output_filepath是每次都会创建一个新的csv结果文件。
412
+ def llm_summary(file, file_content, output_filepath):
413
+ # call_content = file_content
414
+ # call_content = pd.read_json(call_content.decode('utf-8'))
415
+
416
+ ### 通过自定义的data_parser解析文件内容。
417
+ print('file:', file)
418
+ call_content = st_data_parser.parser(file=file)
419
+
420
+ print('call_content:', call_content)
421
+
422
+ ### a simple user prompt test.
423
+ ## user_prompt = f"""
424
+ # 我给你的数据中包括了一通完整的法律援助中心的电话记录,其中的数据格式说明如下:
425
+ # 1. "input"和“instruction”都代表了用户的问题,可以忽略“instruction”部分的内容。
426
+ # 2. “output”是法律顾问的回答内容。
427
+
428
+ # 现在,我需要你帮忙我整理这通电话的内容,用如下格式(你只需要提供以下格式要求的内容,不需要输出任何其他说明或者解释。):
429
+ # 【用户问题】用一段话来总结用户的核心问题。
430
+ # 【法律顾问回答】用一段话来总结法律顾问的回答要点。
431
+ # 【整体情况】用一句话来简单概述判断这一通话的整体情况。
432
+ # 【是否解决】判断问题是否解决。
433
+
434
+ # 数据内容如下:{call_content}
435
+ # """
436
+
437
+ user_prompt = prompt_sys + prompt_rule + prompt_input + prompt_caution + """我需要你帮忙我整理这通电话的内容,用如下格式(你只需要提供以下格式要求的内容,不需要输出任何其他说明或者解释。):\n""" + prompt_output + f"""数据内容如下:f{call_content}"""
438
+
439
+ print("---"*30)
440
+ print('user_prompt:', user_prompt)
441
+
442
+ llm_output = qwen_response.call_with_messages(prompt=user_prompt)
443
+ # summary = chatgpt.chatgpt(user_prompt=user_prompt)
444
+ # print(summary)
445
+
446
+ ## 将文件编号和summary存入summary.csv文件
447
+ # summary_csv = pd.read_csv('./summary_qwen.csv')
448
+ summary_csv = pd.read_csv('./summary_qwen.csv', encoding='utf-8')
449
+ # summary_csv = pd.read_csv('./summary_qwen.csv', encoding='utf-8', low_memory=True)
450
+ print('summary_csv:', summary_csv)
451
+ print("---"*30)
452
+ filename = os.path.basename(file.name) # Get the filename from the file path
453
+ # filename = os.path.basename(file_path) # Get the filename from the file path
454
+ filename_without_extension = os.path.splitext(filename)[0]
455
+
456
+ ### 每次运行都创建一个新的oupout文件。
457
+ # output_filepath = create_newfile.new_output_file(username)
458
+ final_output_filepath = f'{output_filepath}'
459
+ # final_filepath = f'./{username}/output.csv'
460
+ # final_filepath = './summary_qwen.csv'
461
+ save_csv_info(filepath=final_output_filepath, ID=filename_without_extension, output=llm_output)
462
+
463
+ return None
464
+
465
+ ### 主程序main
466
+ def main(uploaded_file=uploaded_file):
467
+ output_filepath = create_newfile.new_output_file(username)
468
+
469
+ ## 在存在上传文件时,启动LLM程序。
470
+ if uploaded_file and submit_btn:
471
+ ### Progress bar, 进度条设定
472
+ progress_bar_text = "**正在处理您的任务...**"
473
+ progress_bar = st.progress(0, text=progress_bar_text)
474
+
475
+ ###记录运行时间
476
+ start_time = time.time()
477
+
478
+ ### 记录正常运行的文件数,和缺失的文件数
479
+ success_files = []
480
+ fail_files = []
481
+
482
+ for i, file in enumerate(uploaded_file):
483
+ print(f'正在处理第{i+1}个文件', file.name)
484
+ try:
485
+ llm_summary(file=file, file_content=file.read(), output_filepath=output_filepath) ## 核心程序。
486
+ success_files.append(file.name)
487
+ except Exception as e:
488
+ print(e)
489
+ fail_files.append(file.name)
490
+ pass
491
+ progress_bar.progress((i+1)/len(uploaded_file), text=progress_bar_text) ## 展示进度条。
492
+ progress_bar = st.empty ## 重置进度条。
493
+
494
+ final_data = pd.read_csv(f'{output_filepath}', encoding='utf-8') ## 在ste.download_button处需要先获得data内容,这里将data进行赋值。
495
+ # final_data = pd.read_csv(f'./{username}/output.csv', encoding='utf-8') ## 在ste.download_button处需要先获得data内容,这里将data进行赋值。
496
+
497
+ end_time = time.time()
498
+ run_time = round((end_time - start_time),2)
499
+
500
+ ### 输出结果。
501
+ st.success(f"任务结束!请点击下方按钮保存结果文件。总运行时长{run_time}秒。成功处理了{len(success_files)}个文件;未完成文件数{len(fail_files)}个。", icon='💯')
502
+ if len(fail_files) > 0:
503
+ failed_file_elements = ', '.join(fail_files) ## 无法直接放入f""中。
504
+ st.warning(f"未完成的文件如下:{failed_file_elements}") ## 一次性打印出每个列表元素。1
505
+
506
+ # st.download_button(label='下载输出文件!', data=final_data, file_name='summary_qwen.csv', mime='text/csv')
507
+ ste.download_button(
508
+ label="点击下载结果文件",
509
+ data=final_data,
510
+ file_name='final_data.csv',
511
+ mime='text/csv',
512
+ )
513
+
514
+
515
+ return None
516
+
517
+ if __name__ == '__main__':
518
+ main()
config.yaml ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ credentials:
2
+ usernames:
3
+ joeshi:
4
+ email: joe.joeshi@gmail.com
5
+ name: joeshi
6
+ password: '$2b$12$8Jbjy0Cvq4UnXksw2PUa8.BOmssCExwIS/SrSZX4JwGWu1zJJ5Jxu' # To be replaced with hashed password
7
+ cindyji:
8
+ email: joe.joeshi@gmail.com
9
+ name: cindyji
10
+ password: '$2b$12$CA3Kc0sL0jVax7Wx0bbC7Op3edhtxlFUJkHS6ABjZCBN/1kbS3yem' # To be replaced with hashed password
11
+ test:
12
+ email: joe.joeshi@gmail.com
13
+ name: test
14
+ password: '$2b$12$RfaFTOmCII1x7X.U6O9u6OFjTlqYSK88EZy5Yy80nV.uxaxILSmsC' # To be replaced with hashed password, test
15
+ temp:
16
+ email: joe.joeshi@gmail.com
17
+ name: temp
18
+ password: '$2b$12$AvcADYBmeN77qFQvZ.mIf.fjMzJRgk/HH5OkLxCax6x3NsAQWrHki' # To be replaced with hashed password, test
19
+ guojing:
20
+ email: 1234@gmail.com
21
+ name: guojing
22
+ password: '$2b$12$NOBKb.j/KJzX1SrN2f9yQunnW3aGZmvK1Km.Cdl70Pmpb.jslRh7m' # To be replaced with hashed password, test
23
+ chengrui:
24
+ email: 1234@gmail.com
25
+ name: chengrui
26
+ password: '$2b$12$yru/vqM1aNEkG8yFt/3mvuULC8tllGEP0ht.nwuH14SBxvsire7g6' # To be replaced with hashed password, test
27
+ lbh:
28
+ email: 1234@gmail.com
29
+ name: lbh
30
+ password: '$2b$12$UKz0v6TN/AYaZ6vXt6Iike8711zV1M3g89zZk2jYPt0L9sFDPOYs.' # To be replaced with hashed password, test
31
+ austins:
32
+ email: 1234@gmail.com
33
+ name: austins
34
+ password: '$2b$12$Sfjuq84o8OXUrAzy945gN.WZBH2vBNW22T7LeZnIS.CmqXrZuKja.' # To be replaced with hashed password, test
35
+ lhj:
36
+ email: 1234@gmail.com
37
+ name: lhj
38
+ password: '$2b$12$YYt7FgQ.61SJ6U9m0JJUgesMXmYjz1oQG37PlrDA6kh3YIZmG6Aai' # To be replaced with hashed password, test
39
+ apples:
40
+ email: 1234@gmail.com
41
+ name: apples
42
+ password: '$2b$12$/6kuag4n0De3taSZiyBuPOr7APy3pz1O7Ms/ICZMy1kxwRpH9ucK.' # To be replaced with hashed password, test
43
+ carriec:
44
+ email: 1234@gmail.com
45
+ name: carriec
46
+ password: '$2b$12$A8gBPYSbDgFgAbr9QGANUeZx6J0jYq56yuesd6FeWDeyTQ0DLURRS' # To be replaced with hashed password, test
47
+ wuqijun:
48
+ email: 1234@gmail.com
49
+ name: wuqijun
50
+ password: '$2b$12$I8jYTti0r9cajzMbP6wgN.5Dx8mqE89ZFZYE9a0L107JdqzTNWEpu' # To be replaced with hashed password, test
51
+ sunzhifeng:
52
+ email: 1234@gmail.com
53
+ name: sunzhifeng
54
+ password: '$2b$12$oGvNcCTX/cdgPigUMd.vwekjQoKz4EPg87Nqh7.K/gHoFrKKHdVPi' # To be replaced with hashed password, test
55
+ pattern:
56
+ email: 1234@gmail.com
57
+ name: sunzhifeng
58
+ password: '$2b$12$uEy0iXQg4LuwTivV7JmcGuWSL.Gn21RY7iD/lNxsPBtT0PGRvjuxi' # To be replaced with hashed password, test
59
+ mao:
60
+ email: 1234@gmail.com
61
+ name: mao
62
+ password: '$2b$12$kMCNK85MgjZACFToD.L5puQkWOVsTdn7Lj/QVRBaVpHBMtiWQ8Nwe' # To be replaced with hashed password, test
63
+ cq:
64
+ email: 1234@gmail.com
65
+ name: cq
66
+ password: '$2b$12$YfjCXWbXXoada3kHdy9aiOYrI.3Mz94VIN.wrssaDGP2dJjgtVHcW' # To be replaced with hashed password, test
67
+ scottl:
68
+ email: 1234@gmail.com
69
+ name: scottl
70
+ password: '$2b$12$XTsFPlqFhI7EdobL2ZqF0uoAhgoq0Hmy/Gtmnsgo2u9C2waLl2eh.' # To be replaced with hashed password, test
71
+ test001:
72
+ email: 1234@gmail.com
73
+ name: test001
74
+ password: '$2b$12$.IqUmcWhPlKlJv.Y3Ghy8uoFdwA/1KOYuFMzst11sMqvJOfNs21vu' # To be replaced with hashed password, test
75
+ test002:
76
+ email: 1234@gmail.com
77
+ name: test002
78
+ password: '$2b$12$EI3cGR5pSddL/36wvOEiBOA0FGF3w5WhecCOxzgZCU63T0Oys3TbW' # To be replaced with hashed password, test
79
+ test003:
80
+ email: 1234@gmail.com
81
+ name: test003
82
+ password: '$2b$12$a487ZDz97h7gjXQIcoIWFOlKuQIoVEGz1eBdzz7Al1TzhO3RRr5kW' # To be replaced with hashed password, test
83
+ test004:
84
+ email: 1234@gmail.com
85
+ name: test004
86
+ password: '$2b$12$GjiDKG6FtZN/4YI5JN87y.zamKszqizPnTm6odM9nU62bg.9bjPt.' # To be replaced with hashed password, test
87
+ test005:
88
+ email: 1234@gmail.com
89
+ name: test005
90
+ password: '$2b$12$TpEenOq.c9HTjpw8ELIq5OPwTYt6TEYrJ4iANE2rCXUicV9aKHkyC' # To be replaced with hashed password, test
91
+ cookie:
92
+ expiry_days: 30
93
+ key: random_signature_key # Must be string
94
+ name: random_cookie_name
95
+ preauthorized:
96
+ emails:
97
+ - joe.joeshi@gmail.com
email_icon.png ADDED
internet_icon.png ADDED
llm_icon.png ADDED
log_icon.png ADDED
myavatars.png ADDED
qwen_response.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ from http import HTTPStatus
3
+ import dashscope
4
+
5
+ ### 参考:
6
+ ## export DASHSCOPE_API_KEY="sk-948adb3e65414e55961a9ad9d22d186b"
7
+ dashscope.api_key = "sk-948adb3e65414e55961a9ad9d22d186b"
8
+
9
+
10
+ def call_with_messages(prompt):
11
+ messages = [{'role': 'system', 'content': 'You are a helpful assistant.'},
12
+ {'role': 'user', 'content': prompt}]
13
+ # {'role': 'user', 'content': '如何做西红柿炒鸡蛋?'}]
14
+ response = dashscope.Generation.call(
15
+ "qwen-plus", ## 支持32K的模型。
16
+ # "qwen-turbo", ## 支持8K的模型。
17
+ messages=messages,
18
+ # set the random seed, optional, default to 1234 if not set
19
+ seed=random.randint(1, 10000),
20
+ # set the result to be "message" format.
21
+ result_format='message',
22
+ )
23
+ if response.status_code == HTTPStatus.OK:
24
+ print(response)
25
+
26
+ else:
27
+ print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
28
+ response.request_id, response.status_code,
29
+ response.code, response.message
30
+ ))
31
+
32
+ return response['output']['choices'][0]['message']['content'] ### 这里是content的内容,不是message的全部内容。
33
+
34
+
35
+ # if __name__ == '__main__':
36
+ # # call_with_messages() ### original code here.
37
+ # res = call_with_messages() ## working.
38
+ # # print(res)
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ dashscope==1.17.0
2
+ langchain==0.2.5
3
+ numpy==1.26.4
4
+ openai==1.34.0
5
+ pandas==2.2.2
6
+ python-dotenv==1.0.1
7
+ pytz==2024.1
8
+ PyYAML==6.0.1
9
+ PyYAML==6.0.1
10
+ Requests==2.32.3
11
+ streamlit==1.33.0
12
+ streamlit_authenticator==0.2.3
13
+ streamlit_ext==0.1.10
solution_icon.png ADDED