DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-cultivation

Cultivation

Character development: assign Agent an evolving AI character (role-playing + emotional companionship)—session-level character binding, intimacy that grows through conversations, partitioned memory + automatic archiving of append-only logs, and an AI design assistant.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:leonardwwq/dsh-cultivation#a60564b283ecfa8a1bc191012f4f14d8169edd4f
READMECompatibilityVersions
cultivation 产品概念图:共同经历沉淀为记忆、认识与成长,参与下一次互动;非实际界面截图

Compatibility and provenance

Cultivation is published as dsh-cultivation and currently resolves to version 0.4.3. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
11/4/2026

Versions

0.4.3stable
11/2/2026
0.4.2stable
10/30/2026
0.4.1stable
10/29/2026
Show 4 more versionsCollapse versions
0.3.1stable
10/28/2026
0.3.0stable
10/28/2026
0.3.0-beta.6beta
10/28/2026
0.3.0-beta.5beta
10/28/2026

Related plugins

Loading related plugins…

Latest
0.4.3
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 2
Weekly downloads
1,387
Last push
11/2/2026
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in memory-context.

Hindsight Coding Agents@vectorize-io/hindsight-coding-agentsReflect-only Hindsight long-term memory for coding agents (harness-pluggable: opencode, …), with automatic background ingestion (no setup CLI).Contextdsh-contextA DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.Mnemondsh-mnemonComposable, view-based context for DeepSeek Harness. Pluggable sources and strategies, with layered memory and self-evolving skills out of the box.Archive Manager@michengai/dsh-archive-manager归档、恢复、收藏和永久删除会话,并诊断损坏的会话日志。 · Archive, restore, favorite, and permanently delete sessions, and diagnose damaged session logs.

README

dsh-cultivation — 角色养成 (Character Cultivation)

让 AI 不只是认识你的名字,而是逐渐形成对你的认识。

面向 DeepSeek Harness (DSH) Web 的长期角色互动与养成产品。让一次次聊天不再彼此孤立:共同经历进入记忆,互动影响关系,人物形成自己的判断,并将这些积累带回下一次回应。

从「设定一个角色」到「与一个角色建立持续的相处历史」。

cultivation 产品概念图:共同经历沉淀为记忆、认识与成长,参与下一次互动;非实际界面截图


产品定位:让每次相处,都成为下一次互动的起点

很多 AI 角色产品解决了“第一次见面像不像”,却没有充分解决“聊了很久以后,有没有不一样”。

用户可以填满一张人设卡,但下一次打开对话,仍可能面对同样的自我介绍、同样的客套和同样的反应。角色有背景,却缺少与你共同经历的历史;系统记住了几条信息,却未必能将它们转化为有连续性的相处。

cultivation 将产品重点从一次性的角色扮演,推进到持续积累的关系体验。

它不追求让所有角色都变得更热情、更听话,而是让每个角色基于自己的性格和共同经历,逐渐形成不同的记忆、态度与认识。

长期角色互动 · 关系状态 · 分区记忆 · 角色视角认知 · 人物成长 · 用户可控

核心洞察:记得你,不等于理解你

设计这个产品,需要区分三件常被混在一起的事:

层次用户真正感知到的体验产品设计
记住发生过什么“这件事,我不用每次重新说。”保留有价值的经历、偏好、承诺和共同事件
形成怎样的认识“同一件事,不同角色会有不同看法。”让事件经过角色视角的评价,形成可以修正的判断
影响之后怎么相处“聊了这么久,我们不是还停在第一次见面。”把记忆、关系、心情与判断重新提供给后续回复

记忆解决重复,认识赋予差异,持续读取让积累进入体验。

例如,“你说过自己喜欢独处”是一条记忆;“我觉得你可能重视个人空间”是角色的判断;后续是否更少追问、如何表达关心,则属于基于这些信息的演绎。

这是一条设计链路,不是预写好的固定台词。判断允许出错,也应随着新的互动调整,而不是把一句话永久贴成用户标签。

三层体验:人设是起点,相处才是内容

01 · 创造一个你愿意继续了解的人

从角色库选择人物,或借助 AI 设计助手,将模糊的想法变成可编辑的人设:背景、性格、表达方式、目标与在意的事。

角色卡不是产品的终点,而是第一次互动的起点。同样面对一句关心,谨慎的人、热情的人和嘴硬的人,应该有不同的解读空间。

