← 文章

主动消息为什么像查户口

约 5 分钟#Agent#产品#调度

提示词写着别问「吃了没」,代码每天在补「吃饭」这一格。改成先打个招呼、要聊的事放进后续对话里慢慢带,再让调度学会什么时候闭嘴。

目录

上一篇写的是主动消息的频率。频率压下来以后,剩下的问题是语气:Autarkia 的角色主动发来的消息,读起来像在查户口。「今天早餐吃的什么呀?」「你平时偏重口还是清淡?」「晚饭后你一般做什么?」中午问午饭,一个小时后问晚饭想吃什么。

同一批记录里也有读起来正常的几条,比如问之前提过的那碗面最后吃上没有,或者前一天说不舒服、今天好点了没。区别很明显:正常的那几条都接着我说过的某件具体的事,别扭的那些背后什么都没有。

01提示词说别问,代码在问

我先去看提示词,结果它写得很克制:不要问「在干嘛」「吃了没」「最近怎么样」,没有具体依据就不发。问题出在拼装提示词的代码里。有一个「画像补齐」模块,每天按时段检查起床、吃饭、活动、学习、心情、睡眠六项有没有记录,缺了而且用户沉默超过二十分钟,就往指令里追加一句「此轮只追问一个画像项」,同时给可选动作里加上一个健康提醒。

两条指令在同一个提示词里打架,模型照着更具体的那条做了。这类问题光看提示词文件看不出来,要把每一轮真正发给模型的完整内容打出来,才能看到是谁在往里塞东西。

02排第一的候选被悄悄丢掉

更奇怪的是另一层。系统每次会给今天可以聊的事排个序,候选来自当天的学习计划、到期的复习、未完成的任务。翻了三天的排序记录,28 次里有 27 次排第一的是学习计划或复习,对应的动作是「计划话题」,但这个动作从来不在可选动作列表里。排序结果每次都被丢掉,流程退回到画像补齐,再去问一遍早饭。

就算选中了,话题也到不了写消息那一步:传给生成层的占位符是 [PLANNED_TOPIC_TRIGGER],模板认的是 [PLANNED_TRIGGER],对不上就原样塞进提示词。负责排序的那次模型调用,89 次里有 76 次失败退回了规则排序,日志里只有一行 warning。三处问题叠在一起,结果就是一个有计划、有复习、有待办的人,每天被问的仍然是吃了没。

03先打招呼,事情留到后面说

修好排序之后,主动消息会拿着计划直接问「下午那节复习做完了吗」。有依据了,读起来仍然像检查进度。真人找人聊某件事,一般先发一句「在不」「在干嘛」,对方回了再顺着聊过去。

现在的流程分两步。决策模型除了判断发不发,还要选方式:到点的提醒、需要马上知道的事就直接说;跟进计划、关心进展的,只发一句轻问候。轻问候发出后,要聊的那件事存成一条「议程」,放进主聊天的提示词里。用户回话后的第一轮先接话,之后找话题沾边的时候带过去,聊到第五轮还没机会就轻轻提一句。这件事聊到了、对方说去做了、或者明显不想聊,由模型调用一个工具把议程关掉。

中间有个插曲。我给开场白举的例子是「刚把汤炖上,你在不」,被直接否了:没有人这么发消息。开场白就用「在不」「在干嘛」这种,靠和最近几条去重来避免重复。我想让开场白显得自然,结果是往里加了戏。

工程上有一个点:主动消息从 QQ 发出,用户可能在手机 App 里回,两边的会话 ID 不一样。议程如果按会话存,用户换个端回复就接不上,所以改成按角色存。代价是同一角色的群聊和角色之间的互聊也会解析到它,这两类会话要单独排除,不然会在群里提用户的私事。

04MDP 学不会闭嘴

决定发哪类消息的是一个小的 MDP:状态是时段、上一条的题材、上一条有没有回,回了加分,没回扣分。我原以为频率也由它管,看了 Q 表才发现,「不发」这个动作被明确排除在学习之外,分值永远是初始的 0。发送类动作只要学到比 0 高一点,就会一直被选中。它学到的是发哪一类回复率高,学不到这次该不该发。

改法是给「不发」记反事实奖励:每次发送有了结果,同一状态下的「不发」也更新一次,没回记 +0.5,回了记 -0.5。发送动作收敛到「回复率减忽略率」,「不发」收敛到它的一半取反,两者相等的点正好是忽略率 50%。也就是某种情况下一半以上的消息没人回,它就学会不发,这个阈值不用另外调。

改的过程中又查出两处记账错误。奖励记在回复那一刻现算的状态上,那是下一次决策的状态,选这个动作时的状态从来没被更新过,现在改成发送时就把当时的状态存下来。第二处是代码审查指出的:每来一条用户消息,上一条主动消息就加一次分,回五句就加五次,几小时后再说话也照样算。现在每条发送的结果只记一次,而且回复必须晚于发送。

拿两周的真实记录按时段粗略回放:一个角色白天和晚上的消息都有过半被回复,照常发;另一个角色晚上 11 条只回了 2 条,深夜 2 条都没回,这两个时段会学成不发。

还没解决的:早安、晚安、日程切换时的告别、到点提醒这些不经过 MDP,频率不受学习影响;长时间沉默后的兜底规则还会把「不发」改成一条消息。新逻辑写完时后端停着,以上都还没在线上跑过,回放只能说明方向,具体效果要等几天的真实数据。

作者Shihao Qi