Spaces:
Sleeping
Sleeping
| # api/teacher_agent.py | |
| """ | |
| 教师端 AI Agent:基于与 Clare 相同的 Weaviate(GenAICourses)与 OpenAI,为教师提供: | |
| - 课程描述生成 | |
| - 课程文档内容建议 | |
| - 作业和题库生成建议 | |
| - 学生学习评估分析 | |
| """ | |
| from typing import Optional | |
| from .config import client, DEFAULT_MODEL, USE_WEAVIATE | |
| from .weaviate_retrieve import retrieve_from_weaviate | |
| TEACHER_SYSTEM = """你是一位面向高校教师的 AI 助教,擅长课程设计、教学材料建议与学习评估分析。 | |
| 你与 Clare 共用同一套 GENAI 课程知识库(Weaviate)。回答时请优先依据提供的「课程知识库摘录」, | |
| 并结合通用教学经验,给出简洁、可操作的建议。若未提供知识库摘录,则基于通用教育学与学科知识回答。""" | |
| def _lang_instruction(reply_language: Optional[str]) -> str: | |
| if reply_language == "en" or reply_language == "english": | |
| return "You must reply in English only." | |
| if reply_language == "zh" or reply_language == "中文" or not reply_language: | |
| return "请务必仅用中文回答。" | |
| return "" | |
| def _call_llm( | |
| user_content: str, | |
| system_extra: str = "", | |
| reply_language: Optional[str] = None, | |
| max_tokens: int = 1500, | |
| history: Optional[list] = None, | |
| ) -> str: | |
| """ | |
| history: List of tuples [(user_msg, assistant_msg), ...] for conversation context | |
| """ | |
| system = TEACHER_SYSTEM | |
| lang = _lang_instruction(reply_language) | |
| if lang: | |
| system = system + "\n\n" + lang | |
| if system_extra: | |
| system = system + "\n\n" + system_extra | |
| messages = [{"role": "system", "content": system}] | |
| # Add conversation history if provided | |
| if history: | |
| for user_msg, assistant_msg in history[-10:]: # Keep last 10 turns | |
| if user_msg: | |
| messages.append({"role": "user", "content": user_msg}) | |
| if assistant_msg: | |
| messages.append({"role": "assistant", "content": assistant_msg}) | |
| messages.append({"role": "user", "content": user_content}) | |
| try: | |
| resp = client.chat.completions.create( | |
| model=DEFAULT_MODEL, | |
| messages=messages, | |
| temperature=0.6, | |
| max_tokens=max_tokens, | |
| timeout=60, | |
| ) | |
| return (resp.choices[0].message.content or "").strip() | |
| except Exception as e: | |
| print(f"[teacher_agent] LLM error: {repr(e)}") | |
| return f"生成时出错:{repr(e)}。请稍后重试。" | |
| def generate_course_description( | |
| topic: str, | |
| outline_hint: Optional[str] = None, | |
| reply_language: Optional[str] = None, | |
| history: Optional[list] = None, | |
| user_message: Optional[str] = None, | |
| ) -> str: | |
| """ | |
| 课程描述生成:根据课程主题(及可选大纲要点)生成一段可用于课程介绍/选课页的描述。 | |
| reply_language: "en" | "zh" | None(默认中文) | |
| user_message: 持续对话时的用户消息(可选) | |
| """ | |
| rag = retrieve_from_weaviate(topic, top_k=6) if USE_WEAVIATE else "" | |
| if user_message: | |
| # 持续对话模式:直接使用用户消息 | |
| user = user_message | |
| if rag: | |
| user = f"**参考知识库摘录:**\n{rag[:4000]}\n\n---\n\n{user}" | |
| else: | |
| # 初始提交模式:使用表单字段 | |
| user = f"请根据以下信息,生成一段简洁的**课程描述**(约 150–250 字),适合放在课程介绍或选课页面。\n\n" | |
| user += f"**课程主题/名称:** {topic}\n\n" | |
| if outline_hint: | |
| user += f"**大纲或要点(可选):**\n{outline_hint}\n\n" | |
| if rag: | |
| user += "**参考知识库摘录(请据此保持与现有课程内容一致):**\n" + rag[:4000] + "\n\n" | |
| user += "请直接输出课程描述正文,无需重复题目。" | |
| return _call_llm(user, reply_language=reply_language, max_tokens=800, history=history) | |
| def suggest_course_doc_content( | |
| topic: str, | |
| current_doc_excerpt: Optional[str] = None, | |
| doc_type: str = "讲义/课件", | |
| reply_language: Optional[str] = None, | |
| history: Optional[list] = None, | |
| ) -> str: | |
| """ | |
| 课程文档内容建议:针对某一主题或现有文档片段,给出可写入讲义/课件的内容建议。 | |
| """ | |
| rag = retrieve_from_weaviate(topic, top_k=8) if USE_WEAVIATE else "" | |
| user = f"请针对以下**课程文档**(类型:{doc_type})给出**内容建议**:结构要点、关键概念、可选的例子或习题方向。\n\n" | |
| user += f"**主题或章节:** {topic}\n\n" | |
| if current_doc_excerpt: | |
| user += f"**当前已有内容(片段):**\n{current_doc_excerpt[:2000]}\n\n" | |
| if rag: | |
| user += "**参考知识库摘录:**\n" + rag[:5000] + "\n\n" | |
| user += "请用分点或短段落给出建议,便于教师直接采纳或改写。" | |
| return _call_llm(user, reply_language=reply_language, max_tokens=1200, history=history) | |
| def suggest_assignments_questions( | |
| topic: str, | |
| week_or_module: Optional[str] = None, | |
| question_type: str = "混合", | |
| reply_language: Optional[str] = None, | |
| history: Optional[list] = None, | |
| ) -> str: | |
| """ | |
| 作业和题库生成建议:根据主题(及可选周次/模块)给出作业题、练习题或考试题建议。 | |
| question_type 可为:选择题、简答题、开放题、混合 等。 | |
| """ | |
| rag = retrieve_from_weaviate(topic, top_k=8) if USE_WEAVIATE else "" | |
| user = f"请根据以下课程信息,给出**作业与题库**的生成建议:包含题目类型、难度分布、2–3 道示例题(含参考答案要点)。\n\n" | |
| user += f"**主题:** {topic}\n\n" | |
| if week_or_module: | |
| user += f"**周次/模块:** {week_or_module}\n\n" | |
| user += f"**题型偏好:** {question_type}\n\n" | |
| if rag: | |
| user += "**参考知识库摘录:**\n" + rag[:5000] + "\n\n" | |
| user += "请直接给出建议与示例题,便于教师录入题库或布置作业。" | |
| return _call_llm(user, reply_language=reply_language, max_tokens=1500, history=history) | |
| def analyze_student_assessment( | |
| assessment_summary: str, | |
| course_topic_hint: Optional[str] = None, | |
| reply_language: Optional[str] = None, | |
| history: Optional[list] = None, | |
| ) -> str: | |
| """ | |
| 学生学习评估分析:根据教师提供的学生表现摘要(如作业/测验得分、常见错误、参与度等), | |
| 给出简要分析结论与教学改进建议。 | |
| """ | |
| rag = "" | |
| if course_topic_hint and USE_WEAVIATE: | |
| rag = retrieve_from_weaviate(course_topic_hint, top_k=4) | |
| user = "请根据以下**学生学习评估信息**,给出简要的**分析结论**与**教学改进建议**(分点、可操作)。\n\n" | |
| user += f"**评估摘要:**\n{assessment_summary}\n\n" | |
| if course_topic_hint: | |
| user += f"**相关课程主题:** {course_topic_hint}\n\n" | |
| if rag: | |
| user += "**参考知识库摘录(可选,用于对齐课程目标):**\n" + rag[:3000] + "\n\n" | |
| user += "控制在 300–500 字。" | |
| return _call_llm(user, reply_language=reply_language, max_tokens=800, history=history) | |