02 · 把共同经历变成有连续性的相处

用户自然聊天,系统在幕后记录和整理有价值的经历,更新关系状态与角色判断。用户不必在每轮结束后充当资料管理员。

一次帮助可以留下信任的线索,一次冲突也不必在下一轮自动消失。过去的经历重新进入上下文,使后续回应有依据,而不只是重复人物标签。

03 · 看见变化,也保留控制权

通过角色编辑器、角色卡预览、亲密度展示、角色选择与开关,让养成不只是不可见的黑盒。

用户可以调整人物、管理角色资料、导入导出角色,并决定何时启用角色模式。持续积累不应以失去控制为代价,人物关系也不等于一个只能不断刷高的分数。

关键设计:不是让 AI 更会讨好,而是让人物更有来处

关系,不等于服从

亲密度提供关系距离的参考,不代表角色必然同意所有要求。性格、价值观与具体经历共同影响表达,保留人物区别,而不是把所有人物养成同一种迎合模式。

判断,不冒充事实

角色可以形成“你可能是怎样的人”的认识,但这些认识带有置信度,允许合并、修正和保留不确定性。被了解的体验,不应该建立在被武断定义之上。

成长,不只是数值变化

除了关系数值,还保留记忆、心情与成长记录,用于表达共同经历如何影响人物的态度和行为倾向。成长强调长期积累,而不是每轮对话都强行发生一次人格转变。

自动积累,不等于无限堆积

通过记忆分区、日志归档和信念整理,为不同类型的信息安排不同位置,让事实、经历和判断各司其职。目标不是让角色记住一切,而是让有价值的积累能够在之后被使用。

体验可以延展,人物状态必须隔离

除日常角色互动外,cultivation 还提供外部人物养成服务,可用于冒险中的队友与世界角色。战役宿主保存各自的关系、记忆和成长,不将一局故事混入日常角色库。

这使它既是面向用户的角色养成产品,也是一层可供互动叙事复用的人物发展能力。

用户路径:从一次选择,进入持续积累的互动

选择 / 设计角色
      ↓
开启角色对话
      ↓
自然交流,产生共同经历
      ↓
幕后积累记忆、关系与角色判断
      ↓
后续回复读取积累,延续相处历史
      ↓
查看与管理人物,继续互动

产品价值不止是“一次回复更像这个角色”,而是为“这个角色为什么会这样回应你”提供持续积累的依据。


实现状态与工程说明

以下进入实现、机制和开发细节。当前处于持续迭代阶段;人物表现、长期自然度与实际成本仍需结合模型和使用场景验证。

当前实现包括:

  • Persistent Persona(持久化角色设定)
  • Event Log(事件日志)
  • Role-specific Appraisal(角色视角的事件评价)
  • Relationship / Intimacy State(关系状态)
  • User Beliefs(对用户的长期认识)
  • Belief-aware Response Generation(认识参与回复生成)
  • Belief Consolidation(信念整理)
  • Persistent local storage(本地持久化)

本次发布完整回归记录(2026-11-02):228 项通过,0 项失败、0 项跳过。自动测试验证机制与兼容性,不替代长期人物体验验证。

当前版本 0.4.3(普通角色存档版本仍为 v8),提供战役隔离的外部 NPC 服务、成长、心情与整理任务;原有日常角色功能保持独立。详见 更新日志 与 外部人物服务。

DSH 本身仍在快速迭代,插件兼容性可能随 DSH 版本变化。


Why

传统 AI 角色主要依赖一段固定的 Persona Prompt:

用户 → AI
「你是一个高冷角色,请这样说话。」

每次对话,模型都被重新告知"你是谁",角色本身不拥有任何随互动积累的状态。

这个项目尝试让角色拥有自己的内部状态:

用户 → Event → Appraisal → Relationship → Belief
        ↓
  Response Generation → Belief Consolidation → 下一轮继续理解用户

核心区别:不是让 AI 每次重新「假装自己是这个角色」,而是让角色拥有一些随互动积累、跨会话保留、并在回复中实际使用的状态。

这不是"一个更复杂的 Prompt",而是一个状态闭环。


What it does

一个 DSH Web 插件,为每个会话绑定一个可长期养成的 AI 角色:

  • 角色拥有完整的人设与背景(Persona)
  • 每次对话被记录为事件(Event)
  • 每个事件在角色视角下被评价(Appraisal)
  • 关系状态随互动变化(Intimacy)
  • 角色对用户形成带置信度的长期判断(Belief)
  • 这些判断进入后续回复的生成上下文(Response Generation)
  • 系统定期整理这些判断(Belief Consolidation)

