OneBot v11
- 适配器
- NapCat、Lagrange.Core、go-cqhttp
- 连接
- 适配器主动连接 Diana 的反向 WebSocket
- 地址
ws://HOST:18080/onebot/v11/ws- 能力
- 群列表、CQ 码、引用、群文件、本地媒体
配置
先建立稳定的模型连接,再分配模型职责和平台通道,最后按群收敛触发、时间、用户与工具边界。
平台接入
所有启用的机器人配置会并行运行,回复始终回到来源通道。凭据在「机器人」页按平台填写;密钥字段留空表示沿用已保存的那份,填写才覆盖。
真正影响部署的不是平台本身,而是消息怎么进来。前四个平台由 Diana 主动出站建立连接,家庭宽带或内网也能直接用;飞书和企业微信只能由平台把事件 POST 过来,必须有一个公网可达的 HTTPS 地址。
| 平台 | 接入方式 | 需要公网地址 |
|---|---|---|
| OneBot v11 | 反向 WebSocket,由适配器连到 Diana | 否 |
| Telegram | Bot API 长轮询,Diana 主动出站 | 否 |
| QQ 官方机器人 | 开放平台 WebSocket 网关,Diana 主动出站 | 否 |
| 钉钉 | Stream 模式长连接,Diana 主动出站 | 否 |
| 飞书 | 事件订阅回调,由飞书 POST 过来 | 是 |
| 企业微信 | 自建应用回调,由企业微信 POST 过来 | 是 |
ws://HOST:18080/onebot/v11/wsopen.larksuite.com飞书和企业微信要把下面的地址填到各自后台的事件接收配置里。HOST 必须是平台服务器能访问到的公网地址,并且是 HTTPS。
https://HOST/api/channels/feishu/callback
https://HOST/api/channels/wecom/callback
同一平台配置了多个机器人时,在地址后面加配置档 ID 区分,例如 /api/channels/feishu/callback/<profile-id>;只有一个时用上面的短地址即可。
平台服务器带不了登录会话,所以它们由各自的规范验签:企业微信校验 msg_signature、按 WXBizMsgCrypt 解密并核对报文里的企业 ID;飞书核对 Verification Token,配了 Encrypt Key 时还会验 X-Lark-Signature 并解密。回调地址本身是公开信息,不能当凭据用,所以验签凭据请务必填写。
/media/resolver 地址;Telegram 拉不到本机地址,改为直接 multipart 上传。每个机器人保存独立的平台、账号、主人、人设和模型分配。多个平台同时运行时,回复始终回到来源通道。会话上下文固定按机器人隔离,不能关闭;同编号的群聊或私聊不会合并。需要交流时,可单独配置消息互通,或在双方机器人启用跨平台记忆后检索非敏感群公共事实与摘要,不共享原始聊天和个人记忆。
旧配置中的 isolate_platform_contexts 字段不再生效,原设置接口已移除。此前共享的历史记录保留在原位置,不会自动分配给各机器人;后续消息进入各自的隔离会话。
模型配置
Provider 管理 Base URL、API Key 和协议。页面上方从服务端同步模型目录,下方填写或选择默认模型;机器人配置再将不同职责绑定到具体模型。
| 角色 | 用途 | 测试要求 |
|---|---|---|
| 对话 | 最终回复、Agent 推理 | 验证中文表达、工具调用和长上下文。 |
| 视觉 | 普通图片、截图、历史图片 | 发送真实图片,验证小字 OCR、界面结构和多图关系。 |
| 意图识别 | 主动回复、回复抑制、关系判断 | 验证低延迟、稳定结构化输出和边界案例。 |
| 图片生成 | 文生图与图片编辑 | 必须实际生成并返回图片,不能只测文本连通性。 |
“识别机器人并自动不回复”默认打开,用于避免机器人之间循环对话;有明确业务需要时再关闭。
配置档的“凭据方式”可以用 OAuth 代替 API Key。控制台常跑在服务器上、浏览器未必同机,所以回调不强求落回本机:点“登录”后在自己的浏览器里完成授权,把地址栏那条回调地址整条粘回来即可(只粘其中的 code 也认)。令牌在过期前自动续期;同时填了 API Key 的话,续期失败会回落到它,不至于整个配置档一起哑掉。
提供商是配置而不是代码。内置 OpenRouter,其余在“自定义提供商”里填授权地址、令牌地址、Client ID 和 Scope 自行接入,适合自建网关或未内置的服务。两个地址必须是 https,本机回环地址(127.0.0.1)可以用 http。
拿到令牌之后怎么带给模型接口,同样是配置项。默认 Authorization: Bearer <token> 适用于绝大多数提供商;个别家不吃这一套——Anthropic 收到 Authorization 里的 OAuth 令牌会直接回 401“OAuth authentication is currently not supported.”,它要求令牌放在 x-api-key 里且不带前缀。所以自定义提供商的“高级”里可以指定令牌请求头、令牌前缀和一组附加请求头。换用非默认落点时,各家 SDK 自己写上的鉴权头会被摘掉,避免同一个请求带两种鉴权。
换令牌那一步的请求体格式同样在“高级”里选。RFC 6749 §4.1.3 规定令牌接口用 application/x-www-form-urlencoded,所以那是默认值;JSON 是部分服务自己的方言,内置的 OpenRouter 就只收 JSON。发错格式时对方通常只回一句“参数缺失”,不会说是整包没解析出来,排查方向容易被带到 Client ID 上去。在这个选项出现之前存下来的自定义提供商会继续按 JSON 发,免得本来配通的配置突然换不到令牌;新建的按规范走 form。
那类用法要向授权服务器谎报客户端身份,也超出消费级订阅本身的授权范围,是否使用属于部署者自己的判断;需要的话可以在“自定义提供商”里自行填写。
llm:
context_window_tokens: 65536
max_context_tokens: 65536
max_output_tokens: 2048
timeout: 60000ms
图片同样占用视觉 token。视觉质量差时,优先检查模型职责是否真的绑定了视觉模型、原图是否进入请求、图片是否因数量或 token 预算被裁剪,再考虑提高细节等级和上下文上限。
群聊策略
群管理会通过 OneBot get_group_list 同步机器人加入的全部群,而不仅是已经存在本地配置的群。连接不可用时才回退显示 SQLite 中保存的群配置。
人设可移植
人设库把「它是谁、怎么说话」存成具名的几套,随时切换。整库和单套都能导出成同一种文件,也都能被导入回来 —— 换机器、备份、或者把调好的人设发给别人,都是这一个文件。
库是套用来源,不是活绑定:选一套就把那几个字段填进机器人表单,之后跑的是表单里的值。改库里那份不会偷偷改变已经配好的机器人。
{
"version": 1,
"personas": [
{
"name": "然然",
"system_prompt": "你叫嘉然,大家喊你然然。你不是助手,是这个群里的一员。",
"reply_style": "human",
"action_description_enabled": false,
"self_reference": "我",
"sentence_enders": ""
}
]
}
导入接受三种形状,不用为格式回去改文件:完整的 {"personas": [...]}、光一个数组 [...]、或者单独一套 {...}。文件里没有 ID 和时间戳 —— 那些是本机状态,导入时一律重新分配。
| 字段 | 必填 | 说明 |
|---|---|---|
name | 是 | 库里显示的名字,最多 40 字。 |
system_prompt | 否 | 基础人设正文,最多 4000 字。 |
reply_style | 否 | 表达风格,见下表。留空表示这套人设不指定风格。 |
action_description_enabled | 否 | 是否在台词前后穿插括号动作,默认 false。 |
self_reference | 否 | 机器人怎么称呼自己,例如 我、本喵。 |
sentence_enders | 否 | 句尾语气词候选,逗号分隔。填多个是候选,模型按当下语气挑。 |
| 值 | 风格 |
|---|---|
human | 真人感 —— 一个具体的人在跟你说话,情绪外放、会黏人 |
assistant | 助手 —— 默认值 |
gentle | 温柔 |
lively | 活泼 |
concise | 简洁 |
catgirl | 猫娘 |
roleplay | 扮演 —— 界面上是「动作描写」开关,导入时会转成 assistant 加 action_description_enabled: true |
写了别的值不会导入失败:那几套会按「助手」导进来,界面上会单独提示是哪个词没认出来,方便手写文件时排查拼写。
回复模式(搭话频率)、语气跟随时段、拒答话术、模型分配都不在人设文件里。它们描述的是「这台机器人在这个群里怎么运行」,跟它是谁无关 —— 同一套人设放在办公群和水群,本来就该有不同的搭话频率。
「导入」还认 SillyTavern 角色卡:V1/V2/V3 的 JSON 卡和内嵌卡的 PNG(tEXt 块里的 chara/ccv3)都能直接选中。卡里的 description、personality、scenario、示例对话和开场白会拼成一份人设正文({{char}}/{{user}} 宏就地展开,超出 4000 字时整段整段舍弃靠后的内容);内嵌的 character_book 顺路并进世界书。多个备选开场白、作者注释这类和运行方式对不上的字段不导入。
仓库里有几个手写的示例文件可以直接导入:examples/personas/。
世界观与关系
世界书是机器人所处世界的设定集,在「机器人 → 人设 → 世界书」里维护。设定按树状章节组织,路径本身就是语境(注入时写成「枝江 / 港口:……」)。每个节点自己声明注入方式:常驻的每轮都带上,写世界的骨架;带触发词的只在最近对话聊到时注入,写细节,不浪费上下文。只有标题的节点当目录用,自身不注入;关掉一章,底下的节一起停用。
世界书是所有机器人共用的一本,用不用由每台机器人的开关决定(默认用,书是空的时开着也不注入内容)。整本可以导出成 JSON 再导入回来,条目的父子关系会按文件里的引用重建;和人设文件一样,ID 是本机状态,导入时一律重新分配。
导入还兼容 SillyTavern 世界书:世界书文件顶层的 entries、角色卡里内嵌的 character_book 都能直接选中导入。字段按语义折算——蓝灯 constant 对常驻、绿灯关键词对触发词、comment 对标题(缺了退回第一个触发词或内容开头)、disable 对停用,按 order 排好顺序落在根上。次要关键词(keysecondary,AND ANY 逻辑)也会搬过来:主词命中还要求任一副词在场才注入;其他副词逻辑(NOT ANY 等)语义相反,硬搬会把排除当要求,导入时退回只看主词。递归扫描、概率、插入位置这些酒馆扫描器的高级字段没有对应概念,导入时忽略,注入行为以本地规则为准。
人机恋默认关闭,由主人在同一页开启。开着时用户本人认真表白,机器人会看好感度和相处时长决定答不答应 —— 不够会被温柔婉拒,不报数字。恋爱是单偶的:同一台机器人同一时间只有一位恋人,已有恋人时任何表白都会被婉拒(不透露现任是谁),现任分手或被主人解除后才能确立新的关系。确立后记纪念日、语气按恋人来,好感度掉太低会进入冷战。整月和周年当天的白天(9 点到 22 点),它会主动私聊一句纪念日祝福,每天至多一条、进程重启也不会重发。本人随时可以提出分手,主人也能替任何人解除,分手不清好感度和画像。恋人关系只改变语气和相处方式,不解锁任何权限;机器人不会主动求爱。关闭时机器人完全不知道这个功能存在,被表白就按普通关系自然回应。
「机器人 → 人设 → 拟人化」里还有三个独立开关,默认全关:
Agent 与工具
Agent 运行器将结构化工具结果送回模型,直到得到最终回复或达到步数上限。工具注册表根据平台、关系权限、群配置和功能状态收敛。
联网搜索自带且不可安装/卸载。提示模型在时效性、事实核验、陌生实体和推荐类问题上优先检索。
一次性和周期任务统一持久化,控制台展示周期、下一次执行时间、来源和状态。
按配置发现外部扩展,受工作目录、允许列表、权限和超时限制。
识别、生成和编辑分别授权;图片生成使用真实生图请求做健康测试。
diana.host_stats 让机器人回答「内存占了多少」「CPU 忙不忙」「现在多少度」这类问题:CPU 型号与占用、平均负载、内存、磁盘、Diana 自身占用,以及这台机器能提供的温度、功率和电池。只读、无参数,采集与控制台总览页共用同一份实现。
温度走 /sys/class/hwmon,功率走 RAPL 的能量计数,电池走 /sys/class/power_supply,都不依赖 lm-sensors 之类的外部命令;容器里只要挂了 /sys 就能读。RAPL 给的是累计能量而非瞬时功率,所以功率要两次采样之间的差值才算得出来,第一次调用会如实说明这一点。macOS 的 powermetrics 需要 root、Windows 缺少通用接口,这两个平台的温度与功率直接报「读不到」——报一个编出来的数比不报更糟。这条对所有项都成立:读不到的项不会填 0,而是带上读不到的原因。
这个工具同样只对主人开放:主机名、磁盘路径和硬件型号不该对群里所有人可见。
本地那几个工具全部锁在数据目录下的 workspace 里,路径固定不可配置,绝对路径和 ../ 一律拒绝。三档权限各自独立:
| 档位 | 工具 | 默认 | 开关 |
|---|---|---|---|
| 读 | read_file、list_files、grep、find_files | 开 | 跟随「内置 Agent」总开关 |
| 写 | write_file、edit_file | 新建配置默认开 | 「允许写入文件」 |
| 执行 | run_command | 新建配置带只读白名单 | 命令白名单非空才注册 |
新建的机器人装完即可用:写入默认打开(锁在数据目录下的 workspace 内,碰不到配置和数据库),命令白名单预置一组只报状态、不碰数据的命令——uptime、free、df、uname、nproc、date、hostname、whoami。
收进这份默认白名单的标准有三条,缺一不可:不读任意路径的文件、不出网、不改任何东西。因为没有可用沙盒时,白名单里的程序就是以 Diana 自己的进程权限直接跑的——白名单只管得到「能不能跑」,管不到「能碰什么」。所以 cat、ls、find(能读任意路径)、curl、wget(能出网)、ps(会带上别的进程的完整命令行,那里面可能有别人的密钥)都被刻意排除;工作目录内的读取用 read_file / grep / find_files,它们锁在 workspace 里。
已经在跑的部署升级后不会凭空多出命令执行和文件写入:当初留空的白名单仍然是空的,关着的写入开关仍然关着。默认值是给新用户的便利,不该变成对存量部署的静默扩权。老部署想要这些能力,用同一张表单上的「填入推荐默认值」把推荐值填进来——它只改表单,点「保存配置」才生效,授权动作是你自己做的。
edit_file 的每个替换必须在原文件里唯一命中一处,命中多处或找不到都整批拒绝而不是改错地方;多个替换都按原文件定位,不是依次生效——依次生效会让后一个替换命中前一个刚写进去的内容,而那种改动从调用方的输入上完全看不出来。
这三档只对主人开放,但「调用发生在主人的会话里」不等于「这次调用是主人要的」:群里其他人的消息和主人的消息在同一个上下文里,模型是读完那些之后才决定调用工具的。所以真正的边界是这里的开关和白名单,而不是身份判断——需要哪一档就开哪一档,不需要的保持关闭。
安全边界
config.yaml、模型 API Key、Bot Token 和平台 Cookie 不进入 Git。