Files
HomeAgent/internal/agent/personal.go
JianFeeeee 7318a10828 feat(persona): 人格设定配置项化 + 默认模板契约测试 + 腐坏告警
起因(v1.2.0 压测):线上实例内核日志/接口都报 1.2.0,agent 被问版本时却按人格卡
自述 v0.9.0 + C ABI v2(该机制 v1.0.0 已删除)。根因是人格只有「文件」一个来源且无人
维护——写死的版本号必然随发版腐坏。

改动:
1. 新增配置项 core.agent.personal_prompt(多行文本),默认值为内置模板
   config.DefaultPersonaPrompt,随其它默认值同批播种(老安装不注入,语义不变)
2. 默认模板**不含任何版本号字面量**,并显式要求「被问到版本/构建信息时以运行时快照
   (healthcheck_kernel)为准」——从根上消掉这类腐坏
3. 人格来源优先级:personal/personal.md(存在且非空)> 配置项 > 无
   启动日志明确打印来源;文件含腐坏内容(版本号字面量 / 已删除机制的说法)时告警并
   建议迁移到配置项
4. internal/agent.PersonaStaleHints:腐坏检测(版本号正则 + 已删除机制词表)

契约测试(防复发):
- TestDefaultPersonaPromptHasNoVersionLiterals:默认模板不得含 v?\d+\.\d+\.\d+,
  且必须含「运行时快照」要求
- TestPersonaPromptRegisteredWithDefault:注册存在、默认值一致、播种真的写入
- TestPersonaStaleHints:线上人格卡原文必须被识别(v0.9.0 / C ABI v2),干净文本不误报

验证:go build ./cmd/homed ok;go vet 三个包 ok;go test ./internal/config ./internal/agent ok;
端到端两场景(无文件→来源=配置项 1307 字节;有旧文件→来源=文件 + 告警列出 v0.9.0 与 C ABI v2)。
2026-09-12 12:42:43 +08:00

66 lines
1.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package agent
import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
)
type Personality struct {
Content string
Path string
}
func LoadPersonality(path string) (*Personality, error) {
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return &Personality{}, nil
}
return nil, fmt.Errorf("read personal.md: %w", err)
}
return &Personality{
Content: string(data),
Path: path,
}, nil
}
func SavePersonality(path, content string) error {
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("create personality dir: %w", err)
}
return os.WriteFile(path, []byte(content), 0644)
}
func (p *Personality) InjectPrompt() string {
if p.Content == "" {
return ""
}
return fmt.Sprintf("【人格设定】\n%s\n", p.Content)
}
// 会随时间腐坏的人格内容特征。现场:人格卡写死 v0.9.0 与早已删除的 C ABI v2
// 实例被问版本时自述错误v1.2.0 压测发现)。
var (
personaVersionRe = regexp.MustCompile(`\bv?\d+\.\d+\.\d+\b`)
personaStalePhrases = []string{"C ABI v2", "plugin.so", "c-shared", "描述式索引", "引用计数式"}
)
// PersonaStaleHints 返回人格文本里会腐坏的内容(空 = 干净)。
// 供启动时告警:引导改用配置项 core.agent.personal_prompt默认模板不含这些
func PersonaStaleHints(content string) []string {
var out []string
if m := personaVersionRe.FindAllString(content, -1); len(m) > 0 {
out = append(out, fmt.Sprintf("版本号字面量 %v版本应来自运行时快照", m))
}
for _, p := range personaStalePhrases {
if strings.Contains(content, p) {
out = append(out, "可能已过期的说法: "+p)
}
}
return out
}