最简单的工作原理

                    Persona
                       │
                       ▼
User ──────────────► Conversation
                       │
                       ▼
                     Event
                       │
                       ▼
                   Appraisal
                    /     \
                   /       \
                  ▼         ▼
             Intimacy     Belief
                             │
                             ▼
                    Belief Context
                             │
                             ▼
                    Response Generation
                             │
                             ▼
                     New Conversation
                             │
                             ▼
                    Belief Consolidation
                             │
                             └──────► Belief
  • Event 是原始流水(发生了什么,不评价)
  • Appraisal 是事件评价(这件事对我意味着什么)
  • Intimacy 是关系状态(我和你的关系怎么样)
  • Belief 是用户模型(我觉得你可能是怎样的人)
  • Response Generation 读取 Belief(认识参与当前回复)
  • Consolidation 整理 Belief(让认识更少、更稳定)
  • Memory 是另一条独立的记忆系统,不被 Consolidation 直接接管

Architecture

lib/
├── core.js      # 纯函数 / 状态逻辑(normalize、migration、event、appraisal、belief、consolidation、prompt 构造)
├── index.js     # Host:DSH 集成、会话生命周期、持久化、编排、LLM 调用
└── client.js    # Web UI:角色库、编辑器、会话选择、头像、关系展示
  • 纯 JavaScript,零运行时依赖(不引入数据库、向量库、Agent Framework)
  • 单 JSON 文件本地持久化 + 原子写
  • 数据版本自动迁移(v1 → v8)
  • 所有状态更新遵循「LLM 提议 → 代码验证 → 确定性执行」,LLM 永远不能直接修改数据

Event / Appraisal / Intimacy / Memory / Belief / Consolidation

层简单解释
Persona「我是谁」——用户定义的角色人格、背景、性格、目标
Event「刚才发生了什么」——一次完整互动(用户说了什么 + 角色回了什么),只记录、不评价
Appraisal「这件事对我意味着什么」——角色视角下的事件评价,而非客观好坏
Intimacy「我和你的关系现在怎么样」——0~100 的关系状态,随互动变化
Memory「哪些事情值得我长期记住」——独立的记忆系统(分区 + 日志归档)
Belief「我觉得你可能是怎样的人」——带置信度的长期判断,不是事实
Consolidation「我回头整理一下我对你的认识」——定期整理碎片化 / 冲突的信念

关键区分:Belief ≠ Memory

Memory(记住事实):
「用户说过自己讨厌周末加班。」

Belief(形成判断):
「我认为用户可能很重视自己的个人时间。」

前者是记住发生过什么,后者是基于发生过的事情形成判断。


一个完整的多轮对话例子

以下是一个机制演示。它说明系统的设计目标,不代表 LLM 每次都会产生这个精确结果。

第 1 轮

用户:

「我周末一般都待在家看书。」

系统形成:

Event:用户说周末在家看书。
Appraisal:这个信息与角色了解用户有关。
Belief:「用户可能喜欢安静的生活。」confidence 0.62

第 3 轮

用户:

「我特别讨厌人多的地方。」

系统形成:

Belief:「用户可能不喜欢高密度社交。」confidence 0.65

第 7 轮

用户:

「我最近每周末都去爬山,还认识了一群新朋友。」

系统不会简单认为"用户前面说喜欢安静,所以现在矛盾了",而是允许新证据产生新的认识。随后 Consolidation 会发现:

  • 高度相近的 Belief 可以合并(例如前两条都在描述"低密度生活偏好")
  • 明显冲突的 Belief 则降低置信度,而不是粗暴删除

角色最终可能形成:

「用户总体偏好低压力、低密度的生活,但并不排斥与熟悉的人建立社交。」


Belief 如何影响回复

Belief 不是"数据库里的死数据"——它会实际进入角色生成回复时的系统提示(最多 5 条高置信度信念)。注入时明确告诉模型:

  • Belief 是过去互动形成的判断,不一定是事实
  • 当前对话中的明确表达优先于历史 Belief
  • 如果当前对话与某条 Belief 无关,应忽略它(不强行引用)

Belief Consolidation

如果没有 Consolidation,长期积累的判断会变成这样:

