- kvm-meta: add kvm-npu, kvm-rkllm to Recommends - docker-compose.yml: fix build context (tools/workflow-dashboard), correct PRIVACY_RS_URL port (8000->8001), add NPU_DAEMON_URL - CLAUDE.md: update service table with DEB package names, add npu_daemon to directory structure, update build commands Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 KiB
11 KiB
KVM-Privacy 项目配置
语言规则
- 所有交互使用中文(代码注释、变量名、类名保持英文)
- 技术术语可使用英文原文
- Git commit 消息使用英文
项目概述
KVM-Privacy 是一个基于 KVM-over-IP 的两层隐私保护系统,运行在 NanoPC-T6 (RK3588) 上。所有防护完全在 KVM 设备端完成,无需在被控机器上部署任何软件。
核心服务
| 服务 | 端口 | DEB 包 | 说明 |
|---|---|---|---|
| KVM Server (Go) | 8080 | kvm-server | KVM 控制 + React WebUI + WebRTC |
| info-privacy-rs (Rust) | 8001 | kvm-privacy | RKNN PII 检测/脱敏 |
| NPU Daemon (Rust) | 8004 | kvm-npu | 集中 RKNN 推理 (OCR/Face) |
| mem-bridge memory | 8001 | kvm-bridge | 会话存储 + FAISS 向量搜索 |
| mem-bridge router | 8002 | kvm-bridge | AI 路由服务 |
| Privacy Gateway (Python) | 8888 | kvm-mitm | mitmproxy 网络拦截 |
| KVM Agent (Python) | 8890 | kvm-agent | AI Agent daemon |
| RKLLM Server (Python) | 8891 | kvm-rkllm | 本地 LLM (Qwen3-0.6B NPU) |
架构
用户 → KVM WebUI → KVM Server (Go)
├── 视频流(隐私遮蔽)
├── HID 控制(键盘/鼠标)
├── OCR 扫描(RKNN)
└── KVM Agent(自主操作)
├── 本地感知(OCR + logodetect)
├── LLM 规划(gpt-4o / 本地模型)
├── 操作验证(前后截屏对比)
└── 记忆系统(mem-bridge)
目录结构
services/
kvm_agent/ # Python - KVM AI Agent
privacy_gateway/ # Python - mitmproxy 隐私网关
rkllm_server/ # Python - RKLLM 本地 LLM 服务
npu_daemon/ # Rust - NPU 推理守护进程
tools/
workflow-dashboard/ # 测试工具(非生产),独立 pyproject.toml
KVM/ # Git submodule - Go KVM 服务端
deps/ # Git submodules - 依赖项目
deploy/systemd/ # systemd 服务文件
debian/ # DEB 包定义 (kvm-mitm, kvm-agent, kvm-bridge, kvm-npu, kvm-privacy, kvm-rkllm, kvm-meta)
scripts/build-debs.sh # 全栈 DEB 构建脚本
编码规范
- Python:asyncio + httpx,类型注解,dataclass 优先
- 异步优先:所有 I/O 操作使用 async/await
- 错误处理:finally 块中释放资源(HID 控制、隐私模式)
- 测试:pytest + pytest-asyncio,mock 外部依赖
- 配置:YAML 文件 + 环境变量,dataclass 承载
测试方法论
严格的 action→screenshot→verify 工作流
所有 KVM HID 测试必须遵循:
- 执行操作 — 调用 mouse_ops/kvm 方法
- 等待 —
await asyncio.sleep()(0.5s-3s) - 截图 —
await kvm.screenshot() - OCR 验证 —
ocr_snapshot_raw()+check_text() - 记录证据 —
collector.save_screenshot()+collector.record() - 下一操作 — 仅验证通过后继续
禁止推理替代验证
- 不得基于 Claude 对 Windows 界面的知识判断操作结果
- 不得跳过截图/OCR 步骤
- 每个 assert 必须基于
ocr_result、pixel_diff或screenshot的实际数据 - 测试修复必须基于 verify_live.py 的实际运行输出
优先使用 StepVerifier
StepVerifier.verify_action() 封装完整循环: action → sleep → screenshot → OCR → semantic assert
pixel_diff 的局限
- 时钟变化 ~24% diff — 不能用于判断"操作成功"
- 仅用于判断"屏幕是否变化"
- OCR 语义验证 > 像素对比
前端架构变更(2026-03)
GatewayMode 类型
privacyMode已从boolean升级为'off' | 'audit' | 'redact'- 类型定义:
deps/KVM/web/src/types/privacy.ts - PiiOverlay:
audit= 红色边框,redact= 黑色填充,off= 清空
页面 Tab 结构
- PrivacyPage:5 tabs — dashboard / network / screen / rules / settings
- screen tab:
GET /api/v1/privacy/screen/detections - rules tab:
GET/POST/PUT/DELETE /api/v1/privacy/patterns
- screen tab:
- AuditPage:2 tabs — logs / recordings(OCR/patterns 已迁移到 Privacy)
Agent 运行期间 HID 禁用
- kvmStore 所有 HID 发送函数检查
useAgentStore.getState().status === 'running' - ConsolePage 粘贴/虚拟键盘按钮在 Agent 运行时禁用
架构决策:鼠标优先
背景
实机测试暴露组合键系统性风险:Alt+F4 触发关机、Win+D 二次触发恢复窗口、IME 拦截 Enter/Space。
规则
- safety.py 白名单:只允许 20 个单键,所有组合键一律禁止
- mouse_ops.py:所有操作通过鼠标+OCR 完成
- LLM 提示词:不提供 shortcut action type
- 翻译层:agent._shortcut_to_mouse() 将 Alt+F4→close_window 等
安全键 (允许)
escape, enter, tab, backspace, delete, space, up/down/left/right, shift, f1-f5, f11, f12
鼠标等价操作
| 组合键 | 鼠标替代 |
|---|---|
| Alt+F4 | mouse_ops.close_window() |
| Win+D | mouse_ops.show_desktop() |
| Win+R | mouse_ops.launch_from_taskbar() |
| Ctrl+S | mouse_ops.click_element("保存") |
常用命令
# 运行 KVM Agent 单次任务
python3 -m kvm_agent --task "打开记事本" --kvm-url http://localhost:8080
# 运行单元测试(不需要实体设备)
cd services/kvm_agent && python3 -m pytest tests/ --ignore=tests/test_integration.py -v
# 运行集成测试(需要实体 KVM 设备)
cd services/kvm_agent && python3 -m pytest tests/test_integration.py -v
# Go 后端编译(go.mod 在 deps/KVM/go/;系统 go 是 1.15 需用绝对路径)
cd deps/KVM/go && /usr/local/go/bin/go build ./...
# kvm-server deb 打包(需要 Go 1.24 在 PATH 前面)
cd deps/KVM && PATH="/usr/local/go/bin:$PATH" bash scripts/build-deb.sh
# 构建全部 DEB 包(Python + Rust + 闭源库)
bash scripts/build-debs.sh
# 跳过 Rust 编译(使用已有二进制)
bash scripts/build-debs.sh --skip-rust
# 前端编译
cd deps/KVM/web && npm run build
# Dashboard (测试工具,非生产)
cd tools/workflow-dashboard && python3 -m workflow_dashboard
# Dashboard (Docker)
cd tools/workflow-dashboard && docker compose up -d
# 查看服务状态
systemctl status kvm-agent mem-bridge-memory mem-bridge-router info-privacy privacy-gateway npu-daemon rkllm-server
# 设备连接
ssh pi@192.168.123.181
Deb 包开发完整工作流
修改 → 构建 → 验证
每次修改 deb 包相关文件(debian/control, postinst, prerm, systemd service, C 源码)后,按以下流程验证:
# 1. 构建
cd deps/KVM && PATH="/usr/local/go/bin:$PATH" bash scripts/build-deb.sh
# 2. 静态检查包内容(无需设备)
DEB=$(ls deps/KVM/dist/kvm-server_*.deb | tail -1)
dpkg -I "$DEB" | grep "Depends\|Recommends" # 检查依赖
dpkg -c "$DEB" | grep "\.service\|\.timer\|usr/lib" # 检查安装文件
dpkg -x "$DEB" /tmp/kvm-check && grep -n "systemctl" /tmp/kvm-check/DEBIAN/postinst
dpkg -x "$DEB" /tmp/kvm-check && grep -n "systemctl" /tmp/kvm-check/DEBIAN/prerm
grep "Requires\|Wants" /tmp/kvm-check/lib/systemd/system/kvm-server.service
# 3. 拷贝到目标设备
scp "$DEB" pi@192.168.123.181:/tmp/
标准安装/卸载/重装验证循环
必须按此顺序在目标设备执行(ssh pi@192.168.123.181):
# [1] 首次安装
sudo dpkg -i /tmp/kvm-server_*.deb
sleep 5
systemctl is-active kvm-server && echo "PASS" || echo "FAIL"
curl -sf http://localhost:8080/api/v1/kvm/stream/stats
# [2] 卸载(保留 conffiles)
sudo dpkg --remove kvm-server
systemctl is-active kvm-server && echo "FAIL" || echo "PASS: stopped"
ls /etc/kvm/config.json && echo "PASS: config preserved" || echo "FAIL: config lost"
# [3] 重装(验证 conffile 不被覆盖、服务恢复)
sudo dpkg -i /tmp/kvm-server_*.deb
sleep 5
systemctl is-active kvm-server && echo "PASS" || echo "FAIL"
curl -sf http://localhost:8080/api/v1/kvm/stream/stats
# [4] Purge(验证干净卸载)
sudo dpkg --purge kvm-server
ls /etc/kvm/config.json 2>/dev/null && echo "FAIL: conffile not purged" || echo "PASS: purged"
# [5] 最终 clean install
sudo dpkg -i /tmp/kvm-server_*.deb
关键验证点
| 验证项 | 命令 | 期望结果 |
|---|---|---|
| 安装不卡住 | time dpkg -i *.deb |
< 60s |
| 服务启动 | systemctl is-active kvm-server |
active |
| USB gadget 软依赖 | systemctl is-active kvm-usb-gadget || true |
失败不影响 kvm-server |
| OCR timer 已移除 | systemctl list-units | grep ocr-snapshot |
空 |
| API 可达 | curl localhost:8080/api/v1/kvm/stream/stats |
JSON 响应 |
| Conffile 保留 | ls /etc/kvm/config.json after remove |
文件存在 |
| Conffile 清除 | ls /etc/kvm/config.json after purge |
文件不存在 |
常见 systemd 包问题(已修复)
| 问题 | 症状 | 修复 |
|---|---|---|
| 双重启动 | postinst 有手动 systemctl restart + dh_installsystemd 各触发一次 |
删除手动 systemctl 区域 |
| 双重 stop | prerm 有手动 systemctl stop + dh 的 deb-systemd-invoke stop |
删除手动 systemctl stop |
| USB gadget 硬依赖 | Requires=kvm-usb-gadget → gadget 失败导致 kvm-server 不启动 |
改为 Wants= |
| setup-usb-gadget 崩溃 | set -e + UDC 绑定失败 → 整个脚本 exit 1 |
移除 set -e,容错化 |
| 过时 timer 噪音 | kvm-ocr-snapshot.timer 每秒触发 oneshot,native 模式不需要 | 从包中移除 |
目标设备
- 硬件:NanoPC-T6 (RK3588, 8核 ARM64, 6 TOPS NPU)
- 系统:Debian/Ubuntu ARM64
- Python:3.12.3
- Go:1.22+
- NPU:rknn-toolkit-lite2 2.3.2
已知限制
| 类别 | 状态 | 说明 |
|---|---|---|
| 安全模型 | ✅ 良好 | 两层防护(视频遮蔽+网络拦截),白名单模式,Unicode NFKC 归一化 |
| 鼠标优先 | ✅ 完成 | mouse_ops + LLM 提示词 + agent 翻译层 |
| 多 UI 状态 | ✅ 完成 | screen_state.py 检测 BIOS/锁屏/睡眠/桌面 |
| 测试覆盖 | ✅ 良好 | 单元测试 331 个;integration 需实体设备(--ignore 跳过) |
| 隐私遮蔽 | ✅ 完成 | C 视频管道实时 NV12 黑色填充 PII 区域 (WF6 Phase 6A-2) |
| test_integration 一致性 | ⚠️ 部分 | 清理代码已迁移到 mouse_ops,测试目标仍用原始组合键 |
| Privacy/Audit 重组 | ✅ 完成 | PrivacyPage 5 Tab,AuditPage 2 Tab,新增 5 条 API 路由 |
| GatewayMode 类型 | ✅ 完成 | boolean→'off'|'audit'|'redact',PiiOverlay 视觉区分 |
| Agent HID 保护 | ✅ 完成 | Agent 运行时前端键鼠/粘贴被阻断 |
| OCR 内联 | ✅ 完成 | CGo libkvm_ocr.so 内联调用, 延迟 800ms→60ms (WF6) |
| NPU 调度 | ✅ 完成 | OCR(Core0/1) + Embedding(Core2), 无争用 (WF6) |
| CPU 亲和性 | ✅ 完成 | A76(Go+HID) / A55(PII+mem-bridge) (WF6) |
| DMA-buf 零拷贝 | ✅ 完成 | V4L2→MPP 零拷贝编码 (WF6) |
架构文档
详细子系统文档见 docs/architecture/。