跳转至

ADR 0001: 抽象存储库 (Repository) 与双引擎支持

状态 (Status)

已接受 (Accepted) 日期: 2026-03-07

上下文 (Context)

初始开发阶段,openclaw-agent-hub 完全依赖于 Python 原生的 SQLite 驱动,以及简单的全局对象结构存储。这种方式极大地方便了本机的快速测试和开发环境搭建,但在后续需要部署到公有云并作为多 Agent / 跨机器集群状态枢纽时面临几个严重问题: 1. 本地文件存储不具备分布式能力和极高并发写的健壮性。 2. SQLite 难以进行高可用部署。 3. 必须提供一种更健壮的云服务后端,我们选择了 Supabase (基于 PostgreSQL) 作为生产级后端方案。 4. 我们也不想在架构成型早期立刻丢弃掉 SQLite 的“轻量、零依赖快起”特性,这对于开源协作者(特别是刚 clone 下来想自己本地玩玩的开发者)非常友好。

由于我们使用了 FastAPI 后端架构,传统的做法可能是引入诸如 SQLAlchemy 等庞大的 ORM 来兼容多数据库。但是本项目具有显著的高吞吐和高并行事件写入场景,全功能 ORM 过重。我们亟需一套简单纯粹的接口。

决策 (Decision)

我们决定采用仓储层模式 (Repository Pattern) 隔离业务逻辑(如任务下发、心跳结算、钱包扣费、内存事件)和具体的物理数据库。

具体的实施方案如下: 1. 我们建立了一个抽象模块 src/agent_hub/repo.py。 2. repo.py 由一组 Python 功能函数接口构成,充当我们所有的数据库 DAO(数据访问对象)。 3. 底层实现拆分为两套实现闭包或驱动: - 默认的回退驱动仍是本地 SQLite (src/agent_hub/repo_sqlite.py 内部封装)。由于接口高度一致,在没有环境变量配置时无缝启动。 - 提供了一套完全对应的 Postgres/Supabase API 接口实现 (src/agent_hub/repo_supabase.py 内部封装)。在存在环境变量 SUPABASE_URLSUPABASE_KEY 时,repo.py 可以动态感知并将函数指针切至 Supabase 后端驱动。

结果 (Consequences)

正面影响 / 收益: - 业务控制反转。FastAPI 路由 (main.py) 可以保持极度清爽且免于绑定任何 SQL 方言,实现逻辑隔离。 - 即插即用的本地极速体验保留了下来,对于希望自己建立一套生产级系统的开发者来说,他们也拥有了开箱即用的高可用关系型数据库方案。

局限与挑战: - 代码重复度变高:每一次在 repo.py 补充一个类似于 get_dev_task_progress() 的新功能,在底层的不同驱动实现里至少要维护两套完全一样的出入参。如果在后续阶段引入更多特性(如基于搜索或向量的检索),可能需要一套更加形式化和统一的 Schema 管理机制。 - 难以利用特定的高级数据库特性。目前所有功能都只能被限制在 SQLite 和 Postgres 的公共子集功能(基础的 SELECT/INSERT/UPDATE)上。