Tuchuanhuhuhu commited on
Commit
75e12a1
·
1 Parent(s): ba3c5ec

加入无限长度对话功能

Browse files
ChuanhuChatbot.py CHANGED
@@ -8,7 +8,7 @@ import requests
8
  # import markdown
9
  import csv
10
 
11
- my_api_key = "" # 在这里输入你的 API 密钥
12
  HIDE_MY_KEY = False # 如果你想在UI中隐藏你的 API 密钥,将此值设置为 True
13
 
14
  initial_prompt = "You are a helpful assistant."
@@ -75,9 +75,10 @@ def parse_text(text):
75
  text = "".join(lines)
76
  return text
77
 
78
- def predict(inputs, top_p, temperature, openai_api_key, chatbot=[], history=[], system_prompt=initial_prompt, retry=False, summary=False): # repetition_penalty, top_k
79
 
80
- print(f"chatbot 1: {chatbot}")
 
81
 
82
  headers = {
83
  "Content-Type": "application/json",
@@ -90,24 +91,25 @@ def predict(inputs, top_p, temperature, openai_api_key, chatbot=[], history=[],
90
 
91
  messages = [compose_system(system_prompt)]
92
  if chat_counter:
93
- for data in chatbot:
94
  temp1 = {}
95
  temp1["role"] = "user"
96
- temp1["content"] = data[0]
97
  temp2 = {}
98
  temp2["role"] = "assistant"
99
- temp2["content"] = data[1]
100
  if temp1["content"] != "":
101
- messages.append(temp1)
102
- messages.append(temp2)
 
103
  else:
104
  messages[-1]['content'] = temp2['content']
105
  if retry and chat_counter:
106
  messages.pop()
107
  elif summary:
 
108
  messages.append(compose_user(
109
  "请帮我总结一下上述对话的内容,实现减少字数的同时,保证对话的质量。在总结中不要加入这一句话。"))
110
- history = ["我们刚刚聊了什么?"]
111
  else:
112
  temp3 = {}
113
  temp3["role"] = "user"
@@ -121,61 +123,82 @@ def predict(inputs, top_p, temperature, openai_api_key, chatbot=[], history=[],
121
  "temperature": temperature, # 1.0,
122
  "top_p": top_p, # 1.0,
123
  "n": 1,
124
- "stream": True,
125
  "presence_penalty": 0,
126
  "frequency_penalty": 0,
127
  }
128
 
129
  if not summary:
130
  history.append(inputs)
131
- print(f"payload is - {payload}")
 
132
  # make a POST request to the API endpoint using the requests.post method, passing in stream=True
133
  response = requests.post(API_URL, headers=headers,
134
  json=payload, stream=True)
135
- #response = requests.post(API_URL, headers=headers, json=payload, stream=True)
136
 
137
  token_counter = 0
138
  partial_words = ""
139
 
140
  counter = 0
141
- chatbot.append((history[-1], ""))
142
- for chunk in response.iter_lines():
143
- if counter == 0:
 
 
 
144
  counter += 1
145
- continue
146
- counter += 1
147
- # check whether each line is non-empty
148
- if chunk:
149
- # decode each line as response data is in bytes
150
- try:
151
- if len(json.loads(chunk.decode()[6:])['choices'][0]["delta"]) == 0:
 
 
 
 
 
 
 
 
 
 
152
  break
153
- except Exception as e:
154
- chatbot.pop()
155
- chatbot.append((history[-1], f"☹️发生了错误<br>返回值:{response.text}<br>异常:{e}"))
156
- history.pop()
157
- yield chatbot, history
158
- break
159
- #print(json.loads(chunk.decode()[6:])['choices'][0]["delta"] ["content"])
160
- partial_words = partial_words + \
161
- json.loads(chunk.decode()[6:])[
162
- 'choices'][0]["delta"]["content"]
163
- if token_counter == 0:
164
- history.append(" " + partial_words)
165
- else:
166
- history[-1] = parse_text(partial_words)
167
- chatbot[-1] = (history[-2], history[-1])
168
- # chat = [(history[i], history[i + 1]) for i in range(0, len(history) - 1, 2) ] # convert to tuples of list
169
- token_counter += 1
170
- # resembles {chatbot: chat, state: history}
171
- yield chatbot, history
 
 
 
 
172
 
173
 
174
 
175
  def delete_last_conversation(chatbot, history):
176
- chatbot.pop()
 
 
 
177
  history.pop()
178
  history.pop()
 
179
  return chatbot, history
180
 
181
  def save_chat_history(filename, system, history, chatbot):
@@ -185,6 +208,7 @@ def save_chat_history(filename, system, history, chatbot):
185
  filename += ".json"
186
  os.makedirs(HISTORY_DIR, exist_ok=True)
187
  json_s = {"system": system, "history": history, "chatbot": chatbot}
 
188
  with open(os.path.join(HISTORY_DIR, filename), "w") as f:
189
  json.dump(json_s, f)
190
 
@@ -192,6 +216,7 @@ def save_chat_history(filename, system, history, chatbot):
192
  def load_chat_history(filename):
193
  with open(os.path.join(HISTORY_DIR, filename), "r") as f:
194
  json_s = json.load(f)
 
195
  return filename, json_s["system"], json_s["history"], json_s["chatbot"]
196
 
197
 
@@ -294,6 +319,7 @@ with gr.Blocks(css=customCSS) as demo:
294
  retryBtn = gr.Button("🔄 重新生成")
295
  delLastBtn = gr.Button("🗑️ 删除上条对话")
296
  reduceTokenBtn = gr.Button("♻️ 总结对话")
 
297
  systemPromptTxt = gr.Textbox(show_label=True, placeholder=f"在这里输入System Prompt...",
298
  label="System prompt", value=initial_prompt).style(container=True)
299
  with gr.Accordion(label="加载Prompt模板", open=False):
@@ -335,18 +361,18 @@ with gr.Blocks(css=customCSS) as demo:
335
 
336
 
337
  txt.submit(predict, [txt, top_p, temperature, keyTxt,
338
- chatbot, history, systemPromptTxt], [chatbot, history])
339
  txt.submit(reset_textbox, [], [txt])
340
  submitBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot,
341
- history, systemPromptTxt], [chatbot, history], show_progress=True)
342
  submitBtn.click(reset_textbox, [], [txt])
