系统架构设计
1. 项目目标
Everpast 希望把家庭监控系统从"录像存储 + 人工回放"的老传统,转变为"自然语言时间线 + AI 查询 + 精准回放"的新范式。
传统监控系统只回答"有没有画面?画面有没有人?",但用户真正关心的是:
- 什么时候有人来过?
- 某个物品是什么时候被拿走或放下的?
- 家中一天的活动结构是什么?
- 是否出现了厨房火源、老人跌倒、异常停留等风险?
这些问题无法只靠录像文件解决,必须把画面转化为可检索、可理解、可推理的事件记录。因此,本项目的核心资产不是视频文件本身,而是由视觉语言模型生成的 自然语言时间线。
系统总体目标:
- 接入家庭摄像头和录像系统;
- 通过轻量 VLM 将画面转写为自然语言事件;
- 将事件写入可索引的时间线存储;
- 用户通过自然语言查询事件,而不是拖动进度条;
- 必要时精准返回相关视频片段;
- 以插件系统扩展老人看护、智能家居联动、每日回顾等能力。
2. 总体架构
系统采用"视频底座 + 消息中枢 + AI 事件生成 + 时间线存储 + 查询引擎 + 插件生态"的分层架构。
2.1 架构分层
| 层级 | 核心职责 |
|---|---|
| 输入层 | 摄像头、可选传感器接入 |
| 视频底座层 | 录像、截图、目标检测、视频片段管理 |
| 系统管理层(可选) | 系统守护进程、网络配置、存储管理、系统更新、首次启动向导(仅在 OS 集成部署中存在) |
| 核心中枢层 | 组件生命周期、消息路由、权限、日志、配置管理(含 Schema 校验与热加载)、插件管理 |
| AI 理解层 | 画面事件生成、自然语言查询、视频片段定位 |
| 数据层 | 时间线、配置、日志、媒体文件引用 |
| 扩展层 | 插件化业务逻辑,如看护、告警、日报、智能家居联动 |
| 用户交互层 | 时间线浏览、自然语言查询、视频回放、通知 |
3. 核心设计原则
3.1 时间线文本是核心资产
系统不再把"视频文件"作为唯一核心资产,而是把视频中发生的事情转化为自然语言时间线。
视频仍然保留,但它的主要用途变为:
- 作为原始证据;
- 支持用户在需要时回看;
- 为 AI 查询结果提供可验证片段;
- 支持后续重新分析或纠错。
时间线文本承担日常检索、推理和插件触发的主要职责。
3.2 轻重结合的双层 AI
系统不让大模型全天候处理视频,而是采用两层 AI 分工:
| 层级 | 模型 | 运行方式 | 职责 |
|---|---|---|---|
| 轻量视觉层 | Qwen3-VL-4B/8B 等轻量 VLM | 本地、低频/事件触发运行 | 将画面转为自然语言事件 |
| 重量推理层 | DeepSeek / 本地 LLM / 其他 LLM | 用户查询时按需调用 | 阅读时间线、回答问题、定位片段 |
3.3 控制面与数据面分离
系统中的小消息和大文件分开传输:
| 类型 | 通道 | 示例 |
|---|---|---|
| 控制面 | MQTT | 事件通知、任务下发、状态心跳、插件命令 |
| 数据面 | 文件系统 / HTTP | 截图、视频片段、模型文件、导出文件 |
原则:
- MQTT 只传消息信息,不传大文件;大文件通过本地共享目录或 HTTP 传输并在消息中引用。
- Mosquitto 作为 MQTT Broker;Genapsed 作为应用层中枢处理权限校验、消息路由、ACK 和入库编排。
3.4 系统是平台,不是单一应用
核心系统只提供底座能力:
- 接收视频事件;
- 生成时间线;
- 路由消息;
- 管理插件;
- 提供查询接口。
具体场景能力通过插件实现——老人看护、厨房安全、每日回顾、时间安排分析、智能家居联动等。
4. 核心组件职责边界
4.1 组件总览
| 组件 | 职责 | 详细设计文档 |
|---|---|---|
| Share | Python 共享基础包,提供配置、Topic、消息信封、MQTT 适配、数据目录、文件引用和 MySQL 连接模型 | — |
| Frigate NVR | 摄像头接入、录像、截图、移动/目标检测、事件来源 | Frigate-NVR集成 |
| NVR-Bridge | 第一阶段只适配 Frigate,转换 Frigate MQTT 事件和 HTTP API 媒体引用为 Everpast 标准消息 | Frigate-NVR集成 |
| Genapsed | 系统启动、组件管理、MQTT 路由、权限、日志、插件生命周期、配置管理 | Genapsed-核心组件 |
| Supervisor | 系统管理守护进程:网络配置、存储管理、系统更新、健康检查、首次启动配置向导(仅 OS 集成部署) | Supervisor-系统管理组件 |
| MiniVLM | 根据截图/关键帧生成自然语言事件和候选结构化字段 | MiniVLM-事件生成 |
| 时间线存储模块 | 保存事件、索引时间/摄像头/对象/动作、提供查询接口 | — |
| LLM 查询引擎 | 理解用户问题、读取时间线、定位视频片段、生成回答 | — |
| 插件系统 | 扩展业务能力,订阅事件并执行特定逻辑 | — |
| Web UI | 时间线浏览、自然语言查询入口、视频回放、系统配置 | WebUI设计 |
标记为"—"的文档尚未编写,属于后续文档补齐任务。
4.2 Share 共享基础包
Share 是各 Python 子模块复用的基础库,包名为 everpast_share。它不作为独立进程运行,也不承载业务编排,
而是提供组件之间必须保持一致的底层约定:
- 组件配置 Schema 校验和 JSON 对象文件读写;
- 统一数据目录布局,默认根目录为主仓库
data/; - MQTT Topic、QoS 策略、MessageEnvelope 和 MQTT 客户端适配;
- MySQL 连接配置、SQLAlchemy URL 构造、脱敏和组件数据库授权模型;
- 公共/私有临时文件传输引用管理;
- 组件 ID、插件 ID 和消息参与方 ID 校验。
Genapsed、www-server、Timeline 和 MiniVLM 的运行时适配应优先复用 Share 中的通用模型,避免各子模块重复定义 Topic、 数据库 URL 或数据目录规则。
4.2.1 本地数据存储标注
默认数据根目录为主仓库 data/,该目录整体不进入 Git。存储根目录由 Genapsed 的 --data-root 启动参数或配置管理确定;启动参数解析后的值会写入配置主源中的 data_root_dir,并通过 EVERPAST_DATA_ROOT 传给 Genapsed 拉起的组件和插件。组件不再各自硬编码 ../data/<component>,只从统一根目录派生自己的私有数据目录。下表是当前代码实现采用的数据存储标注,后续新增组件或插件应按同一规则声明自己的读写边界。
| 路径 | 内容 | 默认写入方 | 默认读取方 | 生命周期 / 清理 |
|---|---|---|---|---|
data/<component_id>/ | 组件私有运行数据、Genapsed 渲染出的组件配置文件 | 对应组件;跨组件配置文件由 Genapsed 渲染写入 | 对应组件;其他组件默认不可读 | 由组件和 Genapsed 生命周期管理 |
data/plugin/<id>/ | 插件私有运行数据、插件配置运行产物 | 对应插件;插件配置文件由 Genapsed 渲染写入 | 对应插件;其他插件默认不可读 | 插件卸载或用户清理时处理 |
data/logs/<component>/YYYY-MM-DD.jsonl | 组件结构化运行日志 | 对应组件;Docker 依赖日志由 Genapsed 采集后写入对应组件目录 | Genapsed / www-server 可按授权查询;组件可读自己的日志 | 默认按 14 天或 1GB 上限清理 |
data/logs/<component>/stdout.log | 开发模式下 Genapsed 拉起组件的 stdout/stderr 原文 | Genapsed 开发启动器 | 开发者、Genapsed 日志查询服务 | 开发调试文件,按日志清理策略或手动清理 |
data/db/mysql/ | MySQL 数据文件 | MySQL 容器 | MySQL 容器;组件通过各自 MySQL 用户访问 | 数据库生命周期管理,不能由普通组件直接改文件 |
data/db/mosquitto/ | Mosquitto 持久化数据 | Mosquitto 容器 | Mosquitto 容器 | Broker 生命周期管理 |
data/genapsed/dev/compose.yaml | 开发模式 Compose 文件 | Genapsed | 开发者、Genapsed | 可重复渲染覆盖 |
data/genapsed/docker/compose.yaml | Docker 数据库/部署辅助 Compose 文件 | Genapsed | 开发者、Genapsed | 可重复渲染覆盖 |
data/genapsed/database/credentials.json | Genapsed 初始化生成的组件数据库凭据 | Genapsed | 被授权组件按需读取自己的连接信息;文件权限应限制为本机运行用户 | 重新初始化数据库时更新 |
data/temp/share/public/<msg-UUID>/<file> | 跨组件公共大文件临时传输 | 发送方组件或 Genapsed 文件传输服务 | 所有可信组件可读写 | 消息处理完成后由 Genapsed 或发送方清理 |
data/temp/share/private/<msg-UUID>/<file> | 可能包含隐私内容的大文件临时传输,如原始监控片段 | 发送方组件或 Genapsed 文件传输服务 | 仅可信组件挂载/读取;不可信 Docker 组件不挂载 | 消息处理完成后由 Genapsed 或发送方清理 |
配置主源在 MySQL 的 everpast_system.component_configs;摄像头语义化元数据在 everpast_system.camera_registry;组件本地配置文件只是 Genapsed 从数据库渲染出的运行产物。结构化业务数据、状态和时间线数据进入 MySQL;运行日志使用 JSONL 文件,不写 MySQL;大文件不通过 MQTT 传输,只在 MQTT payload 中引用共享目录相对路径。
Docker 插件默认不挂载整个 data/ 根目录。插件或附加容器必须声明需要的 data_mounts,Genapsed 只把该插件自己的 data/plugin/<id> 下对应子路径挂入容器,避免不可信第三方插件读取或修改核心组件、数据库和共享私有数据。
4.3 Frigate NVR
Frigate NVR 是开源的 AI 友好型 NVR,负责摄像头接入、录像、目标检测、截图、视频片段精准裁剪等视频底座能力。它输出原生检测事件到 MQTT,不直接生成系统时间线,也不直接发布 Everpast 标准消息。视频片段的精准裁剪由 Frigate 负责,利用其成熟的视频处理逻辑,查询引擎和插件只需提供时间范围引用即可获取对应片段。
详细实现:MQTT 事件格式、配置参数、API 用法见
Frigate-NVR集成。
4.4 NVR-Bridge
NVR-Bridge 是视频底座适配层。第一阶段只兼容 Frigate,订阅 Frigate 原生 <topic_prefix>/events MQTT 事件,调用 Frigate HTTP API 生成截图和视频片段引用,并输出 everpast/nvr_bridge/event/high 标准事件信封。Genapsed 只处理标准消息和显式路由,不直接解析各类 NVR 的私有事件格式。
4.5 Genapsed
Genapsed 是系统的第一个核心组件,负责生命周期管理、MQTT 消息路由、插件管理、权限控制、日志查询与管理和配置管理(含 Config Manager 模块)。
详细实现:MQTT Topic 规范、消息格式、插件安全、权限系统、配置管理模块见
Genapsed-核心组件。
4.6 Supervisor
Supervisor 是 OS 层面的系统管理守护进程,仅在 Everpast OS 集成部署中存在。它管理 systemd 服务、网络配置、存储、更新和首次启动配置向导。
详细实现:7 大模块设计、接口定义、部署方案、路线图见
Supervisor-系统管理组件。
4.7 MiniVLM 事件生成模块
MiniVLM 是系统的"视觉翻译层",接收 Genapsed 路由来的 analyze_task,任务中包含 NVR-Bridge 归一化后的 Frigate 截图/关键帧引用;当前开发期 worker 使用静态后端打通链路,真实 VLM 后端接入后生成自然语言事件,并通过 MQTT 交给 Genapsed 调用 Timeline 入库。
详细实现:Prompt 设计方案、采样策略、去重合并逻辑、配置项见
MiniVLM-事件生成。
4.8 时间线存储模块
时间线存储模块负责把 Genapsed 传入的 MiniVLM 事件转化为可长期保存和检索的数据。它写入事件表、媒体引用表,支持按时间/摄像头/事件类型/对象/动作查询,为 LLM 查询引擎和插件提供数据访问。
当前实现使用 MySQL 作为唯一正式数据库后端,配合 SQLAlchemy / PyMySQL。开发环境可以由 Genapsed 生成项目内 Docker Compose 启动 MySQL,部署环境也可以接入外部 MySQL,但数据库、账号、组件库区和 GRANT 初始化仍由 Genapsed 执行。
4.9 LLM 查询引擎
LLM 查询引擎负责把用户自然语言问题转化为时间线查询和推理结果。它先读取时间线文本,调用 LLM 推理,必要时定位对应视频片段返回给用户。LLM 不可用时降级为关键词/结构化搜索。
AI 端点自定义:系统所有 AI 功能(MiniVLM、LLM 查询引擎)均向用户开放端点自定义。用户可在管理端配置自定义 API 端点(支持 OpenAI-compatible 接口),系统提供几组预设端点(如 DeepSeek、OpenAI、本地 Ollama 等),用户也可添加自己的 API 地址和密钥。
详细设计待补充。预设端点包括 DeepSeek API、OpenAI API、本地 Ollama 等常见后端,用户可自由切换或添加自定义端点。
4.10 插件系统
插件系统承载项目的扩展能力。插件可以订阅事件、注册关注点、添加 Prompt 片段、触发通知、提供 UI 页面、以容器或宿主机方式运行。
第一阶段策略:插件默认视为可信,直接在宿主机运行(使用独立 venv),降低初期复杂度。但架构上预留容器隔离接口和权限分级机制,为后续未认证插件的沙箱隔离留好拓展性。详细设计待补充。
5. 数据流概览
5.1 从摄像头到时间线
5.2 从用户查询到视频回放
查询原则:
- 优先查询时间线,而不是重新扫描全部视频;
- 先缩小时间范围,再调用 LLM 推理;
- 回放片段应基于事件
time_range和media_refs.video定位; - LLM 不可用时降级为关键词搜索和结构化字段过滤。
6. 插件系统架构
插件通过 Genapsed 接入系统:
插件可以声明:插件 ID、版本、订阅事件类型、注册事件类型、MiniVLM Prompt 关注点、需要的数据目录、运行方式(宿主机/容器)。
插件默认不能直接访问所有系统资源:
- 第一阶段插件默认可信,直接在宿主机运行(独立 venv);
- 架构预留容器隔离接口,后续可对未认证插件启用 Docker 沙箱;
- 每个插件只能发布/订阅自己的 topic;
- 文件访问通过 Genapsed 管理临时目录和权限。
7. 部署架构
7.1 单机家庭部署
适合家庭 NAS、迷你主机、小型 GPU 主机。
7.2 多设备部署
初期不考虑多设备部署。第一阶段聚焦单机家庭部署(§7.1),多设备分布式部署方案留待后续版本规划。
7.3 云端辅助模式
中央主机负责核心处理,云端仅提供 LLM API 和可选备份存储。
8. 技术选型
| 层级 | 选型 | 原因 |
|---|---|---|
| 视频底座 | Frigate NVR | 开源成熟,支持摄像头、录像、对象检测和事件输出 |
| 消息总线 | MQTT | 轻量、发布订阅、适合 IoT 和组件解耦 |
| 核心中枢 | Genapsed | 自研组件,用于生命周期、权限、插件和路由统一管理 |
| 视觉模型 | Qwen3-VL-4B/8B | 轻量视觉语言模型,适合本地低成本运行 |
| 查询模型 | 用户自定义端点(预设:DeepSeek / OpenAI / 本地 Ollama 等) | 开放端点自定义,用户可自由切换 AI 后端,平衡成本和效果 |
| 数据面 | 文件系统 / HTTP | 适合传输视频、截图等大文件,避免压垮 MQTT |
| 结构化数据库 | MySQL | 配置、时间线、组件数据和权限隔离统一使用 MySQL;Genapsed 负责初始化组件库、账号和 GRANT |
| 本地数据库容器 | Docker Compose | Genapsed 生成项目内 data/genapsed/docker/compose.yaml 管理开发/部署 MySQL 容器,不修改系统 Docker 全局配置 |
| 插件隔离 | 宿主机 venv(一期);预留 Docker 接口 | 初期默认可信降低复杂度,架构上预留容器隔离拓展性 |
| 前端界面 | Vue 3 + Vite + Element Plus Web UI | 当前 WebUI 代码使用 Vue 3 与 Element Plus,跨平台,适合家庭局域网访问;详见 WebUI设计 |
| 视频片段裁剪 | Frigate NVR | Frigate 拥有完善的视频处理逻辑,精准裁剪由其负责 |
9. 安全与权限设计
Topic 权限: 每个插件只能发布到自己的 topic 并订阅 Genapsed 授权的 topic,不能监听全局消息总线。Genapsed 负责全部权限检查。
文件权限: 插件默认只能访问自己的数据目录,大文件通过临时目录或 HTTP 授权链接传递,传输完成后清理。
隐私保护:
- 原始视频本地保存;
- VLM 本地优先;
- 云端 LLM 默认只接收脱敏后的时间线文本(无图像);
- 支持关闭云端调用;
- 用户可配置数据保留期限。
10. 可观测性与故障恢复
日志覆盖范围: 组件生命周期、MQTT 消息、MiniVLM 推理、时间线写入、插件运行。运行日志主源为 Genapsed 管理的本地 JSONL 文件,按天切分并按保留时间/总大小清理,不写入 MySQL。
健康检查: Genapsed 定期检查 Frigate、MQTT Broker、MiniVLM、时间线数据库、LLM 查询引擎、插件、磁盘空间是否正常。
故障恢复策略:
| 故障 | 恢复策略 |
|---|---|
| MQTT 断开 | 自动重连,必要时本地暂存事件 |
| MiniVLM 超时 | 发布预警,建议调高采样间隔或切换模型 |
| 时间线数据库不可写 | 暂停写入并告警 |
| 插件崩溃 | Genapsed 重启或禁用插件 |
| LLM API 不可用 | 降级为关键词/结构化搜索 |
11. 后续文档拆分建议
本文件描述系统总体架构。各组件详细设计分布在以下文档中:
| 文档 | 内容 |
|---|---|
Genapsed-核心组件 | MQTT Topic 规范、消息格式、插件安全、权限系统、配置管理模块 |
MiniVLM-事件生成 | Prompt 设计、采样策略、去重合并、配置项、性能优化 |
Supervisor-系统管理组件 | 系统管理 7 大模块、接口设计、部署方案、OS 镜像路线图 |
Frigate-NVR集成 | Frigate 配置、API、事件接入 |
WebUI设计 | 用户端和管理端 Web 界面 |
尚需补写的文档(标记为架构设计阶段未完成):
| 文档 | 内容 |
|---|---|
时间线存储设计.md | 数据库 Schema、索引、查询接口 |
LLM查询引擎设计.md | 查询流程、Prompt 模板、降级策略 |
插件系统架构.md | 插件生命周期管理、分发机制、开发指南 |
MQTT通讯协议规范.md | 完整 Topic 定义、消息格式、QoS 策略 |
12. 架构决策记录
以下为已确认的架构决策,供后续开发参考:
| 决策 | 结论 | 确认时间 |
|---|---|---|
| 结构化数据库 | MySQL,配合 SQLAlchemy / PyMySQL;SQLite 不作为受支持后端 | 2026-07 |
| 本地数据库启动 | Genapsed 生成项目内 Docker Compose;默认 MySQL 数据放 data/db/mysql,Compose 文件放 data/genapsed/docker/compose.yaml,镜像可配置仓库前缀 | 2026-07 |
| AI 端点 | 全开放自定义 + 预设(DeepSeek / OpenAI / Ollama) | 2026-07 |
| 多设备部署 | 初期不考虑,聚焦单机部署 | 2026-07 |
| 视频裁剪 | Frigate 负责 | 2026-07 |
| Web UI | Vue 3 + Vite SPA,配合 Element Plus 和 @element-plus/icons-vue;当前通过单应用内分区视图组织用户端、管理端和开发控制台,不直接连接 MQTT,由后端通过 HTTP API、WebSocket 或 SSE 提供数据 | 2026-07 |
| 插件运行 | 一期默认可信(宿主机 venv),预留 Docker 接口 | 2026-07 |
| 本地数据目录 | 主仓库 data/ 为默认数据根;组件使用独立子目录,数据库放 data/db,跨组件大文件经 `data/temp/share/public | private` 临时传输 |