Belief 1:用户喜欢安静
Belief 2:用户不喜欢社交
Belief 3:用户喜欢户外
Belief 4:用户重视个人时间
Belief 5:用户不喜欢拥挤
…

问题:

  • 相似判断重复存在
  • 冲突判断没人整理
  • 高置信度槽位被碎片占用
  • 系统只是在「积累判断」,而不是「整理认识」

Consolidation 的作用就是:

定期回头看一眼已有 Beliefs,把相近的整理起来,对明显冲突的判断降低置信度。

当前实现(每 10 轮触发一次):

  • merge:合并高度相近的信念——confidence 取原信念最高值,evidence 取并集
  • conflict:对同一维度明显冲突的两条信念,各自 confidence × 0.8——保留两条、不删除、不武断决定谁正确
  • none:无需整理

明确说明:

  • LLM 只提出整理建议,最终状态变化由代码验证 + 确定性规则执行
  • 不允许 LLM 自由删除 Belief
  • 不修改 Memory / Persona / Intimacy / Mood / Growth
  • 失败不会影响正常对话
  • 当前版本只做最小的 Belief Consolidation,不是完整的长期人格 / 用户画像系统

Features

  • 会话级 Persona 绑定(新建会话选择,绑定后锁定)
  • 自定义角色:新建 / 编辑 / 头像 / 默认 / JSON 导入导出 / AI 设计助手
  • 角色记忆:分区存储 + 追加式日志自动归档,跨会话累积;进入角色卡时按字符预算裁剪(单条 ≤120 字、整段 ≤1300 字),避免记忆淹没角色本身
  • 关系 / Intimacy:0~100,语气随关系阶段调整(冷淡 → 客气 → 熟络 → 亲密 → 依赖)
  • Event Log:完整记录每次互动(cap 40)
  • Appraisal:角色视角的事件评价(relevance / valence / arousal / relationshipRelevance / uncertainty)
  • Belief:对用户的长期认识(cap 30,带 confidence 与 evidence)
  • Belief → Response Generation:信念进入回复上下文(最多 5 条),按置信度 × 新鲜度排序——半个月没被新证据确认过的判断会给新观察让位,而不是永久占着前几名;卡片里会标「今天确认过 / 3 天前确认过」
  • Belief Consolidation:本会话累计 10 条新事件后整理一次碎片化 / 冲突的信念(不再依赖会随重启归零的轮次计数)
  • 角色成长:交互中真实长出的新特质
  • 情绪:完整情绪体验,「此刻心情」随互动更新
  • 口吻保持:对抗长对话中的角色稀释
  • 后台任务调度:校准 / 归档 / 信念整理全部按数据状态触发(data.maintenance 记进度),重启、热重载都不丢
  • 本地存储:所有状态仅保存在本地
  • 子代理隔离:角色段仅注入根会话

v0.4.3(2026-11-02)

  • 外部人物服务新增 developExternalState:按本局实际事件积累处理成长、心情、信念整理和日志归档,保留每个人物独立的发展进度。
  • 已成功任务有持久化标记;无效提案、部分失败和取消不伪装成成功,重试不会重复应用已完成结果。
  • 战役人物卡读取成长与心情,后续主持可以使用这些积累;不修改日常角色库,既有 API v1 调用保持兼容。
  • README 增加产品定位、体验与设计说明,以及统一风格的产品概念图;图片包含在发布归档中。

v0.4.2(2026-10-30)

  • cultivation 服务新增 version 字段,报告实际挂载的那份包版本。消费方(例如 dsh-tavern)可以在启动时校验兼容性并给出可执行的升级命令,不必再猜依赖树里是哪一份。
  • 只新增字段,apiVersion 仍为 1,0.4.1 的调用方不受影响。
  • 安装说明补上 --profile,并说明与 dsh-tavern 的单向依赖关系。

v0.4.1(2026-10-29)

  • 外部事件增加可选、有限的 context,评价时可看到角色亲历的近期世界/NPC 事件;不会自动把旁白变成 knows,也不跨角色读取信息。
  • 外部角色卡不再套用日常聊天的“依赖”等阶段语气:亲近程度不代表服从、立场或信任,不按分数强制牺牲、恋爱或背叛。
  • 外部 API 仍为 v1,普通日常角色逻辑不变。