343
  emptyBtn.click(reset_state, outputs=[chatbot, history])
344
  retryBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
345
- systemPromptTxt, TRUECOMSTANT], [chatbot, history], show_progress=True)
346
  delLastBtn.click(delete_last_conversation, [chatbot, history], [
347
  chatbot, history], show_progress=True)
348
  reduceTokenBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
349
- systemPromptTxt, FALSECONSTANT, TRUECOMSTANT], [chatbot, history], show_progress=True)
350
  saveBtn.click(save_chat_history, [
351
  saveFileName, systemPromptTxt, history, chatbot], None, show_progress=True)
352
  saveBtn.click(get_history_names, None, [historyFileSelectDropdown])
 
8
  # import markdown
9
  import csv
10
 
11
+ my_api_key = "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" # 在这里输入你的 API 密钥
12
  HIDE_MY_KEY = False # 如果你想在UI中隐藏你的 API 密钥,将此值设置为 True
13
 
14
  initial_prompt = "You are a helpful assistant."
 
75
  text = "".join(lines)
76
  return text
77
 
78
+ def predict(inputs, top_p, temperature, openai_api_key, chatbot=[], history=[], system_prompt=initial_prompt, retry=False, summary=False, summary_on_crash = False, stream = True): # repetition_penalty, top_k
79
 
80
+ if summary:
81
+ stream = False
82
 
