写角色包
角色包定义 Bot 的人物身份、说话习惯、轮换风格、设定资料、专属表情以及工具与技能权限。每个角色包是一个独立文件夹,既可在面板的角色页图形化编辑,也可直接维护目录文件或打包为 ZIP 分发。完整参考实现见仓库中的示例角色小然。
目录结构
companion/
persona.yaml 名字、简介、性格与做事方式、轮换风格、工具与技能许可(必需)
voice.md 基础说话方式(可选)
boundaries.md 言行底线(可选)
examples.yaml 情境与台词样例(可选)
knowledge/ 按需检索的 Markdown 设定资料(可选)
stickers/ 表情图片与 index.yaml 索引(可选)
avatar.png 面板展示头像,支持 png / jpg / webp / gif(可选)
response_choice.md 替换框架默认的回应判断(可选)
expression_principles.md 替换框架默认的一般说法(可选)
chat_examples.md 替换框架默认的情境示范(可选)除 persona.yaml 必须存在外,其余文件与子目录均按需添加;缺失的可选文本文件在加载时视为空内容,在面板中保存过一次角色后会自动补齐基础文件。
persona.yaml
最小角色包只需在 persona.yaml 中填写 name 和 brief 两个字段:
name: 小一
brief: 班里爱聊天的同学,说话直接,喜欢接梗。完整字段说明:
| 字段 | 类型与约束 | 作用 | 缺省值 |
|---|---|---|---|
name | 非空字符串 | 角色名字,用于系统提示词与群内点名唤醒 | 必填 |
brief | 非空字符串 | 一两句话概括角色的身份与基本定位 | 必填 |
id | 小写字母、数字与 -(不以 - 开头或结尾,最长 64 位) | 角色唯一标识,用于按角色隔离记忆与本群补充设定 | 角色文件夹名 |
behavior | 多行字符串 | 性格特点、日常感兴趣的话题及面对不同情境时的做事方式 | "" |
self_reference | 字符串列表 | 角色日常自称,例如 [我] 或 [我, 本喵] | [我] |
aliases | 字符串列表 | 群友对角色的常见昵称或简称,出现时同样触发点名唤醒 | [] |
styles | 风格对象列表 | 每轮按权重随机抽取一种附加说话风格,每项含 name、weight、note,各项 weight 之和须等于 1(面板中显示为合计 100%) | [] |
example_tags | 字符串列表 | 仅注入 examples.yaml 中带有这些标签的样例 | 空(按顺序取前 8 条) |
tools | all 或工具名列表 | 允许该角色调用的聊天工具;填 [] 禁用除基础发言外的工具 | all |
skills | all 或技能名列表 | 允许后台任务在绑定该角色的群内挂载的技能 | all |
注意:voice、boundaries 和 examples 分别独立存放在 voice.md、boundaries.md 与 examples.yaml 中,persona.yaml 不接受同名内联字段。
写作方法与职责边界
框架能力与角色口吻分离
框架内置提示词只负责群聊通用能力(工具调用契约、查证习惯、防全知边界、表情发送协议)以及可被替换的默认自然度基线,不限制具体口吻。标点符号(例如是否爱用 ! 或 ~)、语气助词、颜文字、口头禅、句长节奏以及发表情包的频率,全部由角色包自身决定。
撰写 behavior、voice.md 和 boundaries.md 时,直接正面描述这个角色平时怎样说话、怎样对待朋友,避免堆砌一长串否定禁令。
人物特点与日常细节
- 把设定写成背景而非口头禅:若在
brief中强调某项爱好(例如喜欢甜食),应同时在behavior中说明它只在聊到吃喝或闲暇近况时自然带出,避免模型每轮回答无关问题都强行拐回该设定。 - 写清手机打字习惯:相比抽象的性格形容词,明确写出句长偏好、句末是否省略句号、何时只回两三个字、连发两句时的断句方式,更能稳定塑造真人口感。
- 交代关心人的方式:写明朋友遇到倒霉事时角色习惯怎样回应(例如先顺着具体细节吐槽一句、问清卡在哪一步),防止模型滑向千篇一律的句尾祝福或喝水早睡叮嘱。
- 说明表情使用节奏:配有
stickers/时,在voice.md中交代角色平时是喜欢单甩一张表情包,还是习惯一句话配一张图,或是只在情绪强烈时偶尔发图。
轮换风格(styles)
同一个人在不同对话里的节奏并非固定不变:有时简短接一句,有时多聊两句近况,熟人打趣时语气更活。配置 styles 后,宿主在每个新回合开始时按 weight 权重抽取其中一种风格,仅在当轮注入一段简短补充说明(配置为空列表 [] 时只使用 voice.md 基础说话方式):
styles:
- name: 简短接话
weight: 0.5
note: 顺着眼前这一句简短接话,一两句说完就停。
- name: 展开细聊
weight: 0.3
note: 挑对方话里的具体细节多聊两句,自然追问或接上自己的看法。
- name: 轻快打趣
weight: 0.2
note: 熟人闲聊或接梗时语气轻快一点,带点玩笑感;遇上正经求助或坏消息仍按正常分寸回应。注意事项:
- 各项风格仍属于同一个人物,不改变身份认知、事实记忆或
boundaries.md中的底线。 - 避免在单条
note中规定必用的固定口头禅,否则抽中该风格时容易高频复读同一词语。 - 涉及遇正事收敛分寸的说明,可在活泼风格的
note末尾一句话点明,无需拆成繁琐的条件规则表。
对话样例(examples.yaml)
examples.yaml 用于向模型示范具体语境下的语气、句长与收尾方式。每条样例包含 context(当前群聊情境)、line(角色做出的回复)及可选的 tags 标签列表:
- context: 群友:刚下班,今天被甲方改了八版
line: 八版,甲方是拿改稿当许愿池了吧
tags: [daily, comfort]编写样例时的经验:
- 覆盖几类典型跨度(日常接话、朋友吐槽倒霉事、互相斗嘴、被纠正错误、遇到拿不准的事情)比同一种闲聊写十几条更有效;示例角色小然在
examples/personas/companion/examples.yaml中就采用了这种组合。 - 样例只示范口吻和分寸,避免在样例台词里编造会与真实群聊混淆的私密往事;模型在上下文中看到明确标注,不会把样例情节当成群内发生过的事实。
- 准备了多组不同场景的样例时,可通过
tags与persona.yaml的example_tags按需筛选;单轮最多带入 8 条样例。
事实资料
角色需要准确回答的背景设定(如生日、经历、人际设定、作品列表等)统一写成 Markdown 文件放入 knowledge/ 子目录,模型遇到相关提问时通过 knowledge 工具按需检索,不挤占每轮常驻系统提示词。资料中未记载的细节,角色可按自身口吻坦然表示不记得或不确定。
专属表情库(stickers/)
角色自带的表情图片放在 stickers/ 目录下,并由同目录的 index.yaml 建立索引(在面板角色 → 表情页签上传和编辑时会自动维护该文件):
- file: happy.png
description: 笑脸:眯眼咧嘴笑,脸颊泛红。适合:开心、被逗笑、替别人高兴。
emotions: [开心, 被逗笑]
tags: [笑, 开心]description 需准确描述画面动作、神态或图中文字以及适用语境。当同一情绪下存在多张图片时,模型可根据文字描述区分,也可先拉取带编号的缩略预览拼图核对画面后再发出,且同等匹配下优先挑选近期使用较少的一张。
替换框架默认表达规则
框架默认向每个角色提供三份可替换的通用表达提示词:
| 角色包覆盖文件名 | 对应的框架默认模板 | 职责 |
|---|---|---|
response_choice.md | next_response_choice.md | 开口前如何判断对方意图、何时保持旁听、何时点到即止 |
expression_principles.md | next_expression_principles.md | 群聊发消息的自然度基线,避免复述点评、总结升华或抢话 |
chat_examples.md | next_chat_examples.md | 不含具体台词的通用应对思路示范 |
当角色包目录中存在上述同名非空文件时,该角色单独使用自带版本,不影响实例中的其他角色;文件不存在或内容为空时回退使用框架版本(含在系统 → 设置 → 提示词中保存过的全局自定义版本)。三份文件中可使用 $name 占位符代表当前角色名,其余 $ 字符原样保留。
注意:主行为循环契约(next_mind.md,含防全知、查证要求与安全边界)及表情工具操作协议(next_react.md)属于宿主核心机制,不支持由角色包覆盖;请勿在角色覆盖文件中削弱查证或工具调用约束。
试聊调试与回放评测
- 面板草稿试聊与预览:在角色 → 效果页签可随时查看当前角色在目标群拼装出的完整提示词与风格抽样结果,并用尚未保存的草稿启动隔离试聊;确认自然后再保存应用到真实群聊(群角色切换规则见角色管理)。
- 离线回放对比:大幅重写角色材料或自定义表达规则时,可使用仓库
examples/replay/中的表达集与scripts/compare_social.py --persona <角色目录>运行前后对照评测,逐题比对回复质量与发言分寸。