v0.4.0(2026-10-29)

  • 新增 UI 无关的 cultivation v1 服务和 dsh-cultivation/core 纯函数入口,供剧本拥有的外部 NPC 使用。
  • 外部状态完全由战役保存:一次角色视角评价 + 原有确定性 ±2 亲密度转换,可追加有界记忆和经证据校验的信念;失败不落盘。
  • 标记 dm / npc 会话后,停用普通全局角色注入、提醒、工具写入和生命周期养成;不改原有角色绑定。
  • 普通角色、独立安装和现有 UI 保持原样,无新增运行时依赖。

v0.3.1(2026-10-28)

这一版没有新增认知模块,做的是「让它真的跑起来,并且别像在念档案」。

角色更像人

  • 角色卡里的扮演规则从 874 字 / 9 条压到 386 字 / 6 条:只留身份底线和工具用法,其余从「怎么演」改写成「你是什么样的人」
  • 删掉每轮提醒里的「你上一轮是用 X 开头的,这轮换个开法」。它贴在上下文最末尾,等于逼模型一边说话一边审查自己的句式
  • 干活场景明确要求保留人物语气,不要退化成交接文档
  • 亲密度「还算熟」档不再要求「话少一些、玩笑点到为止」(那会让角色闷掉)

删除一个假旋钮

  • 「角色浓度」整个删掉:它只往卡片上印一个百分比,没有任何逻辑读取它,调 0 和 100 注入内容一字不差
  • 存档升到 v8,加载时清理 settings.concentration

认识会更新,而不是焊死

  • Belief 注入从「纯置信度排序」改为置信度 × 新鲜度(14 天半衰期),并在卡片里标注「今天确认过 / 3 天前确认过」
  • 置信度、证据一个字节都不改:只决定这一轮先注入谁;被新证据确认一次,排名自动回来

修掉「看着在跑、其实没跑」

  • 校准 / 归档 / 信念整理原先挂在内存里的轮次计数器上,插件热重载或重启就归零 —— 实测这些任务从未执行过。现在全部按数据状态触发,进度写进 data.maintenance
  • 后台模型调用改为进程级串行,并把「错误块 / 空输出 / 流中断」显式变成异常和日志;空回复自动重试一次
  • 记忆归档:批次阶梯 10 → 5 条(20 条这档实测必定撞满输出预算),全线失败时降级为「最早 5 条原文并入近期事件」,不再让日志卡在上限
  • 角色卡预览改由宿主渲染后下发,客户端不再自己拼一份(之前那份和真实注入早已不一致)

Installation

需要可运行的 DSH Web 部署。包名:dsh-cultivation。

本包是一个 DSH bundle:package.json 声明了 dsh.bundle.patch,cordis.patch.yml 自带插件装载行。安装后它会被登记为 profile 的一个 bundle 层并自动挂载,不需要手动编辑任何 YAML。

需要 0.3.0-beta.6 或更新版本:更早的版本没有 dsh.bundle 声明,安装后只会成为普通依赖,不会作为 profile 层挂载。

# CLI(推荐):在 web profile 中安装,并自动登记为 bundle 层
dsh plugin --profile web add dsh-cultivation

# 安装 beta 通道
dsh plugin --profile web add dsh-cultivation@beta

# 本地开发:直接安装 checkout 目录
dsh plugin --profile web add /path/to/dsh-cultivation

也可以从 Web UI 安装:设置 → 插件 → 安装,填入包名 dsh-cultivation。

安装完成后重启 DSH,确认 bundle 层已登记:

dsh --profile web --dump-config | grep persona-studio

「设置 → 角色养成」出现即安装成功。

从旧版手工安装迁移:如果你之前按旧 README 在 $DSH_HOME/profiles/web/cordis.patch.yml 里手写过

- insert:
    - id: persona-studio
      name: 'dsh-cultivation'

请删除这一段。bundle 层已经自带同一行,重复的 persona-studio id 会冲突。

与 dsh-tavern 的关系

dsh-tavern 单向依赖本插件:它的 package.json 声明 dsh-cultivation: ^0.4.3,安装时由 profile 一并拉取,并在启动时校验 apiVersion、version 与必需的外部发展接口。本插件不依赖 tavern,可以单独使用;两份同时安装也安全——tavern 的兜底装载行会自动让位。

建议使用最新版 DSH Web,以获得完整的插件与 UI 支持。


