2026-08-03 17:22:22 +08:00
|
|
|
|
# 三系统职责划分:Sense / Brain / Bell
|
|
|
|
|
|
|
|
|
|
|
|
> 本文档回答一个问题:**一段代码该写进哪个目录。**
|
|
|
|
|
|
> 划分依据来自《03-通用场景应用方案》的 L0–L5 分层与组件选型,本文档只是把它按三个可独立开发的系统重新切分。
|
|
|
|
|
|
> 定稿:2026-08-03
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 三系统总表
|
|
|
|
|
|
|
|
|
|
|
|
| | **Sense** | **Brain** | **Bell** |
|
|
|
|
|
|
| --- | --- | --- | --- |
|
|
|
|
|
|
| 中文 | 感知系统 | 推理系统 | 管理系统 |
|
|
|
|
|
|
| 小学生版 | 感觉到 | 想一想 | 打铃叫人 |
|
|
|
|
|
|
| 对应层 | L1 接入 | L2 流水线 + L3 算法 | L4 业务 + L0 基座 |
|
|
|
|
|
|
| 语言 | Go | Python / CUDA | Go + 前端 |
|
|
|
|
|
|
| 有无状态 | 有(设备台账) | **无状态** | 有(事件、告警) |
|
|
|
|
|
|
| DB schema | `sense` | 无 | `bell` |
|
|
|
|
|
|
| 契约角色 | 供流与信号 → Brain | **产出**事件 | **消费**事件 |
|
|
|
|
|
|
| 首次交付 | M1 | M3 | M3(最小)→ M4(完整) |
|
|
|
|
|
|
|
|
|
|
|
|
### 1.1 各自装什么
|
|
|
|
|
|
|
|
|
|
|
|
**Sense —— 把现场的流和信号稳定地拿进来并管住**
|
|
|
|
|
|
|
2026-08-04 10:05:56 +08:00
|
|
|
|
- 设备台账(`devices`,含 `modality`:video / radar / contact / button / wearable / other,以及决定成像、媒体、遥测、空间配置等页面与操作的 `capabilities`)
|
2026-08-03 17:22:22 +08:00
|
|
|
|
- ONVIF 客户端:连接、GetProfiles、GetStreamUri、SetSystemDateAndTime
|
|
|
|
|
|
- mediamtx API 客户端(**自行用 oapi-codegen 从其 OpenAPI 生成**,不依赖第三方 SDK)
|
|
|
|
|
|
- **对账器**:水平触发、`sync_state`、独立信号量、10% 孤儿删除安全闸、只收敛不回滚
|
|
|
|
|
|
- 探活与断线重建
|
|
|
|
|
|
- WireGuard 控制面隧道
|
|
|
|
|
|
- mediamtx 鉴权回调(401 + 踢流是四种停用粒度之一)
|
|
|
|
|
|
- 容量配额执行:设备新增/启用时读取 Bell 的站点配额,只拒绝超额变更;配额服务暂时不可用时不影响已有流
|
2026-08-04 11:08:41 +08:00
|
|
|
|
- Area 准入执行:消费 Bell 的版本化 `capture_policy` 投影;策略不可用时只拒绝相关新写入,不静默中断已有设备
|
2026-08-03 17:22:22 +08:00
|
|
|
|
- 流绑定与媒体分片调度:维护 `mtx_instance`,默认 16 路交付;扩到 128 路时按 `media_shard.max_streams` 横向分片
|
|
|
|
|
|
- 边缘节点 agent:推流、本地环形缓冲、断网续传
|
|
|
|
|
|
- **设备型触发源**:雷达、门磁、按钮、ONVIF 事件订阅
|
|
|
|
|
|
- 非视频传感器的信号接收(signal plane,不走 mediamtx)
|
|
|
|
|
|
|
|
|
|
|
|
**Brain —— 看画面、出判定**
|
|
|
|
|
|
|
|
|
|
|
|
- Savant 流水线与适配器(ZeroMQ 边界,适配器故障隔离,实时模式丢帧)
|
|
|
|
|
|
- 模型:检测 / 姿态 / 跟踪 / ReID(`anon_id`)/(M5)人脸
|
|
|
|
|
|
- **`Detector` 与 `PoseEstimator` 接口解耦**——这是 AGPL 逃生通道的前提,换 YOLOX + RTMPose 时判定算法不动
|
|
|
|
|
|
- 判定内核:几何证据 + 时间窗状态机(从 silver_pose 抽取,两边共用)
|
|
|
|
|
|
- 事件 mapper:判定结果 → 事件契约 v0.1
|
|
|
|
|
|
- **像素级**运动侦测触发(要解码,所以在这里)
|
|
|
|
|
|
- 推理 worker 注册与分片:单逻辑推理分片默认最多 16 路;64/128 路由多个 worker 承担,路由变更不改判定代码
|
|
|
|
|
|
|
|
|
|
|
|
**Bell —— 记录、派发、追到人确认**
|
|
|
|
|
|
|
|
|
|
|
|
- 事件接收与校验(schema 校验 + 契约 README §5 那六条代码级断言 + 生成 ULID)
|
|
|
|
|
|
- 事件存储:**不可变**,误判只改 `outcome`
|
|
|
|
|
|
- 规则引擎 + 场景包加载
|
|
|
|
|
|
- 告警状态机:升级链、ack、抑制、静默(**≤4h,无永久选项**)
|
|
|
|
|
|
- 投递:push / 短信 / 语音,**双供应商**
|
|
|
|
|
|
- 误报反馈闭环:`outcome` 回写 Brain
|
2026-08-04 11:08:41 +08:00
|
|
|
|
- Tenant/Site/Area、`capture_policy`、多租户 RBAC、`tenant_features`(人脸授权开关:未授权时能力在 API 与 UI 中**不可见**,不是禁用)
|
|
|
|
|
|
- 全局审计日志;接收 Sense 设备操作审计并保留来源上下文
|
2026-08-03 17:22:22 +08:00
|
|
|
|
- 站点容量配额的唯一真相源:`site.max_video_channels` 默认 16、上限 128;提供版本化内部读取接口/投影给 Sense 执行
|
|
|
|
|
|
- 管理后台前端 + 大屏:按 128 路设计分页/虚拟列表、筛选与批量操作,不一次性加载全部视频
|
|
|
|
|
|
|
|
|
|
|
|
### 1.2 不属于任何一个目录的东西
|
|
|
|
|
|
|
|
|
|
|
|
| 组件 | 说明 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| **mediamtx** | 独立二进制,外部依赖。Sense 管它的配置与生命周期,`Sense/deploy/` 放基线配置 |
|
|
|
|
|
|
| **PostgreSQL / MinIO / Prometheus** | 基础设施,独立部署清单 |
|
|
|
|
|
|
| **silver_pose** | 独立仓库,是 Brain 判定内核的来源与单机演示形态。**不改名、不合并**——它现在能卖,Brain 还不能 |
|
|
|
|
|
|
| **`_reference/`** | 只读参考源码(如 MiBeeNvr)。按《03》§1.4 白名单借鉴 ONVIF、IP 自愈、健康检测、测试组织与 UI 交互;禁止复制媒体内核、SQLite 真相源、AI/用户体系,禁止整仓进生产或加入 go.mod |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 目录结构
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 Sense(Go)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
Sense/
|
|
|
|
|
|
├── cmd/
|
|
|
|
|
|
│ ├── sense-api/ 控制面服务:设备台账、鉴权回调、对账器
|
|
|
|
|
|
│ └── sense-agent/ 边缘节点:推流、环形缓冲、隧道
|
|
|
|
|
|
├── internal/
|
2026-08-04 10:05:56 +08:00
|
|
|
|
│ ├── device/ 设备台账(devices,含 modality + capabilities)
|
2026-08-03 17:22:22 +08:00
|
|
|
|
│ ├── onvif/ 连接、GetProfiles、GetStreamUri、SetSystemDateAndTime
|
|
|
|
|
|
│ ├── mtx/ oapi-codegen 生成的 mediamtx 客户端 + 薄封装
|
|
|
|
|
|
│ ├── reconcile/ 对账循环(幂等 + 退避 + 安全闸)
|
|
|
|
|
|
│ ├── probe/ 探活
|
|
|
|
|
|
│ ├── trigger/ 设备型触发源(雷达/门磁/按钮/ONVIF 事件)
|
|
|
|
|
|
│ ├── tunnel/ WireGuard 控制面
|
|
|
|
|
|
│ ├── authcb/ mediamtx 鉴权回调
|
|
|
|
|
|
│ └── store/ M1 先 SQLite,schema 与生产 Postgres 保持一致
|
|
|
|
|
|
├── deploy/
|
|
|
|
|
|
│ └── mediamtx.yml 基线配置
|
|
|
|
|
|
└── api/openapi.yaml
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 Brain(Python / CUDA)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
Brain/
|
|
|
|
|
|
├── pipeline/ Savant 流水线定义与适配器
|
|
|
|
|
|
├── models/
|
|
|
|
|
|
│ ├── detector/ Detector 接口 + YOLO / YOLOX 实现
|
|
|
|
|
|
│ ├── pose/ PoseEstimator 接口 + YOLO-pose / RTMPose 实现
|
|
|
|
|
|
│ ├── tracker/ ByteTrack / BoT-SORT
|
|
|
|
|
|
│ └── reid/ 匿名同一性,产出 anon_id
|
|
|
|
|
|
├── judge/
|
|
|
|
|
|
│ ├── evidence.py 几何证据(躯干角、髋部下坠比)
|
|
|
|
|
|
│ └── state.py 时间窗状态机 NORMAL/SUSPECT/CONFIRMED/RECOVERING
|
|
|
|
|
|
├── emit/
|
|
|
|
|
|
│ ├── mapper.py 判定结果 → 契约 v0.1
|
|
|
|
|
|
│ └── publisher.py 投递(HTTP 起步 → ZeroMQ);**失败落本地队列重试,不阻塞主链路**
|
|
|
|
|
|
├── trigger/ 像素级运动侦测
|
|
|
|
|
|
└── contracts/ ← 与 Bell/contracts/ 逐字节相同
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 Bell(Go + 前端)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
Bell/
|
|
|
|
|
|
├── cmd/bell-api/
|
|
|
|
|
|
├── internal/
|
|
|
|
|
|
│ ├── ingest/ 接收事件、schema 校验、六条断言、生成 ULID
|
|
|
|
|
|
│ ├── event/ 事件存储(不可变,只允许追加 outcome)
|
|
|
|
|
|
│ ├── rule/ 规则引擎 + 场景包加载
|
|
|
|
|
|
│ ├── alert/ 告警状态机、升级链、ack、静默
|
|
|
|
|
|
│ ├── deliver/ push / 短信 / 语音,双供应商
|
|
|
|
|
|
│ ├── feedback/ 误报回流,outcome 回写 Brain
|
|
|
|
|
|
│ ├── tenant/ 多租户 RBAC、tenant_features
|
|
|
|
|
|
│ ├── audit/ 审计日志
|
|
|
|
|
|
│ └── store/ Postgres(schema: bell)
|
|
|
|
|
|
├── web/ 管理后台前端
|
|
|
|
|
|
├── packs/ 场景包(**纯配置** —— M5 架构验收点)
|
|
|
|
|
|
└── contracts/ ← 与 Brain/contracts/ 逐字节相同
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> `contracts/` 只在 Brain 与 Bell 各存一份(生产者与消费者),**Sense 不需要**——它不碰事件契约。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-08-04 10:05:56 +08:00
|
|
|
|
## 3. 八条边界(不写死就会漂)
|
2026-08-03 17:22:22 +08:00
|
|
|
|
|
|
|
|
|
|
| # | 边界 | 定论 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| 1 | mediamtx 二进制归谁 | 独立进程。**Sense** 管配置与生命周期,部署清单放 `Sense/deploy/` |
|
|
|
|
|
|
| 2 | 触发源归谁 | 按性质切:**设备型**(雷达/门磁/按钮/ONVIF 事件)→ Sense,它们本来就是设备;**像素级**运动侦测 → Brain,它要解码 |
|
|
|
|
|
|
| 3 | pre-roll 证据切片谁裁 | 录制在 Sense(mediamtx),事件在 Brain 产出。**Bell 发起回捞**(它拥有事件),Sense 提供切片接口 |
|
|
|
|
|
|
| 4 | ULID 谁生成 | **Bell**。Brain 只填 `source_event_id`。见契约 README §4 |
|
|
|
|
|
|
| 5 | 一个 PostgreSQL 还是三个 | **一个实例,schema 分离**(`sense` / `bell`),Brain 无 schema。"DB 是唯一真相源"是对账器成立的前提,拆库即失效 |
|
|
|
|
|
|
| 6 | 16 路与 128 路分别指什么 | **16 路是默认交付规格,128 路是本阶段单逻辑站点上限**,都不是“单进程/单服务器保证值”。媒体与推理必须横向分片;单机承载量由分辨率、码率、帧率、模型和硬件基准测试决定 |
|
|
|
|
|
|
| 7 | 站点配额谁拥有、谁执行 | **Bell 拥有 `sites.max_video_channels`,Sense 在设备新增/启用写路径执行**。通过版本化内部 API 或只读投影同步,不允许 Sense 直接写 Bell schema;依赖暂时不可用时拒绝新变更,但已有视频链路继续运行 |
|
2026-08-04 11:08:41 +08:00
|
|
|
|
| 8 | 设备模态与隐私准入怎么建模 | 台账使用 `modality + capabilities`,不以摄像头作为唯一根实体;**Bell 拥有 Area 与 `capture_policy`,Sense 消费带版本投影并按设备 `captures_image` 能力在新增/启用写路径执行**。策略不可用时拒绝相关新变更并告警,已有链路不静默停用;M1 固化模型,M6 再增加非视频适配器 |
|
|
|
|
|
|
| 9 | 接入操作审计怎么进入 Bell | Sense 在同一事务写设备期望态和持久化 outbox,再由幂等 relay 异步汇入 Bell 全局审计;不得先执行高风险操作再尽力入队。字段、签名、重放和留存由独立 API/契约任务冻结 |
|
2026-08-03 17:22:22 +08:00
|
|
|
|
|
2026-08-04 11:08:41 +08:00
|
|
|
|
第 2、3、6、7、8、9 条是本文档新定的,若实施中发现更合适的切法,改这里并同步《02》《03》。
|
2026-08-03 17:22:22 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 标识符约定
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
仓库/目录 Sense Brain Bell
|
|
|
|
|
|
镜像 yov/sense:x.y yov/brain:x.y yov/bell:x.y
|
|
|
|
|
|
日志/指标前缀 sense_ brain_ bell_
|
|
|
|
|
|
三字母码 SEN BRN BEL
|
|
|
|
|
|
DB schema sense — bell
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**命名规则:系统名不得是该系统领域模型里的实体名。**
|
|
|
|
|
|
`bell` 域内有 `alerts` 表 → 系统不能叫 Alert(`alert.alerts` 无法读,且撞 Prometheus 内置的 `ALERTS` 序列)。另两个同样干净:`sense` 域内是 `devices`/`streams`,`brain` 域内是 `models`/`detections`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 里程碑与目录的对应
|
|
|
|
|
|
|
|
|
|
|
|
| 阶段 | 动哪个目录 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| **M0** 摄像头兼容性验证 | 无生产代码;可直接运行 MiBeeNvr 等 `_reference/` 项目作为隔离实验室测试台,产物允许丢弃 |
|
|
|
|
|
|
| **M1** 5 路接入骨架 + mediamtx | **仅 Sense**;MediaMTX 正式进入,完整 MiBeeNvr 不得替代生产媒体数据面 |
|
|
|
|
|
|
| **M2** 对账器 + 多租户 + 隧道 + 16 路开通 | **仅 Sense**;至少一个站点验证默认 16 路配额与全流程 |
|
|
|
|
|
|
| **M3** 默认 16 路推理 + 规则引擎 + 事件预警 | **Brain + Bell 同时起步**,契约在此首次被真实使用 |
|
|
|
|
|
|
| **M4** 64 路分片 + 灰度 + 管理系统 | Sense 与 Brain 完成横向分片,Bell 完成 128 路规模下的列表与批量交互;验证单分片故障隔离 |
|
|
|
|
|
|
| **M5** 128 路容量验收 + 第二三场景包 + 触发式推理 + 人脸 | Sense/Brain 验证扩容不改业务代码;Bell 的 `packs/`(**纯配置**)+ Brain 的模型与触发 |
|
2026-08-04 10:05:56 +08:00
|
|
|
|
| **M6** 异构传感器 + 两级判定 | Sense 的 `trigger/` 与 `device/` 增加非视频协议适配器与能力实现(`modality + capabilities` 模型已从 M1 保留)+ Brain 两级判定 |
|
2026-08-03 17:22:22 +08:00
|
|
|
|
|
|
|
|
|
|
> M3 是契约第一次被真实使用的时刻。**在此之前契约允许原地修订,之后版本递增规则绝对生效**(契约 README §1)。
|