# app.py import gradio as gr from knowledge import lookup_course from deepseek_client import ask_deepseek import random def format_output(text: str, mode: str) -> str: # 去除所有非语句隔断的标点符号和表情符号,仅保留句号、问号、感叹号、分号、逗号、冒号、引号、括号、破折号、下划线、斜杠、百分号、数字、字母、汉字 import re # 允许的标点符号 allowed_punct = r'。??!!;;,,::“”"\(\)()\-——_、/%%《》<>' # 保留汉字、字母、数字和允许的标点 cleaned = re.sub(fr'[^\u4e00-\u9fa5a-zA-Z0-9{allowed_punct}\s]', '', text) # 鼓励语 encouragements = [ "继续加油,你一定可以掌握这些知识!", "学习路上,有我陪伴你一起进步!", "每一次努力,都是进步的阶梯!", "相信自己,你会越来越棒!", "知识的积累,成就更好的你!" ] # 学习名句 quotes = [ "学而不思则罔,思而不学则殆。——孔子", "敏而好学,不耻下问。——孔子", "业精于勤荒于嬉,行成于思毁于随。——韩愈", "书山有路勤为径,学海无涯苦作舟。", "知之者不如好之者,好之者不如乐之者。——孔子", "非学无以广才,非志无以成学。——诸葛亮", "黑发不知勤学早,白首方悔读书迟。——颜真卿" ] encouragement = random.choice(encouragements) quote = random.choice(quotes) return f"{cleaned}\n\n{encouragement}\n{quote}" def student_assistant(user_input: str, mode: str, messages: list) -> tuple: user_input = user_input.strip() if not user_input: return format_output("请输入课程名或问题。", mode), messages if mode == "课程知识点": # 切换到知识点模式时清空历史 return format_output(lookup_course(user_input), mode), [] else: # 构造历史对话 if messages is None: messages = [] messages = messages.copy() messages.append({"role": "user", "content": user_input}) reply = ask_deepseek(user_input, messages=messages[:-1]) messages.append({"role": "assistant", "content": reply}) return format_output(reply, mode), messages with gr.Blocks() as demo: gr.Markdown("# 智能学习助手 Demo\n输入课程名或问题,选择模式,获取答案。") with gr.Row(): user_input = gr.Textbox(label="输入课程名或问题", placeholder="如:C语言程序设计", lines=1) mode = gr.Radio(choices=["课程知识点", "与 LLM 问答"], label="模式选择", value="课程知识点") output = gr.Textbox(label="输出结果", interactive=False) state = gr.State([]) # 新增:用于存储对话历史 btn = gr.Button("提交") gr.Examples( examples=[ ["C语言程序设计", "课程知识点"], ["Web前端开发", "课程知识点"], ["计算机科学导论", "课程知识点"], ["Python程序设计", "课程知识点"], ["数据结构", "课程知识点"], ["操作系统", "课程知识点"], ["数据库原理", "课程知识点"], ["计算机网络", "课程知识点"], ["人工智能基础", "课程知识点"], ["Java程序设计", "课程知识点"], ["什么是二叉树?", "与 LLM 问答"], ["请介绍 SQL 的基本语法", "与 LLM 问答"] ], inputs=[user_input, mode] ) btn.click(student_assistant, inputs=[user_input, mode, state], outputs=[output, state]) user_input.submit(student_assistant, inputs=[user_input, mode, state], outputs=[output, state]) if __name__ == "__main__": demo.launch(share=True)