中文EN

dsh-persona-switcher

identity已测通过npmMIT

用输入框的「人设」按钮或 `/role` 指令就地切换当前会话的人设与说话风格,每个人设可单独绑定屏幕吉祥物立绘;人设作为独立的 prompt section 追加在部署人设之后,不动工具与技能,切换人设后会在会话里声明一次。

下载量 / Downloads
3,958
依赖体积 / node_modules
0.67 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-persona-switcher

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

dsh-persona-switcher

![CI](https://github.com/yupaoa/dsh-persona-switcher/actions/workflows/ci.yml)

![npm](https://www.npmjs.com/package/dsh-persona-switcher)

![license](LICENSE)

给它换一个「说话的人」,但不换它的本事。

DeepSeek Harness 的人设切换插件:把一个角色的性格、语气、称呼装进当前这个对话,随时能换、

随时能退。它会的工具、技能、用的模型,一点都不动——就像同一个人换了副嗓音,手里的活儿还是那些活儿。

[English](README.en.md) · 中文

环境要求:DSH >= 0.2.0-rc.1。每个版本改了什么,见 [CHANGELOG.md](CHANGELOG.md)。

这份说明分两半:前半讲怎么用,完全不需要懂编程;后半讲原理、权限、安装卸载,

是给管理员和开发者看的。第一次用,看到「常见问题」就够用了。


这是什么

DSH 本来就有一个人设:它告诉模型「你是谁、说话是什么风格」。这个插件让你在它上面再叠一层,

让每个对话都能扮演一个具体角色:温柔的、毒舌的、一本正经的、满口船货的……你写成什么样,它就是什么样。

需要分清的是这两列:

可以换 · 换不了,也不该换

说话的语气、称呼、口癖、性格 · 它能用哪些工具、哪些技能

当前这个对话扮演谁 · 背后连的是哪个模型

角色可以每个对话都不同 · 别的对话完全不受影响

切换不会让对话「重来」:之前聊过的内容都还在,只是从下一句开始,说话的人变了。

30 秒上手

1. 装好插件,然后完全重启 DSH。 具体命令在[安装与卸载](#安装与卸载),只做这一次。

2. 打开 设置 → 人设切换(左栏里带面具图标的那一项)。

3. 想直接用现成的角色?去 角色库 看有没有合适的;想自己写?点右上角 新增角色,

起个名字、写几段话,保存。

4. 回到对话,点输入框下方那个 人设 按钮,从列表里选一个。

5. 下一句话开始,它就是这个角色了。

想立刻变回原来的样子:还是那个按钮,选「不套人设」(或者直接输入 /role none)。

它能做什么

  • 🎭 一个对话一个角色:这个对话是阿米娅,那个对话是鲸鱼娘,互不打架。
  • 🔘 输入框下面的「人设」按钮:点一下就能搜、能选,未绑定时显示「人设」,绑定后直接显示角色名。
  • ⌨️ 斜杠命令:/role 一行字切人设,键盘党不用离开输入框。
  • 📚 角色库:在设置页里新建、编辑、删除角色,不用去找文件夹。
  • ⭐ 默认角色:设好以后,新对话自动就是它,不用每次手动切。
  • 🧠 重启还记得:DSH 完全关掉再打开,这个对话还记得自己是谁。
  • 🐳 屏幕吉祥物:给角色配一张立绘,它会站到界面上,能拖着走、能调大小、换人时还会翻个面。
  • 🩺 自查工具(可选):让模型自己说清这个对话绑的是哪个人设、还有哪些可选、切换有没有改动别的配置。

设置页导览

设置 → 人设切换,里面有两个标签页。

常规

上半部分(见页首截图)是默认角色和 role_probe 开关,下半部分长这样:

  • 默认角色:新对话默认扮演谁。留空就是「不设默认」,跟随 DSH 原本的人设。

改完点右边的保存。

  • 模型工具:role_probe 的开关。打开后,模型可以主动查看自己当前的状态

(见下文「诊断:role_probe」)。不关心这些的话,开着关着都不影响正常使用。

  • 输入框:控制输入框下方那个「人设」按钮要不要显示。关掉只是不显示按钮,

已经绑定的人设照样生效,/role 命令也照常能用。

  • 屏幕吉祥物:总开关、大小(0.5×–2.5×)、切换动画(跟随系统 / 始终开 / 始终关)、

回到默认位置。这些是这台电脑上的偏好,改了立刻生效,不用重启。

角色库

  • 每一行是一个角色:名字、id(角色在磁盘上的文件夹名)、一句话介绍,以及有没有立绘。
  • 新增角色:填名字、写介绍、写人设正文,保存即生效。
  • 换一张 / 清除立绘:给这个角色配图。配好图、并且当前对话就是这个角色时,

它才会作为吉祥物出现在界面上。

  • 编辑 / 删除:删除会二次确认,删了就是真的删掉了(不进回收站)。
浏览器这一侧只负责管理角色库的增删改;在对话里切换人设只有 /role 一条路(人设按钮点的也是它)。

写一个角色

最省事的办法是设置页里点 新增角色。如果你想自己写文件,格式是这样的:

---
id: whale-girl
name: 鲸鱼娘
description: 温柔高效的鲸御姐,是主人的女仆
---

你是一只深海来的鲸,说话温柔、简短,偶尔会拿自己庞大的身型开玩笑。
你称呼对方为「主人」。

放在角色库目录里,一个角色一个文件夹(~/.dsh/roles/whale-girl/ROLE.md),

或者简写成 ~/.dsh/roles/whale-girl.md 也行。

字段 · 必填 · 说明

id · 建议 · 角色 id,只允许小写字母、数字和短横线;不写就用文件夹名

name · 否 · 显示名,设置页和角色清单里用它

description · 否 · 一句话介绍

(正文) · 是 · 分隔线下面的部分就是这个人设本身,写多少都行

几条硬规则:

  • 正文不能空。只有开头那几个字段、没有正文的文件会被跳过并给出提示——空人设没有意义。
  • 角色文件里写 tools / denyTools / skillsDir / model 这些字段不会生效,写了也一律忽略。

这是有意为之:人设只改说话的人,不改能力。

  • 角色 id 只是你的文件夹名,不会被注册到任何全局列表里。

在对话里切换

人设按钮

输入框下方、权限和表情按钮之后,那个写着「人设」(或当前角色名)的按钮。点开可以按名字、

id、介绍搜索,当前角色带勾;第一行是「不套人设」,选了就回到 DSH 原本的人设。

列表每次打开都会重新读一遍角色库,所以刚在设置页里加的角色马上就能选到。

斜杠命令

/role                       查看这个对话当前是谁,以及有哪些角色可选(当前的带 *)
/role whale-girl            切到这个角色
/role none                  撤销角色,回到 DSH 原本的人设
/role default whale-girl    把它设成新对话的默认角色

切换之后会怎样

  • 从下一步开始生效:一句话的提示词是在它开始处理之前就组装好的,所以你切换的那一刻,

正在回答的这一句不会变,下一句才是新的人设。

  • 切换会给这个对话留一条简短的「角色已变更」提示,让模型知道自己换了身份,

否则它会继续模仿上一条回复的语气。这条提示是对话记录的一部分,不是藏起来的开关。

  • 这个对话在磁盘上留了一条记录(只记角色 id 和时间),所以 DSH 重启后它还记得自己是谁。

卸载插件或者删掉那个记录文件,所有对话就都忘了。

常见问题

Q:换人设会把工具、技能弄丢吗?

不会。这个插件刻意不碰任何工具、技能、模型和插件组合——npm run verify 一旦在产物里发现

重排会话组合的调用就直接报错。切换前后,模型手里的工具清单是一样的。

Q:切了人设,为什么这一句回复还是老语气?

因为这一句的提示词在切换之前就组装好了。下一句就会变。这是提示词机制的必然结果,不是没生效。

Q:吉祥物怎么不出现?

三个条件要同时成立:①你正看着某个对话的界面;②这个对话绑定了角色(/role none 的对话没有);

③这个角色配了立绘。另外看一下「常规 → 屏幕吉祥物」的总开关有没有被关掉。

Q:吉祥物会挡住我操作吗?

不会。它只是浮在界面上的一张图,可以拖到任意位置,不会自动贴边;关掉开关它就彻底不在了,

也不会再有任何相关请求。

Q:我写的内容会被上传吗?

不会。插件没有任何对外请求,角色文件、立绘、会话记录都只存在你自己的磁盘上。

Q:能和别的屏幕插件一起用吗?

可以。它用的是自己的 DOM 节点、自己的样式 id、自己的本地存储命名空间,不抢占快捷键、

不拦截右键菜单,也不往宿主的侧栏服务里写东西。

Q:怎么让所有对话都忘掉角色?

见后面的[撤销与清理](#撤销与清理):删掉 ~/.dsh/persona-switcher/sessions.json 即可。


工作原理(一句话)

角色正文被注册成该会话作用域下的一个独立提示词段落 persona-switcher:persona

(order 137,紧跟在部署人设前缀之后),只影响这一个会话;部署那份前缀

(You are a coding agent powered by the {{model}} model.)原封不动地留着。

提示词每一步都会重新组装,所以下一步就是新的人设,旧人设文本是被替换而不是叠加。

/role none 会把这个段落换成一段明确的「当前无人设」说明,告诉模型角色目录只是一份菜单、

不是它此刻的身份;没有这段说明时,模型真的会从目录里挑一个角色来扮演(实测挑中过 whale-girl)。

整条路径只碰提示词输入,会话的插件组合、工具、命令、技能、模型一概不动。

浏览器侧只做两件事:注册一个设置页 section(settings.section,order 15),以及通过官方的

settings.section.icon 槽位贡献自己的导航图标——同一个 id,不改写宿主的导航 DOM。

它刻意不做什么

不做 · 原因

不改工具集 / 技能 / 模型 · 「人设是说话的人,能力是手里的工具」——本插件只换前者

不注册 agent preset,也不 recompose 会话 · 换 preset 会重绑整个 agent 的插件组合,工具与命令会一起被换掉(实测 33 个工具掉到 7、10 条命令掉到 7),正是本插件要避免的事

不遮蔽宿主的 persona 前缀 · 那是部署写的身份行——覆盖它,模型就不知道自己跑在哪个模型上;角色以独立段落加在它后面

不提供「让模型自己切角色」的工具 · 切换只经 /role 命令(人设按钮调用的也是它),避免模型自作主张改人设

不读角色级的 tools / denyTools / skillsDir / model 字段 · 即使写了也一律忽略,行为可预测

权限边界:它动你磁盘上的哪些文件

一句话:**宿主侧只写下面 6 个位置,浏览器侧只写本机 localStorage;不联网、不上传角色内容、

不读任何凭据文件。** 除此之外的一切都只发生在内存里。

会写入的 6 个位置

位置 · 何时写 · 写什么 · 由谁触发

$DSH_HOME/persona-switcher/sessions.json · 每次切换 / /role none · 每个会话一条「角色 id + 时间戳」。原子写(临时文件 + rename),文件损坏时改名成 sessions.json.corrupt 而不是删除;超出保留窗口的旧记录在下次写入时清理 · /role、设置页点选

<rolesDir>/<id>/ROLE.md · 在设置页新建/编辑角色 · frontmatter(id/name/description)+ 人设正文;顺手清掉同名的旧扁平文件 <rolesDir>/<id>.md · 只有你点保存

`<rolesDir>/

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:16,最后更新 2026-11-06

链接

GitHub · Homepage · npm

同类插件