Files
yovision/docs/raw/08-三系统职责划分.md

11 KiB
Raw Permalink Blame History

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