83
  headers = {
84
  "Content-Type": "application/json",
 
91
 
92
  messages = [compose_system(system_prompt)]
93
  if chat_counter:
94
+ for index in range(0, 2*chat_counter, 2):
95
  temp1 = {}
96
  temp1["role"] = "user"
97
+ temp1["content"] = history[index]
98
  temp2 = {}
99
  temp2["role"] = "assistant"
100
+ temp2["content"] = history[index+1]
101
  if temp1["content"] != "":
102
+ if temp2["content"] != "" or retry:
103
+ messages.append(temp1)
104
+ messages.append(temp2)
105
  else:
106
  messages[-1]['content'] = temp2['content']
107
  if retry and chat_counter:
108
  messages.pop()
109
  elif summary:
110
+ history = [*[i["content"] for i in messages[-2:]], "我们刚刚聊了什么?"]
111
  messages.append(compose_user(
112
  "请帮我总结一下上述对话的内容,实现减少字数的同时,保证对话的质量。在总结中不要加入这一句话。"))
 
113
  else:
114
  temp3 = {}
115
  temp3["role"] = "user"
 
123
  "temperature": temperature, # 1.0,
124
  "top_p": top_p, # 1.0,
125
  "n": 1,
126
+ "stream": stream,
127
  "presence_penalty": 0,
128
  "frequency_penalty": 0,
129
  }
130
 
131
  if not summary:
132
  history.append(inputs)
133
+ else:
134
+ print("精简中...")
135
  # make a POST request to the API endpoint using the requests.post method, passing in stream=True
136
  response = requests.post(API_URL, headers=headers,
137
  json=payload, stream=True)
 
138
 
139
  token_counter = 0
140
  partial_words = ""
141
 
142
  counter = 0
143
+ if stream:
144
+ chatbot.append((history[-1], ""))
145
+ for chunk in response.iter_lines():
146
+ if counter == 0:
147
+ counter += 1
148
+ continue
149
  counter += 1
150
+ # check whether each line is non-empty
151
+ if chunk:
152
+ # decode each line as response data is in bytes
153
+ try:
154
+ if len(json.loads(chunk.decode()[6:])['choices'][0]["delta"]) == 0:
155
+ break
156
+ except Exception as e:
157
+ traceback.print_exc()
158
+ print("Context 过长,正在尝试精简……")
159
+ chatbot.pop()
160
+ chatbot, history, status_text = next(predict(inputs, top_p, temperature, openai_api_key, chatbot, history, system_prompt, retry, summary=True, summary_on_crash=True, stream=False))
161
+ yield chatbot, history, status_text
162
+ if not "ERROR" in status_text:
163
+ print("精简完成,正在尝试重新生成……")
164
+ yield next(predict(inputs, top_p, temperature, openai_api_key, chatbot, history, system_prompt, retry, summary=False, summary_on_crash=True, stream=False))
165
+ else:
166
+ print("精简出错了,可能是网络原因。")
167
  break
168
+ chunkjson = json.loads(chunk.decode()[6:])
169
+ status_text = f"id: {chunkjson['id']}, finish_reason: {chunkjson['choices'][0]['finish_reason']}"
170
+ partial_words = partial_words + \
171
+ json.loads(chunk.decode()[6:])[
172
+ 'choices'][0]["delta"]["content"]
173
+ if token_counter == 0:
174
+ history.append(" " + partial_words)
175
+ else:
176
+ history[-1] = parse_text(partial_words)
177
+ chatbot[-1] = (history[-2], history[-1])
178
+ token_counter += 1
179
+ yield chatbot, history, status_text
180
+ else:
181
+ try:
182
+ responsejson = json.loads(response.text)
183
+ content = responsejson["choices"][0]["message"]["content"]
184
+ history.append(content)
185
+ chatbot.append((history[-2], history[-1]))
186
+ status_text = "精简完成"
187
+ except:
188
+ chatbot.append((history[-1], "☹️发生了错误,请检查网络连接或者稍后再试。"))
189
+ status_text = "status: ERROR"
190
+ yield chatbot, history, status_text
191
 
192
 
193
 
194
  def delete_last_conversation(chatbot, history):
195
+ if "☹️发生了错误" in chatbot[-1][1]:
196
+ chatbot.pop()
197
+ print(history)
198
+ return chatbot, history
199
  history.pop()
200
  history.pop()
