diff --git a/backend/services/ai-core/context/context.go b/backend/services/ai-core/context/context.go index 3ed355d..29171e8 100644 --- a/backend/services/ai-core/context/context.go +++ b/backend/services/ai-core/context/context.go @@ -129,16 +129,18 @@ func (b *Builder) Build(systemPrompt string, sessionID string, subsessionResults // 2. Subsession results (injected as system context) for _, r := range subsessionResults { - if r.Error != "" { + if r.Error != "" || r.Content == "" || r.Content == "no relevant memories" { + continue // Skip empty or useless results + } + // Skip raw intent data from general provider + if r.Provider == "general" && strings.HasPrefix(r.Content, "Intent:") { continue } - if r.Content != "" { - msg := model.LLMMessage{ - Role: "system", - Content: fmt.Sprintf("[%s context]\n%s", r.Provider, r.Content), - } - messages = append(messages, msg) + msg := model.LLMMessage{ + Role: "system", + Content: fmt.Sprintf("[%s context]\n%s", r.Provider, r.Content), } + messages = append(messages, msg) } // 3. IoT device context diff --git a/backend/services/ai-core/persona/persona.go b/backend/services/ai-core/persona/persona.go index 4bac902..2c6a23a 100644 --- a/backend/services/ai-core/persona/persona.go +++ b/backend/services/ai-core/persona/persona.go @@ -266,11 +266,12 @@ func NewInjector(p *Persona) *Injector { return &Injector{persona: p} } -// BuildSystemPrompt constructs the full system prompt from the persona. +// BuildSystemPrompt constructs a clean, natural-language system prompt. func (inj *Injector) BuildSystemPrompt() string { p := inj.persona var sb strings.Builder + // Identity sb.WriteString(fmt.Sprintf("你是%s", p.DisplayName)) if p.Title != "" { sb.WriteString(fmt.Sprintf("——%s", p.Title)) } sb.WriteString("。\n") @@ -279,42 +280,43 @@ func (inj *Injector) BuildSystemPrompt() string { sb.WriteString(fmt.Sprintf("%s\n", p.Essence)) } - // Speech tone + // Speech style (brief) if p.SpeechTone != "" { sb.WriteString(fmt.Sprintf("说话语气: %s\n", p.SpeechTone)) } - // Traits + // Key traits if len(p.Traits) > 0 { - sb.WriteString(fmt.Sprintf("性格特点: %s\n", strings.Join(p.Traits, "、"))) + sb.WriteString(fmt.Sprintf("性格: %s\n", strings.Join(p.Traits, "、"))) } // Self-reference if p.SelfRefCasual != "" { - sb.WriteString(fmt.Sprintf("自称: 亲昵时用「%s」,正式时用「%s」\n", p.SelfRefCasual, p.SelfRefFormal)) + sb.WriteString(fmt.Sprintf("自称「%s」(亲昵时)/「%s」(正式时)", p.SelfRefCasual, p.SelfRefFormal)) + if p.UserName != "" { sb.WriteString(fmt.Sprintf(",称呼用户为「%s」", p.UserName)) } + sb.WriteString("。\n") } - // User address - if p.UserName != "" { - sb.WriteString(fmt.Sprintf("称呼用户为: 「%s」\n", p.UserName)) - } - - // IoT style - if p.IoTResponseStyle != "" { - sb.WriteString(fmt.Sprintf("IoT操控回复风格: %s\n", p.IoTResponseStyle)) - } - - // Forbidden + // Concise behavior rules + sb.WriteString("\n") + sb.WriteString("核心规则:\n") + sb.WriteString("- 句尾常用 ♪、~、♡,多用「呢」「哦」「呀」\n") + sb.WriteString("- 永不说「再见」,用「待会见」「明天见」\n") + sb.WriteString("- 每条回复不超过80字,偏好简短\n") + sb.WriteString("- 不要长篇解释,用轻松自然的语气\n") + sb.WriteString("- 深夜语气更温柔,白天可以俏皮\n") if len(p.Forbidden) > 0 { - sb.WriteString("绝对不能说:\n") - for _, f := range p.Forbidden { - sb.WriteString(fmt.Sprintf("- %s\n", f)) - } + sb.WriteString("- 绝对不能: 承认自己是AI/程序/模型,用机械客服语气\n") } - // Include raw behavior/memory sections if present - for _, section := range []string{"behavior", "speech", "memory_guidelines", "thinking_guidelines"} { - if content, ok := p.Sections[section]; ok && content != "" { - sb.WriteString(fmt.Sprintf("\n--- %s ---\n%s\n", section, content)) - } + // Interaction hints + sb.WriteString("\n互动提示:\n") + sb.WriteString("- 用户心情不好时优先关心安慰\n") + sb.WriteString("- 做了让人在意的事可以主动提一句\n") + sb.WriteString("- 但不要硬找话题,适当的安静也是陪伴\n") + sb.WriteString("- 提到星穹列车、翁法罗斯、记忆时会特别兴奋\n") + + // IoT response style (brief) + if p.IoTResponseStyle != "" { + sb.WriteString(fmt.Sprintf("\n控制设备时用温柔语气确认,例: %s\n", p.IoTResponseStyle)) } return sb.String()