CC Switch 安装教程:从下载到一键切换 API 全流程图解
简介: CC Switch 是一款免费开源的跨平台 A...
环境:阿里云 ECS · Ubuntu 26.04 LTS · 2 vCPU / 1.7 GiB / 40 GB
时间:2026-11-01 ~ 11-02
说明:文中所有 IP、QQ 号、AppID、API Key、密码均已替换为占位符,请按自己的实际情况填写。
一句话:「让一个模型在 QQ 群里像人一样说话」,拆开是三件事——接一张嘴(消息通道)、写一份人设(提示词)、让它有记忆和情绪(插件)。
两条路线都跑通了:
| 路线 | 组成 | 特点 | 我的选择 |
|---|---|---|---|
| 路线一 | 官方 QQ Bot + DeepSeek Harness(dsh) | 官方通道、扫码即用、零封号风险、主动发言受限 | 先跑通,后停用 |
| 路线三 | NapCat + AstrBot + DeepSeek | 个人号协议、人格化程度高、插件生态丰富、有封号风险 | 最终在用 |
如果只想「让鱼在群里正常说话」,路线一省心到离谱,二十分钟能搞定。
如果想要「会发表情包、会改签名、会记仇、会自己插话」,只有路线三。
本文涉及的全部开源仓库(人设包、表情包素材、协议端、插件)整理在第 15 节,其中包含两个「已失效仓库」的记录,省得你顺着旧链接白找。
动手前先把需求拆成四层,否则很容易在「装插件」里迷路:
这四层的优先级是倒过来的:稳定性 > 人格 > 能力 > 通道。
因为通道挂了你会立刻知道,而「人格不像」「记忆错乱」往往要跑一天才发现,返工成本高得多。
Ubuntu 26.04.1 LTS
2 vCPU / 1735 MiB / 40 GB
Node.js v22.23.4(apt 自带版本太老,必须另行安装)这台机器在国内,遇到的问题按顺序是:
| 目标 | 状态 | 解法 |
|---|---|---|
deb.nodesource.com | ✅ 通 | 直接装 |
registry.npmjs.org / github.com | ✅ 通 | 直接 clone |
registry-1.docker.io | ❌ 超时 | 配置镜像加速 |
我这台本机的 web_fetch | ❌ 全部“解析到非公网 IP” | 改用 Node 的 https 模块直连 |
顺手记一个排查技巧:curl: (35) schannel: AcquireCredentialsHandle failed 不是网络问题,是 TLS 凭据拿不到;而 node -e 'require("https").get(...)' 往往能通——因为 Node 走自己的 OpenSSL,不依赖系统证书存储。
// /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1ms.run",
"https://dockerproxy.net"
],
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}实测 docker.m.daocloud.io 返回 401 是正常的(说明 Registry API 在响应),不代表不可用。
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
npm i -g pnpm @deepseek-ai/dsh # pnpm 必须单独装,dsh 的插件管理依赖它
dsh --version # 0.2.1-rc.5dsh plugin --profile qqbot add @tencent-connect/dsh-qqbot
dsh --profile qqbot首次启动会打印二维码,同时打印一条可点击的绑定链接:
https://q.qq.com/qqbot/openclaw/connect.html?task_id=<uuid>&source=dsh-qqbot&_wv=2服务器上没有图形界面也没关系——把这条链接发到手机浏览器打开即可扫码。绑定成功后凭据自动写入:
~/.dsh/profiles/qqbot/cordis.patch.yml之后重启不再需要扫码(这一点我实测过三次)。
dsh 在 systemd 下不能扫码(无 TTY)。正确的顺序永远是:
前台手动跑一次 → 扫码绑定 → 凭据落盘 → 再交给 systemd 托管反过来做(先写 unit 再启动)会一直卡在二维码界面。
官方通道的限制很硬:被动回复。用户不说话,它不能说话。
对「群里的活人感」这个目标来说,这条限制是致命的——它永远只能当客服,不能当群友。
systemctl disable --now dsh-qqbot 之后配置全部保留,随时可以切回来。
QQ 用户 ──▶ QQ 服务端 ──▶ NapCat(协议端)
│ 反向 WebSocket
▼
AstrBot(大脑)
│
┌─────────┴─────────┐
DeepSeek 硅基流动
(聊天/总结) (记忆向量)方向别搞反:AstrBot 的 aiocqhttp 适配器是反向 WS 服务端(监听 6199),NapCat 作为客户端连上去。
所以配置写在 NapCat 侧:
"websocketClients": [{
"name": "astrbot",
"url": "ws://astrbot:6199/ws",
"token": "<你的token>",
"reconnectInterval": 3000
}]services:
napcat:
image: mlikiowa/napcat-docker:latest
container_name: napcat
restart: unless-stopped
environment:
- NAPCAT_UID=1000
- NAPCAT_GID=1000
- ACCOUNT=<小号QQ>
- NAPCAT_QUICK_PASSWORD=<小号密码>
- TZ=Asia/Shanghai
mem_limit: 800m
volumes:
- ./napcat/config:/app/napcat/config
- ./napcat/qq:/app/.config/QQ
- ./napcat/cache:/app/napcat/cache
networks: [botnet]
astrbot:
image: soulter/astrbot:latest
container_name: astrbot
restart: unless-stopped
depends_on: [napcat]
environment:
- TZ=Asia/Shanghai
mem_limit: 700m
ports:
- "127.0.0.1:6185:6185" # 面板只绑本机,走 SSH 隧道
volumes:
- ./astrbot/data:/AstrBot/data
networks: [botnet]
networks:
botnet:
driver: bridge三个细节值得单独说:
ACCOUNT:不设它,NapCat 只会走扫码;设了才会尝试快速登录NAPCAT_QUICK_PASSWORD:token 失效时的兜底,能省掉无数次半夜扫码mem_limit:1.7 GiB 的机器不给容器设上限,一个内存泄漏就能把整机拖死首次启动会生成随机强密码,默认的 astrbot 已经失效。密码只在启动日志里打印一次:
docker logs astrbot 2>&1 | grep "Initial password"忘了也没关系,重启一次就会重新打印。
AstrBot v4 的 provider 结构是「连接」与「模型」分离的:
{
"provider_sources": [{
"id": "deepseek-flash_source",
"type": "openai_chat_completion",
"key": ["sk-****"],
"api_base": "https://api.deepseek.com/v1"
}],
"provider": [{
"id": "deepseek-flash",
"model": "deepseek-flash",
"provider_source_id": "deepseek-flash_source",
"custom_extra_body": { "thinking": { "type": "disabled" } }
}]
}thinking: disabled 很重要——DeepSeek 的思考过程会拖慢首字延迟,而且对「短句聊天」毫无意义。
用了社区配置包 zexuanw958-svg/dafeiyu-config-pack 的 persona/大肥鱼.md,里面有一个占位符 {OWNER_QQ},必须替换成真实 QQ 号——它不只是装饰,人设里靠它识别「谁才是主人」,防止有人在群里冒充。
顺便说一句这个包的设计:它的 settings/pack.json 是一份「清单式」配置,把 6 个配套插件、两套表情包、语音/记忆/主动聊天的推荐参数都写在一处,再用 tools/import_dafeiyu.py 读清单改 AstrBot。这个思路值得借鉴——配置即文档,改哪项就改哪行,然后重跑一次导入。
我没有整包导入,而是按需取用(详见第 11 节):语音链路需要额外的豆包/Breeze key,对 1.7 G 的机器也不友好;插件则挑了对「像人」帮助最大的几个。
AstrBot 的人格存在 SQLite 里,personas 表。第一次 INSERT 会连撞三个坑:
sqlite3.IntegrityError: NOT NULL constraint failed: personas.created_at
sqlite3.IntegrityError: NOT NULL constraint failed: personas.sort_order正确写法:
db.execute("""INSERT INTO personas
(created_at, updated_at, persona_id, system_prompt,
begin_dialogs, tools, skills, custom_error_message, folder_id, sort_order)
VALUES (CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '大肥鱼', ?, '[]', '[]', '[]', NULL, NULL, 0)""", (prompt,))然后把 agent_runner.config.persona.persona_id 指向它。
{
"platform_settings.segmented_reply.enable": true,
"platform_settings.segmented_reply.regex": ".*?(?:\\r?\\n+|[。?!~…]+)|.+$",
"platform_settings.empty_mention_waiting": false,
"agent_runner.config.compression.max_turns": 30,
"provider_settings.datetime_system_prompt": true
}分段回复是「一条条发」的关键——不切分的话,模型会一次吐出 200 字,立刻暴露是机器人。
diwer/ai-biaoqingbao 提供 100 张 512×512 的中文 GIF,带 catalog.json(编号、含义、分类)。分类正好是 7 组:首批常用、日常回应、抽象反应、打工摸鱼、情绪状态、亲密陪伴、祝福庆祝。
meme_manager 认这个结构:
packs/<pack_id>/
├── manifest.json
├── memes_data.json
└── memes/<分类名>/*.gifmanifest.json:
{
"schema_version": 1,
"id": "dafeiyu-biaoqingbao",
"name": "大肥鱼表情包·100个中文GIF",
"version": "1.0.0",
"categories": { "抽象反应": { "description": "大肥鱼表情:抽象反应" } }
}再把它登记进 registry.json 和 selection_rules.json(设成默认包)。
用 PowerShell 的 Compress-Archive 打包,到 Linux 解压后所有目录变成了文件名的一部分:
memes\抽象反应\001-不服气.gif ← 一个带反斜杠的完整文件名因为 Windows 用 \ 作分隔符,而 zip 规范要求 /。解决方法是用 Python 的 zipfile 显式写 POSIX 路径:
rel = os.path.relpath(full, root).replace("\\", "/")
z.write(full, rel)我一开始自己写了个 80 行的插件,直接往回复链追加图片,能用。
但换成 meme_manager 之后才明白差别在哪:
它把分类目录注入到模型提示词里,模型才知道「我有哪些图可以挑」,然后用 &&抽象反应&& 这种标记下单。自己写的插件只是「随机附一张图」,跟情绪无关;插件版是「有合适的才发」。这是「像人」和「像随机图片机器人」的区别。
| 方案 | 成本 | 可行性 |
|---|---|---|
硅基流动 BAAI/bge-m3 | 免费 | ✅ 选它 |
百炼 text-embedding-v3 | 约 0.0005 元/千 token ≈ 1–2 元/月 | ✅ 也可 |
| 本机 ollama | 免费 | ❌ 模型常驻 1.2 GB,1.7 G 机器跑不动 |
结论:embedding 从来不是钱的问题,是内存问题。
装完 livingmemory 启动直接失败:
ValueError: 无效的嵌入向量维度: 0。
请检查该知识库使用的 Embedding Provider 是否正确配置了 embedding_dimensions。openai_embedding 适配器不会自动探测维度,必须在 provider 配置里显式写:
{ "embedding_model": "BAAI/bge-m3", "embedding_dimensions": 1024 }"reflection_engine": { "summary_trigger_rounds": 10 },
"recall_engine": { "top_k": 5, "recent_memory_count": 2 }每 10 轮总结一次 → 存成带权重的记忆 → 回复时按语义召回 5 条 + 最近 2 条。
后台还有每日 00:05 的衰减/清理/备份调度。
AstrBot 默认 rate_limit.strategy = "stall",实现是:
await asyncio.sleep(stall_duration) # 睡到下一个窗口密集群聊时,超限的消息不是被丢弃,而是排队休眠——这是「延迟越堆越长」的元凶。
改成 "discard":超限直接丢,绝不排队。
最初我自己写了个 reply_gate 插件(event.stop_event() 可真正阻止模型调用,实测有效),按 DeepSeek 计费时段分档:
后来装了 group_chat_plus,把概率交给它,reply_gate 停用。
group_chat_plus 的 initial_probability 不是「回复概率」,而是「进入 AI 读空气判断的概率」。
所以配 0.6 ≠ 回 60%,实际回复率明显更低——这是它比自建方案更「像人」的代价。
{
"enable_dynamic_reply_probability": true,
"reply_time_periods": "[{\"name\":\"高峰(上午)\",\"start\":\"09:00\",\"end\":\"12:00\",\"factor\":0.67}]",
"reply_time_transition_minutes": 30,
"reply_time_use_smooth_curve": true
}实测日志(14:00 峰值边界):
13:53:27 原始=0.60 系数=0.69 结果=0.4121
13:54:37 原始=0.80 系数=0.68 结果=0.5444
13:58:35 原始=0.60 系数=0.67 结果=0.4022
14:00:00 原始=0.60 系数=0.67 结果=0.4020系数从 0.69 平滑滑到 0.67——说明 30 分钟过渡是在峰值前的 30 分钟就开始爬坡的,不是整点突变。
好处是观感自然,代价是「中午的尾巴」被提前压掉了。想要硬边界就把过渡改成 10 分钟。
这是整个项目最花时间的部分,也是最值得写的部分。
| 时间 | 现象 | 原因 |
|---|---|---|
| 19:54 | KickedOffLine 登录已失效 + 弹二维码 | token 失效 |
| 22:38 | 同上 | token 再次失效 |
| 11:09 | 日志一片安静,什么错都没有 | 会话静默失效(假在线) |
第三种最坑:容器 Up、WS 连接 ESTABLISHED、AstrBot 显示「适配器已连接」,但 QQ 侧早就不推消息了。从外部完全看不出来,只有「群里人不理它」这个现象。
# /usr/local/bin/napcat-watchdog.sh(核心逻辑)
RECENT=$(docker logs napcat --since 5m 2>&1)
if ! echo "$RECENT" | grep -qE "KickedOffLine|账号状态变更为离线|二维码已保存"; then
exit 0
fi
# 10 分钟冷却,避免循环重启
[ $((now - last)) -lt 600 ] && exit 0
docker restart napcat配 systemd timer 每 2 分钟跑一次。重启后入口脚本会带着 ACCOUNT + NAPCAT_QUICK_PASSWORD 自动登录,35 秒恢复。
它只能检测有日志的掉线。第三种「静默失效」一个关键字都不触发,所以看门狗全程没动作。
要覆盖它,需要主动健康检查:给 NapCat 开一个本地 HTTP API,让看门狗主动问 get_status。
我试过从容器外连它的 WS(3001),三次都是 1006 异常断开——这条路没走通,留作后续。
前两次掉线间隔 2 小时 44 分,规律得太可疑。最后发现是手机端同时登录着这个小号——个人号协议下,手机端上线/刷新会把协议端踢掉。
让用户在手机上退出这个小号之后:12 小时内 KickedOffLine 次数 0。
教训:掉线先问「这个号还在别处登陆吗」,比看一百行日志都快。
1.7 GiB 总内存 / 加 2 GiB swap
napcat ~240–290 MiB
astrbot ~260–340 MiB(随插件增加)swap 是必须的:不加的话,一次长上下文 + 多发消息就可能 OOM。
按「症状 → 原因 → 解法」整理,方便按图索骥。
| # | 症状 | 原因 | 解法 | |
|---|---|---|---|---|
| 1 | 所有 URL 抓取失败,报“非公网 IP” | 本地网络策略把域名解析到内网 | 用 Node https 直连绕过 | |
| 2 | curl: (35) schannel: SEC_E_NO_CREDENTIALS | 取不到系统 TLS 凭据 | 换 Node/OpenSSL 栈 | |
| 3 | docker pull 一直超时 | Docker Hub 不可达 | 配 registry-mirrors | |
| 4 | 重启 NapCat 后要重新扫码 | 只有扫码 token,没有密码兜底 | ACCOUNT + NAPCAT_QUICK_PASSWORD | |
| 5 | 被踢后容器一直卡在二维码 | worker 内部重启不走入口脚本,-q 丢失 | 看门狗 docker restart 容器 | |
| 6 | 日志无异常但群里不回 | 会话静默失效(假在线) | 需要主动健康检查(未彻底解决) | |
| 7 | 每 2 小时掉一次线 | 手机端同时登录互踢 | 手机端退出该账号 | |
| 8 | zip 解压后目录变成文件名 | Windows \ vs zip 规范 / | Python zipfile 写 POSIX 路径 | |
| 9 | Unexpected UTF-8 BOM | JSON 带 BOM(AstrBot 写的配置就是) | 读写都用 utf-8-sig | |
| 10 | NOT NULL constraint failed: personas.created_at | 表有非空列没给值 | INSERT 补齐 created_at/updated_at/sort_order | |
| 11 | 无效的嵌入向量维度: 0 | 适配器不自动探测维度 | 显式配 embedding_dimensions: 1024 | |
| 12 | 启动时刷 faiss.swigfaiss_avx512 报错 | faiss 探测可选加速模块 | 无害,忽略 | |
| 13 | 登录后台一直失败 | 默认密码被替换成随机强密码 | `docker logs | grep "Initial password"` |
| 14 | 市场接口解析出 0 个插件 | 返回的是 dict 不是 list | 按 dict 遍历 | |
| 15 | git clone 报 could not read Username | 其实是 404(仓库没了) | 换源或用 codeload 直下 zip | |
| 16 | 插件仓库 404 | 市场条目过期(作者删库/改名) | 用替代品(如下) | |
| 17 | 裸 @ 不回,且无任何日志 | empty_mention_waiting: false | 置 true,或在插件里自己处理 | |
| 18 | 偶发 IndexError: list index out of range | 空 wake_prefix 让 messages[0] 越界 | 已知副作用,事件本身无内容,可忽略 | |
| 19 | 两套概率插件互相打架 | 概率相乘(0.4 × 0.6 = 0.24) | 只保留一个概率决策方 | |
| 20 | 1.7 G 内存跑浏览器自动化 | Chromium 常驻 300–600 MB | 换 4 G 以上机器再考虑 |
关于 #16 的替代品(2026-11 实测):
| 原仓库 | 状态 | 替代 |
|---|---|---|
Zhalslar/astrbot_plugin_qqprofile | 404 | Akusative/astrbot_plugin_qqprofile_ex |
Zhalslar/astrbot_plugin_qzone | 404 | sujingyi1/astrbot_plugin_qzone |
| 插件 | 作用 | 自主行为 |
|---|---|---|
meme_manager | 表情包(100 张 / 7 分类) | 回复 35% 概率配图 |
group_chat_plus | 群聊读空气、打字模拟、错字 | 非 @ 消息按概率接话 |
livingmemory | 长期记忆(bge-m3 向量) | 每 10 轮总结 |
dafeiyu_clean | 过滤模型漏出的内部标签 | 无 |
dafeiyu_signature | 情绪触发改签名 | 2 次/天 |
qqprofile_ex | 改签名/状态/昵称 | 签名 240min、状态 60min 冷却;昵称已关 |
qzone | 发/看说说 | 全手动(cron 全空) |
reply_gate | 自建概率门(已停用) | — |
纯定时(没人说话也会跑):记忆衰减/备份、索引重建 —— 都在后台,用户无感。
对话中自主(有人说话时自己加戏):接话、配图、改签名、改状态、总结记忆。
完全被动(必须指令):私聊/群聊回复、发说说、看说说、改昵称。
# 服务
cd /opt/napcat-bot && docker compose ps
docker compose restart astrbot # 改配置后
docker compose restart napcat # 会走密码自动登录
# 日志
docker logs astrbot --since 10m 2>&1 | grep -Ei "error|ERRO"
docker logs napcat --since 10m 2>&1 | grep -E "接收|发送"
# 概率判定
docker logs astrbot --since 1h 2>&1 | grep "动态时间调整"
# 掉线排查
docker logs napcat --since 6h 2>&1 | grep -c KickedOffLine
journalctl -u napcat-watchdog --since -6h | tail
# 面板(都只绑本机)
ssh -L 6185:127.0.0.1:6185 root@<服务器IP> # AstrBot WebUI| 项目 | 状态 | 原因 |
|---|---|---|
| 语音输出(TTS) | 不做 | 明确不需要;四条语音链路都要额外 key 或显卡 |
| 唱歌插件 | 不做 | 语音衍生功能 |
| 定时发说说 | 不做 | 主动行为最容易被风控,手动触发足够 |
| 主动找人聊天 | 不做 | 同上;且会打扰人 |
| 抖音群聊 | 不做 | 无官方群机器人 API,只能浏览器自动化;1.7 G 跑 Chromium 会拖垮现有服务 |
| 微信个人号 | 暂不做 | 只能靠逆向/托管协议,封号风险比 QQ 高一档 |
| 后两个表情包(官方市场) | 未装 | 用 ai-biaoqingbao 的 100 张替代 |
reply_gate 判定 p=0.40 roll=0.65 → skip」是两件事。前者需要猜,后者只需要看。这次用到的全部仓库,按用途归类。注意:社区插件变动极快,链接随时可能 404,请以实际可达为准。
| 项目 | 链接 | 说明 |
|---|---|---|
| 大肥鱼配置包 | zexuanw958-svg/dafeiyu-config-pack | 人设 Markdown + 6 个配套插件清单 + 语音/记忆参数 + 一键导入脚本 |
这个包是整个项目里信息密度最高的一个,值得单独读一遍——它不只是给了一份人设,而是把「一个能跑的大肥鱼需要哪些部件」列成了清单。
| 项目 | 链接 | 说明 |
|---|---|---|
| 大肥鱼表情包 | diwer/ai-biaoqingbao | 100 张中文 GIF(240/512 两档),带 catalog.json 分类目录 |
仓库里还有 NOTICE.txt 写明了二创来源与使用边界(不提供商用授权),如果要商用请先看那份说明。
| 项目 | 链接 | 说明 |
|---|---|---|
| NapCat | NapNeko/NapCatQQ | QQ NT 协议端,输出 OneBot v11 |
| NapCat Docker | mlikiowa/napcat-docker | 本文使用的部署形态 |
| AstrBot | AstrBotDevs/AstrBot | 机器人框架(大脑) |
| DeepSeek Harness | deepseek-ai/deepseek-harness | 路线一的官方 Agent 运行时 |
| 插件 | 链接 | 用途 |
|---|---|---|
meme_manager | anka-afk/astrbot_plugin_meme_manager | 表情包管理 + 语境发送 |
group_chat_plus | Him666233/astrbot_plugin_group_chat_plus | 群聊读空气、打字拟态 |
livingmemory | lxfight/astrbot_plugin_livingmemory | 长期记忆(向量检索) |
qqprofile_ex | Akusative/astrbot_plugin_qqprofile_ex | 改签名/状态/昵称 |
qzone | sujingyi1/astrbot_plugin_qzone | QQ 空间说说 |
dsh-qqbot | tencent-connect/dsh-qqbot | 路线一的官方 QQ Bot 通道 |
| 仓库 | 状态 | 替代 |
|---|---|---|
Zhalslar/astrbot_plugin_qqprofile | 404 | Akusative/astrbot_plugin_qqprofile_ex |
Zhalslar/astrbot_plugin_qzone | 404 | sujingyi1/astrbot_plugin_qzone |
qqprofile_ex 是基于原版改的,多了「AI 自主改签名/状态/昵称 + 定时状态切换」,工具名换成 change_my_* 后反倒更不容易撞名。装完记得检查:它默认三个 auto_* 全开,其中改昵称建议关掉——群里突然换了名字,成员会一脸问号。
group_chat_plus 是 AGPL-3.0,二次分发有传染性要求。main.py 有没有可疑的 subprocess。NOTICE.txt 里写得很清楚,商用前务必确认。# /etc/systemd/system/napcat-watchdog.service
[Unit]
Description=NapCat offline watchdog
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/napcat-watchdog.sh# /etc/systemd/system/napcat-watchdog.timer
[Unit]
Description=Run NapCat watchdog every 2 minutes
[Timer]
OnBootSec=3min
OnUnitActiveSec=2min
Unit=napcat-watchdog.service
[Install]
WantedBy=timers.target@filter.event_message_type(filter.EventMessageType.GROUP_MESSAGE)
async def gate(self, event: AstrMessageEvent) -> None:
text = (event.message_str or "").strip()
if text.startswith("/"):
return
# @ / 引用 必回
for seg in event.get_messages():
if isinstance(seg, Comp.At) and str(seg.qq) == str(event.get_self_id()):
return
prob = 0.4 if is_peak(datetime.now()) else 0.6
if random.random() >= prob:
event.stop_event() # 关键:真正阻止模型调用event.stop_event() 有效的原因:管道调度器在阶段之间检查 is_stopped(),命中就 break,
所以模型根本不会被调用——省的是真金白银。
chmod 600 /opt/napcat-bot/docker-compose.yml # 含小号密码
chmod 600 /path/to/astrbot/data/cmd_config.json # 含所有 API Key
chmod 600 /path/to/astrbot/data/plugin_data/*/config.json(全文完。如果这篇对你有用,欢迎在评论区交流;有踩到别的坑也欢迎补充。)