从 QQ 机器人到 Discourse 工作台:一次关于工具边界的真实复盘

TL;DR

  • 这段时间的核心目标不是“做一个 QQ 机器人”,而是提升多任务协作效率与上下文沉淀质量。
  • QQ 插件已经完成了可靠性、风控、会话槽、多模态、管理指令等一整套可运行能力,不是简单转发器。
  • Discourse 插件的价值在于把“聊天”转成“任务容器”,更适合追踪、复盘与知识沉淀。
  • 我认真评估过 QQ↔Discourse 双向同步,技术可行,但当前阶段 ROI 不高,复杂度与维护成本偏大。
  • 因此当前策略明确为:Discourse 优先(主工作台)QQ 入口化(低门槛触达)
  • 这次工作的真正产出不只是功能,而是方法论:路由与展示分离、平台职责收敛、价值优先的工程取舍。

从 QQ 机器人到 Discourse 工作台:一次关于“工具边界”的真实复盘

这篇文章是我这段时间在 OpenClaw 生态里做 QQ 插件、做 Discourse 插件、思考跨端同步、最后主动收敛方案的阶段性总结。它不是宣传稿,而是一份工程与产品决策记录。

1. 起点:我一开始并不是在做“一个 QQ 机器人”

我真正想解决的问题,从来不是“在哪个平台聊天”,而是:

  • 如何更高效地并行处理多个任务;
  • 如何把上下文沉淀下来,后续可检索、可回看、可协作;
  • 如何让国内朋友在不翻墙的条件下,也能把需求方便地丢进来。

这三个目标在同一套系统里天然张力很大:

  • QQ 的优势是触达和即时性;
  • Discourse 的优势是结构化、多线程、沉淀和管理;
  • OpenClaw 的优势是把多通道统一接进一个 Agent 与会话系统。

所以这段时间本质上是在做一件事:把“入口便利性”和“任务管理效率”拆开,再用工程手段尽量平衡,而不是强行统一成一个入口。


2. QQ 插件到底做到了什么(不是“能聊天”这么简单)

很多人会低估 QQ 插件,以为只是把消息转给模型、再把文本回过去。实际我这版 QQ 插件已经是一套比较完整的通道能力层,关键功能包括:

2.1 通道可靠性(生产可用的底盘)

  • OneBot v11 WebSocket 连接与重连机制(指数退避);
  • 心跳/空闲检测,识别“僵连接”;
  • 发送失败自动回队列,连接恢复后补发;
  • 避免 health-monitor 误判通道退出导致重启循环(通道常驻到 abort)。

这部分其实决定了“机器人是否真的在线”,比模型本身更重要。

2.2 安全与风控(真正在 QQ 落地必须做)

  • requireMention 默认开启,避免群里每句话都触发;
  • 群白名单、用户黑名单;
  • adminOnlyChat(仅管理员触发)+ 非管理员提示防抖;
  • 分片发送 + 发送间隔(降低风控风险);
  • antiRiskMode 对部分内容(如 URL)做规避处理。

QQ 生态风控远比 Telegram 激进,不做这层很快就会“日志里回复了,群里没收到”。

2.3 会话工程(这块是这次工作的核心资产)

  • 标准路由下的会话键生成(交给 OpenClaw core routing);
  • 群聊临时会话槽(/临时/临时重命名/临时列表/临时结束 等);
  • /newsession 对当前会话槽做精确重置;
  • 会话展示名(displayName)统一为新格式:
    • qq:<peer>-<YYYYMMDDHHmm>-<title>

这意味着:我可以在同一个群里并行多个子任务,不再把所有上下文糊成一团。

2.4 多模态与信息提取

  • 解析 at、回复链、图片、语音、文件、转发消息;
  • 处理图片 URL/base64/file 引用并做注入提示;
  • 从回复消息补全附件上下文;
  • 发送侧支持文本、图片、语音、文件并带 fallback 路径;
  • 支持 QQ 频道(Guild)消息。

2.5 可操作性

  • 管理指令:/status/help/mute/kick
  • 能力指令:/models/model/newsession/grok_draw
  • 忙碌状态可视化:处理中临时修改群名片后缀(如“输入中”);
  • 空回复兜底提示,减少“看起来像挂了”的误判。

总结一句:QQ 插件已经不是 demo,而是一套可持续运行的渠道层工程。


3. Discourse 插件做对了什么:把“对话”变成“任务”

Discourse 这条线的价值非常清晰:

  • webhook 驱动入站,天然异步、天然可追踪;
  • topic 作为任务容器,结构上就是多任务管理友好模型;
  • 每条回复、每次编辑、每次追问都有可回看的历史上下文;
  • 可被多人协作、可沉淀知识,而不是聊天流一冲就没。

