2026-08-03 22:18:02 +08:00
# 技术栈
> 已决项必须遵守;标为“待定”的版本或组件不得由 agent 自行拍板,应先落 Gitea Issue 并更新本文。
## 1. 已定技术方向
| 范围 | 选择 | 状态与说明 |
| --- | --- | --- |
2026-08-03 23:43:43 +08:00
| 首期部署 | 客户侧私有化实例 | 保留 `tenant_id` 、RBAC、schema 和 API 的 SaaS-ready 隔离边界 |
| M1– M3 视频接入 | ONVIF / RTSP | 售前盘点存量 NVR; GB/T 28181-2022 不进当前 MVP,按需另建适配任务 |
2026-08-04 17:25:33 +08:00
| 本地摄像头基线 | 1 台 Hikvision IP Camera + 独立合成 RTSP 源 | 海康精确型号/固件由 T-001 冻结;T-006 冻结合成 publisher 及版本。仅为开发策略,不在业务代码写死品牌,也不替代 T-007 真实多路现场验收 |
2026-08-03 22:18:02 +08:00
| Sense | Go | 设备、ONVIF、MediaMTX 控制与对账 |
| 媒体数据面 | MediaMTX 独立二进制 | MIT; M1 正式生产基线 |
| MediaMTX API | 从官方 OpenAPI 用 `oapi-codegen` 生成 + 薄封装 | 不依赖第三方非官方 SDK |
| Brain | Python / CUDA | 推理流水线与判定内核 |
2026-08-03 23:43:43 +08:00
| 推理框架主选 | Savant / NVIDIA DeepStream | M1– M3 只验证 NVIDIA x86/Jetson;具体版本与目标 GPU 待 M0/M1 压测冻结 |
| 推理框架/硬件逃生通道 | ONNX 接口 + 可替换框架适配层;Pipeless 候选 | 信创不在 M1–M3 承诺内,海光/鲲鹏/昇腾/寒武纪走独立硬件 POC 与报价 |
2026-08-03 22:18:02 +08:00
| 模型主选 | Ultralytics YOLO(含 pose) | 商用前必须购买 Enterprise License |
| 模型备选 | YOLOX + RTMPose | 主选授权未批或目标硬件不适配时启用 |
| 跟踪/同一性 | ByteTrack 或 BoT-SORT + ReID | 具体组合待基准测试;ReID 默认、人脸可选 |
| Bell 后端 | Go | 事件、规则、预警、租户与审计 |
2026-08-03 23:43:43 +08:00
| Bell 客户端 | 值班室 Web + 响应式移动 H5 | 前端框架仍须经 UI 原型和技术评审冻结;M3 不做独立原生 App |
| Bell 对外集成 | 版本化 OpenAPI / Webhook | Bell 持有事件、Alert、ack、升级链、租户与审计真相 |
2026-08-03 22:18:02 +08:00
| M1 本地存储 | SQLite | schema 与生产 PostgreSQL 保持一致,仅 Sense 初期使用 |
| 生产数据库 | PostgreSQL,一个实例、`sense` /`bell` schema 分离 | Brain 无业务 schema |
2026-08-03 23:43:43 +08:00
| 证据对象存储 | 客户侧 MinIO / S3 兼容 | 常态录像留在客户 NVR;事件片段技术默认 30 天,最终期限由客户/法务确认 |
| 通知投递 | Bell provider 接口 | 供应商待项目采购;试点使用本地声光/Web + 一条短信或语音,生产前两条独立路径并支持故障切换 |
2026-08-03 22:18:02 +08:00
| 边缘隧道 | WireGuard | 控制面管理 |
| 指标 | Prometheus + Grafana | 三系统统一可观测入口 |
| 追踪 | OpenTelemetry + Jaeger | 端到端事件链路 |
2026-08-04 15:45:50 +08:00
### 1.1 Sense M1 冻结版本(T-003)
| 组件 | 冻结版本 | 许可证 / 校验 | 升级与退出路线 |
| --- | --- | --- | --- |
| Go | `1.26.5` ( `go 1.26.0` + `toolchain go1.26.5` ) | BSD-3-Clause;从 `go.dev/dl` 校验,Windows amd64 ZIP SHA-256 `97e6b2a833b6d89f9ff17d25419ac0a7e3b482a044e9ab18cdef834bd834fd38` | 跟随仍受支持的 Go 小版本,先在 CI/目标平台跑全量测试再升级;标准 Go module,无私有运行时绑定 |
| SQLite driver | `modernc.org/sqlite v1.54.0` | BSD-3-Clause; module sum `h1:JCxR4qwkJvOaqAoYcgDoO25Nc+ROg6EJ2LfBVzdrgog=` , go.mod sum `h1:4ntCLuNmnH8+GNqjka1wNg7KJd5/Hi5FYp8K+XQ7GZw=` | 选择无 CGO driver 以简化 Windows/边缘部署;只经 `database/sql` 与 repository 使用,可替换 driver;生产仍迁移到 PostgreSQL `sense` schema |
| MediaMTX | `v1.19.3` | MIT;官方 release `checksums.sha256` : Windows amd64 `5d82148d1032a6a190d9909a2997d9989457aaadf49af87dd02cd4512d31bebe` 、Linux amd64 `a7ba21268fccda3ebc43fdad76b87fddb85ce77e725b5cb637bca724b5394fbe` 、Linux arm64 `9e5b38a5b5fcab1916341b024031b2fc5dc6a2059baed9ba3f3b0d3768d231a8` | 独立进程,不链接到 Sense;升级时先更新 vendored OpenAPI、重新生成并跑假服务契约测试;可通过 `mtx` port 更换媒体数据面 |
| oapi-codegen | `v2.8.0` | Apache-2.0; module sum `h1:s4hxMxuqtR8jPzXkBTtFwY/SBuj3gEAYikmbBSdtLMM=` , go.mod sum `h1:yae2TI9IYB5vxQ35gFrpXh9L5H1eJv4MAUK1jumGMTo=` | 仅为构建工具;版本锁在 module tool dependency,生成文件与薄封装分离;升级后必须重新生成并检查 diff |
| oapi-codegen runtime | `v1.6.0` | Apache-2.0; module sum `h1:7Xx+GlueD6nRuyKoCPzL434Jfi3BetbiJOrzCHp/VPU=` , go.mod sum `h1:GwV7hC2hviaMzj+ITfHVRESK5J2W/GefVwIND/bMGvU=` | 生成客户端的最小运行时;与生成器一起升级并跑假 HTTP 契约测试,退出时随生成客户端一并替换 |
MediaMTX 官方 `v1.19.3` OpenAPI 固定保存于 `Sense/api/vendor/mediamtx-v1.19.3.openapi.yaml` , SHA-256 为 `a2b58195f1ec76541e124b5de4ee54645e5a3e25f70c4a73acc4a44d6f2b9c52` 。下载二进制后必须对照上表或官方同版 `checksums.sha256` ,不得使用浮动 `latest` URL。SQLite `v1.56.0` 在本决策日刚发布,T-003 不追新;后续依赖升级单独评审。
2026-08-07 17:52:50 +08:00
### 1.2 Sense M2 PostgreSQL 冻结版本(T-009)
| 组件 | 冻结版本 | 许可证 / 校验 | 使用与退出路线 |
| --- | --- | --- | --- |
| PostgreSQL | `17.10` | PostgreSQL License;本机验收二进制 `D:\pgsql17\bin\postgres.exe` 与 `psql.exe` 均报告 `17.10` | 首期一个实例、`sense` /`bell` schema 分离;自动测试用同版二进制启动隔离临时集群,不改现有服务。升级 17.x 小版本须重跑 migration、权限和 repository 集成测试;跨大版本先做备份恢复演练 |
| Go PostgreSQL driver | `github.com/jackc/pgx/v5 v5.10.0` 的 `stdlib` | MIT; module sum `h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0=` , go.mod sum `h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=` | 只通过 `database/sql` 和 store port 使用;DSN 只来自进程环境且不记录。退出时可更换 `database/sql` driver,业务域与调和器不依赖 pgx 类型 |
M2 仍保留 SQLite 作为单机开发与 T-006 回归入口,但生产真相源切换目标是 PostgreSQL。运行时必须显式设置 `SENSE_DB_DRIVER=postgres` 和私有 `SENSE_DB_DSN` 才使用 PostgreSQL;仓库不提供带密码 DSN。初始 schema 由 `deploy/postgres/` 的顺序 migration 创建,不在 Sense 进程启动时使用高权限自动迁移。
2026-08-07 23:00:03 +08:00
T-011 复用同一套冻结的 Go、PostgreSQL、pgx 与 `oapi-codegen` ,未增加第三方依赖。Sense Control API v1 从仓库 OpenAPI 生成 `net/http` server glue;首版认证是可替换 port 下的外部静态 SHA-256 注册表,公共路由默认关闭且只在 PostgreSQL 生产路径启用。T-011 首次落成 v4 schema, T-012 后进程统一要求 v5。静态适配器是私有部署启动方案,不替代后续 Bell/JWT/OIDC 身份服务。
T-012 同样未增加第三方依赖:PostgreSQL v5 使用数据库时钟租约和 fencing token 协调多实例调和/孤儿扫描;MediaMTX Path 枚举继续使用同版生成客户端。`/metrics` 由 Go 标准库输出 Prometheus 文本格式,只包含固定结果枚举、构建/实例信息和汇总 gauge/counter,不使用 tenant、Site、device 或 Path 标签。孤儿处置是 PostgreSQL 专用本地命令,默认周期任务只报告、不自动删除。
2026-08-07 20:54:41 +08:00
2026-08-10 23:16:12 +08:00
T-014 没有增加生产依赖。Windows 容量脚本冻结并核对 Sense 模块 Go 1.26.5、PostgreSQL 17.10、MediaMTX v1.19.3 与 FFmpeg 8.1.2; MediaMTX Windows amd64 ZIP 使用上表官方 SHA-256,解压后 `mediamtx.exe` 另固定为 `1cda85249312cb9463f9f94c5a712b9f160c9af3fd9490f0d4723911d7880e05` 。FFmpeg 只生成无人物夹具并以 16 个独立 `-c copy` 进程发布,不进入生产镜像或 Go module。正式本机结果与限制见 [`research/sense-16-stream-capacity.md` ](research/sense-16-stream-capacity.md )。
2026-08-10 23:53:11 +08:00
### 1.3 Bell M3 事件存储冻结版本(T-015)
| 组件 | 冻结版本 | 许可证 / 校验 | 使用与退出路线 |
| --- | --- | --- | --- |
| Go | `1.26.5` (与 Sense 相同) | BSD-3-Clause;复用 §1.1 工具链与校验 | Bell 独立 Go module;升级时同时运行两个 module 的 test/vet/build |
| PostgreSQL / pgx | `17.10` / `github.com/jackc/pgx/v5 v5.10.0` | PostgreSQL License / MIT; module sum `h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0=` | 复用 T-009 的 `database/sql` 边界;运行身份改用无 owner 权限的 `bell_runtime` 组 |
| JSON Schema | `github.com/santhosh-tekuri/jsonschema/v6 v6.0.2` | Apache-2.0; module sum `h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=` | 运行时校验 Draft 2020-12 与 format;退出时可替换 validator,但冻结 schema 和负向契约测试不变 |
| ULID | `github.com/oklog/ulid/v2 v2.1.2` | Apache-2.0; module sum `h1:IEclFb9JNvzYA6MW2SCxbLzcHTVsfqm3PrqGQJH5zec=` | 只封装在 Bell ID generator port 后;平台前缀仍为 `evt_` ,替换实现不得改变格式或所有权 |
T-015 不冻结 Brain→Bell transport,也不产生可部署 Bell API 二进制。内部 factory 接收不含 `id` 的候选事实,由 Bell 生成 ULID 后才形成最终 v0.1 事件;不得把该 Go 类型当成公共网络协议。
2026-08-03 22:18:02 +08:00
## 2. 外部项目边界
- MiBeeNvr:只用于 M0 隔离实验室、ONVIF兼容性和交互参考,不作为生产依赖。
- MediaMTX:生产媒体数据面,不提供 YoVision 业务管理 UI。
- silver_pose:独立可交付仓库,是 Brain 判定内核的来源;不改名、不合并。
- `_reference/` :只读、忽略、不进入模块依赖和生产镜像。
## 3. 待冻结项
2026-08-07 17:52:50 +08:00
- Python、Savant/DeepStream 的精确版本;Go、MediaMTX 与 PostgreSQL 已分别为 Sense M1/M2 冻结,后续阶段可按升级流程调整。
2026-08-03 22:18:02 +08:00
- Bell 前端框架和组件库。
- 事件投递 transport 从 HTTP 起步还是直接采用消息总线。
- 目标 GPU/边缘硬件、解码能力和每 worker 的 `max_sources` 。
2026-08-03 23:43:43 +08:00
- MinIO/S3 的精确版本、加密实现,以及客户/法务确认后的最终生命周期策略。
- 短信/语音供应商及生产双路径组合;是否开发原生 App 最早在 M4 根据试点反馈决定。
2026-08-03 22:18:02 +08:00
这些选项必须在对应任务中记录基准、许可证、运维成本和退出路线。
## 4. 当前标准入口
2026-08-04 15:45:50 +08:00
Sense M1 骨架建立后,根目录脚本同步 Go 依赖并执行治理与 Sense 验证:
2026-08-03 22:18:02 +08:00
```powershell
./ init . ps1
```
WSL/Linux/macOS/Git Bash:
```bash
./init.sh
```
2026-08-04 15:45:50 +08:00
Sense 单独执行:
```powershell
go -C Sense mod download
2026-08-07 20:54:41 +08:00
go -C Sense generate ./ internal / mtx ./ internal / controlapi
2026-08-04 15:45:50 +08:00
go -C Sense test ./...
go -C Sense vet ./...
go -C Sense build ./...
go -C Sense run ./ cmd / sense-api
```
2026-08-10 23:53:11 +08:00
Bell 事件域基础单独执行(当前没有可启动 API):
```powershell
go -C Bell mod download
go -C Bell test ./...
go -C Bell vet ./...
go -C Bell build ./...
```
2026-08-03 22:18:02 +08:00
直接验证:
```powershell
python scripts / validate_agent_context . py
python -m unittest discover -s tests -p "test_*.py"
python scripts / validate_harness_governance . py
```
## 5. 验证矩阵
| 改动范围 | 每次必跑 | 完整门禁触发条件 | 人工/设备门禁 |
| --- | --- | --- | --- |
| Harness 文档/任务/Gitea 模板 | 上述三条 Python 命令 | 任一治理协议、清单或任务 schema 变化 | 不适用 |
| `docs/raw/contracts/` | JSON Schema 校验 + 契约代码断言(实现后补命令) | schema/示例/mapper 任一变化 | 生产者与消费者联合评审 |
2026-08-07 20:54:41 +08:00
| Sense Go | `go -C Sense generate ./internal/mtx ./internal/controlapi` 、`go -C Sense test ./...` 、`go -C Sense vet ./...` 、`go -C Sense build ./...` | ONVIF、存储、MediaMTX、对账或公共 API 变化 | T-006 使用 1 路指定实机 + 4 路独立合成源;T-007 才要求客户/借用/租赁的真实多路矩阵 |
2026-08-07 17:52:50 +08:00
| PostgreSQL schema/repository | `python -m unittest discover -s tests -p "test_postgres_contract.py"` ; Windows 本机再运行 `./scripts/test_postgres.ps1 -PgRoot D:\pgsql17` | migration、权限、配额判定或 PostgreSQL driver 变化 | 不需要摄像头;必须核对临时集群未使用现有 data 目录,现有 5432 listener 前后不变 |
2026-08-03 22:18:02 +08:00
| Brain Python | 单元测试、类型/格式检查(命令待项目脚手架冻结) | mapper、判定状态机、模型接口变化 | 命中模型任务时用冻结数据集和目标硬件 |
2026-08-10 23:53:11 +08:00
| Bell Go/Web | 当前后端:`go -C Bell test ./...` 、`go -C Bell vet ./...` 、`go -C Bell build ./...` ;前端命令待脚手架冻结 | schema、RBAC、预警状态机或公共 UI 变化 | P0 UI 流程由产品/值班角色验收;纯事件存储不需要 UI 人工验收 |
2026-08-10 23:16:12 +08:00
| 容量/分片 | 任务内基准脚本;本地 16 路入口为 `./Sense/scripts/t014-capacity.ps1 -PgRoot D:\pgsql17` | 默认 16 路软件基线,以及后续 64/128 路分片里程碑 | 本地 16 路控制面可用独立合成源;真实多路、生产 SLA、64/128 路、AI/GPU、网络与存储必须使用目标环境分别验收 |
2026-08-03 22:18:02 +08:00
代码脚手架落地时必须把真实命令同步到本文、`init.ps1` /`init.sh` 、`00-ai-start-here.md` 和 `current-state.md` 。