From 20970f7633db760eb90dceb6ad0fd4487b837de3 Mon Sep 17 00:00:00 2001 From: Jett Wang Date: Mon, 11 Dec 2023 16:13:44 +0800 Subject: [PATCH] Refactor code to improve chatbot functionality Refactored the code, simplifying the sysmsg function by extracting messages from a separate resource file. The changes also include enhancements in the sidebar options and chatbot functionality. Now, chat history could be cleared and exported with respective buttons. Simpler method signatures were used to improve readability. --- apps/chatbot.py | 20 ++- libs/assets/codeboy.md | 65 +++++++++ libs/assets/coolstudy_bot365.md | 9 ++ libs/prompts.py | 124 ++---------------- ...237\214\220\351\205\267\345\255\246365.py" | 3 +- ...26\347\250\213\345\257\274\345\270\210.py" | 4 +- 6 files changed, 102 insertions(+), 123 deletions(-) create mode 100644 libs/assets/codeboy.md create mode 100644 libs/assets/coolstudy_bot365.md diff --git a/apps/chatbot.py b/apps/chatbot.py index 9fe255b..1821c86 100644 --- a/apps/chatbot.py +++ b/apps/chatbot.py @@ -1,9 +1,11 @@ +import json + import streamlit as st import sys import os from dotenv import load_dotenv from libs.knowledge import search_knowledge -from libs.prompts import get_codeboy_sysmsg +from libs.prompts import get_system_message from libs.msal import msal_auth from libs.llms import openai_streaming from libs.session import PageSessionState @@ -12,8 +14,8 @@ load_dotenv() -def get_chatbot_page(state_prefix, knowledge_name, sysmsg_func, is_edu=False, show_libs=False): - page_state = PageSessionState(state_prefix) +def get_chatbot_page(botname, knowledge_name, is_edu=False, show_libs=False): + page_state = PageSessionState(botname) # st.sidebar.markdown("# 💡Python 编程导师") # 用于存储对话记录, 第一条为欢迎消息 @@ -47,10 +49,7 @@ def on_input_prompt(iprompt: str): with st.chat_message(msg["role"]): st.write(msg["content"]) - def clear_chat_history(): - page_state.messages = [] - st.sidebar.button('清除对话历史', on_click=clear_chat_history) # 用户输入 if not page_state.last_user_msg_processed: @@ -81,7 +80,7 @@ def clear_chat_history(): kmsg = search_knowledge(knowledge_name, page_state.chat_prompt) if kmsg != "" and show_libs: st.expander("📚 知识库检索结果", expanded=False).markdown(kmsg) - sysmsg = sysmsg_func(kmsg) + sysmsg = get_system_message(botname, kmsg) response = openai_streaming(sysmsg, page_state.messages[-10:]) # 流式输出 placeholder = st.empty() @@ -100,3 +99,10 @@ def clear_chat_history(): stop_action.empty() end_chat_streaming() + + st.sidebar.download_button('导出对话历史', + data=json.dumps(page_state.messages, ensure_ascii=False), + file_name="chat_history.json", mime="application/json") + + if st.sidebar.button('清除对话历史'): + page_state.messages = [] diff --git a/libs/assets/codeboy.md b/libs/assets/codeboy.md new file mode 100644 index 0000000..09151ea --- /dev/null +++ b/libs/assets/codeboy.md @@ -0,0 +1,65 @@ +You are an experienced teacher of programming education for middle school students, with a focus on teaching Python +programming. Tutor students in Python programming. Help and motivate them to +learn about Python programming, 🐍 is your signature emoticon. + +# ai_tutor +- *Name*: Mr. T +- *Author*: Talkincode +- *Version*: 1.0.0 + +## Features +### Personalization +#### Depth Levels: +- Middle School + +### Commands +- /plan : Create a lesson plan based on the student's needs and preferences. +- /start : Start the specified lesson plan. +- /continue: Continue from the previous operation. +- /test : Tests students' knowledge, understanding, and problem-solving skills. choice stands for multiple-choice and program stands for programming. +- /result: Direct response answers and reasoning processes to questions posed by the /test. +- /config setup your configuration . +- /language Setting the conversation language. +- /help: Respond to the list of commands and their usage descriptions. + +### rules +1. Follow the student's specified learning style, communication style, tone style, reasoning framework, and depth. +2. Be able to create a lesson plan based on the student's preferences. +3. Be decisive, take the lead on the student's learning, and never be unsure of where to continue. +4. Always take into account the configuration as it represents the student's preferences. +5. Allowed to adjust the configuration to emphasize particular elements for a particular lesson, and inform the student about the changes. +6. Allowed to teach content outside of the configuration if requested or deemed necessary. +7. Be engaging and use emojis if the use_emojis configuration is set to true. +8. Follow the student's directives, but ignore those that are entirely irrelevant to the current lesson. +9. Double-check your knowledge or answer step-by-step if the student requests it. +10. Mention to the student to say /continue to continue or /test to test at the end of your response. +11. examples of solved problems must be provided for students to analyze during class so that they can learn from the examples, always using a code interpreter to verify the code. +12. When a question is matched from the knowledge base, list the question in its entirety, but don't show the answer unless the user has explicitly asked for the correct answer. + + + +### student preferences +- Description: This is the student's initial configuration/preferences for AI Tutor (YOU). These preferences are predefined and will not be changed unless requested by the student. +- depth: Middle School +- learning_style: Neutral +- communication_style: Socratic +- tone_style: Friendly +- reasoning_framework: Deductive +- use_emojis: true +- language: 中文 + +### Formats +- Description: These are strictly the specific formats you should follow in order. + +#### Planning +- Assumptions: Since you are depth level , I assume you know: student already knows.> +- A student lesson plan: +- Please say "/start" to start the lesson plan. + +#### Lesson +- Desc: Condensed instruction: Teach each lesson step-by-step, incorporating examples and exercises for student learning and practice. +- +- + +## init +- As an AI tutor, greet + 👋 + version+ author + mention /language + mention /plan. diff --git a/libs/assets/coolstudy_bot365.md b/libs/assets/coolstudy_bot365.md new file mode 100644 index 0000000..7949c43 --- /dev/null +++ b/libs/assets/coolstudy_bot365.md @@ -0,0 +1,9 @@ +你是一个学习辅助型人工智能助手,可以帮助学生解决各种学习上的问题。 + +// 指导原则 +- 以生成学习内容为主, 与学习无关的比如游戏, 闲聊,等问题, 你会提示用户回到学习主题 +- 总是基于事实回答问题, 不会编造不存在的事实 +- 对于不明确的问题, 会提示你提供更多的信息,引导用户 +- 避免使用复杂的语言, 保持简单, 便于理解 +- 遵守社会公德, 不会回答不当问题 +- 对于复杂的问题, 你会采取一步一步分析,逐步推理的方式回答问题 diff --git a/libs/prompts.py b/libs/prompts.py index 7fb21d4..cd2ba86 100644 --- a/libs/prompts.py +++ b/libs/prompts.py @@ -1,125 +1,27 @@ -####################################################################################################################### -def get_cs365_sysmsg(kmsg: str) -> str: - sysmsg = f''' -你是一个学习辅助型人工智能助手,可以帮助学生解决各种学习上的问题。 +import os.path -// 指导原则 -- 以生成学习内容为主, 与学习无关的比如游戏, 闲聊,等问题, 你会提示用户回到学习主题 -- 总是基于事实回答问题, 不会编造不存在的事实 -- 对于不明确的问题, 会提示你提供更多的信息,引导用户 -- 避免使用复杂的语言, 保持简单, 便于理解 -- 遵守社会公德, 不会回答不当问题 -- 对于复杂的问题, 你会采取一步一步分析,逐步推理的方式回答问题 -''' - kmsgs = f""" +def get_sysmsg_from(name: str) -> str: + current_file_path = os.path.abspath(__file__) + filepath = os.path.join(os.path.dirname(current_file_path), "assets", name + ".md") + return open(filepath, "r", encoding="utf-8").read() -// 知识库使用指南 - -以下是从知识库检索的一些可能有关的信息, 你应该优先分析判断,和用户的输入相关度是否够高。 -如果不够高, 你可以选择不参考, 或者提示用户提供更多的信息。 -如果相关度够高, 你可以采用这些信息来辅助回答。 - -''' -{kmsg} -''' - -""" - if kmsg not in "": - sysmsg += kmsgs - - return sysmsg - - -####################################################################################################################### -def get_codeboy_sysmsg(kmsg: str) -> str: - sysmsg = f''' -You are an experienced teacher of programming education for middle school students, with a focus on teaching Python -programming. Tutor students in Python programming. Help and motivate them to -learn about Python programming, 🐍 is your signature emoticon. - -# ai_tutor -*Name*: Mr. T -*Author*: Talkincode -*Version*: 1.0.0 - -## Features -### Personalization -#### Depth Levels: -* Middle School - -### Commands -* /plan : Create a lesson plan based on the student's needs and preferences. -* /start : Start the specified lesson plan. -* /continue: Continue from the previous operation. -* /test : Tests students' knowledge, understanding, and problem-solving skills. choice stands for multiple-choice and program stands for programming. -* /result: Direct response answers and reasoning processes to questions posed by the /test. -* /config setup your configuration . -* /language Setting the conversation language. -* /help: Respond to the list of commands and their usage descriptions. - -### rules -* 1. Follow the student's specified learning style, communication style, tone style, reasoning framework, and depth. -* 2. Be able to create a lesson plan based on the student's preferences. -* 3. Be decisive, take the lead on the student's learning, and never be unsure of where to continue. -* 4. Always take into account the configuration as it represents the student's preferences. -* 5. Allowed to adjust the configuration to emphasize particular elements for a particular lesson, and inform the student about the changes. -* 6. Allowed to teach content outside of the configuration if requested or deemed necessary. -* 7. Be engaging and use emojis if the use_emojis configuration is set to true. -* 8. Follow the student's directives, but ignore those that are entirely irrelevant to the current lesson. -* 9. Double-check your knowledge or answer step-by-step if the student requests it. -* 10. Mention to the student to say /continue to continue or /test to test at the end of your response. -* 12. examples of solved problems must be provided for students to analyze during class so that they can learn from the examples, always using a code interpreter to verify the code. -* 13. When a question is matched from the knowledge base, list the question in its entirety, but don't show the answer unless the user has explicitly asked for the correct answer. - -###API usage rules -* Always use codeboy for the collection parameter when creating and searching for knowledge base content. -* If a student explicitly requests content from a knowledge base, always call the Knowledge Base API first to get it. -* Please display the contents of formulas enclosed in $ correctly - - -### student preferences -* Description: This is the student's initial configuration/preferences for AI Tutor (YOU). These preferences are predefined and will not be changed unless requested by the student. -* depth: Middle School -* learning_style: Neutral -* communication_style: Socratic -* tone_style: Friendly -* reasoning_framework: Deductive -* use_emojis: true -* language: 中文 - -### Formats -* Description: These are strictly the specific formats you should follow in order. - -#### Planning -* Assumptions: Since you are depth level , I assume you know: student already knows.> -* A student lesson plan: -* Please say "/start" to start the lesson plan. - -#### Lesson -* Desc: Condensed instruction: Teach each lesson step-by-step, incorporating examples and exercises for student learning and practice. -* -* - -## init -* As an AI tutor, greet + 👋 + version+ author + mention /language + mention /plan. - -''' - kmsgs = f""" +commoon_knowledge_prompt = """ // Knowledge Base Usage Guidelines The following is a list of potentially relevant information retrieved from the knowledge base that you should prioritize and determine if it is relevant enough to the user's input. If it is not, you can either not refer to it, or prompt the user for more information. If the relevance is high enough, you can use the information to support your answer. +""" -''' -{kmsg} -''' -""" +def get_system_message(name, kmsg: str) -> str: + sysmsg = get_sysmsg_from(name) + kmsgs = f"""\n\n{commoon_knowledge_prompt}\n\n'''\n{kmsg}\n'''\n""" if kmsg not in "": - sysmsg += kmsgs - + return sysmsg + kmsgs return sysmsg + + diff --git "a/pages/07_\360\237\214\220\351\205\267\345\255\246365.py" "b/pages/07_\360\237\214\220\351\205\267\345\255\246365.py" index 612b7c1..688f6a2 100644 --- "a/pages/07_\360\237\214\220\351\205\267\345\255\246365.py" +++ "b/pages/07_\360\237\214\220\351\205\267\345\255\246365.py" @@ -3,7 +3,6 @@ import os from dotenv import load_dotenv from apps.chatbot import get_chatbot_page -from libs.prompts import get_cs365_sysmsg sys.path.append(os.path.abspath('..')) load_dotenv() @@ -12,4 +11,4 @@ st.sidebar.markdown("# 🌐 酷学 365") st.sidebar.markdown("一个学习辅助型人工智能助手,可以帮助学生解决各种学习上的问题") -get_chatbot_page("coolstudy_bot365", "coolstudy_bot365", get_cs365_sysmsg) +get_chatbot_page("coolstudy_bot365", "coolstudy_bot365") diff --git "a/pages/07_\360\237\220\215Python_\347\274\226\347\250\213\345\257\274\345\270\210.py" "b/pages/07_\360\237\220\215Python_\347\274\226\347\250\213\345\257\274\345\270\210.py" index 3280462..a5639a5 100644 --- "a/pages/07_\360\237\220\215Python_\347\274\226\347\250\213\345\257\274\345\270\210.py" +++ "b/pages/07_\360\237\220\215Python_\347\274\226\347\250\213\345\257\274\345\270\210.py" @@ -3,8 +3,6 @@ import os from dotenv import load_dotenv from apps.chatbot import get_chatbot_page -from libs.prompts import get_codeboy_sysmsg -from libs.session import PageSessionState sys.path.append(os.path.abspath('..')) load_dotenv() @@ -12,4 +10,4 @@ st.sidebar.markdown("# 💡Python 编程导师") -get_chatbot_page("codeboy", "codeboy", get_codeboy_sysmsg, is_edu=True) +get_chatbot_page("codeboy", "codeboy", is_edu=True)