OpenClaw 接入 OneBot 实现 QQ 消息收发
前言
最近在做作业批改系统,需要实现老师通过机器人向学生发送成绩和通知的功能。本文记录如何将 OpenClaw 与 OneBot 协议对接,实现 QQ 私聊和群消息的自动发送。
背景
为什么选择 OneBot?
OpenClaw 原生支持 QQ 频道机器人,但频道机器人无法进入普通 QQ 群。为了覆盖更多使用场景,选择通过 OneBot 协议作为中转:
1 | OpenClaw → OneBot 插件 → OneBot 实现(LLOneBot)→ QQ 群/好友 |
技术栈
- OpenClaw: AI 网关,负责消息路由和 Agent 管理
- OneBot 插件:
@kirigaya/openclaw-onebot - OneBot 后端: LLOneBot(基于 NTQQ 的 OneBot 11 实现)
安装与配置
1. 安装 OneBot 插件
1 | openclaw plugin install @kirigaya/openclaw-onebot --allow-dangerous |
注意:该插件包含
child_process调用,需要--allow-dangerous参数。
2. 配置 OneBot 连接
编辑 ~/.openclaw/openclaw.json,添加 onebot 通道配置:
1 | { |
3. 配置 Agent 绑定
将 onebot 通道绑定到指定 agent:
1 | { |
4. 重启 Gateway
1 | openclaw gateway restart |
消息发送
私聊消息
通过 jarvis agent 发送私聊消息:
1 | openclaw agent --agent jarvis -m "通过 onebot 给 QQ 891878708 发私聊消息:你好" |
群消息
发送群消息:
1 | openclaw agent --agent jarvis -m "通过 onebot 给群 875860223 发送群消息:大家好" |
封装 Skill
为了便于复用,创建了 onebot-messenger skill:
1 | skills/onebot-messenger/ |
skill 中记录了完整的使用方法和作业系统集成示例:
- 发送成绩通知
- 群发作业提醒
- 发送批改反馈
性能优化
问题(还没解决!!)
使用 openclaw agent 命令发送消息耗时约 1 分钟,主要卡在:
- 进程启动
- 插件重复加载
- WebSocket 连接初始化
解决方案
直接使用 HTTP API(推荐)
- 绕过 OpenClaw 命令行开销
- 响应时间 < 1 秒
编写常驻脚本
- 保持 WebSocket 连接
- 直接调用 OneBot 接口
总结
通过 OpenClaw + OneBot 的组合,可以实现:
- ✅ QQ 私聊消息自动发送
- ✅ QQ 群消息自动发送
- ✅ 与作业系统深度集成
- ⚠️ 需要优化性能(建议使用 HTTP API 直接调用)
后续计划:
- 编写常驻 Python 脚本提升发送速度
- 封装更多消息类型(图片、@成员等)
- 实现消息模板系统
参考
续:作业批改系统集成 RAG 与 QQ 消息发送
2026-04-22 更新
在完成了基础的 OneBot 消息发送功能后,我开始思考如何将其与作业批改系统的数据结合起来。目标是让老师能够通过自然语言指令,让 AI 自动查询作业数据并发送到 QQ 群。
需求分析
需要实现的功能:
- 数据向量化:将班级作业数据(成绩分布、学生学情、高频错题等)存入向量库
- RAG 检索:老师可以通过自然语言查询数据
- 自动发送:查询结果自动格式化为成绩单,通过 OneBot 发送到指定 QQ 群
技术方案设计
方案一:直接查询数据库
前端收集数据 → 后端查询数据库 → 格式化消息 → 调用 OpenClaw 发送
缺点:
- 老师需要明确知道作业 ID
- 不够灵活,无法支持复杂查询
方案二:RAG 向量检索(最终选择)
1 | PageFour 页面数据 → 导出文本 → 切割分块 → 向量化 → 存入 PostgreSQL + pgvector |
优点:
- 支持自然语言查询:”3班 Java 作业成绩如何?”
- 无需记住具体 ID
- 可以组合多个条件查询
实现过程
1. 数据库设计
复用现有的 document_chunk 表存储仪表盘数据:
1 | -- 添加元数据字段支持 |
表结构说明:
document表:存储文件元信息(原文件上传用)document_chunk表:存储切割后的文档块 + 向量(RAG 检索用)
2. 后端实现
接口层 (DashboardController.java):
1 |
|
服务层 (DashboardRagServiceImpl.java):
核心逻辑:
- 格式化仪表盘数据为 Markdown 文本
- 使用
SmartChunkService智能切割 - 生成 embedding 向量
- 存入数据库并附加元数据
1 |
|
3. 前端实现
PageFour.vue 添加上传按钮:
1 | <button |
一键上传逻辑:
1 | async uploadToRag() { |
遇到的问题与解决方案
问题 1:格式化字符串类型不匹配
错误日志:
1 | java.util.IllegalFormatConversionException: f != java.lang.Integer |
原因:StudentOverviewDTO.avgScore 是 Integer 类型,但代码中使用了 %.1f 格式化。
解决:
1 | // 错误 |
问题 2:是否需要额外存储文档块?
疑问:之前没有 pgvector 扩展时,需要额外存储文档块吗?
解答:
- 之前:只能用
embeddingTEXT 字段存逗号分隔的向量,检索时全表扫描,Java 代码计算余弦相似度 - 现在:PostgreSQL 安装了 pgvector 扩展后,有
embedding_vec字段(vector 类型),支持 SQL 的<=>操作符直接做向量相似度搜索
document_chunk 表本身就存储了:
content:文档块文本内容embedding_vec:向量(pgvector 专用)
不需要额外存储。
问题 3:Service 接口与实现分离
规范:项目采用接口 + 实现类的结构 (Service/ 和 Service/ServiceImpl/)
实现:
1 | Service/ |
优化点
- 防重复上传:每天每个班级只能上传一次,避免重复数据
- 元数据标签:包含 type、classId、className、date 等,便于精确检索
- 状态显示:前端按钮显示”今日已上传”,防止误操作
使用流程
- 老师进入 PageFour(教学数据中心)页面
- 选择班级,查看数据
- 点击”🚀 上传到知识库”按钮
- 数据自动格式化、切割、向量化、存入数据库
- 老师可以通过自然语言查询:
- “3班有哪些学生需要关注?”
- “把 Java 作业成绩单发到 3 班群”
后续计划
- 实现消息发送接口,打通 RAG → OneBot 的完整链路
- 支持更多数据类型(作业详情、错题分析等)
- 添加删除/更新知识库数据的功能
总结
通过将作业数据向量化存入 RAG,结合 OneBot 消息发送,实现了:
- ✅ 自然语言查询班级数据
- ✅ 一键上传数据到知识库
- ✅ 防重复上传机制
- ✅ 元数据标签支持精确检索
下一步是完成消息自动发送功能,实现”查询 → 生成消息 → 发送到 QQ 群”的完整闭环。