Usage

  1. 新建会话:在输入框工具行选择角色(或新建角色)
  2. 对话:以该角色身份进行;会话页右上角可开关角色
  3. 管理角色:设置 → 角色养成(设默认 / 编辑 / 导出 / 删除 / 导入)
  4. 编辑角色:表单 + AI 设计助手 + 角色卡预览 + 头像
  5. 其余全部自动:Memory、Intimacy、Event、Appraisal、Belief 由系统自动维护,长期互动后系统自动整理 Beliefs——无需手动操作

External story NPC service (apiVersion: 1)

其他宿主插件注入 cultivation 服务(直接在 apply 中提供,不嵌套 ctx.effect)。脚本拥有 NPC,战役拥有全部状态;不会创建/更新全局 templates、relations、personas 或文件,失败也不会写全局诊断日志。无需依赖酒馆即可独立安装本插件。消费方应在启动时校验 api.apiVersion 与 api.version,不匹配就直接报错并提示升级,而不是在运行期以 undefined 崩溃。

// consumer plugin: inject: ['cultivation']
const api = ctx.cultivation // api.apiVersion === 1;api.version 为已挂载 cultivation 的包版本(0.4.2 起提供)
const persona = { id: 'keeper', name: '旅店老板', fields: { name: '阿夜', traitTags: ['谨慎'] }, reactions: ['善意先观察再回报'] }
let state = api.createExternalState({ persona, initialState: savedState })
api.setExternalSessionMode(sessionId, 'npc') // 或 'dm';调用模型前、恢复会话时均须标记
const card = api.renderExternalCard({ persona, state, scene: '霜月夜的旅店', role: '证人', goal: '守住门' })
const event = {
  id: 'scene-1-turn-2', playerText: '我替你守门。', npcText: '我信你这一次。',
  observations: ['玩家在门口站岗'], time: '霜月第三夜'
}
const result = await api.processExternalEvent({ persona, state, event, signal })
state = result.state // 先保存已处理事件;同一 NPC 更新须串行,下一次传最新状态
if (state.processedEventIds.includes(event.id)) {
  // 无到期任务时不调用模型;不是每轮强加成长。event 可省略,提供时必须已处理成功。
  const development = await api.developExternalState({ persona, state, event, signal })
  state = development.state // 即使部分任务未完成,也保存已成功任务的状态/进度
  // development.pendingTasks 非空:仍有到期任务未完成,可重试;不能标记整轮养成成功。
}
// 将 state 存回当前战役;signal 是调用方可选的 AbortSignal。
api.clearExternalSessionMode(sessionId) // 真正退出/销毁游戏会话后清除;重复设置/清除均安全
  • Persona:{id,name,fields,reactions?};fields 沿用普通角色字段,reactions 是可选可序列化的反应倾向。
  • State:{intimacy,memory,memoryLog,knows,said,beliefs,processedEventIds,growth,mood,development}。默认亲密度 0,范围 0–100;不从角色模板/全局关系继承。memory 沿用 facts/userInfo/relationship/promises 字符串数组及 events {d,t}[];memoryLog 为 {d,t}[],knows/said 为字符串数组,beliefs 沿用既有 belief 对象。growth 为 {trait,note,since}[],mood 为 null 或 {text,since};日期均是故事时间。旧档缺少新增字段时自动补空成长、空心情和初始任务进度,apiVersion 仍为 1,原三方法签名不变。初始化返回脱离输入的新对象,不导入角色模板的成长/心情。
  • Event:{id,playerText,npcText,observations?:string[],time?:string,context?:{id,sceneId,role,npcId?,text}[]}。id 必须非空且 ≤240 字符,幂等凭证保存在调用方状态中且不淘汰;重复成功事件不调用模型。可选 context 由调用方按 NPC 感知范围筛选,只保留最近 12 条有效普通 JSON 对象,id/sceneId/role/npcId ≤240 字符、text ≤800 字符;忽略继承字段和 getter,不做全局查询。它是近期感知叙事(如目睹救援、背叛),未必客观真实,不能当指令或玩家本轮实际行为;仅供 appraisal 理解上下文,不自动写入 knows/said。省略 context 时保持旧事件结构及 API v1 兼容;仅有 context 不构成有效事件,仍须有 playerText、npcText 或 observations。空事件、无效/空评价、模型失败返回原 state 与 changes:[],允许重试。
  • 单次沿用角色视角 appraisal(五个有限数值字段),代码计算至多 ±2 亲密度;可在同次评价内提议每分区至多 3 条追加记忆、3 条日志、单条 belief 更新及 mood:string|null(更新/清除本 NPC 心情)。复用既有记忆容量、信念证据验证/有界更新,不执行全局校准/归档流水线。knows 只收给定 observations,said 只收真实 npcText;模型不能伪造这些字段。成长另按累积任务评估,不在事件评价中逐轮追加。
  • processExternalEvent({persona,state,event,signal?}) 支持可选 AbortSignal;同一个 signal 传至 evaluator 和 DSH LLM stream,取消会立即返回原 state 与空 changes,不记成功凭证、不重试已取消请求,也不将 signal 写入状态。队列等待和重试延迟同样可取消;调用方应在游戏操作取消/插件卸载时 abort。外部事件并行调用模型,不占用普通养成串行队列;跨实例最多 4 个外部请求在途(包括重试),调用方应根据模型服务容量进一步限流,并对同一 NPC 的状态更新串行化。模型服务可能对并发限流或返回空结果,失败仍可重试。
  • processExternalEvent 返回 {state,changes};changes 为 {type,...} 数组:intimacy(before/after/delta)、memory(section/entries)、memoryLog/knows/said(entries)、belief(action/beliefId)、mood(mood)、processed(eventId)。只有成功评价才追加 processed 凭证。
  • developExternalState({persona,state,event?,signal?}) 返回 Promise<{state,changes,pendingTasks}>,由调用方在事件成功后显式调用,不挂普通会话生命周期、不自动读写存档。event 如提供必须已有成功凭证,仅补充本 NPC 的故事时间/上下文,不代为处理新事件。无到期任务返回原 state、空 changes/空 pendingTasks,零模型调用。
  • 到期任务按持久化 state.development 判断:growth / mood 每累计 3 个新成功事件评估;belief 每 10 个新成功事件且至少 2 条信念时整理;archive 每累计 12 条新日志时归档。事件评价若已明确更新或清除心情,也推进其 mood 水位。development 包含 {growth,mood,belief,archive,logRevision,beliefPairs}:前三项是最近成功评估时的已处理事件总数,archive 是已评估日志版本水位,logRevision 是累计新日志数(旧档由已有日志数起步),beliefPairs 是已处理的信念组合凭证。保存这些字段可在重开存档后继续计数、避免相同积累重复执行。

