11 KiB
11 KiB
三系统职责划分: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)。