QClaw客户端架构与Queue Guard排队机制探索

腾讯安全管家推出的Qclaw,每天送4000万免费Tokens,基本上每天都在更新,目前支持多Agent,界面美观实用方便,是目前本地部署openclaw的最佳选择。
以下为探索记录:

  1. “当前为高峰期,已为您暂停任务。” 的问题
  2. 配置的覆盖机制和自定义配置的实现

一、架构关系

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
QClaw Electron (桌面客户端)
├── UI 界面(对话、设置、工作流)
├── 进程管理(启动/停止/守护 OpenClaw Gateway)
├── 认证管理(登录、JWT token、GUID)
├── 资源调度(queue-guard 的排队接口)
└── 配置管控(写入/覆盖 openclaw.json 的部分字段)

OpenClaw Gateway (AI Agent 运行时)
├── Agent 管理(main、写作助手、代可行等)
├── 会话管理(session、对话历史)
├── 插件系统(queue-guard、skill-interceptor 等)
├── 工具调用(exec、browser、web\_search 等)
├── 渠道接入(微信、webchat 等)
└── 配置读取(openclaw.json)

二、关键机制

1. 启动顺序

1
2
3
4
5
6
7
8
9
QClaw Electron 启动
注入环境变量(QCLAW\_USER\_GUID、QCLAW\_USER\_ID、QCLAW\_LLM\_BASE\_URL 等)
写入/同步 openclaw.json(可能会覆盖 AI 修改的字段)
拉起 OpenClaw Gateway 子进程
Gateway 加载配置、注册插件、开始服务

2. 配置管控

配置层级谁管控示例
客户端管控字段QClaw Electronmessages.queue.modechannelsmodels.baseUrl
Agent 可修改字段OpenClaw / AIskills.entriessession.maintenance
共享字段双方都可写Electron 启动时会重新同步

3. 认证链

1
2
3
4
5
6
7
8
9
用户登录 QClaw 账号
Electron 获取 JWT token → AES-128-CBC 加密
通过 HTTP endpoint 推送给 queue-guard 插件
queue-guard 解密后用于排队接口认证
排队通过 → LLM 请求带上原始 token

4. 资源调度

1
2
3
4
5
6
7
8
9
用户发消息 → OpenClaw Gateway
queue-guard 拦截 fetch
调用 QClaw 后端排队接口(命令字 4158)
QClaw 后端根据全局负载决定排队/放行
放行 → 真实 LLM 请求发出

5. 日志机制

  • 浏览器日志在 C:\Users\you\.qclaw\browser\openclaw\user-data\Default\LOG(Chromium 日志)
1
2
3
4
OpenClaw 日志 → C:\\Users\\you\\.qclaw\\logs\\openclaw\\
 ├── \config-audit.jsonl (记录配置写入审计 每次openclaw.json变更的时间、进程、hash、字节数等)
 ├── \*.log (早期未加密)
 └── \*.enc (当前 AES 加密,AI 无法读取)

6. 修改失败的原因

1
2
3
4
5
6
7
8
9
AI 通过 config.patch 写入 queue.mode = "queue"
Gateway 重启(SIGUSR1)
QClaw Electron 检测到 Gateway 重启
Electron 重新同步 openclaw.json(覆盖为客户端默认值 followup)
结果:修改被还原

7. 总结

  • QClaw Electron = 管理者(壳),负责 UI、认证、资源调度、配置同步
  • OpenClaw Gateway = 执行者(引擎),负责 AI 对话、工具调用、插件运行
  • Electron 对 Gateway 拥有最终控制权,包括配置覆盖和进程生命周期

要修改 messages.queue.mode,需要在 **QClaw 客户端设置** 里改,而不是通过 OpenClaw API。

三、默认配置文件

QClaw 的客户端默认配置文件在:

1
C:\\Program Files\\QClaw\\resources\\openclaw\\config\\openclaw.json

这就是 QClaw Electron 启动时用来同步/覆盖用户配置的模板文件。

对比

字段默认模板你的用户配置说明
messages.queue.modefollowupfollowup被模板覆盖回来了
queue-guard.enabledtruetrue两者一致
models.providers.qclaw.baseUrl${QCLAW\_LLM\_BASE\_URL}${QCLAW\_LLM\_BASE\_URL}模板占位符
channels.wechat-access.guid${QCLAW\_USER\_GUID}实际值Electron 启动时替换
channels.wechat-access.token"" (空)实际值Electron 启动时填入
session.maintenance365d/100万/1gb同左一致