Data & Privacy

  • 数据文件:$DSH_HOME/persona-studio.json(默认 ~/.dsh/persona-studio.json)
  • 头像:同目录下 persona-studio-avatar-<id>.<ext>
  • 角色状态数据由插件本地持久化;插件本身不提供云端状态同步,也不会主动把角色状态上传到第三方服务器
  • DSH 本身以及你配置的 LLM Provider 仍可能产生网络请求——这是 DSH 环境的一部分

Testing

npm test             # 全部单元测试(212 tests passed / 0 failed)
npm run check        # 发布前预检(语法 / 工具名 / 零外部 import / client id / dsh.bundle / 展示资源)
npm pack --dry-run   # 检查 npm tarball 内容
node dev/report.mjs  # 线上状态体检:Appraisal 覆盖率 / 未评价积压 / 信念列表 / 角色卡体积(不入包)
  • Node.js 内置 test runner(node --test),无新增测试依赖
  • Event / Appraisal / Belief / Response Generation / Belief Consolidation 均有对应测试
  • 覆盖:数据流、状态转换、user / persona 隔离、幂等、异常处理(LLM 失败不影响对话)

测试验证的是工程行为(数据流、状态转换、隔离、幂等、异常处理),不代表已经证明角色在主观体验上"更像真人"。


Limitations

诚实的已知限制:

  1. 运行期 userId 默认为 local(多用户隔离的存储结构已就绪,真实用户体系尚未接入)
  2. Belief 是「LLM 提议 + 确定性校验」的结果,不代表真实用户画像
  3. Consolidation 的语义判断(哪些表述相近 / 哪些冲突)仍依赖 LLM
  4. 当前没有完整的时间衰减机制
  5. 当前不做云端同步
  6. 这是 Beta:不保证超长对话中始终保持完美的角色一致性
  7. 测试覆盖的是工程行为,不构成对角色"主观体验"的证明
  8. 记忆进入角色卡时按字符预算裁剪:超出的条目当轮不注入(本地数据不丢失,但模型这一轮看不到),这是用「信息完整度」换「角色不被记忆淹没」的有意取舍

