1. openclaw 接入 qq 时,pnpm workspace 到底卡在哪
openclaw 是一个把多渠道消息接入统一处理的开源框架,qq 是它支持的通道之一,适合在本地多包仓库里做机器人调试。你如果正在用 pnpm workspace 管理 openclaw 的多个子包,大概率会遇到这样一幕:装@openclaw/channel-qqbot的时候终端直接甩出ERR_PNPM_ADDING_TO_ROOT,或者装完了通道却起不来,日志里全是模块找不到。这两个现象看着像一回事,其实是两类问题——一个是 pnpm 的工作区保护机制在拦你,另一个是接入配置没对齐。
我试过在根目录直接pnpm add,结果被 pnpm 挡回来,当时以为是网络问题,折腾半天才发现是 workspace 结构在起作用。pnpm 不允许你随手往根目录塞依赖,因为根package.json是工作区的锚点,乱加依赖会破坏子包之间的链接关系。所以排查的第一步,是先分清你面对的是「依赖装不进去」还是「装进去了但通道连不上」。前者是 workspace 链接问题,后者多半是 config.toml 或 settings.json 里的接入参数没写对。
这篇就按这个思路走:先给你一份可复制的 workspace 级配置骨架,再给 TaoToken 统一 Key 的接入片段,然后一步步验证依赖安装、通道连通、报错日志定位。目标很明确——让你能自己判断,到底是 pnpm 的锅还是配置的锅。
2. 前置准备:TaoToken 统一 Key 与 openclaw 环境
在动配置之前,先把 Key 和环境理顺。openclaw 接入 qq 通道时,模型调用这一层可以走 TaoToken 的统一入口,这样你多个子包共用一套 Key,不用在每个包里重复填。TaoToken 的官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api ,注意 API 地址不带 UTM 参数,配置里填这个就行。
你需要先拿到 Key。登录后进控制台,在 API Keys 页面创建一个,复制出来备用。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,API Keys 页面是 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。如果你后面要长期跑编码类或 Agent 类任务,可以看下 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它更适合高频调用场景。
环境这边,确认三件事:Node 版本建议 18 以上,pnpm 版本 8 以上(pnpm -v看一眼),openclaw 仓库已经 clone 到本地并且是 workspace 结构。所谓 workspace 结构,就是根目录有个pnpm-workspace.yaml,里面用packages:列出了所有子包路径。你可以先cat pnpm-workspace.yaml确认一下,如果这个文件不存在,那你的仓库根本不是 workspace,后面的-w报错也就不会出现,问题方向要换。
注意:TaoToken 是模型调用的统一接入层,不是用来替代编辑器或本地运行时的。openclaw 本身的依赖安装、通道逻辑还是走 pnpm 和 Node,两者别混。
3. 可复制的 workspace 级配置骨架
这一节给你两份骨架:一份是 pnpm workspace 层面的依赖处理方式,一份是 openclaw 接入 qq 通道的 config.toml 和 settings.json。先解决依赖装不进去的问题。
3.1 依赖安装:-w 与 --filter 怎么选
ERR_PNPM_ADDING_TO_ROOT的根因是你在 workspace 根目录执行了pnpm add,而 pnpm 默认不允许往根加依赖。两种正规解法:
如果你确实要把 qq 通道依赖加到根(比如根包负责统一启动),显式加-w:
pnpm add @openclaw/channel-qqbot -w完整写法等价:
pnpm add @openclaw/channel-qqbot --workspace-root更规范的做法是加到具体子包,用--filter指定包名。假设你的核心包叫openclaw-core:
pnpm add @openclaw/channel-qqbot --filter openclaw-core子包名从各子包package.json的name字段拿。你可以先pnpm ls -r --depth -1列出所有包名,确认要装到哪个。
至于pnpm config set ignore-workspace-root-check true,这个只建议临时调试用,它会永久关掉根目录检查,之后你误操作往根塞依赖也不报错,工作区结构容易乱。排查完记得改回来:pnpm config set ignore-workspace-root-check false。
3.2 config.toml 骨架
openclaw 的通道配置一般放在根目录或子包的config.toml。下面这份是 qq 通道加 TaoToken 接入的最小骨架,字段名按你实际版本微调:
[channel.qq] enabled = true # qq 机器人相关凭证,按官方申请结果填 app_id = "你的_app_id" token = "你的_qq_token" # 消息接收模式,本地调试常用 websocket mode = "websocket" [model] # 统一走 TaoToken 入口 provider = "taotoken" base_url = "https://taotoken.net/api" api_key = "你的_TaoToken_Key" model = "claude-3-5-sonnet" [log] level = "debug"base_url填https://taotoken.net/api,不要带 UTM 后缀。api_key就是前面在 API Keys 页面拿到的那个。
3.3 settings.json 骨架
有些 openclaw 版本用settings.json管理运行时参数,和 config.toml 分工不同。下面这份对应 workspace 根级:
{ "workspace": { "rootCheck": true, "linkMode": "isolated" }, "channel": { "qq": { "enabled": true, "reconnect": true, "reconnectInterval": 5000 } }, "model": { "provider": "taotoken", "baseUrl": "https://taotoken.net/api", "apiKey": "你的_TaoToken_Key" } }linkMode设isolated是 pnpm 的默认链接策略,子包依赖各自隔离,避免版本串味。如果你之前手动改过hoist相关配置,先还原成默认再排查。
4. 逐步验证:依赖、通道、日志三步走
配置写完别急着启动,按顺序验证,每步都有明确的成功信号。
4.1 依赖安装验证
先装依赖,观察输出:
pnpm install成功的话最后会显示Done in Xs,没有ERR_PNPM_开头的报错。如果还有ERR_PNPM_ADDING_TO_ROOT,说明你某条 add 命令没带-w或--filter,回去补上。装完确认 qq 通道包在不在:
pnpm ls @openclaw/channel-qqbot -r能列出包名和版本就说明依赖链接正常。这一步过了,workspace 链接问题基本排除。
4.2 通道连通验证
启动 openclaw,把日志级别开到 debug:
pnpm --filter openclaw-core start看日志里有没有channel qq connected或类似的连接成功字样。如果卡在连接阶段,重点看两处:qq 的app_id/token是否正确,以及mode是否和你的机器人配置匹配。本地调试用 websocket 模式时,确认没有别的进程占用同一连接。
4.3 模型调用验证
通道连上后,发一条测试消息触发模型调用。如果日志里出现 401 或 403,多半是 TaoToken Key 没填对或过期,回 API Keys 页面重新生成一个。如果出现连接超时,检查base_url是不是写成了带 UTM 的地址,正确写法是https://taotoken.net/api。想单独验证模型通不通,可以用模型对话页面发一条测试:https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite ,那边能直接看到返回,省得在 openclaw 里绕。
三步都过了,说明依赖、通道、模型调用全链路正常。哪一步卡住,问题就锁定在哪一层。
5. 本篇常见报错排查
把几个高频报错和对应动作列一下,方便你对号入座。
ERR_PNPM_ADDING_TO_ROOT:根目录执行 add 没带-w。加-w或改用--filter装到子包。
Cannot find module '@openclaw/channel-qqbot':依赖没装成功,或者装到了错误的子包。用pnpm ls -r确认包在哪个位置,再检查启动命令的--filter是否指向了正确的包。
401 Unauthorized/403 Forbidden:TaoToken Key 错误或过期。去 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 重新生成,更新 config.toml 和 settings.json 里的api_key。
ECONNREFUSED或连接超时:base_url写错,或者本地网络到 API 入口不通。确认填的是https://taotoken.net/api,不带多余参数。
qq 通道反复重连:app_id/token不匹配,或mode选错。对照 qq 机器人后台的配置逐项核对。
workspace 内子包版本冲突:linkMode被改过,或者某个子包手动装了不同版本的同一依赖。还原linkMode为isolated,然后pnpm install重装。
提示:排查时把日志级别设成 debug,报错定位会快很多。生产环境记得调回 info,不然日志量太大。
6. 后续接入与长期使用建议
依赖和配置跑通之后,如果你打算长期在 openclaw 里跑编码类或 Agent 类任务,可以了解下 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它针对高频调用场景做了优化。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有各语言的调用示例,遇到参数不确定的时候翻一下比猜快。如果你用的是 Claude Code 这类工具链,Anthropic 兼容接入的说明在 https://taotoken.net/claudecode-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claudecode-anthropic&utm_campaign=rewrite ,配置方式和 openclaw 里的base_url思路一致。
最后说个实际经验:workspace 里改配置后,别只重启单个子包,最好在根目录pnpm install一次再启动,让链接关系重新建立。很多「改了没生效」的情况,其实是 pnpm 的软链接还指向旧路径。