机制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
QClaw Electron 启动
读取默认模板:C:\\Program Files\\QClaw\\resources\\openclaw\\config\\openclaw.json
替换 ${...} 占位符为实际值(token、guid、userId 等)
与用户配置:C:\\Users\\youfo\\.qclaw\\openclaw.json 合并
写入用户配置(模板中声明的字段会覆盖 AI 的修改)
拉起 OpenClaw Gateway

结论

messages.queue.mode: "followup" 硬编码在默认模板里,每次 QClaw 启动都会强制写回。要通过 AI 修改这个值,需要同时修改默认模板文件,但那个文件在 Program Files 下,需要管理员权限,且 QClaw 更新后会被还原。
正确的修改方式是在 QClaw 客户端的设置界面里操作,这样 Electron 会在自己的管理层记录这个变更,启动时不会再覆盖。

四、queue-guard(模型排队守卫)

定位

L2 中间件层插件,不注册 Channel/Route/Command,只拦截 globalThis.fetch

解决什么问题

QClaw 使用共享模型资源,高峰期请求过多时直接发出去会被拒。queue-guard 在请求发出前先排队,等资源空闲再放行,避免无意义的失败请求。

工作流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
用户发消息
OpenClaw 准备调用 LLM(llm\_input 钩子记录 sessionKey)
fetch 拦截器检测到 LLM 请求(model 含 "modelroute")
每 2 秒轮询后端排队接口(命令字 4158)
┌─ 资源可用 → 放行真实请求 → 正常对话
├─ 超时 120s → fail-open 直接放行 → 不阻塞用户
└─ 用户中止(点停止)→ 返回伪造响应 → "当前为高峰期,已为您暂停任务。"

拦截范围

  • 拦截:model 包含 modelroute 的请求(QClaw 默认路由模型)
  • 放行:自定义模型(如 deepseek-chat、本地模型)直接通过,不排队
  • 放行:所有非 LLM 请求(GET、无 body、不含 messages 数组的)

4 个源码模块

文件作用
index.ts插件入口,注册钩子、HTTP endpoint、Gateway Method
src/interceptor.tsfetch 拦截器核心,识别 LLM 请求并触发排队
src/queue-api.ts排队状态管理、轮询逻辑、会话-排队状态关联
src/aes-decrypt.tsAES-128-CBC 解密用户 JWT token
src/jprx-sign.tsJPrx 防重放签名

可配置参数

跨插件通信

通过 globalThis 上的 EventBus 广播事件:

  • queue-guard:state — 排队状态变更(排队中/就绪/超时)
  • queue-guard:notify — 排队进度通知,钉钉/微信插件监听此事件向用户展示排队提示

关键设计原则

  1. fail-open — 排队接口异常或超时时直接放行,绝不阻塞用户
  2. 不侵入其他插件 — 纯 fetch 拦截,不修改任何其他插件源码
  3. 全渠道统一生效 — 主会话、微信、钉钉等所有渠道的 LLM 请求都会经过排队

遇到的问题

“当前为高峰期,已为您暂停任务。” 就是 interceptor.ts 里硬编码的伪造响应文本,在排队被用户中止时返回。
这不是 AI 生成的,而是插件的兜底行为。

五、问题分析

原因是两个机制叠加:

直接原因

queue-guard 排队 + followup 模式冲突
配置:

followup 模式下,新消息进来会自动取消上一个未完成的请求。
流程是这样的:

1
2
3
4
5
6
7
8
9
你发消息 → queue-guard 开始排队(等待模型资源)
 ↓(排队中,还没到)
你又发了消息 / UI 超时重试
followup 模式取消上一个排队中的请求
queue-guard 返回伪造响应("当前为高峰期...")
webchat UI 收到 abort 信号,消息闪现后消失

为什么没中断

session 一条条发,没有重复发送,所以请求能正常完成。

根本问题

高峰期 + followup 模式 = 容易互相取消请求

六、建议

如果中断频繁,有两个思路:

  1. 发完消息等一等(不要重复发送),排队最多 2 分钟会自动放行
  2. 把 queue mode 改成其他模式

queue mode 模式说明

模式说明
followup新消息取消上一个未完成的请求
steer新消息转发给当前运行中的 agent(不取消)
steer-backlogsteer + 消息积压
steer+backlog同上
collect收集一批消息后一起处理
queue先进先出排队
interrupt中断当前请求
原文链接: https://www.17you.com/library/qclaw-electron-openclaw-gateway-architecture/ 已复制!
知识和正确的认知铸就美好旅程

加入自游人,有空让我们一起游,打破认知的围墙!

一起 AI、一起搞钱、一起做数字游民,四海漫游。

请点击联系我


相关内容