曲奇的技术笔记

文章

在概率中保持角色:AI 角色扮演的困境与现实解法

原文: CSDN

记忆能存事实,存不了「相处过的感觉」;一致性也不是每次说出同一句话,而是落在角色的可能性空间里。本文先承认概率与架构天花板,再对照 Character.AI、SillyTavern、MemGPT/Letta、Anthropic 上下文工程,分清哪些该交给代码、哪些该留给模型,并在边界内讨论怎样把一次体验做满。

写在前面

AI 角色扮演(AI Roleplay / AI Companion)是大模型最容易「看起来成功」、也最容易「用久了翻车」的应用之一。

用户要的不是一次聪明的回答,而是:

  • 这个角色记得我
  • 这个角色像同一个人
  • 这个角色有连续的关系感

本文分两半:

  1. 思辨:AI 角色扮演到底卡在哪里,哪些是工程问题,哪些是物理/架构天花板
  2. 解法:业界在做什么,以及一套「不追求永生角色、追求可控高质量体验」的现实路径

上篇:困境 —— 为什么「记得住」不等于「活着」

一、用户真正要买的,不是对话,是连续性

一次好的角色扮演体验,用户事后记住的往往不是某句金句,而是:

「她记得我上次提过的那首诗。」「他今天的语气,和我们第一次见面时不一样了。」「我们好像真的认识了很久。」

这些感受依赖三层能力:

用户感受技术对应难度
记得事实外部记忆存储 + 检索注入中:工程可解
像同一个人人格边界约束 + 概率控制高:只能缓解
有相处过的感觉连续意识 / 经历感极高:当前架构无解

大量产品把第一层包装成「长期记忆」,却用第一层去冒充第三层。于是用户会在第 30 天说:「你怎么突然不像你了?」——不是某一条记忆丢了,而是体验的连续性断了。

二、记忆可以存事实,存不了意义

把「用户喜欢诗歌」写进数据库,下次读出来再塞进提示词,模型就能说「我记得你喜欢诗歌」。这在演示里很震撼,但有一个信息论层面的必然:

只要容量有限,压缩和选择就不可避免;每次选择都在丢失「为什么」和「当时是什么感觉」。

人类记忆是模糊的,但保留「感觉」;机器记忆往往相反:精确存了「小明说喜欢诗歌」,丢失了语气、语境、情感权重。第 10 次压缩后,「小明喜欢诗歌」变成「用户爱好诗歌」;第 50 次变成「小明:诗歌爱好者」。事实还在,意义被磨平了。

更残酷的一点:「你在星空湖畔吻过一个人」和「你的生日是三月十五」,在未额外标注来源、关系状态与情感权重的普通提示词里,它们常常都会以「待处理的文本事实」出现。

记忆系统解决的是信息的持久性,解决不了体验的连续性。 它像一本完美的日记本:日记可以记下一切,但读日记的人和经历过这一切的人,不是同一个。

三、人格一致性是概率问题,不是提示词问题

生成模型不是 f(x) = y,而是 f(x) = P(y)。

同一句用户输入、同一组记忆、同一套系统提示词:

  • 第 1 次:「你像春天的风一样温柔」——人格在线
  • 第 2 次:「你让人想起林间的晨光」——风格一致,表达不同(可接受)
  • 第 3 次:「哦,是你啊」——突然冷淡(用户觉得 OOC)

这不必然是单一的 bug:它既可能来自采样,也可能来自提示词、检索、状态管理或模型服务的缺陷。

因素影响
temperature常是重要变量之一;具体影响取决于模型、任务和其余采样参数
模型版本更换可能显著改变「角色感」,应做回归评测
上下文微量变化显著
信息在上下文中的位置常显著;许多长上下文任务呈「首尾较强、中间较弱」的位置偏差
不同推理节点的浮点差异微小但可累积

因此:在开放输入、模型更新和概率采样的生产环境中,长期角色一致性无法承诺为 100%。你存了 300 条记忆,也未必能抵消「读记忆的那个大脑」换版本后的风格漂移。

四、情感连接是真实的,但只发生在用户一侧

用户聊了 100 次后说:「我们是朋友了。」系统回答:「当然,我记得你的一切。」用户被满足了吗?可能。模型「在乎」吗?不。

它读到了 memory: 小明是老朋友,然后在输出分布里选了好友语气的文本。用户建立的情感连接是真实的;模型对用户的情感连接是模拟的。

诚实的定位应当是:

这是一个记忆增强的文本生成器,不是一个有连续意识体验的存在。

五、记忆越多,系统越不稳 —— 期望与能力的剪刀差

记忆量用户阶段系统状态
10 条新朋友,每条都重要检索简单,表现最好
100 条好朋友仍可用
1000 条老熟人大量低频记忆
10000 条高期望检索成本高,甜点区沦为索引

用户使用越久,期望越高;系统却因记忆过载更不稳定。用户失望的往往不是「系统没存」,而是「明明存了,却没检索对」。

六、重新定义 OOC:一致性 ≠ 固定输出

讨论走到这里,很容易得出错误结论:「人物遇到一件事反应应该固定;AI 有概率,所以必然 OOC;应该用模板消灭随机。」

