一、问题:机器人数据的三副面孔
做机器人数据存储的同学对这张清单不会陌生:
| 数据形态 | 例子 | 常见去处 |
|---|---|---|
| 时序帧 | 位姿、关节角、传感器读数 | SQLite / TimescaleDB / 纯文件 |
| 向量 | 视觉 embedding、语言特征 | FAISS / 专用向量库 |
| 事件文本 | "抓取滑落""路径避障"、操作日志 | ES / 纯文本 |
| 二进制 | 点云压缩块、图像帧 | 文件系统 + 自管索引 |
真实查询往往跨形态:"找出最近一周 embedding 相似于某次失败抓取、且事件文本提到 slipped 的帧,按分钟聚合看趋势"。用胶水方案拼,事务边界、故障恢复、导出格式各管各的,每个环节都是潜在的静默不一致;到了边缘设备上还要面对"不能常驻服务进程"的约束。
MoteDB 的答案很直接:一个嵌入式 SQL 引擎原生承载全部四种形态。纯 Rust、MIT、单进程零外部依赖,VECTOR / TIMESTAMP / TEXT / BLOB 是同张表里的一等公民。
CREATE TABLE frames (
ts TIMESTAMP,
task TEXT,
note TEXT, -- 事件文本(内置 jieba 分词的 BM25 全文索引)
emb VECTOR(384) -- 向量列(DiskANN 图索引)
) TIMESERIES(ts);
-- 跨形态查询,一个引擎完成:
SELECT task, note FROM frames
WHERE MATCH(note) AGAINST('slipped') -- 全文
ORDER BY emb <-> '[0.1, 0.2, ...]' -- 向量距离
LIMIT 10;
二、五个核心设计
2.1 列段存储 + WAL 组提交
写入走列段(ColSegmentStore):每列独立段文件、mmap 读、manifest 追加日志;WAL 按分区组提交(多分区并行 fsync,攒批摊薄延迟)。这是"单表多模态"能同时扛住高频传感器写入与分析型扫描的底座。
2.2 连续视图(0.18):定义一次,当普通表查
时序聚合的常见痛点是"查询时要不要现算"。MoteDB 用 CREATE CONTINUOUS VIEW 把定义存进系统表,查询时惰性刷新,外层 WHERE / 聚合 / ORDER BY 随便组合:
CREATE CONTINUOUS VIEW sensor_1m AS
SELECT TIME_BUCKET('1m', ts) AS minute, device,
AVG(v) AS v_avg,
FIRST(v, ts) AS v_open, -- 桶内时间最早的值(0.18 新增两参时序聚合)
LAST(v, ts) AS v_close
FROM sensor GROUP BY minute, device;
-- 之后当普通表用:
SELECT COUNT(*) FROM sensor_1m WHERE device = 'arm_a';
语义如实声明:v1 为查询时全量重算(查询时点一致),桶级增量顺延后续版本。
2.3 混合检索:BM25 × 向量 KNN 一次调用
端侧模型上机后,检索与记忆全在本地。hybrid_search 一次调用返回 RRF 融合榜,避免应用层自己维护两套索引的分数校准:
hits = db.hybrid_search(
"f_note", # BM25 全文索引(中文走 jieba)
"slipped", # 查询词
"f_emb", # 向量索引
query_vec, k=5)
向量索引是 DiskANN(FreshDiskANN + 重排),带新鲜度护栏:增量数据未入图占比超阈值时该查询自动降级精确暴力扫并触发后台重建——正确性优先于延迟。
2.4 采集 → 运输 → 部署的一条链
- 采集:机器人端高写入目录,原子发布 + 崩溃注入测试保证断电安全;
- 运输:
EXPORT DB TO 'snap.mote' [COMPRESSED]单文件打包(逐文件 CRC、可选 zstd); - 部署:目标机
read_only=True打开,所有写路径拒绝、多读者共存;0.18 新增多进程共享只读——一个写者进程 + N 个读者进程同挂活动目录(flock SH/EX),读者零字节落盘。
2.5 训练生态衔接
EXPORT LEROBOT:直接产出 LeRobot v3 数据集,官方LeRobotDataset可读;IMPORT MCAP:机器人领域标准录制格式直接入库;- 内置 MCP server:把数据库作为工具挂给任何支持 MCP 的智能体(含通义系 Agent);
- Arrow/pandas 互操作:
query_arrow()返回规范pyarrow.Table,向量列为FixedSizeList<float32>。
三、工程护栏:为什么敢在边缘设备上跑
数据库的可信度不靠口号,列举三条可复验的机制:
差分测试。同一份随机谓词(混型、NULL、边界值、方括号向量文本、ISO 时间戳)在九条执行路径上对拍(SELECT / DELETE / UPDATE / JOIN 两种表序 / 子查询 IN / 聚合 / GROUP BY+HAVING),任何一路答案不一致即失败。0.18 统一 SQL 比较语义(原 11 处实现收编为一个语义层)时,该 harness 上线当天揪出 7 个预先存在的跨路径分歧。
性能门禁。CI 里有机器无关的性能门(复杂度断言而非绝对延迟),回归变红。基准数据带完整机型与口径,见仓库 BENCHMARK.md。
语义棘轮。src/sql 内裸值比较点只许降不许升(上限数值在独立文件里,调低 conspicuous),防止语义实现回潮分裂。
全量测试 4300+,另有崩溃注入(kill -9 × 索引 × 反复循环)、SQLite 为 oracle 的差分 fuzzing 常驻 CI。
四、和通义生态的衔接点
具身智能的模型侧正在快速演进——通义在物理世界智能方向已有公开布局(Qwen-RobotSuite 基础模型套件、RobotWorld 世界模型,端侧还有 Qwen3-4B 一类小模型)。我们不造模型,做的是这些模型上机后的另一半:记忆体。具体衔接:
- 端侧 Qwen 小模型做 on-device RAG / 长期记忆 → MoteDB 的混合检索与嵌入式形态;
- 机器人数据管线 → MCAP 导入 / LeRobot 导出 / Arrow 互操作;
- Agent 工具化 → 内置 MCP server;
- 面向 LLM 的能力发现 → 站点提供 llms.txt 机器可读能力清单。
五、10 分钟上手
pip install motedb-python
仓库 examples/motedb-demo.ipynb 是一个在 Colab 上约 1 分钟跑完的闭环演示:写入机器人帧数据 → 连续视图聚合 → 向量 KNN → 混合检索 → Arrow 导出 → 单文件快照只读部署。
Rust:cargo add motedb(crates.io);Node:npm install motedb(预编译覆盖 macOS arm64/x64 与 Linux x64/arm64)。
六、写在最后
MoteDB 开发至今约 10 个月,当前 0.18.2,路线图上还有 bucket 级增量刷新、列级 UNIQUE、Python 类型存根等。仓库挂着 10 条打好标签的 good first issue,如果你想深入一个存储引擎的内部(列段、WAL、DiskANN、MVCC),这是门槛较低的入口。
所有能力声明与对应测试的映射在仓库 CAPABILITIES.md——我们习惯把"已知限制"也写在那里,欢迎按清单拷问。
相关链接