1. 为什么 QQ 机器人要拆成 AstrBot 和 NapCat 两层
很多人第一次做 QQ 机器人,脑子里想的是「找个框架,填个 API Key,机器人就能聊天」。真动手才发现,卡住的地方根本不是模型,而是 QQ 账号怎么登录、消息怎么从 QQ 客户端交到你的程序里。这两件事如果混在一个进程里做,出问题的时候你根本不知道是登录掉了、协议变了,还是模型超时。
AstrBot 加 NapCat 这套组合,核心思路就是把职责切开。NapCat 是一个基于 NTQQ 的 OneBot v11 协议端,它负责登录 QQ 账号,把收到的私聊、群聊消息通过 HTTP 或 WebSocket 暴露出来,同时提供发送消息的接口。AstrBot 则是一个面向大模型的聊天机器人框架,它负责接收 OneBot 事件、管理模型提供商、维护人格设定、加载插件和 MCP 服务,最后把回复内容交回给协议端发送。
你可以这样理解:NapCat 是「耳朵和嘴」,负责听 QQ 消息、把回复说出去;AstrBot 是「大脑」,负责理解消息、调用模型、决定怎么回。两者之间用 OneBot v11 标准协议通信,所以理论上 NapCat 可以换成其他 OneBot 实现,AstrBot 也可以换成别的框架,耦合度很低。
这种拆分带来的最大好处是排障路径清晰。QQ 登录失败,只看 NapCat 的日志和扫码状态;AstrBot 收不到消息,检查 OneBot 反向 WS 或 HTTP 上报地址是否配对;模型不回复,去 AstrBot 的模型提供商页面点测试;人格、插件、MCP 不生效,那一定是 AstrBot 内部配置的问题,跟 QQ 登录无关。每一层都有独立的验证手段,不会出现「几个服务同时怀疑」的混乱。
本文要跑的完整链路是:Docker 拉起 AstrBot 和 NapCat 两个容器,NapCat 扫码登录 QQ,AstrBot 创建 QQ 个人号机器人并连上 NapCat,接入 DeepSeek 模型完成一次真实对话回环,然后演示人格切换、插件安装和 MCP 扩展点,最后把模型 endpoint 改到 TaoToken 统一通道,验证多模型切换的可行性。适合已经会一点 Docker、想让 QQ 机器人真正跑起来、并且希望后续能扩展 MCP 工具调用的开发者。
2. 前置准备:Docker 环境与 TaoToken 统一模型通道
在开始配置之前,先把运行环境和模型接入这两件事准备好。环境这块,我实测下来 Windows 11 加 Docker Desktop 是最省事的组合,Linux 服务器也可以,命令略有不同。模型这块,如果你只用 DeepSeek 官方 API,可以跳过 TaoToken 部分;但如果你想让机器人后续能灵活切换 Claude、GPT 等模型,建议一开始就把 endpoint 指向统一通道,省得以后改配置。
2.1 Docker 环境检查
Windows 11 上先确认 Docker Desktop 已经启动,右下角托盘图标是绿色运行状态。然后按 Win + R 输入 powershell 打开 PowerShell,执行:
docker version
docker compose version
两条命令都能输出版本信息,说明 Docker 和 Compose 都就绪。如果 docker compose 报错,可能是 Docker Desktop 版本太旧,升级到最新版即可。Linux 环境下用 sudo docker version 和 sudo docker compose version 检查,没装的话先按官方文档装好 Docker Engine 和 Compose 插件。
2.2 获取 TaoToken API Key
TaoToken 是一个大模型统一接入通道,把 DeepSeek、Claude、GPT 等模型的 API 格式统一成 OpenAI 兼容接口。对 AstrBot 来说,这意味着你只需要配一个 Base URL 和一个 Key,就能在多个模型之间切换,不用为每个厂商单独改代码。
先访问官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册账号,然后进入控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 创建 API Key。Key 只在创建时显示一次,复制后先存到安全的地方。
拿到 Key 之后,记下两个关键信息:Base URL 是 https://taotoken.net/api,Model ID 根据你要用的模型填,比如 DeepSeek 系列可以填 deepseek-chat 或 deepseek-reasoner。这两个值后面在 AstrBot 的模型提供商配置里会用到。
如果你只想用 DeepSeek 官方 API,那就去 https://platform.deepseek.com 创建 Key,Base URL 填 https://api.deepseek.com,Model ID 填 deepseek-chat。两种方式在 AstrBot 里的配置步骤几乎一样,区别只是 Base URL 和 Key 不同。
2.3 目录规划
建议在磁盘上单独建一个目录放这套服务,比如 D:\astrbot-qq。所有配置文件、数据卷都放这里面,以后备份和迁移都方便。Linux 下对应 ~/astrbot-qq。目录建好后,后面的 compose 文件和配置都基于这个路径来写。
3. 可复制配置:Docker Compose 拉起 AstrBot 与 NapCat
这一节给出完整的 compose 配置和 AstrBot 的模型提供商配置片段,你可以直接复制修改。配置的核心是把两个容器的端口、数据卷和网络关系写清楚,让 NapCat 的 OneBot 接口能被 AstrBot 访问到。
3.1 Docker Compose 文件
在 D:\astrbot-qq 目录下新建 docker-compose.yml,内容如下:
services:
napcat:
image: mlikiowa/napcat-docker:latest
container_name: napcat
restart: unless-stopped
environment:
- NAPCAT_UID=1000
- NAPCAT_GID=1000
ports:
- "6099:6099"
- "3000:3000"
- "3001:3001"
volumes:
- ./napcat/config:/app/napcat/config
- ./napcat/data:/app/.config/QQ
networks:
- astrbot-net
astrbot:
image: soulter/astrbot:latest
container_name: astrbot
restart: unless-stopped
ports:
- "6185:6185"
- "6199:6199"
volumes:
- ./astrbot/data:/AstrBot/data
- ./astrbot/config:/AstrBot/config
environment:
- TZ=Asia/Shanghai
networks:
- astrbot-net
networks:
astrbot-net:
driver: bridge
几个关键点说明一下。NapCat 的 6099 是 WebUI 管理端口,3000 和 3001 分别是 HTTP 和 WebSocket 的 OneBot 接口端口,AstrBot 通过容器网络访问这两个端口。AstrBot 的 6185 是 WebUI 管理端口,6199 是它对外暴露的 OneBot 反向接口端口。两个容器放在同一个 bridge 网络 astrbot-net 里,这样 AstrBot 可以用容器名 napcat 直接访问 NapCat,不用管宿主机 IP。
数据卷方面,NapCat 的配置和 QQ 登录数据分别挂到 ./napcat/config 和 ./napcat/data,AstrBot 的数据和配置挂到 ./astrbot/data 和 ./astrbot/config。这样容器重建不会丢登录状态和配置。
3.2 启动容器
在 D:\astrbot-qq 目录下打开 PowerShell,执行:
docker compose up -d
第一次会拉取镜像,耐心等几分钟。启动完成后用 docker compose ps 确认两个容器都是 Up 状态。然后浏览器访问 http://localhost:6185 和 http://localhost:6099,两个页面都能打开,说明部署这一层没问题。
如果 6185 打不开,先看 AstrBot 容器日志:
docker logs astrbot --tail 50
常见原因是端口被占用,改 compose 里的宿主机端口映射即可。6099 打不开同理,看 docker logs napcat --tail 50。
3.3 AstrBot 模型提供商配置片段
AstrBot 的模型提供商配置存在 ./astrbot/data/cmd_config.json 里,但更推荐在 WebUI 里改,避免手写出错。如果你要直接改配置文件,模型提供商部分的结构大致如下:
{
"provider": [
{
"id": "taotoken-deepseek",
"type": "openai_chat_completion",
"provider": "openai",
"key": ["sk-你的TaoToken密钥"],
"api_base": "https://taotoken.net/api",
"model": "deepseek-chat",
"timeout": 120
}
]
}
注意 api_base 填 https://taotoken.net/api,不要带末尾斜杠。model 字段填你要用的模型 ID,比如 deepseek-chat。key 是一个数组,可以放多个 Key 做轮询。type 用 openai_chat_completion,因为 TaoToken 兼容 OpenAI 的 chat completions 接口。
如果你用 DeepSeek 官方 API,把 api_base 改成 https://api.deepseek.com,key 换成 DeepSeek 的 Key,model 保持 deepseek-chat 即可。
4. 验证请求:从 QQ 消息到模型回复的完整回环
配置写完,接下来要一步步验证链路。顺序很重要:先确认 NapCat 登录 QQ,再确认 AstrBot 收到消息,最后确认模型能回复。每一步都有明确的成功标志,不要跳步。
4.1 NapCat 登录 QQ
浏览器打开 http://localhost:6099,第一次进入需要 Token。Token 在容器日志里,执行:
docker logs napcat 2>&1 | Select-String "Token"
复制输出的 Token 填进 WebUI 登录。登录后进入「网络配置」,确认 OneBot 11 的 WebSocket 服务已启用,端口是 3001,路径默认 /。然后回到首页,用准备做机器人的 QQ 账号扫码登录。扫码成功后,NapCat 首页会显示账号在线状态。
这一步的成功标志是:NapCat 显示 QQ 在线,且 WebSocket 服务处于监听状态。如果扫码后一直转圈,检查手机 QQ 是否确认登录,或者换个网络环境重试。
4.2 AstrBot 创建 QQ 个人号机器人
浏览器打开 http://localhost:6185,初始用户名和密码都是 astrbot。第一次登录会提示改密码,改完重新登录。
进入「机器人」页面,点击「创建机器人」,消息类别选「QQ个人号」,然后配置 OneBot 连接。关键参数如下:
- 连接方式:反向 WebSocket
- 主机:
0.0.0.0 - 端口:
6199 - Token:留空或自定义(需与 NapCat 侧一致)
保存并启用后,AstrBot 会监听 6199 端口等待 NapCat 连接。但这里有个方向问题:AstrBot 作为反向 WS 服务端,NapCat 作为客户端主动连过来。所以还需要在 NapCat 的 WebUI 里添加一个反向 WebSocket 客户端,指向 AstrBot 的地址。
在 NapCat WebUI 的「网络配置」里新增一个 WebSocket 客户端:
- URL:
ws://astrbot:6199/ws - 启用:是
注意这里的 astrbot 是容器名,因为两个容器在同一 Docker 网络里,可以直接用容器名解析。如果你没把两个容器放同一网络,这里要填宿主机的局域网 IP。
保存后,AstrBot 的机器人页面应该显示「已连接」。如果没连上,看 AstrBot 日志里有没有 WebSocket 连接记录。
4.3 验证消息链路
用另一个 QQ 账号给机器人账号发一条消息,比如「你好」。然后看 AstrBot 的「平台日志」页面,如果能看到这条消息的事件记录,说明 QQ → NapCat → AstrBot 这一段通了。
这一步的成功标志是:AstrBot 日志里出现收到的消息内容。如果日志没动静,检查 NapCat 的反向 WS 客户端是否真的连上了 AstrBot,以及 AstrBot 的机器人是否处于启用状态。
4.4 配置模型并测试回复
消息链路通了之后,进入 AstrBot 的「模型提供商」页面,点击「新增模型提供商」。如果你用 TaoToken,选择「OpenAI 兼容」类型,填入:
- API Base:
https://taotoken.net/api - API Key:你的 TaoToken Key
- Model:
deepseek-chat
保存后点击「测试」,如果返回模型回复内容,说明模型通道正常。然后回到 QQ,再给机器人发一条消息,这次应该能收到 AI 回复。
完整的回环是:QQ 消息 → NapCat → AstrBot → TaoToken/DeepSeek → AstrBot → NapCat → QQ 回复。任何一环断了,回复都不会出现。实测下来,最常见的断点是 NapCat 的反向 WS 没连上 AstrBot,或者模型 Key 填错导致测试失败。
4.5 一条验证指令
在 QQ 里给机器人发送:
/persona list
如果机器人返回人格列表,说明 AstrBot 的命令系统正常工作,消息回环完全打通。这个指令不依赖模型,纯粹验证 AstrBot 内部逻辑,适合作为链路验证的最后一环。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
配置过程中最容易遇到的几个报错,这里逐个给出原因和排查方法。这些报错我在不同环境里都踩过,按下面的顺序查基本能定位。
5.1 401 Unauthorized
模型测试时返回 401,说明 API Key 无效或没被正确读取。先检查 AstrBot 模型提供商里的 Key 是否完整复制,有没有多余空格。如果用 TaoToken,确认 Key 是在控制台创建的,且账户有余额。如果用 DeepSeek 官方,确认 Key 没有过期。
还有一种情况是 Base URL 填错。TaoToken 的 Base URL 是 https://taotoken.net/api,DeepSeek 官方是 https://api.deepseek.com。填成带 /v1 的路径有时也能用,但 AstrBot 的 OpenAI 兼容类型会自动拼接 /v1/chat/completions,所以 Base URL 不要带 /v1,否则会变成 /v1/v1/chat/completions 导致 404 或 401。
5.2 local proxy failed
这个报错通常出现在 AstrBot 尝试访问模型接口时,网络层被拦截或 DNS 解析失败。如果你在容器里跑 AstrBot,先确认容器能访问外网:
docker exec -it astrbot curl -I https://taotoken.net/api
如果这条命令超时,说明容器网络有问题,检查 Docker 的 DNS 设置或宿主机的网络策略。如果宿主机本身需要特定网络配置才能访问外网,容器也要做对应配置。
5.3 reading choices 相关报错
这个报错一般出现在模型返回的 JSON 结构不符合预期时。AstrBot 期望的是 OpenAI 格式的 choices[0].message.content,如果模型返回了别的结构,就会报读取 choices 失败。用 TaoToken 统一通道时,因为接口是 OpenAI 兼容的,正常不会出现这个问题。如果出现,先确认模型 ID 填对了,比如 deepseek-chat 而不是 deepseek。另外检查 type 是否选成了 openai_chat_completion,选错类型会导致解析失败。
5.4 OAuth 相关报错
如果你在 AstrBot 里配置了需要 OAuth 的模型提供商(比如某些 Claude 接入方式),可能会遇到 OAuth 回调失败。这类报错通常和回调地址、客户端 ID 有关。排查方法是确认 OAuth 应用里配置的回调 URL 和 AstrBot 实际使用的地址一致。如果用的是 TaoToken 统一通道,因为走的是 API Key 认证,不涉及 OAuth,可以直接绕过这类问题。
5.5 NapCat 连不上 AstrBot
如果 AstrBot 机器人页面一直显示未连接,先确认 NapCat 的反向 WS 客户端 URL 是否正确。容器网络里用 ws://astrbot:6199/ws,宿主机网络里用 ws://127.0.0.1:6199/ws。然后看 AstrBot 日志有没有 WebSocket 握手记录。如果 NapCat 日志报连接被拒绝,说明 AstrBot 的 6199 端口没监听,检查机器人是否启用。
5.6 配置三件套对照
无论用哪种接入方式,模型配置的核心都是三件套:Base URL、API Key、Model ID。用 TaoToken 时:
- Base URL:
https://taotoken.net/api - API Key:控制台创建的 Key
- Model ID:
deepseek-chat或deepseek-reasoner
用 DeepSeek 官方时:
- Base URL:
https://api.deepseek.com - API Key:DeepSeek 平台创建的 Key
- Model ID:
deepseek-chat
这三个值任何一个填错,都会导致模型测试失败。建议在 AstrBot 里保存后先点测试,通过了再去 QQ 里发消息。
6. 扩展点:人格、插件与 MCP 的接入方式
链路跑通之后,机器人能回复了,但默认回复比较像标准助手。这一节讲怎么通过人格、插件和 MCP 让机器人变得更有用。这三者的定位不同:人格改变说话风格,插件增加具体功能,MCP 让模型能调用外部工具。
6.1 人格设定与切换
AstrBot 的人格设定在「更多功能 → 人格设定」里。新建一个人格,填人格 ID 和系统提示词。比如你想让机器人用轻松的语气聊天,系统提示词可以写「你是一个说话轻松、喜欢用短句的朋友,回答不超过三句话」。
创建后在 QQ 里用命令切换:
/persona 你的人格ID
切换后发消息测试,回复风格应该会变。如果上下文里还有旧人格的对话,执行 /reset 清空上下文,避免风格串扰。查看当前可用人格列表用 /persona list。
6.2 插件安装与点歌测试
AstrBot 的插件市场在「插件」页面。搜索「音乐」或「点歌」,找到点歌插件后点击安装。安装时如果拉取 GitHub 慢,可以选加速节点。安装完成后,插件页面会显示使用说明。
回到 QQ 发送:
/点歌 恋人
如果机器人返回歌曲卡片,说明插件生效。插件的本质是给 AstrBot 增加一个封装好的功能模块,它不依赖模型,纯粹是命令触发的逻辑。所以插件适合做确定性强的功能,比如点歌、查天气、签到。
6.3 MCP 服务接入:以 12306 为例
MCP 和插件的区别在于,MCP 是把外部工具以标准化方式暴露给模型调用,模型可以自己决定什么时候用哪个工具。AstrBot 的 MCP 配置在「MCP」页面。
点击「同步服务器」会跳转到 ModelScope 的 MCP 市场,找到 12306-mcp,复制它的配置:
{
"mcpServers": {
"12306-mcp": {
"command": "npx",
"args": ["-y", "12306-mcp"]
}
}
}
回到 AstrBot,点击「新增服务器」,粘贴配置,先测试再保存。测试通过后,在 QQ 里直接问「明天北京到上海的高铁」,模型会调用 12306-mcp 查询并返回车次信息。
这一步验证的是 AstrBot → MCP → 12306-mcp → 返回结果 的链路。MCP 的价值在于让模型能动态调用外部服务,而不是把所有功能都写死在插件里。
6.4 把模型 endpoint 改到 TaoToken 统一通道
如果你一开始用的是 DeepSeek 官方 API,现在想换成 TaoToken 统一通道,只需要在 AstrBot 的模型提供商里改两个字段:API Base 改成 https://taotoken.net/api,API Key 换成 TaoToken 的 Key。Model ID 可以保持不变,也可以换成其他模型,比如 claude-3-5-sonnet 或 gpt-4o。
改完后点测试,通过后回 QQ 发消息验证。这样你就有了一个可以在多个模型之间切换的机器人,后续想换模型不用改代码,只改配置即可。对于需要长期跑、可能换模型的场景,这种统一通道的方式省事很多。
如果你打算长期跑编码类或 Agent 类任务,可以了解下 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它针对高频调用场景做了优化。模型对话调试可以用 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite ,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,API Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。
整套跑下来,我的经验是:先把 QQ 消息链路和模型回复验证通,再去折腾人格、插件和 MCP。顺序反了的话,出问题要同时排查好几个层,很容易卡住。另外 NapCat 的登录状态偶尔会掉,如果机器人突然不回复了,先去 NapCat 看 QQ 是否还在线,这一步能省很多时间。



被折叠的 条评论
为什么被折叠?