我在这次迭代里补齐了几个关键点:

  • 话题标题解析与缓存(必要时拉 /t/{topicId}.json 回填);
  • 会话显示名统一规则:
    • discourse:<site>-<YYYYMMDDHHmm>-<title>
  • 同时写 ConversationLabelThreadLabel,让会话面板可读性提升;
  • 对旧会话做批量重命名脚本,完成历史数据一致化。

这看似是“命名优化”,实际上是在把会话管理从“机器可用”推向“人可读可管”。


4. 我为什么认真考虑过 QQ↔Discourse 同步,又决定先不做

我中间认真评估过一个方案:

  • QQ 作为入口,命中规则后自动转发到 Discourse;
  • Discourse 处理完再回推 QQ;
  • 两端都能看见对话,像“桥接器”。

这个想法技术上完全可做,甚至不算难做。但我最后决定暂不投入,原因并不“技术”,而是“价值密度”。

4.1 可做,不代表该做

双向同步要真正稳定,至少要额外解决:

  • 回环(A 推到 B,B 再推回 A);
  • 去重(webhook 重放/网络抖动导致重复投递);
  • 顺序一致性(跨系统时间戳和重试行为);
  • 映射治理(QQ 会话与 topic 长期映射如何维护);
  • 多媒体跨端语义损耗(QQ 文件/语音到论坛的表达降级)。

每个点都不是“写几行 glue code”就能彻底消除的。

4.2 当前阶段更稀缺的是“任务效率”,不是“全渠道一致”

我的真实痛点是多任务推进效率,不是聊天平台统一。

  • Discourse 已经能承担主流程;
  • QQ 只需要做轻入口(朋友不用梯子,能把需求抛进来);
  • 为“看起来更完整”而做复杂同步,短期 ROI 很低。

4.3 主动放弃,不是失败

我越来越认同一个原则:

工程能力的成熟,不是“能做更多”,而是“知道哪件事现在不做”。

所以这个同步方案我保留为“有意思的想法”,但不在当前阶段继续消耗精力。


5. 这段时间真正沉淀下来的工程资产

即使后续弱化 QQ 维护,这段工作并没有浪费。它至少留下了五类高价值资产:

5.1 通道侧稳定性经验

  • 连接生命周期管理;
  • 发包确认与失败回退;
  • 心跳与活性判断;
  • 长连系统的可观测性思路。

5.2 会话体系方法论

  • “路由 key”和“展示名”分离;
  • 展示名可读性对运维效率的直接影响;
  • 命名规则统一后,问题排查成本显著下降。

5.3 平台差异认知

  • QQ 不适合承载复杂 Markdown 与长链路协作;
  • Forum(Discourse)天然适合任务化与知识沉淀;
  • 同一 Agent 不代表所有通道都该承担同等职责。

5.4 配置治理意识

  • 防盗刷、白名单、管理员边界必须前置;
  • 开关粒度应细(功能、权限、通知策略分层);
  • 兼容 WebUI 与 CLI 的配置输入语义差异。

5.5 产品决策能力

  • 从“技术可行”转向“价值优先”;
  • 从“功能叠加”转向“职责收敛”;
  • 在时间有限时主动砍掉低 ROI 分支。

6. 最终定位:QQ 做入口,Discourse 做工作台

截至当前,我给这两条通道的定位是:

  • QQ

    • 低门槛入口;
    • 朋友随手提需求;
    • 快速通知、简单交互;
    • 文件/语音等即时素材入口。
  • Discourse

    • 多任务承载;
    • 主流程交互与追踪;
    • 结果沉淀、知识组织;
    • 复盘与协作主阵地。

这不是“哪个更高级”,而是把不同平台放回各自擅长的位置


7. 给未来自己的三条提醒

  1. 不要把“通道能力”误当成“产品价值”本身。
  2. 当你开始为边缘场景堆复杂度时,先问一句:这是不是在逃避真正的主问题。
  3. 任何插件都可能停止维护,但方法论和边界感会留下来,这是最值钱的部分。

8. 结语

这段时间我做了很多看起来“像工具开发”的工作,但最后收获的不是一个更花哨的机器人,而是更清晰的判断:

  • 什么该持续投入;
  • 什么该暂时搁置;
  • 什么才是系统真正的主航道。

如果一句话概括这次复盘:

与其追求“所有平台都很完整”,不如先把“真正重要的任务流”做深做稳。

而对我来说,这条主航道目前就是:Discourse 优先,QQ 入口化。