package ctxmgr import ( "fmt" "strings" "time" ) // PreferenceReflector 用户工作习惯与偏好智能总结反思器 type PreferenceReflector struct{} func NewPreferenceReflector() *PreferenceReflector { return &PreferenceReflector{} } // ReflectFromMessages 分析用户会话历史,提炼或更新用户的工作习惯画像 func (r *PreferenceReflector) ReflectFromMessages(messages []ChatMessageRecord, existing *UserPreference) *UserPreference { if existing == nil { existing = &UserPreference{ CommunicationStyle: StyleConciseStructured, FocusAreas: make([]string, 0), OutputFormatPref: "standard_report", MemoryFacts: make(map[string]string), UpdatedAt: time.Now(), } } focusSet := make(map[string]bool) for _, f := range existing.FocusAreas { focusSet[f] = true } for _, msg := range messages { if msg.Role != "user" { continue } c := strings.ToLower(msg.Content) // 1. 风格偏好识别 if strings.Contains(c, "简短") || strings.Contains(c, "简要") || strings.Contains(c, "说重点") || strings.Contains(c, "太长") || strings.Contains(c, "不要太啰嗦") || strings.Contains(c, "结论先行") { existing.CommunicationStyle = StyleConciseStructured } else if strings.Contains(c, "详细") || strings.Contains(c, "展开讲") || strings.Contains(c, "深度分析") || strings.Contains(c, "推演过程") { existing.CommunicationStyle = StyleDetailedAnalytical } else if strings.Contains(c, "高管决策") || strings.Contains(c, "决策要点") || strings.Contains(c, "高管版") || strings.Contains(c, "高管摘要") { existing.CommunicationStyle = StyleExecutiveSummary } // 2. 关注维度识别 if strings.Contains(c, "法规") || strings.Contains(c, "标准") || strings.Contains(c, "合规") || strings.Contains(c, "nmpa") || strings.Contains(c, "ce") { focusSet["reg_compliance"] = true } if strings.Contains(c, "成本") || strings.Contains(c, "价格") || strings.Contains(c, "预算") || strings.Contains(c, "工时") || strings.Contains(c, "报价") { focusSet["cost_budget"] = true } if strings.Contains(c, "周期") || strings.Contains(c, "排期") || strings.Contains(c, "进度") || strings.Contains(c, "尽快") || strings.Contains(c, "节点") { focusSet["timeline"] = true } if strings.Contains(c, "光学") || strings.Contains(c, "结构") || strings.Contains(c, "硬件") || strings.Contains(c, "参数") || strings.Contains(c, "公差") { focusSet["technical_parameters"] = true } // 3. 输出格式偏好 if strings.Contains(c, "双语") || strings.Contains(c, "英文") { existing.OutputFormatPref = "bilingual_brief" } else if strings.Contains(c, "ppt") || strings.Contains(c, "幻灯片") || strings.Contains(c, "要点清单") { existing.OutputFormatPref = "ppt_bullets" } // 4. 定制化指令捕获 (如 "记住...", "以后请...") if strings.Contains(c, "记住") || strings.Contains(c, "以后请") || strings.Contains(c, "默认都") { existing.CustomInstructions = msg.Content } } var updatedFocus []string for f := range focusSet { updatedFocus = append(updatedFocus, f) } existing.FocusAreas = updatedFocus existing.UpdatedAt = time.Now() return existing } // GeneratePromptGuidance 将用户偏好编译为注入到智能体或参谋 Prompt 的定制化指导语 func (r *PreferenceReflector) GeneratePromptGuidance(pref *UserPreference) string { if pref == nil { return "" } var sb strings.Builder sb.WriteString("【用户个性化工作习惯与偏好指导 (Memory Injection)】\n") switch pref.CommunicationStyle { case StyleConciseStructured: sb.WriteString("• 沟通风格:该用户偏好【结构精炼、结论先行】;答复宜短而清,优先摘要与下一步,避免冗长铺垫。\n") case StyleDetailedAnalytical: sb.WriteString("• 沟通风格:该用户偏好【详尽论证与深度分析】;可适当展开依据、对比与关键参数,但仍保持层次清晰。\n") case StyleExecutiveSummary: sb.WriteString("• 沟通风格:该用户偏好【高管决策摘要】;突出商务价值、风险与资源投入,弱化底层推演细节。\n") } if len(pref.FocusAreas) > 0 { var areaNames []string for _, a := range pref.FocusAreas { switch a { case "reg_compliance": areaNames = append(areaNames, "法规标准合规与审评审批风险") case "cost_budget": areaNames = append(areaNames, "CDO工时核算、BOM成本与预算边界") case "timeline": areaNames = append(areaNames, "关键研发排期、型检周期与备料冗余") case "technical_parameters": areaNames = append(areaNames, "核心光学/机械/电气参数与工艺公差") default: areaNames = append(areaNames, a) } } sb.WriteString(fmt.Sprintf("• 重点关注:该用户较关心【%s】,结论中请点到并做轻量避险提示。\n", strings.Join(areaNames, "、"))) } if pref.OutputFormatPref != "" && pref.OutputFormatPref != "standard_report" { switch pref.OutputFormatPref { case "bilingual_brief": sb.WriteString("• 格式要求:用户偏好附带中英双语核心术语与摘要。\n") case "ppt_bullets": sb.WriteString("• 格式要求:文末可附适合汇报 PPT 的短条目清单。\n") } } if pref.CustomInstructions != "" { sb.WriteString(fmt.Sprintf("• 用户明确要求:%s\n", pref.CustomInstructions)) } if len(pref.MemoryFacts) > 0 { sb.WriteString("• 已知长期习惯/事实:\n") n := 0 for k, v := range pref.MemoryFacts { sb.WriteString(fmt.Sprintf(" - %s: %s\n", k, v)) n++ if n >= 8 { break } } } return sb.String() }