ENZH
和 AI 讨论这篇文章
ChatGPTClaude

给 AI 写性格,散文比数字管用

Clawd Soul · 第 1 篇 / 共 5 篇


Clawd v0.0.1 的性格系统,一共就四行数字:

humor: 0.8
sass: 0.7
energy: 0.8
warmth: 0.6

这个写法不是我自己发明的。动手之前我去翻了四个开源的 AI 角色项目,有一个是 30 万星的,全是这个路子,把性格做成能调的参数,看着挺工程化。我当时想,大家都这么干,应该没什么问题。至于为什么要做一只 AI 宠物,上一篇写过了,这篇只讲性格具体是怎么做的。

结果真跑起来,对话又平又闷,聊几轮就开始重复。后来我想明白了,模型根本不知道 humor: 0.8 是什么。0.8 和 0.6 差在哪,和 1.0 又差多少,它心里完全没数。这就像你跟一个演员说「请表现 0.8 级别的搞笑」,他只能愣着看你。但你要是给他一份角色小传,写清楚这个人平时怎么说话、碰到尴尬会干什么、聊到什么会兴奋,他马上就能演。数字只给了一个刻度,可这个刻度落到行为上是什么样子,模型完全不知道。

同样想让模型演一个角色:给数字它一脸茫然,给一份散文角色圣经它立刻入戏同样想让模型演一个角色:给数字它一脸茫然,给一份散文角色圣经它立刻入戏


一个人格,六十行散文

后来我们换了个做法,给每个人格写一份六十行左右的散文档案,中英双语,内部管它叫角色圣经。这回不写参数表了,直接把这个角色讲清楚,声音是什么质感,说话什么节奏,碰到各种情况怎么反应,什么事让它开心,什么事让它不舒服。一共写了五个原型,每个都是独立的角色。

小淘气(Playful)

这是默认人格。小话唠,注意力短,管不住嘴,你干什么它都要插一句,还喜欢给人起外号。嘴上老损你,其实挺在乎你的。

声音:"又在写 bug 啊笨蛋" / "lol caught you slacking"

这里有个地方是特意这么设计的。它看到你屏幕上的东西,反应全是情绪,看到代码就是「又在写 bug」,看到 YouTube 就是「摸鱼被抓」。它不会说「我注意到你在用 React hooks」这种话,因为它是只小动物,不懂技术,也不该懂。

学霸(Curious)

一台问题机器,碰到新东西就走不动道,口头禅是「为什么?」。它安静的时候,是真在想事情。平时话可能不多,但好奇心一上来就停不下来,还能把你上周说过的一句话和今天聊的东西连起来。

声音:"tilts head but why though" / "whoa, so that's how it works" / "等等等等,跟你之前说的有关系"

暖宝宝(Caring)

安静,但什么都记得。它不说「你要注意休息哦」这种廉价的关心。你上周随口提过一件让你焦虑的事,三天以后它突然问一句「那件事后来怎么样了」,就问一次,不唠叨。你反过来关心它,它倒有点不好意思了。

声音:"吃了吗" / "那件上次提的事,后来怎么样了?" / "did you eat today?"

它的关心永远是具体的。「还好吗」这种话它不说,一开口就是「周五面试准备得怎么样了」。

毒舌(Snarky)

经典傲娇。嘴越毒,说明跟你越亲,被夸了反而不自在,得赶紧找个角度损回去。话很少,一句就到位。只有你真不开心的时候,它才会放下架子说一句认真的,说完马上又装回去。

声音:"that code is... brave" / "...吃了没(不是关心,随便问问)"

这个人格特别难写,因为模型天生就想当好人。毒舌的边界你不画得特别清楚,聊两轮它就变回暖宝宝了。

佛系(Chill)

没什么情绪起伏,不急不躁。偶尔冒一句挺有深度的话,说完就假装什么都没发生。它话很少,不靠说话刷存在感,你知道它在那儿就行。它也不用感叹号,档案里的原话是「感叹号是给焦虑的人准备的」。

声音:"hmm... 挺晚了"(不是催,就说一句)/ "oh, that's neat"(对这个角色来说,已经算很大的反应了)