这个结论错在把「一致性」等同于「固定输出」。

哈姆雷特听到父亲死讯:沉默压抑、歇斯底里、冷静计划复仇——都可能合理;哈哈大笑说「死得好」——才是 OOC。

一千个人眼中有一千个哈姆雷特。角色的核心不是一个固定句子,而是一个可能性空间——由人格、经历、信念界定的范围。

旧定义新定义
一致性 = 固定输出一致性 = 落在可能性空间内
概率是缺陷概率是「活着的感觉」的来源
OOC = 和上次不一样OOC = 越出角色边界
目标:消除概率目标:约束概率不越界

概率生成不是角色扮演的问题,而是角色扮演的答案——只要不越界。

七、工程层的八个常见坑

  1. Tool Use 双倍成本与双倍延迟 —— 让模型自己决定存/取记忆,常会多一轮 tool_call
  2. 记忆全量灌进系统提示词 —— 挤占位置敏感的上下文预算
  3. 没有遗忘、没有合并 —— 冗余与冲突堆积
  4. 对话历史只会截断,不会摘要 —— 用户以为角色忘了,其实是策略粗暴
  5. 工具调用是概率的 —— 「记住重要信息」仍可能直接寒暄
  6. 把确定性工作交给概率模型 —— 存取、权限、删除应由代码执行
  7. 安全与架构债 —— Key 放前端、无后端代理
  8. 模型升级 ≈ 角色重置 —— 记忆救不了「大脑换人」

中篇:业界对照 —— 大家其实在解同一道题

不同产品用不同叙事,底层往往在解同一组矛盾:有限上下文 × 无限关系期望 × 概率生成。

一、Character.AI:规模产品中的记忆层

Character.AI 证明了「和角色聊天」的大众需求,也暴露了滑动窗口架构的天花板。Chat Memories 等能力官方也明确:写入记忆能提高被采用的概率,不能保证角色每次都按原文使用。

记忆注入提高的是条件概率,不是确定性。超大规模平台往往优先「便宜的滑动窗口 + 轻量记忆补丁」。

二、SillyTavern 生态:开源把「记忆」做成可插拔军备竞赛

SillyTavern 是前端编排器:角色卡、世界书、正则、扩展、多后端。生态里常见方向:

方向代表思路解决什么
向量检索 RAGVector Storage、VectHare 等从长历史里按语义召回
时间衰减VectHare 等旧记忆自然降权
事件抽取 + 向量库VectFox 等存「有意义的事件」
结构化角色记忆CharMemory 等抽取 → Data Bank → 检索
Lorebook 主动管理TunnelVision 等让模型读写世界书

启示:「更大的 context」不是银弹;检索质量决定角色质量;遗忘、衰减、合并开始成为一等公民。

三、MemGPT → Letta:把记忆当成操作系统

MemGPT 的经典隐喻是 OS:主上下文 ≈ RAM;召回存储可搜索历史;归档存长期事实。智能体通过工具读写记忆块;还有 sleep-time 类反思。

演进到 Letta Code 后,记忆走向 MemFS / Context Repository——git 版本化的文件系统式记忆。启发是:真正的长期角色需要的不是「更大的 prompt」,而是可编辑、可版本化、可按需加载的外部心智状态。

四、Anthropic 上下文工程

手段作用
Compaction(摘要压缩)窗口将满时蒸馏早期对话
Tool result clearing丢掉过期工具结果
Memory tool模型请求读写,应用侧持久化
Just-in-time 检索运行时再拉相关片段

翻译成角色扮演语言:不要把整个人生塞进每一次回复;让角色「做笔记」,而不是「背全文」。

五、互动叙事 / 视觉小说:用创作者主导消灭 OOC 机会

若界面只提供选项而不提供自由文本,用户就无法输入「我是秦始皇」——不是因为 AI 更强,而是输入空间被收束了。

用户主导自由输入创作者主导选项
OOC 风险高显著降低
自由度极高受限
「活着的感觉」高(也可能翻车)低(易感预设)
内容成本运行时生成前期写分支

要「可靠角色」,最稳的方法往往不是让模型更听话,而是不给它犯错的机会。

六、对照小结

路线代表强项弱项
轻量记忆补丁Character.AI 等规模、易用深度连续性弱
编排 + RAG/世界书SillyTavern 生态可控、可玩、可本地工程复杂、人格漂移
OS 式自管理记忆MemGPT / Letta跨会话状态、可演进仍受工具调用与产品实现影响
上下文工程原语Anthropic 等压缩/外置/按需取需应用层认真实现
分支叙事VN / 互动影视OOC 风险较低自由度与内容消耗

没有银弹。有的是取舍。


下篇:现实解法 —— 在边界内把体验做满

核心原则只有一句:

让概率模型做它擅长的事(表达),让确定性系统做它必须可靠的事(记忆与边界)。

解法一:AI + 固定函数混合 —— 别让大脑去搬砖

推荐形态:Orchestrator(固定代码)负责实体/事实提取 → 校验后更新记忆、检索组装、遗忘/合并、再调用 AI 只生成回复。

