ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从 1 到 2:让 OpenClaw Agent 接管 QQ 的硬核指南(TaoToken 统一 Key 版)

从 1 到 2:让 OpenClaw Agent 接管 QQ 的硬核指南(TaoToken 统一 Key 版) 1. 从单机 Agent 到 QQ 多账号为什么我要折腾这套架构如果你已经在一台机器上跑通了 OpenClaw Agent用 Telegram 或命令行跟它聊得挺顺那下一步大概率会冒出同一个念头能不能让它接管 QQ毕竟国内开发者的日常沟通、群协作、通知触达QQ 的覆盖面比 Telegram 广得多。我最初的想法很简单——既然 OpenClaw 已经能通过命令行调用大模型、维护长期记忆、挂载本地工具链那只要把 QQ 的消息接进来、把回复发出去不就完事了真正动手才发现从 1 到 2 的跨度不在模型能力而在消息链路。单机 Agent 的输入输出是终端你敲一句它回一句进程生命周期清晰。但 QQ 是一个持续在线的长连接场景消息随时可能来Agent 必须常驻监听还要处理登录态、断线重连、多账号隔离。更麻烦的是如果你图省事直接写个 Python 脚本调大模型 API那 QQ 端的 Agent 就变成了一个失忆的复读机——它没有 OpenClaw 的上下文记忆没有系统人设没有你辛苦配好的本地工具链跟 Telegram 端完全是两个灵魂。所以这套架构的核心目标只有一个让 QQ 端复用 OpenClaw 的原生 Agent 内核而不是另起炉灶直连 API。具体拆成三层宿主机 Docker 网络负责隔离与互通NapCatQQ 容器模拟 QQ 登录并通过 OneBot v11 协议暴露 WebSocketOpenClaw Kernel 容器运行 Agent 大脑内部挂一个 Python 桥接脚本作为耳朵和嘴巴。桥接脚本收到 QQ 消息后不调 API而是通过asyncio.create_subprocess_exec召唤底层openclaw agent命令把回复原路发回 QQ。这套方案适合谁适合已经跑通单机 OpenClaw、想扩展到多账号或多场景的开发者。你不需要重新理解大模型只需要把消息管道接对。下面我会把 Docker Compose 配置、WebSocket 连接参数、TaoToken 统一 Key 的接入方式以及消息收发链路的分步验证动作全部给出来最后附一份连接失败排查清单。你照着做能少踩我踩过的坑。2. TaoToken 统一 Key 前置让 OpenClaw 的模型调用不再散落各处在讲 Docker 和 WebSocket 之前得先把模型调用的入口统一掉。原因很现实OpenClaw Agent 内部会调用大模型QQ 桥接脚本又会触发 Agent如果你在每个环节都塞一个不同的 API Key后面排查问题时根本分不清是哪一层出的错。我试过把 Key 写死在桥接脚本里结果 Agent 报 401 的时候我花了半小时才确认是脚本里的 Key 过期而不是 OpenClaw 内核的问题。TaoToken 在这里的角色是统一网关。你只需要在 OpenClaw 的配置里指向它的 API 地址用同一个 Key 覆盖所有模型调用。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数配置里直接写这个就行。具体到 OpenClaw 的配置通常涉及三个要素Base URL、API Key、Model ID。以常见的settings.json或环境变量方式为例你需要确保 Agent 内核和桥接脚本读的是同一份配置。我建议把 Key 放在宿主机的环境变量文件里Docker Compose 通过env_file注入这样容器重启也不会丢。# 宿主机 /root/openclaw/.env TAOTOKEN_API_KEYsk-你的统一Key TAOTOKEN_BASE_URLhttps://taotoken.net/api OPENCLAW_MODELclaude-sonnet-4-20250514然后在 OpenClaw 的配置文件里引用这些变量。如果你用的是settings.json形式大致长这样{ model: { provider: openai-compatible, baseUrl: https://taotoken.net/api, apiKey: ${TAOTOKEN_API_KEY}, modelId: claude-sonnet-4-20250514 }, agent: { memory: true, persona: default } }这里有个细节OpenClaw 的 Agent 命令在调用时会读取这份配置而桥接脚本通过openclaw agent子进程触发时继承的是容器内的环境变量。所以你要保证docker exec进去之后echo $TAOTOKEN_API_KEY能打印出值。如果打印为空说明env_file没生效后面 Agent 一定会报鉴权错误。统一 Key 的好处在这里就体现出来了QQ 端和 Telegram 端共用同一个模型入口记忆和人格自然一致。你不需要在桥接脚本里再写一遍 API 调用逻辑桥接脚本只负责传话模型的事交给 OpenClaw 内核。这样职责清晰出问题也好定位——如果是模型返回异常查 TaoToken 的调用日志如果是消息没发出去查 WebSocket 链路。另外提醒一句TaoToken 的 API Key 管理页面在 https://taotoken.net/api-keys 你可以在这里生成和轮换 Key。如果你后面要扩展到多账号每个 QQ 小号对应一个 OpenClaw 实例但它们可以共用同一个 TaoToken Key计费和额度统一管理不用每个实例单独配。3. 可复制配置Docker Compose 与 WebSocket 连接参数这一节是整篇的核心我会把 Docker Compose 文件、NapCat 的 WebSocket 配置、以及桥接脚本的关键参数全部给出来。你直接复制改改就能用。先看目录结构我习惯这样组织/root/openclaw-qq/ ├── docker-compose.yml ├── .env ├── napcat/ │ └── config/ └── openclaw/ ├── settings.json └── qq_ears_brain.pydocker-compose.yml的内容如下。注意网络部分我建了一个自定义 bridge 网络让两个容器能通过服务名互相访问同时跟宿主机隔离version: 3.8 services: napcat: image: mlikiowa/napcat-docker:latest container_name: napcat_core restart: unless-stopped environment: - NAPCAT_UID1000 - NAPCAT_GID1000 ports: - 3001:3001 - 6099:6099 volumes: - ./napcat/config:/app/napcat/config - ./napcat/data:/app/napcat/data networks: - openclaw_net openclaw: image: openclaw/kernel:latest container_name: openclaw_kernel restart: unless-stopped env_file: - .env volumes: - ./openclaw/settings.json:/home/node/.openclaw/settings.json - ./openclaw/qq_ears_brain.py:/home/node/qq_ears_brain.py depends_on: - napcat networks: - openclaw_net networks: openclaw_net: driver: bridge这里有几个关键点。NapCat 暴露了 3001 端口作为 WebSocket 服务6099 是它的 WebUI 管理端口。OpenClaw 容器通过env_file读取.env里的 TaoToken Key。两个容器在同一个openclaw_net网络里所以桥接脚本里连接 NapCat 的 WebSocket 地址应该用服务名napcat而不是127.0.0.1。NapCat 的 WebSocket 配置在./napcat/config/下通常是一个onebot11_QQ号.json文件。核心参数如下{ http: { enable: false, port: 3000 }, ws: { enable: true, host: 0.0.0.0, port: 3001 }, reverseWs: { enable: false }, token: }host写0.0.0.0是为了让容器内的服务能被同网络的 OpenClaw 容器访问。token留空表示不鉴权如果你在公网环境建议设一个 token 并在桥接脚本里带上。reverseWs是反向 WebSocket我们这里用正向连接所以关掉。桥接脚本qq_ears_brain.py的核心逻辑我按 excerpt 里的框架整理成可运行版本。注意WS_URL用的是服务名napcat端口 3001import asyncio import websockets import json WS_URL ws://napcat:3001 TARGET_QQ 你的大号QQ号 async def call_openclaw_agent(user_message: str) - str: try: process await asyncio.create_subprocess_exec( openclaw, --no-color, agent, --to, TARGET_QQ, --message, user_message, stdoutasyncio.subprocess.PIPE, stderrasyncio.subprocess.PIPE ) stdout, stderr await process.communicate() if process.returncode 0: return stdout.decode(utf-8).strip() else: return f中枢异常: {stderr.decode(utf-8).strip()} except Exception as e: return f桥接 OpenClaw 核心失败{str(e)} async def main(): async with websockets.connect(WS_URL, ping_interval20) as ws: print(赛博触手已连接等待指令...) while True: msg await ws.recv() data json.loads(msg) if data.get(post_type) message and str(data.get(user_id)) TARGET_QQ: user_msg data.get(raw_message, ).strip() reply_text await call_openclaw_agent(user_msg) await ws.send(json.dumps({ action: send_private_msg, params: {user_id: int(TARGET_QQ), message: reply_text} })) if __name__ __main__: asyncio.run(main())注意openclaw命令的参数顺序--no-color必须紧跟在openclaw后面、agent子命令之前。这是 Linux 命令行的位置法则写错了会报unknown option --no-color。这个坑我在下一节会详细说。4. 验证请求与成功结果分步确认消息收发链路配置写完之后不要急着一次性启动所有东西。我建议按先 NapCat、再 OpenClaw、最后桥接脚本的顺序分步验证每步都有明确的成功标志这样出问题能立刻定位到哪一层。第一步启动 NapCat 并确认 WebSocket 监听。执行docker compose up -d napcat然后看日志docker logs --tail 50 -f napcat_core如果配置正确你会看到 NapCat 启动后打印出 WebSocket 服务监听在0.0.0.0:3001。如果没看到检查onebot11_QQ号.json里的ws.enable是不是true。这一步的成功标志是日志里出现类似WebSocket server started on port 3001的字样。第二步扫码登录 QQ 小号。NapCat 首次启动会输出二维码或者你可以访问http://宿主机IP:6099进 WebUI 扫码。用手机小号扫码后日志里会出现Login Success。这一步的成功标志是 NapCat 日志显示账号已上线并且 WebUI 里能看到在线状态。第三步启动 OpenClaw 容器并确认 Agent 可用。执行docker compose up -d openclaw然后进容器手动跑一次 Agent 命令docker exec -it openclaw_kernel openclaw --no-color agent --to 你的大号QQ号 --message 测试一下如果 TaoToken 的 Key 配置正确你会看到 Agent 返回一段正常的回复文本。如果报 401说明 Key 没生效回去检查.env和settings.json。这一步的成功标志是命令行能拿到模型回复。第四步运行桥接脚本并观察连接。前台运行桥接脚本方便看日志docker exec -it openclaw_kernel python3 /home/node/qq_ears_brain.py成功的话会打印赛博触手已连接等待指令...。然后用你的大号 QQ 给小号发一条私聊消息观察脚本日志是否收到post_type: message事件以及是否触发了openclaw agent调用。如果一切正常你的大号会收到小号发来的回复。第五步确认记忆共享。在 QQ 里连续问两个有关联的问题比如先问我叫什么再问我刚才说了什么。如果 Agent 能记住上下文说明它走的是 OpenClaw 内核而不是无状态的 API 直连。这一步是验证架构是否真正复用了 Agent 能力的关键。整个链路跑通后你可以把桥接脚本改成后台运行加上-d参数或者用nohup。但建议第一次一定前台跑看到完整的消息流再放后台。5. 本篇常见错排查401、local proxy failed、reading choices 与 OAuth这一节我把实际踩过的坑按报错类型整理出来你遇到问题时可以直接对照。报错一401 Unauthorized。这是最常见的鉴权失败。表现是 Agent 命令返回401或者invalid api key。原因通常是.env文件没被 Docker Compose 正确读取或者settings.json里的apiKey字段写的是字面量${TAOTOKEN_API_KEY}而没有被替换。排查方法进容器执行echo $TAOTOKEN_API_KEY如果为空检查docker-compose.yml里env_file的路径是否正确。另外确认 TaoToken 的 Key 没有过期可以在 https://taotoken.net/api-keys 重新生成一个。报错二local proxy failed。这个报错通常出现在 OpenClaw 尝试连接模型服务时。表现是 Agent 返回local proxy failed或者连接超时。原因可能是容器内的 DNS 解析有问题或者网络策略限制了出站连接。排查方法进容器执行curl -I https://taotoken.net/api看是否能通。如果不通检查 Docker 网络的 DNS 配置或者确认宿主机的网络策略没有拦截容器出站。报错三reading choices 相关错误。这个报错一般出现在模型返回格式不符合预期时。表现是 Agent 日志里出现reading choices或者cannot read property of undefined。原因通常是模型返回的 JSON 结构跟 OpenClaw 预期的 OpenAI 兼容格式不一致。排查方法确认settings.json里的provider设置为openai-compatiblebaseUrl指向https://taotoken.net/apimodelId填写的是 TaoToken 支持的模型 ID。如果模型 ID 写错返回结构可能不对。报错四OAuth 相关错误。如果你在配置里误开了某些需要 OAuth 的 provider可能会看到OAuth token expired或refresh token failed。OpenClaw 走 TaoToken 统一 Key 时不需要 OAuth所以检查settings.json里有没有多余的oauth字段删掉即可。报错五unknown option --no-color。这个不是网络问题是命令参数顺序问题。表现是桥接脚本调用openclaw agent时报unknown option --no-color。原因是--no-color被放在了agent后面。正确写法是openclaw --no-color agent全局选项必须在子命令之前。这个坑我在 excerpt 里也提到了位置一错全盘崩溃。报错六QQ 消息发了但收不到回复。表现是桥接脚本日志显示已发送但大号 QQ 没收到。这通常是 NapCat 的幽灵假死——本地 Token 没过期但腾讯服务器端已断开连接。解决方法是手机登录小号进设置 - 账号安全 - 登录设备管理把除当前手机外的设备强制下线然后docker restart napcat_core重新扫码登录。如果你在排查过程中需要确认模型调用是否正常可以先用模型对话页面单独测试一下 Key 是否可用https://taotoken.net/model-chat 。接入相关的文档在 https://taotoken.net/doc 里面有各语言的调用示例。6. 扩展到多账号与长期运行把统一 Key 和 Coding Plan 用起来单账号跑通之后从 1 到 2 的下一步就是多账号。我的做法是每个 QQ 小号对应一个 NapCat 容器和一个 OpenClaw 容器但它们共用同一个 TaoToken Key。Docker Compose 里可以用docker-compose -f指定不同的配置文件或者用环境变量区分端口和容器名。关键是.env文件里的TAOTOKEN_API_KEY保持一致这样计费和额度统一管理不用每个实例单独配。多账号场景下桥接脚本里的TARGET_QQ需要改成从环境变量读取这样同一个脚本镜像可以复用到不同实例。WebSocket 地址也要相应调整因为每个 NapCat 容器的服务名不同。我通常用napcat_账号标识来命名服务桥接脚本通过WS_URL环境变量注入。长期运行的话建议把桥接脚本做成 systemd 服务或者用 Docker 的 restart 策略管理。我目前是让 OpenClaw 容器常驻桥接脚本在容器内用supervisor托管这样容器重启后脚本自动拉起。日志方面NapCat 和 OpenClaw 的日志都通过docker logs查看建议配一个日志轮转避免磁盘被撑满。如果你后面要跑更复杂的 Agent 任务比如定时任务、多轮工具调用可以考虑 TaoToken 的 Coding Planhttps://taotoken.net/coding-plan 。它适合长期编码和 Agent 场景额度更充裕。控制台在 https://taotoken.net/console 可以看调用量和余额。最后说一个实际经验这套架构最脆弱的地方不是模型而是 QQ 的登录态。NapCat 的幽灵假死我遇到过好几次表现就是代码不报错但消息不通。后来我养成了一个习惯每天早上看一眼 NapCat 的日志确认Login Success还在。如果发现异常直接走强制下线 重启 重新扫码的流程五分钟能恢复。别在代码层面死磕很多时候问题在腾讯服务器端不在你的脚本里。如果你还没开始配建议先把单账号的 Docker Compose 跑通确认消息能收发再去折腾多账号。一步一步来比一次性堆一堆配置然后面对满屏报错要快得多。
返回列表