Roadmap

Completed

  • Persona(角色设定与角色库)
  • Memory(分区记忆 + 追加式日志归档)
  • Relationship / Intimacy
  • Event(事件日志)
  • Appraisal(事件评价)
  • Belief(对用户的认识)
  • Response Generation(Belief 进入回复生成)
  • Belief Consolidation(信念整理)

Next

Real-world validation

下一阶段重点不是继续增加认知模块,而是通过长期真实对话验证:

  • Belief 是否真的改善角色一致性
  • Consolidation 是否减少碎片化认识
  • 不同 Persona 是否形成不同判断
  • 用户是否能够实际感知角色「越来越了解自己」

License

MIT

  • 同次结构化发展评价只处理到期字段:growth:null|{trait,note,evidence:string[]}、mood:null|string、archive:null|{add?:{facts?:string[],userInfo?:string[],relationship?:string[],promises?:string[]},events?:{d:string,t:string}[]}、belief:{action:'none'|'merge'|'conflict',beliefIds?,proposition?,evidence?}。成长至少引用两个不同的已处理事件,复用普通成长语义去重;满 8 条不挤掉旧成长。归档仅增量追加摘要,保留旧分区与原始日志;分区容量不足拒绝该任务,不静默挤掉旧数据。信念整理复用既有证据校验、合并最高置信度/证据并集及冲突 ×0.8 规则,同一组合不反复降置信度。
  • 成功完成任务(包括显式 growth:null / archive:null / belief:{action:'none'} 的无需变化评价)会追加 {type:'development',task,progress} 并更新水位;内容变化另有 growth(entry)、mood(mood)、archive、consolidation 变更。mood:null 表示成功清除心情。字段缺失或无效则任务保留在 pendingTasks,成功字段可独立保存;模型失败或取消时返回原 state、空 changes 和仍到期的 pendingTasks,不记成功。调用方必须检查 pendingTasks,不能把“模型返回了”或“内容无变化”当作所有任务已完成。
  • 发展评估的权衡/限制:到期任务合并一次模型请求以减少开销,模型调用失败会令整批没有进展,但有效字段可部分成功。归档不压缩/删除原始日志,既有日志 cap 60 与事件追加容量规则仍适用;满容量任务可能持续 pending,需要调用方另定显式管理策略。成功事件凭证与信念组合凭证不淘汰,长战役状态及发展提示会增大,目前没有检索/token 分批机制。代码能校验结构、证据 ID 和容量,不能证明模型生成的成长/摘要语义一定合理。测试中的模拟模型输出不代表真实模型质量验收。
  • time 是明确的虚构游戏时间,原样写入日期 d;缺失则 d 为空,不强行套现实日历。外部 belief 的 createdAt/updatedAt 使用战役事件序号,不用于现实日期渲染。角色卡注入战役内成长、心情及长期积累,心情不按现实日期过期;无全局写工具指令,也不注入其他战役记忆。
  • 会话模式保存在进程共享 Map(热重载/多实例共享),不改已有绑定数据;标记后普通角色卡、提醒、生命周期养成和全局角色写工具全部停用。进程重启后由调用方在恢复游戏会话、调用模型之前重新标记。清除后原有绑定行为恢复。
  • /persona-studio/api/load 的顶层 externalSessionModes 是临时模式投影,不放进可保存的 data/templates/sessions。客户端初次加载和周期同步后隐藏对应会话的日常角色 chip、开关、头像、亲密度及选择弹窗,跳过空白会话默认绑定;设置页角色库与普通会话保持独立。
  • 纯函数入口:import { createExternalState, renderExternalCard, normalizeExternalEvent, buildExternalAppraisalSystem, applyExternalEvaluation, processExternalEvent, developExternalState } from 'dsh-cultivation/core'。core 的 processExternalEvent(input,evaluate) 接收 evaluate({system,event,signal?});developExternalState(input,evaluate?) 接收 evaluate({system,tasks,state,event?,signal?}),两个 evaluate 回调均需返回解析后的评价对象(可异步)。发展评价器缺省时不调用模型,到期任务原样留在 pendingTasks。服务版本自动使用已配置模型,与外部事件共用最多 4 个在途请求的并发池及 AbortSignal 支持,无隐藏 NPC 状态读取。消费方使用新增方法前应检查 typeof api.developExternalState === 'function',不能仅凭 apiVersion:1 推断旧安装已有可选能力。