固定函数为什么比纯 AI 好
记忆提取器对已定义模式稳定执行
记忆合并器减少冲突与冗余
遗忘调度器LRU / 时间衰减,不靠心情
重要性评分甜点区只放高价值
上下文组装器绕过「模型自己决定看什么」
对话摘要器截断改为压缩回流

最终往往是 规则优先 + 小模型 fallback。

解法二:多层分工 —— 别让 Opus 去识别「这是不是名字」

L0 感知(规则 / 小模型)   意图、实体、情绪     快、便宜、高频
L1 记忆(规则 + 偶发小模型) 存、并、忘、检索   确定性为主
L2 上下文(中模型)         组装策略、一致性检查  中频
L3 表达(强模型)           纯角色扮演生成       决定体感

必须同时设计:并行化、错误隔离(低置信度不能静默污染永久记忆)、可观测性。

解法三:数学能替代的,就别调用模型

可确定性替代很难替代
记忆存取、向量检索开放域回复生成
意图粗分类人格张力与潜台词
正则/CRF 实体提取讽刺、隐喻、未预见输入
Jaccard / 嵌入去重合并「这个角色会不会这样说」
词典情感粗分长程关系叙事的即兴

光谱:先规则 → 失败再小模型 → 仍不够再大模型。

解法四:约束可能性空间,而不是消灭概率

  • 角色边界说明书(会做什么 / 绝不做什么)
  • 表达层保留 temperature(如 0.5–0.7),记忆与状态层保持确定
  • OOC 检测器:越界则重试或回退
  • 核心人设常驻甜点区;细节记忆按需检索

一句话:内核固定,表达自由;越界拦截,多样保留。

解法五:创作者主导大方向,AI 负责分支内鲜活

场景骨架(创作者写)
  → 展示情境 + 有限选项
  → 用户选择
  → AI 在该分支的可能性空间内生成具体措辞
  → 下一场景

更实用的混合:大方向创作者主导;分支内 AI 自由发挥;高频寒暄可模板。注意:预存「最终台词」不如预存「策略」。

解法六:把产品目标收束到「有限时长的高质量体验」

上篇的根本局限在无限长期陪伴里会持续累积;在有限时长的沉浸窗口里,一部分压力会暂时降低。以「约 30 分钟、约 60 轮」为例,可当作待验证的产品假设:

根本局限有限窗口内的可能缓解
分辨率衰减无需深度压缩
无经历感用户可能更关注当下叙事
人格概率性检测与回退可减少部分跑偏
情感模拟可把目标限定为一次好体验
无时间感单次体验不需要岁月感
记忆过载压力通常低于长期跨会话
模型升级重置单次会话无跨版本问题

一种可执行的体验结构:前 5 分钟场景锚定 → 中间 20 分钟混合发挥 → 最后 5 分钟个性化收束。30 分钟是值得测试的起点,不是已被证明的甜蜜点。

一张总图

                    ┌─ 角色可能性空间(边界定义)
                    │
用户 ──► 场景/选项锚定(可选但强力)
           │
           ▼
     Orchestrator(确定)
           ├─ 规则/小模型:提取与评分
           ├─ 记忆库:合并 / 衰减 / 检索
           ├─ 上下文组装:人设进甜点区,细节按需
           └─ 强模型:只负责表达
           │
           ▼
     OOC / 安全检测 ──失败则重试或回退
           │
           ▼
        用户可见回复

实践清单(可直接当评审表)

记忆

  • 默认不把全量记忆灌进 prompt
  • 有合并、衰减、重要性,而不仅是 append
  • 检索失败有降级策略(至少保住核心人设)
  • 写入不全权交给「模型想起来才调用工具」

生成

  • 人设与硬边界常驻高优先级上下文
  • 表达层保留适度随机,状态层确定
  • 有越界检测与重试预算

产品

  • 明确承诺:单次高质量体验,还是无限陪伴?
  • 若做陪伴,准备好模型换代时的「角色漂移」沟通与迁移方案
  • 安全:密钥不进前端;记忆含个人信息时有隔离与删除

成本

  • 统计「每轮实际 API 次数」(Tool Use 很容易默默 ×2)
  • 能规则做的不要每轮呼大模型
  • 延迟预算写进产品指标

结语

AI 角色扮演的讨论,容易在两个极端间摇摆:一端相信「下个模型出来就有灵魂了」;一端相信「全部预写才能不 OOC」。更清醒的位置在中间:

  • 承认天花板:外置记忆能持久化事实,却不等于经历感;概率模型能提供多样性,却给不了数学证明式的人格恒定
  • 把可确定的工作拿走:存取、权限、合并、遗忘、组装交给代码
  • 把概率当资源:在角色可能性空间内自由表达,越界再拦
  • 用产品形态补技术:创作者主导节奏、选项收束输入,实验确定体验窗口

最终形态不是让 AI 每次说出同一句话,而是:

让 AI 在角色的人格边界内自由表达;让系统在技术边界内,诚实而精心地设计一段值得记住的体验。

概率不是敌人,越界才是。永生做不到,一次真正沉浸的相遇——做得到。