File size: 4,493 Bytes
634b5dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 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("所有学生特点总结批量更新完毕!")