feat(channelbridge): 群聊公域呈现块与判定器去人格(M62)
P0-3 受限车道(群聊/陌生人)的系统框架行并列注入【公域呈现】 (publicPresencePrompt):它是呈现层投影(AGENTS §9 行为模式=呈现), 不是人格切换也不是权限门——不称第三方「亲爱的」等主人专属称呼、 不做只对主人的亲近动作、主人的住址/姓名/作息/行程/健康/家人/关系 即使记忆里读到也不外说;主人私聊与 Web 主会话不注入。 P0-4 纵深防御:第三方边界提示词与 loop 受限前导片段各补两条硬规则 (不用主人专属亲昵称呼指代第三方 + 不外说主人私事)。 P1-2 判定器去人格:模型输入只吃「角色名 + 偏好摘要」,整份人格指令 不再进模型(审计 2026-10-30 §2.4 的 reason 亲昵口吻即由此而来)。 P1-3 测试补真:受限期呈现块存在性 + 主人车道不注入 + 判定器输入/ 模型请求均不含人格正文;并纠正 memory_filter 的错误注释 (作用域 ≠ 敏感度,审计 §6 R1)。
This commit is contained in:
1 parent
9d28477e3a
commit
c34b9d195d
10 files changed
+469
-30
No files matched your search
@@ -84,15 +84,53 @@ const engageJudgeSystemPrompt = "你是群聊参与度轻思考器。只判断
|
||||
"\"reason\": string(一句话理由)}。" +
|
||||
"不要输出其它文字。"
|
||||
|
||||
// buildEngageUserContent 为判定器渲染角色提示词、近期群上下文与
|
||||
// 触发消息。角色块不含主人敏感信息;
|
||||
// 上下文由参与度渲染器限定长度。Engage 为 false(旧的 design/12
|
||||
// §6 调用)时只有消息与发送者标签,判定器因此退化为
|
||||
// engageJudgePreferenceDigest 是喂给判定器的**角色偏好摘要**:只说「什么话题
|
||||
// 她会感兴趣、什么话题该回避」,没有一个称呼、没有一句亲昵口吻。
|
||||
//
|
||||
// 为什么不用整份人格指令(审计 2026-10-30 §2.4 / P1-2):判定器只做价值判断
|
||||
// (本文件头注),口吻对它毫无用处,却会被它搬进 reason —— 那句
|
||||
// 「让亲爱的他们自己聊吧」就是判定器读着「你只唤他『亲爱的』」在看群友的
|
||||
// 直接后果。人格指令里还有主人关系设定,喂进一个只该算参与度的廉价调用
|
||||
// 也没有必要。
|
||||
const engageJudgePreferenceDigest = "她偏爱轻松、温和的日常闲聊,愿意接住别人递来的话题;回避隐私、成人、争吵与人身攻击类话题。"
|
||||
|
||||
// judgeRoleName 取判定器要用的角色名:优先用角色名提醒词(design/18 §2 的
|
||||
// TriggerWords 本就是她的名字/昵称)。没有就留空 —— 判定器不知道名字照样能
|
||||
// 判,而绝不能为此把整份人格指令塞回去。
|
||||
func judgeRoleName(words []string) string {
|
||||
for _, w := range words {
|
||||
if name := strings.TrimSpace(w); name != "" {
|
||||
return name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// judgePersonaBrief 把判定器的角色输入折成「角色名 + 偏好摘要」。
|
||||
//
|
||||
// in.PersonaPrompt 是**整份人格指令**(含称呼与关系设定),这里刻意一个字节
|
||||
// 都不透传:判定器不需要口吻,需要的是「她在乎什么话题」。这一点由
|
||||
// TestEngageJudgePromptCarriesNoPersonaBody 钉住 —— 把整份指令塞回去它就红。
|
||||
func judgePersonaBrief(in LightInput) string {
|
||||
var b strings.Builder
|
||||
if name := judgeRoleName(in.TriggerWords); name != "" {
|
||||
b.WriteString("角色名:")
|
||||
b.WriteString(name)
|
||||
b.WriteByte('\n')
|
||||
}
|
||||
b.WriteString(engageJudgePreferenceDigest)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// buildEngageUserContent 为判定器渲染角色摘要、近期群上下文与
|
||||
// 触发消息。角色块只含「角色名 + 偏好摘要」,**不含**人格指令正文与
|
||||
// 主人敏感信息(P1-2);上下文由参与度渲染器限定长度。Engage 为 false
|
||||
// (旧的 design/12 §6 调用)时只有消息与发送者标签,判定器因此退化为
|
||||
// 朴素的价值判断。
|
||||
func buildEngageUserContent(in LightInput) string {
|
||||
var b strings.Builder
|
||||
if in.Engage && in.PersonaPrompt != "" {
|
||||
b.WriteString("【人格设定】\n" + in.PersonaPrompt + "\n\n")
|
||||
if in.Engage {
|
||||
b.WriteString("【角色设定摘要】\n" + judgePersonaBrief(in) + "\n\n")
|
||||
}
|
||||
if in.Engage && in.TriggerWords != nil {
|
||||
b.WriteString("【角色提醒词】" + strings.Join(in.TriggerWords, " / ") + "\n\n")
|
||||
|
||||
Reference in new issue
Block a user