150 lines
5.6 KiB
Go
150 lines
5.6 KiB
Go
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()
|
|
}
|