Spaces:
Paused
Paused
| # chat_processor.py | |
| import datetime | |
| from llm_handler import get_gemini_response | |
| from rag_manager import add_documents_to_rag, get_all_student_observations_from_rag | |
| from db_manager import add_or_update_student, get_all_student_names | |
| import prompts | |
| import re | |
| import streamlit as st | |
| def extract_info_from_chat(chat_log_text: str) -> list: | |
| """使用LLM从聊天记录中提取学生表现信息""" | |
| if not chat_log_text.strip(): | |
| return [] | |
| prompt = prompts.CHAT_EXTRACTION_USER_PROMPT_TEMPLATE.format(chat_log_text=chat_log_text) | |
| system_instruction = prompts.CHAT_EXTRACTION_SYSTEM_PROMPT | |
| response_text = get_gemini_response(prompt, system_instruction=system_instruction) | |
| if not response_text: | |
| st.warning("AI未能从聊天记录中提取到文本响应。") | |
| return [] | |
| extracted_items = [] | |
| lines = response_text.strip().split('\n') | |
| for line in lines: | |
| line = line.strip() | |
| if not line: continue # Skip empty lines | |
| # More robust regex: allows for names with spaces if not ending with colon immediately | |
| match = re.match(r"([^:]+?)\s*:\s*(.+)", line) | |
| if match: | |
| student_name = match.group(1).strip() | |
| observation = match.group(2).strip() | |
| if student_name and observation: # Ensure both parts are non-empty | |
| extracted_items.append({"student_name": student_name, "observation": observation}) | |
| else: | |
| print(f"Skipping partially extracted line: '{line}'") # Log for debugging | |
| else: | |
| print(f"Could not parse line from LLM: '{line}'") # Log for debugging | |
| if not extracted_items: | |
| st.info("AI分析完成,但未能按预期格式解析出学生信息。可能是聊天内容不包含相关信息,或AI响应格式不符。") | |
| return extracted_items | |
| def update_student_characteristics_from_rag(student_name: str): | |
| """从RAG中获取学生所有记录,让LLM总结特点,并更新到学生数据库""" | |
| observations = get_all_student_observations_from_rag(student_name) | |
| if not observations: | |
| st.info(f"在RAG中未找到学生 {student_name} 的历史表现记录,无法更新特点。") | |
| # Ensure student exists in DB even if no observations yet, or update timestamp | |
| add_or_update_student(student_name) | |
| return | |
| # Limit number of observations to avoid overly long prompts for LLM | |
| MAX_OBSERVATIONS_FOR_SUMMARY = 50 # Adjust as needed | |
| if len(observations) > MAX_OBSERVATIONS_FOR_SUMMARY: | |
| st.info(f"学生 {student_name} 有超过 {MAX_OBSERVATIONS_FOR_SUMMARY} 条记录,将使用最新的 {MAX_OBSERVATIONS_FOR_SUMMARY} 条进行特点总结。") | |
| observations_to_use = observations[-MAX_OBSERVATIONS_FOR_SUMMARY:] | |
| else: | |
| observations_to_use = observations | |
| observations_text = "\n".join([f"- {obs}" for obs in observations_to_use]) # Add bullet points for clarity | |
| prompt = prompts.STUDENT_CHARACTERISTICS_USER_PROMPT_TEMPLATE.format( | |
| student_name=student_name, | |
| observations_text=observations_text | |
| ) | |
| system_instruction = prompts.STUDENT_CHARACTERISTICS_SYSTEM_PROMPT | |
| summary = get_gemini_response(prompt, system_instruction=system_instruction) | |
| if summary: | |
| if add_or_update_student(student_name, characteristics_summary=summary.strip()): | |
| st.success(f"已更新学生 {student_name} 的特点总结。") | |
| else: | |
| st.error(f"更新学生 {student_name} 的特点总结到数据库时失败。") | |
| else: | |
| st.warning(f"未能为学生 {student_name} 生成特点总结。AI未返回有效内容。") | |
| def batch_update_all_students_characteristics(): | |
| """为数据库中所有学生更新其特点总结""" | |
| student_names = get_all_student_names() | |
| if not student_names: | |
| st.info("学生数据库为空,无法批量更新特点。") | |
| return | |
| st.info(f"开始批量更新 {len(student_names)} 位学生的特点总结...") | |
| progress_bar = st.progress(0) | |
| for i, name in enumerate(student_names): | |
| st.write(f"正在处理: {name}...") # Give some feedback during long process | |
| update_student_characteristics_from_rag(name) | |
| progress_bar.progress((i + 1) / len(student_names)) | |
| st.success("所有学生特点总结批量更新完毕!") |