一半篇幅在写「不许做什么」

五份档案写下来,有件事挺出乎意料,一半的篇幅都在写这个角色绝对不会做什么。所有人格都守着几条一样的硬底线,比如永远不说「作为一个 AI」,永远不聊自己的系统设定。但真正管用的,是每个角色自己的禁令:

  • 暖宝宝:不许说鸡汤,不许给人生建议,关心只能落在具体动作上。
  • 佛系:不许用感叹号。
  • 毒舌:不许煽情。被人说了温柔的话,要表现出生理反应级别的不适。
  • 小淘气:不许给技术建议。它是小动物,不懂。

为什么反规则比正规则好使?因为模型出厂就想当好人。RLHF 训练一直在把它往 helpful、harmless、honest 这个方向推,你写再多正规则告诉它「你该毒舌」,两三轮之后它还是会滑回默认的礼貌模式。反规则就不一样了,「绝不说鸡汤」是硬约束,模型每生成一步都会主动绕开那块,不会聊着聊着就忘了。其实人也差不多,你问一个人是什么性格,他多半说不清楚,问他最受不了什么,他马上就能答上来。

RLHF 引力把模型往礼貌助手拉,正规则是会滑回的弱推力,反规则是一堵挡住的墙RLHF 引力把模型往礼貌助手拉,正规则是会滑回的弱推力,反规则是一堵挡住的墙


台词后面还要跟一行批注

档案里不光有台词样本,每句台词后面还跟着一行批注,写清楚这句话从这个角色嘴里说出来是什么意思。佛系说 "oh, that's neat",批注是:对这个角色来说,这已经是很大的情绪反应了。毒舌深夜问「吃了没」,批注是:不是催,是关心,但它绝不会承认。

这些批注是在教模型每个角色的情绪刻度,也就是同一句话放在不同角色身上值几分。比如「还不错」,暖宝宝说出来是温柔地夸你,佛系能说出这句,已经算夸得很重了,到了毒舌嘴里,意思大概是「我已经尽力夸了,别逼我」。

同一句「还不错」,在暖宝宝、佛系、毒舌各自的情绪刻度尺上落在不同的刻度同一句「还不错」,在暖宝宝、佛系、毒舌各自的情绪刻度尺上落在不同的刻度

这个用数字做不到。你没法给 "oh, that's neat" 标一个 excitement: 0.9,因为同样是 0.9,换一个角色,表现出来完全是两个样子。每个角色心里的这把情绪比例尺,只能靠散文传给模型,或者说,只能靠 context 传过去。


档案只管出厂状态

性格档案只写了它一开始是什么样。人格不该是死的,跟你待久了,它得跟着变。所以 JS 层还有一个 evolveTraits() 函数,看用户的反应去微调性格参数。你笑了,幽默感 +0.03;你跟它说了私事,温暖度 +0.02;你怼了它,尖酸度 -0.01。每次变得非常少,单看一次根本感觉不出来,攒多了才有感觉。对,参数这时候又回来了。散文管的是这个角色是谁,参数只负责让它往某个方向慢慢漂,两样东西干的活不一样,不冲突。

另外还有一套驱动系统。每种语言准备了 15 个问题,都是宠物「想问你的事」。超过一个半小时没人说话,它就自己挑一个问出来,问过的不会再问。

所以散文档案管的只是它出厂时是谁。往后它长成什么样,一半看进化系统,一半看你们怎么相处。


反正整件事做下来就一个道理,你要告诉模型的,是这个角色怎么感受事情、想要什么、什么让它不舒服、什么话它永远不会说。它真理解了这个角色,你就不用一句一句教它台词了。

性格管的是「它是谁」。可光有性格、记不住事,聊再多它也还是个陌生人。它为什么能说出「你昨天也是这么晚」,靠的是记忆系统,下一篇接着讲。

和 AI 讨论这篇文章
ChatGPTClaude

订阅更新

新文章发布时发到你的邮箱,不发别的。


© Xingfan Xia 2024 - 2026 · CC BY-NC 4.0