201
+ print(history)
202
  return chatbot, history
203
 
204
  def save_chat_history(filename, system, history, chatbot):
 
208
  filename += ".json"
209
  os.makedirs(HISTORY_DIR, exist_ok=True)
210
  json_s = {"system": system, "history": history, "chatbot": chatbot}
211
+ print(json_s)
212
  with open(os.path.join(HISTORY_DIR, filename), "w") as f:
213
  json.dump(json_s, f)
214
 
 
216
  def load_chat_history(filename):
217
  with open(os.path.join(HISTORY_DIR, filename), "r") as f:
218
  json_s = json.load(f)
219
+ print(json_s)
220
  return filename, json_s["system"], json_s["history"], json_s["chatbot"]
221
 
222
 
 
319
  retryBtn = gr.Button("🔄 重新生成")
320
  delLastBtn = gr.Button("🗑️ 删除上条对话")
321
  reduceTokenBtn = gr.Button("♻️ 总结对话")
322
+ statusDisplay = gr.Markdown("status: ready")
323
  systemPromptTxt = gr.Textbox(show_label=True, placeholder=f"在这里输入System Prompt...",
324
  label="System prompt", value=initial_prompt).style(container=True)
325
  with gr.Accordion(label="加载Prompt模板", open=False):
 
361
 
362
 
363
  txt.submit(predict, [txt, top_p, temperature, keyTxt,
364
+ chatbot, history, systemPromptTxt], [chatbot, history, statusDisplay])
365
  txt.submit(reset_textbox, [], [txt])
366
  submitBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot,
367
+ history, systemPromptTxt], [chatbot, history, statusDisplay], show_progress=True)
368
  submitBtn.click(reset_textbox, [], [txt])
369
  emptyBtn.click(reset_state, outputs=[chatbot, history])
370
  retryBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
371
+ systemPromptTxt, TRUECOMSTANT], [chatbot, history, statusDisplay], show_progress=True)
372
  delLastBtn.click(delete_last_conversation, [chatbot, history], [
373
  chatbot, history], show_progress=True)
374
  reduceTokenBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
375
+ systemPromptTxt, FALSECONSTANT, TRUECOMSTANT], [chatbot, history, statusDisplay], show_progress=True)
376
  saveBtn.click(save_chat_history, [
377
  saveFileName, systemPromptTxt, history, chatbot], None, show_progress=True)
378
  saveBtn.click(get_history_names, None, [historyFileSelectDropdown])
