docs: initialize YoVision requirements and architecture
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# 三系统职责划分: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 —— 把现场的流和信号稳定地拿进来并管住**
|
||||
|
||||
- 设备台账(`devices`,含 `modality`:video / radar / contact / button / wearable)
|
||||
- ONVIF 客户端:连接、GetProfiles、GetStreamUri、SetSystemDateAndTime
|
||||
- mediamtx API 客户端(**自行用 oapi-codegen 从其 OpenAPI 生成**,不依赖第三方 SDK)
|
||||
- **对账器**:水平触发、`sync_state`、独立信号量、10% 孤儿删除安全闸、只收敛不回滚
|
||||
- 探活与断线重建
|
||||
- WireGuard 控制面隧道
|
||||
- mediamtx 鉴权回调(401 + 踢流是四种停用粒度之一)
|
||||
- 容量配额执行:设备新增/启用时读取 Bell 的站点配额,只拒绝超额变更;配额服务暂时不可用时不影响已有流
|
||||
- 流绑定与媒体分片调度:维护 `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
|
||||
- 多租户 RBAC、`tenant_features`(人脸授权开关:未授权时能力在 API 与 UI 中**不可见**,不是禁用)
|
||||
- 审计日志
|
||||
- 站点容量配额的唯一真相源:`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/
|
||||
│ ├── device/ 设备台账(devices,含 modality)
|
||||
│ ├── 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 不需要**——它不碰事件契约。
|
||||
|
||||
---
|
||||
|
||||
## 3. 七条边界(不写死就会漂)
|
||||
|
||||
| # | 边界 | 定论 |
|
||||
| --- | --- | --- |
|
||||
| 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;依赖暂时不可用时拒绝新变更,但已有视频链路继续运行 |
|
||||
|
||||
第 2、3、6、7 条是本文档新定的,若实施中发现更合适的切法,改这里并同步《02》《03》。
|
||||
|
||||
---
|
||||
|
||||
## 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 的模型与触发 |
|
||||
| **M6** 异构传感器 + 两级判定 | Sense 的 `trigger/` 与 `device/`(modality 扩展)+ Brain 两级判定 |
|
||||
|
||||
> M3 是契约第一次被真实使用的时刻。**在此之前契约允许原地修订,之后版本递增规则绝对生效**(契约 README §1)。
|
||||
Reference in New Issue
Block a user