ChuanhuChatGPT
ChuanhuChatGPT copied to clipboard
前置总结,保留最近的对话
仅讨论该PR是否有必要,目前仅经过了简单测试,不着急merge
很多Issue里都提到了一些关于token超出上限的特殊情况,因此这里给出另一套实现思路:
-
在predict函数中,首先统计history的长度,如果history超出某一个上限~3000,那么先行进行精简
-
非流式地生成精简结果后,从头扫描一遍history,直到token达到~2000,删除这部分history,并以固定地Prompt替换:
user:[ChatGPT刚刚给出的结果](刚刚我们谈到了……),你了解了吗? assistant: 我了解了。 user: [原来的2000~3000聊天内容]
相比原来的实现,具有以下优势:
- 更加稳定,当前情况下,是在生成后再精简,如果用户本段token太长,除非用户先手动精简,否则将在触发一次“error”后被动地触发精简,用户体验差。
- 精简必将损失一些信息,用户对于最近的信息的精确性要求比聊天最开始的信息精确性要求更高
- 利于用户继续进行追问,否则上一条信息中的细节将因精简而消失,且由于该精简为被动触发,用户完全没有机会避免。
具体实现在utils.py 的以下函数中:
def silent_summarize(openai_api_key, system_prompt, history, temperature, top_p, selected_model, all_token_counts)
address to issue #184
现在更新的reduce_token_size
函数改进了这一行为:
def reduce_token_size(
openai_api_key,
system_prompt,
history,
chatbot,
token_count,
top_p,
temperature,
max_token_count,
selected_model=MODELS[0],
):
logging.info("开始减少token数量……")
iter = predict(
openai_api_key,
system_prompt,
history,
summarize_prompt,
chatbot,
token_count,
top_p,
temperature,
selected_model=selected_model,
should_check_token_count=False,
)
logging.info(f"chatbot: {chatbot}")
flag = False
for chatbot, history, status_text, previous_token_count in iter:
num_chat = find_n(previous_token_count, max_token_count)
if flag:
chatbot = chatbot[:-1]
flag = True
history = history[-2*num_chat:] if num_chat > 0 else []
token_count = previous_token_count[-num_chat:] if num_chat > 0 else []
msg = f"保留了最近{num_chat}轮对话"
yield chatbot, history, msg + "," + construct_token_message(
sum(token_count) if len(token_count) > 0 else 0,
), token_count
logging.info(msg)
logging.info("减少token数量完毕")