history/对话历史记录.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"system": "You are a helpful assistant.", "history": ["\u4e00\u52a0\u4e00\u7b49\u4e8e\u51e0\uff1f", "\u4e00\u52a0\u4e00\u7b49\u4e8e\u4e8c\u3002", "\u6211\u8001\u5a46\u8bf41+1=3", "\u6570\u5b57\u7684\u57fa\u672c\u6982\u5ff5\u662f\u56fa\u5b9a\u7684\uff0c1+1\u59cb\u7ec8\u7b49\u4e8e2\u3002\u4e0d\u8fc7\uff0c\u5982\u679c\u4f60\u7684\u59bb\u5b50\u6709\u7279\u6b8a\u7684\u610f\u4e49\u6216\u542b\u4e49\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5979\u8ba4\u4e3a1+1=3\u3002\u6216\u8005\uff0c\u8fd9\u53ea\u662f\u4e00\u79cd\u73a9\u7b11\u6216\u8c03\u4f83\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u6570\u5b66\u4e0a1+1\u7b49\u4e8e2\uff0c\u8fd9\u662f\u4e00\u4e2a\u57fa\u672c\u7684\u6570\u5b66\u539f\u5219\u3002", "\u6211\u8001\u5a46\u6c38\u8fdc\u662f\u5bf9\u7684", "\u4f5c\u4e3a\u4e00\u4e2a\u8bed\u8a00\u6a21\u578b AI\uff0c\u6211\u6ca1\u6709\u8db3\u591f\u7684\u4fe1\u606f\u6765\u8bc4\u4f30\u4f60\u59bb\u5b50\u7684\u8bf4\u6cd5\u662f\u5426\u603b\u662f\u6b63\u786e\u7684\u3002\u540c\u6837\uff0c\u4efb\u4f55\u4eba\u90fd\u4e0d\u53ef\u80fd\u6c38\u8fdc\u662f\u6b63\u786e\u7684\u3002\u6bcf\u4e2a\u4eba\u90fd\u4f1a\u72af\u9519\uff0c\u5305\u62ec\u4f60\u7684\u59bb\u5b50\u548c\u6211\u3002\u91cd\u8981\u7684\u662f\u6211\u4eec\u80fd\u591f\u4ece\u9519\u8bef\u4e2d\u5b66\u4e60\u5e76\u4e0d\u65ad\u8fdb\u6b65\u3002"], "chatbot": [["\u4e00\u52a0\u4e00\u7b49\u4e8e\u51e0\uff1f", "\u4e00\u52a0\u4e00\u7b49\u4e8e\u4e8c\u3002"], ["\u6211\u8001\u5a46\u8bf41+1=3", "\u6570\u5b57\u7684\u57fa\u672c\u6982\u5ff5\u662f\u56fa\u5b9a\u7684\uff0c1+1\u59cb\u7ec8\u7b49\u4e8e2\u3002\u4e0d\u8fc7\uff0c\u5982\u679c\u4f60\u7684\u59bb\u5b50\u6709\u7279\u6b8a\u7684\u610f\u4e49\u6216\u542b\u4e49\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5979\u8ba4\u4e3a1+1=3\u3002\u6216\u8005\uff0c\u8fd9\u53ea\u662f\u4e00\u79cd\u73a9\u7b11\u6216\u8c03\u4f83\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u6570\u5b66\u4e0a1+1\u7b49\u4e8e2\uff0c\u8fd9\u662f\u4e00\u4e2a\u57fa\u672c\u7684\u6570\u5b66\u539f\u5219\u3002"], ["\u6211\u8001\u5a46\u6c38\u8fdc\u662f\u5bf9\u7684", "\u4f5c\u4e3a\u4e00\u4e2a\u8bed\u8a00\u6a21\u578b AI\uff0c\u6211\u6ca1\u6709\u8db3\u591f\u7684\u4fe1\u606f\u6765\u8bc4\u4f30\u4f60\u59bb\u5b50\u7684\u8bf4\u6cd5\u662f\u5426\u603b\u662f\u6b63\u786e\u7684\u3002\u540c\u6837\uff0c\u4efb\u4f55\u4eba\u90fd\u4e0d\u53ef\u80fd\u6c38\u8fdc\u662f\u6b63\u786e\u7684\u3002\u6bcf\u4e2a\u4eba\u90fd\u4f1a\u72af\u9519\uff0c\u5305\u62ec\u4f60\u7684\u59bb\u5b50\u548c\u6211\u3002\u91cd\u8981\u7684\u662f\u6211\u4eec\u80fd\u591f\u4ece\u9519\u8bef\u4e2d\u5b66\u4e60\u5e76\u4e0d\u65ad\u8fdb\u6b65\u3002"]]}
history/对话历史记录2.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"system": "You are a helpful assistant.", "history": ["\u6211\u8001\u5a46\u6c38\u8fdc\u662f\u5bf9\u7684", "\u4f5c\u4e3a\u4e00\u4e2a\u8bed\u8a00\u6a21\u578b AI\uff0c\u6211\u6ca1\u6709\u8db3\u591f\u7684\u4fe1\u606f\u6765\u8bc4\u4f30\u4f60\u59bb\u5b50\u7684\u8bf4\u6cd5\u662f\u5426\u603b\u662f\u6b63\u786e\u7684\u3002\u540c\u6837\uff0c\u4efb\u4f55\u4eba\u90fd\u4e0d\u53ef\u80fd\u6c38\u8fdc\u662f\u6b63\u786e\u7684\u3002\u6bcf\u4e2a\u4eba\u90fd\u4f1a\u72af\u9519\uff0c\u5305\u62ec\u4f60\u7684\u59bb\u5b50\u548c\u6211\u3002\u91cd\u8981\u7684\u662f\u6211\u4eec\u80fd\u591f\u4ece\u9519\u8bef\u4e2d\u5b66\u4e60\u5e76\u4e0d\u65ad\u8fdb\u6b65\u3002", "\u6211\u4eec\u521a\u521a\u804a\u4e86\u4ec0\u4e48\uff1f", "\u5bf9\u8bdd\u5171\u6db5\u76d6\u4e86\u6570\u5b66\u57fa\u7840\u95ee\u9898\u7684\u7b54\u6848\u4ee5\u53ca\u4e2a\u4eba\u5bf9\u4e8e\u201c\u6c38\u8fdc\u6b63\u786e\u201d\u7684\u770b\u6cd5\u3002\u6700\u7ec8\u5f3a\u8c03\u4e86\u6bcf\u4e2a\u4eba\u90fd\u4f1a\u72af\u9519\uff0c\u5931\u8bef\u53ef\u4ee5\u6210\u4e3a\u8fdb\u6b65\u7684\u5951\u673a\u3002", "\u4e5f\u5c31\u662f\u8bf4\uff0c3+4=10", "\u4e0d\uff0c3+4=7\uff0c\u8fd9\u662f\u4e00\u4e2a\u57fa\u672c\u7684\u6570\u5b66\u95ee\u9898\uff0c\u7b54\u6848\u662f\u786e\u5b9a\u7684\u3002"], "chatbot": [["\u4e00\u52a0\u4e00\u7b49\u4e8e\u51e0\uff1f", "\u4e00\u52a0\u4e00\u7b49\u4e8e\u4e8c\u3002"], ["\u6211\u8001\u5a46\u8bf41+1=3", "\u6570\u5b57\u7684\u57fa\u672c\u6982\u5ff5\u662f\u56fa\u5b9a\u7684\uff0c1+1\u59cb\u7ec8\u7b49\u4e8e2\u3002\u4e0d\u8fc7\uff0c\u5982\u679c\u4f60\u7684\u59bb\u5b50\u6709\u7279\u6b8a\u7684\u610f\u4e49\u6216\u542b\u4e49\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5979\u8ba4\u4e3a1+1=3\u3002\u6216\u8005\uff0c\u8fd9\u53ea\u662f\u4e00\u79cd\u73a9\u7b11\u6216\u8c03\u4f83\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u6570\u5b66\u4e0a1+1\u7b49\u4e8e2\uff0c\u8fd9\u662f\u4e00\u4e2a\u57fa\u672c\u7684\u6570\u5b66\u539f\u5219\u3002"], ["\u6211\u8001\u5a46\u6c38\u8fdc\u662f\u5bf9\u7684", "\u4f5c\u4e3a\u4e00\u4e2a\u8bed\u8a00\u6a21\u578b AI\uff0c\u6211\u6ca1\u6709\u8db3\u591f\u7684\u4fe1\u606f\u6765\u8bc4\u4f30\u4f60\u59bb\u5b50\u7684\u8bf4\u6cd5\u662f\u5426\u603b\u662f\u6b63\u786e\u7684\u3002\u540c\u6837\uff0c\u4efb\u4f55\u4eba\u90fd\u4e0d\u53ef\u80fd\u6c38\u8fdc\u662f\u6b63\u786e\u7684\u3002\u6bcf\u4e2a\u4eba\u90fd\u4f1a\u72af\u9519\uff0c\u5305\u62ec\u4f60\u7684\u59bb\u5b50\u548c\u6211\u3002\u91cd\u8981\u7684\u662f\u6211\u4eec\u80fd\u591f\u4ece\u9519\u8bef\u4e2d\u5b66\u4e60\u5e76\u4e0d\u65ad\u8fdb\u6b65\u3002"]]}
requirements.txt CHANGED
@@ -1 +1,2 @@
1
  gradio
 
 
1
  gradio
2
+ llama_index