release: bump version to 0.50.0

This commit is contained in:
rayd1o
2026-05-10 22:06:01 +08:00
parent e1984c7a35
commit 455b8360d0
80 changed files with 10936 additions and 298 deletions

View File

@@ -23,6 +23,7 @@
- [快速开始](/home/ray/dev/linkong/planet/docs/technical/zh/quickstart.md):从零启动 Planet 的最短路径
- [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md):控制台、`planet.sh`、Earth 和 Docs 的完整使用手册
- [常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)Windows / WSL、端口、依赖、动捕、凭证和 Docs 权限的集中排障入口
- [Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md):在 Earth 上为算力中心和 BGP 观测站采集、预览坐标候选
- [数据源、采集器设置与连接验证](/home/ray/dev/linkong/planet/docs/technical/zh/datasource-collector-settings-connectivity.md)数据源目录、采集器设置、连接验证、BarentsWatch 凭证链路
- [通用位置估算管线开发说明](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-development.md):后端 location resolver / pipeline 的接口、注册表和扩展方式

View File

@@ -23,11 +23,12 @@
- 业务层请求整理
- 稳定的 `/api/v1/ai/...` 接口
- 面向 `aiprovider` 的内部服务认证
- 读取配置中心保存的默认 provider、模型和每个 provider 的 key并通过内部请求头覆盖 `aiprovider``.env` 默认值
`aiprovider` 负责:
- 模型协议适配
- 基于 `.env` 选择 provider
- 在没有后端覆盖头时基于 `.env` 选择 provider
- 超时和轻量重试
- 通过 `X-Request-ID` 串联请求追踪
@@ -85,6 +86,18 @@
后端会把 `X-Request-ID` 透传给 `aiprovider`,并在响应中返回同一个 header。
### 设置中心 API
AI 配置页使用的接口:
- `GET /api/v1/settings/integrations`
- `PUT /api/v1/settings/integrations`
- `POST /api/v1/settings/integrations/ai-provider/connect`
- `GET /api/v1/settings/integrations/ai-provider/secrets`
- `GET /api/v1/settings/integrations/ai-provider/presets`
这些接口都需要用户登录。`secrets` 接口只用于配置页点击显示 key/token 时取回明文,隐藏时前端恢复为脱敏预览。
### AI Provider 内部 API
仅供内部调用的接口:
@@ -172,6 +185,75 @@ curl -X POST http://localhost:8010/v1/analyze \
## 配置
### 运行时配置链路
LLM 的全局默认配置由后端配置中心统一决定。实际调用顺序是:
1. 前端或业务代码调用 `backend``/api/v1/ai/...`
2. `backend` 从 PostgreSQL 的 `system_settings` 表读取 `category = external_integrations`
3. `payload.ai_provider.default_provider` 决定当前默认 provider。
4. `payload.ai_provider.providers[provider]` 提供该 provider 的 `api_key``provider_api``base_url``model``max_tokens``anthropic_version`
5. `backend` 把这些值转换成 `X-AI-Provider``X-AI-Provider-API``X-AI-Base-URL``X-AI-API-Key``X-AI-Model` 等内部请求头。
6. `aiprovider` 收到头后用这些值覆盖自己的 `.env`,再调用真实模型厂商。
因此,只要 AI 设置页保存了新的默认 provider/model/keyPlayground、告警摘要、数据源映射生成等所有后端 AI 调用都会使用同一个新默认配置。
#### 持久化结构
AI 配置仍保存在 PostgreSQL不写入 JSON 文件。核心结构如下:
```json
{
"ai_provider": {
"service_url": "http://localhost:8010",
"service_token": "",
"default_provider": "openai",
"providers": {
"openai": {
"provider_api": "openai-completions",
"base_url": "https://api.openai.com/v1",
"model": "gpt-5.1",
"api_key": "<saved secret>",
"max_tokens": 4096,
"anthropic_version": "2023-06-01"
},
"minimax": {
"provider_api": "anthropic-messages",
"base_url": "https://api.minimaxi.com/anthropic",
"model": "MiniMax-M2.7",
"api_key": "<saved secret>",
"max_tokens": 1200,
"anthropic_version": "2023-06-01"
}
},
"timeout_seconds": 60,
"retry_attempts": 2
}
}
```
历史单槽配置会在读取时兼容映射到当前 provider 的 `providers[provider]`,保存后写回新结构。
#### Key fallback
每个 provider 都有自己的 key 槽。解析顺序是:
1. PostgreSQL 中 `providers[provider].api_key`
2. `aiprovider/.env` 中 preset 对应的专属变量,例如 `OPENAI_API_KEY``MINIMAX_API_KEY``ANTHROPIC_API_KEY`
3. `aiprovider/.env` 中的通用 `AI_API_KEY`
`.env` 只是兜底。配置页保存或测试连接成功后PostgreSQL 中的配置会成为全局默认。
#### 配置页行为
- Provider 下拉框决定当前默认 provider。
- 模型下拉框保存当前 provider 的默认模型。
- LLM API Key 输入框隐藏时显示脱敏预览;有 `-` 前缀的 key 会保留前缀,例如 `sk-********`,没有前缀的 key 全量脱敏。
- 点击眼睛会从后端取回完整明文;再次隐藏会恢复脱敏预览。
- “保存 AI 配置”直接保存当前表单为全局默认配置。
- “测试连接”先用当前表单发起真实模型链路测试,成功后也会保存为全局默认配置;失败不会覆盖旧配置。
- 清空输入框并保存表示保留旧 key不表示删除 key。
### 后端
推荐的后端 `.env`
@@ -208,6 +290,18 @@ AI_HTTP_RETRY_ATTEMPTS=2
AI_ANALYSIS_SYSTEM_PROMPT=你是态势感知分析助手。请基于输入的上下文、观测与约束,输出结构化、克制、可执行的分析。
```
可选 provider 专属 key
```env
MINIMAX_API_KEY=sk-cp-xxxxx
OPENAI_API_KEY=sk-xxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxx
DEEPSEEK_API_KEY=sk-xxxxx
DASHSCOPE_API_KEY=sk-xxxxx
MOONSHOT_API_KEY=sk-xxxxx
OPENROUTER_API_KEY=sk-or-xxxxx
```
### OpenAI 兼容示例
```env

View File

@@ -88,7 +88,26 @@ React 路由入口:
手势提示不会抢占 loading 状态。对应样式是 [hud.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/hud.css) 中的 `.earth-status-message.gesture`
### 5. 地球与地形
### 5. 动作捕捉控制适配层
- [motion-control.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/motion-control.js)
职责:
- 作为 Motion Provider manager统一接入 `browser_camera``motion_agent`
- 默认使用浏览器 `getUserMedia` + 本地 MediaPipe 识别;高级模式可连接本地 Motion Capture Agent WebSocket。
- 处理浏览器摄像头权限/安全上下文错误,以及 Agent 断线重连和 `status` / `heartbeat`
- 过滤低置信度和过快重复的手势事件。
-`rotate_left``rotate_right``rotate_up``rotate_down``zoom_in``zoom_out``focus_prev``focus_next``layer_prev``layer_next``confirm` 映射到 `main.js` 暴露的动作入口。
- 解析 `skeleton` 调试事件并派发 `earth:motion-debug-frame`
动作捕捉识别可以在浏览器本地执行,也可以在本地 Agent 中执行,但两者都不会把实时视频帧发给 SaaS 云端。`main.js` 暴露旋转、缩放、目标切换、图层切换和确认入口,并通过 `window.__planetEarth.motion` 提供调试入口。默认只有 URL 参数 `?motion=1`、本地存储 `planet-earth-motion-control-enabled=true`,或 Earth 设置中的“动捕调试模式”打开时才启动当前 provider。
动捕调试面板由 [motion-debug-panel.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/motion-debug-panel.js) 负责。它监听 `earth:motion-debug-frame`,用 canvas 绘制归一化骨架点和连线Browser Camera provider 会额外通过 `earth:motion-debug-video-source` 提供本机 `<video>` 作为调试预览底图,`shared.motionDebugSkeletonOnly` 可切换为只显示骨骼。`停止匹配动作` 通过 `earth:motion-recognition-pause` 暂停 gesture 执行,但继续显示视频和骨架。未匹配动作为红色,匹配后变绿并显示动作名。设置项持久化在 `planet.earth.settings.v2``shared.motionDebugEnabled``shared.motionProvider``shared.motionDebugSkeletonOnly`switch 和输入源控件都预留 `data-gatekeeper-permission="earth.motion_debug"`
[presentation-controller.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/presentation-controller.js) 是新的 Presentation 层。第一阶段只接入 Motion`motion-cruise-adapter.js` 通过 persistent presentation 复用巡航固定卡片位置和 connector但不会让鼠标移动触发自动隐藏connector 每帧重算 source/target anchor让卡片拖动、地球旋转和目标移动时端点继续跟随。BGP/News 仍保持原有 `CruiseSequencer` 自动轮播路径,避免改变既有巡航体验。
### 6. 地球与地形
- [earth.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/earth.js)
- [terrain.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/terrain.js)
@@ -99,7 +118,7 @@ React 路由入口:
- 真实地形 mesh
- terrain tile 拉取、解码、位移、着色
### 6. 图层模块
### 7. 图层模块
- [satellites.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/satellites.js)
- [cables.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/cables.js)
@@ -119,6 +138,8 @@ React 路由入口:
- 面板内容
- hover/lock/selection 语义
`tv.js` 管理 `media-panel` 里的直播 / 态势新闻 tab。toolbar 打开或切换 TV/新闻时,会通过 `earth:tv-visibility-change``earth:tv-tab-change` 回写 Earth 设置:面板可见性仍按 desktop/mobile viewport 存在 `views.<scope>.panelVisibility.media-panel`,当前 tab 存在 `shared.mediaPanelActiveTab`,因此刷新页面后能恢复用户上次打开的直播或新闻状态。`closeTransientMobileOverlays()` 这类临时收起会带 `persist:false`,不会覆盖用户偏好。
其中 Earth 启动加载链现在也拆成了两层:
- `controls.js`
@@ -307,6 +328,8 @@ AISStream 的 `PositionReport` 常带实时位置和 `MetaData.ShipName`,但
算力中心图层行左上角的通知气泡显示 GeoJSON `unresolved` 数量。这个数字表示“完全没有可信坐标、不能渲染到地球上”的记录,不等同于地图上带 `?` 的已定位待确认点。点击气泡会在图层面板右侧打开固定信息卡,信息卡内容区内部滚动,不随鼠标 hover 消失。列表中的单条 `采集` 只展示候选;顶部 `一键采用` 会按当前列表顺序逐条采集、保存最高置信候选,成功一条就移除一条、重新编号,并通过 `earth:compute-center-unresolved-count-change` 同步气泡数量。批量结束后再触发 `earth:compute-center-location-saved` 刷新真实图层。
详情卡里的坐标候选状态由 [info-card.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/info-card.js) 按 `entityType:entityId` 缓存在模块内存中。用户关闭详情卡或待定位列表后再次打开同一个算力中心 / BGP 观测站,已经采集到的候选和状态文案会恢复;`一键采用` 会优先使用缓存候选,避免重复调用在线地理编码或 LLM factcheck。保存成功后该实体的候选列表会清空为“正在刷新图层”状态避免旧候选在刷新后继续误导用户。
asset 图标大小由 `Interactable``icon.fitSize` 控制。SVG / 图片文件应尽量保持原始 viewBox 和路径,不要为了在地球上显示成 60x60 而手写 `transform``drawAssetIcon()` 会把资源等比 contain 到指定尺寸并居中绘制到 atlas canvas。
`Interactable` 默认使用固定屏幕像素尺寸适合船只、BGP 事件、BGP 观测站、算力中心这类需要稳定识别的图标。如果某类图标需要跟随相机距离缩放,可以把 `sizeMode` 设为非 `"fixed"`,并用 `sizeScale.min / max / referenceFov` 控制缩放范围;单个 marker 的业务尺寸差异可以通过 `getPointSizeMultiplier()` 表达,例如 BGP 事件按严重级别调整点大小BGP 观测站按活跃度调整点大小。

308
docs/technical/zh/faq.md Normal file
View File

@@ -0,0 +1,308 @@
# 常见问题
这页集中收录本地启动、Windows / WSL、依赖、动捕、凭证和 Docs 权限相关的常见排障路径。更完整的背景说明仍在对应专题文档中,这里只保留最常用的判断顺序和命令。
## 启动与端口
### 启动时报后端地址已被占用怎么办?
现象通常类似:
```text
后端地址已被占用: 0.0.0.0:8000 / 127.0.0.1:8000 / [::1]:8000
Address already in use
```
先尝试:
```bash
./planet.sh restart -b
```
如果仍然占用,临时换端口:
```bash
./planet.sh start -b 8001
```
在 WSL 中,端口可能不是 Linux 进程占用,而是 Windows 侧 listener。常见输出如下
```text
Windows listener: 0.0.0.0:8000 pid=4700 process=svchost.exe services=iphlpsvc
```
`iphlpsvc` 是 Windows IP Helper 服务。它经常承载 IPv6、隧道、代理、端口转发、WSL 或开发工具注册的网络能力。不要优先 `taskkill` 这个 `svchost.exe`;更推荐先找是不是旧的 portproxy 规则。
管理员 PowerShell 中先查 portproxy
```powershell
netsh interface portproxy show all
```
如果看到 `0.0.0.0:8000``listenport=8000`,删除对应规则:
```powershell
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8000
```
如果没有 portproxy 规则,再确认 PID 内承载的服务:
```powershell
netstat -ano | findstr :8000
tasklist /svc /fi "PID eq 4700"
```
临时排障可以在管理员 PowerShell 中停止 IP Helper
```powershell
Stop-Service iphlpsvc
```
这可能影响部分网络、代理或转发能力。长期不推荐禁用该服务;如果必须保留 Windows 转发,改用不同后端端口更稳。
如果脚本输出 `failed-stop-service``failed-stop-process`,说明当前权限无法清理 Windows listener。脚本会停止启动避免后端再次遇到同一端口冲突。
### 默认端口冲突时应该改哪些参数?
常用端口如下:
| 服务 | 默认端口 | 参数 |
| --- | --- | --- |
| 前端 | `3000` | `-f <port>` |
| 后端 | `8000` | `-b <port>` |
| AI Provider | `8010` | `-a <port>` |
| Motion Agent | `8765` | `--motion-agent-port <port>` |
示例:
```bash
./planet.sh start -f 3001 -b 8001 -a 8101
```
## Windows / WSL / 局域网
### Windows / WSL 下局域网访问不通怎么办?
建议按下面顺序排查:
```bash
# 在 WSL 或运行 Planet 的 shell 中
curl http://localhost:3000
curl http://localhost:8000/health
```
再到 Windows PowerShell 验证:
```powershell
curl http://localhost:3000
curl http://localhost:8000/health
```
如果 WSL 和 Windows localhost 都通,但手机或其他电脑访问不通,再考虑局域网开放:
```bash
./planet.sh start --allow-lan
```
管理员 PowerShell 中配置 portproxy 和防火墙:
```powershell
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3000 connectaddress=127.0.0.1 connectport=3000
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8000 connectaddress=127.0.0.1 connectport=8000
New-NetFirewallRule -DisplayName "WSL Planet 3000" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3000
New-NetFirewallRule -DisplayName "WSL Planet 8000" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8000
```
局域网设备访问的是 Windows 的局域网 IP例如 `http://<Windows局域网IP>:3000/earth`,不是 WSL 内部 IP。
### `--allow-lan` 和 Motion Agent 局域网地址怎么配?
`--allow-lan` 会让前端、后端和可选 Motion Agent 监听 `0.0.0.0`。如果远端浏览器要连本机 Motion AgentEarth URL 需要显式带 Agent 地址:
```text
http://<LAN_IP>:3000/earth?motion=1&motionProvider=agent&motionAgent=ws://<LAN_IP>:8765/ws/gestures
```
如果选择浏览器摄像头输入源,不需要 `motionAgent` 参数。
## 依赖与环境变量
### 为什么不要用 `pip`,要用 `uv`
Planet 的 Python 依赖统一由 `uv``pyproject.toml` 管理。不要用 `pip install` 往当前环境里塞包,否则容易出现锁文件、虚拟环境和启动脚本不一致。
Motion Agent live 模式缺依赖时,推荐:
```bash
uv add mediapipe opencv-python
```
`planet.sh start --motion-agent` 会自动检查并安装这些 live 依赖。若要禁止自动安装:
```bash
PLANET_MOTION_AGENT_AUTO_INSTALL=0 ./planet.sh start --motion-agent
```
### 为什么不要用 `npm run`,要用 `bun`
前端运行时统一使用 Bun避免 WSL / Windows 混合环境里触发 `cmd.exe` 路径兼容问题。
常用命令:
```bash
bun install
bun run dev
bun run build
```
如果非交互 shell 找不到 `bun``planet.sh` 会依次查找当前 PATH、`~/.bun/bin`、zsh 配置和 PowerShell 中的可执行路径。
### `.zshrc` 里的环境变量什么时候会被读取?
`planet.sh` 默认只静态解析 `~/.zshrc` 中简单的:
```bash
export KEY=value
KEY=value
```
这样可以避免 shell 主题、插件或交互初始化拖慢启动。复杂 shell 展开需要显式启用 source 模式:
```bash
PLANET_LOAD_ZSHRC_ENV=source ./planet.sh start -a
```
如果排障时想完全忽略 `~/.zshrc`
```bash
PLANET_LOAD_ZSHRC_ENV=0 ./planet.sh start -a
```
不要把密钥值写进文档或提交到仓库;文档只应写变量名和用途。
## Motion Capture / 摄像头
### Browser Camera 模式需要 `motionAgent` 参数吗?
不需要。浏览器摄像头模式直接用网页 `getUserMedia` 调本机摄像头,并在浏览器本地识别动作。
推荐 URL
```text
/earth?motion=1&motionProvider=browser
```
也可以在 Earth 设置中打开“动捕调试模式”,并把“动捕输入源”选为“浏览器摄像头”。页面必须运行在 HTTPS 或 localhost且用户需要允许浏览器摄像头权限。
### Motion Agent 什么时候才需要?
这些场景才需要 Motion Agent
- 双 USB 摄像头
- RTSP / HTTP 摄像头流
- 边缘设备或客户端集成
- 需要独立本地识别服务
常用命令:
```bash
./planet.sh start --motion-agent
./planet.sh start --motion-agent --motion-agent-camera-indexes 0,1
./planet.sh start --motion-agent --motion-agent-camera-urls rtsp://example/live
./planet.sh start --motion-agent --motion-agent-dry-run
```
`--motion-agent-dry-run` 只用于协议和前端连接测试,不会打开摄像头。
### WSL 下摄像头为什么扫不到?
Windows 摄像头通常不会自动出现在 WSL 的 `/dev/video*`。先确认:
```bash
ls /dev/video*
```
如果没有设备,普通网页演示优先走 Browser Camera。需要 Agent live 模式时,可以用 RTSP / HTTP 摄像头 URL
```bash
./planet.sh start --motion-agent --motion-agent-camera-urls http://192.168.1.20:8080/video
```
USB 摄像头透传到 WSL 属于高级路径;脚本不会默认把无摄像头场景降级成 dry-run。
## Docker / AI Provider
### AI Provider 改了 key、Base URL 或模型后为什么没有重建镜像?
密钥、Base URL、模型这类运行期配置变化不会触发 Docker 镜像重建。重启 AI Provider 即可:
```bash
./planet.sh restart -a
```
首次构建慢通常是 Docker build context、镜像层或 `uv sync` 下载依赖耗时。后续构建会复用 `.dockerignore`、BuildKit 和 uv cache。
### Docker 健康检查没过怎么办?
先看统一健康检查:
```bash
./planet.sh health
```
再看日志:
```bash
./planet.sh log
```
如果只有 AI Provider 异常,优先重启单个服务:
```bash
./planet.sh restart -a
```
## 数据源与采集器凭证
### 采集器连接验证通过,但正式采集拿不到凭证怎么办?
连接验证会读取控制台保存配置、环境变量和部分 `~/.zshrc` 凭证。正式采集更推荐把凭证保存到“设置 -> 采集器设置”,尤其是 AISStream 这类长连接 collector。
如果只把 `AISSTREAM_API_KEY` 放在 `~/.zshrc`,需要确认后端进程实际继承了该变量。否则可能出现连接验证可用,但 collector 运行时没有 key 的情况。
### BarentsWatch / AISStream 凭证应该放哪里?
临时联调可以先放环境变量或 `~/.zshrc`,例如:
```bash
export AISSTREAM_API_KEY="..."
export BARENTSWATCH_CLIENT_ID="..."
export BARENTSWATCH_CLIENT_SECRET="..."
```
稳定运行时,优先在控制台采集器设置中保存凭证,保证连接验证、采集任务和 Earth 实时聚合使用同一份配置。
## Docs / 权限
### 为什么 Docs 里有些文档看不到?
Docs 按 Gatekeeper 权限组控制可见性:
- 快速开始、使用手册、FAQ 等基础文档公开可见。
- 开发文档通常需要 `docs_developer`
- 运维和服务控制文档通常需要 `docs_admin`
- `admin``super_admin` 默认具备 Docs 权限;普通用户需要在控制台“用户管理”中分配权限组。
## Earth 常见操作
### Earth 位置候选采集后没有写入怎么办?
“采集候选”和“保存候选”是两步。候选可以先在 Earth 上预览,只有点击保存或使用待定位列表中的“一键采用”后,才会写入维表并刷新图层。
算力中心候选保存后会写入 `compute_center_locations`。没有可用候选的记录会保留在待定位列表中,系统不会用国家中心点或硬编码 hint 伪造位置。
### 动捕调试面板为什么看不到摄像头画面?
如果输入源是 Browser Camera调试面板会显示浏览器本机摄像头实时预览并在画面上绘制骨架。如果勾选了 `只显示骨骼`,视频预览会被隐藏,只显示深色背景和红/绿骨架。
如果输入源是 Motion AgentAgent WebSocket 只发送归一化关节点、骨架连线和匹配动作,不发送原始摄像头帧,以降低隐私、带宽和延迟风险。因此远端 Agent 模式下看到的是骨架调试视图,而不是视频流。

View File

@@ -61,6 +61,9 @@ class LocationResolver(Protocol):
| `RegistryResolver` | `resolvers/registry.py` | 遗留通用 resolver当前算力中心和 BGP 运行时链路不使用它生成候选 |
| `NominatimResolver` | `resolvers/nominatim.py` | 按领域 query plan 调 Nominatim带 LRU 缓存和速率限制 |
| `InheritFromAnotherEntityResolver` | `resolvers/inherit.py` | 把外部实体的已解析位置包装为候选 |
| `LocationLLMFallback` | `location/llm_fallback.py` | 用户触发候选采集且常规候选为空时,通过当前默认 AI Provider 生成待确认候选 |
Nominatim 是 OpenStreetMap 生态里的地理编码服务:给它一个地点名称、城市、国家或机构查询文本,它会返回可能匹配的经纬度、展示名称和地址结构。它适合把“城市/机构/园区名称”转成候选坐标,但不是权威事实库,可能命中同名地点或过宽泛的行政区,所以本项目只把它作为待确认候选来源,并带缓存和速率限制使用。
`RegistryResolver` 仍保留给后续可能的受控导入场景,但它不应被重新接入算力中心或 BGP 作为“硬编码 hint”候选源。过去仅凭 `operator``city` 等通用字段匹配 registry 容易把多个实体落到同一个点,这是这次下线 registry 候选链路的主要原因。
@@ -81,7 +84,7 @@ StoredComputeCenterLocationResolver()
主地图启动链路只做“源坐标优先,其次数据库维表坐标”。数据库表为 `compute_center_locations`,唯一键是 `(source, source_id)`,用于保存人工确认或从源记录真实坐标迁入的位置。`init_db()` 只幂等迁入源记录里已有的真实经纬度,不迁入旧硬编码 hint不在启动期批量调用 ROR、Nominatim 或 LLM。
手动候选采集链路和渲染链路分开。`collect_location_candidates()` 使用源字段构造 ROR 和 Nominatim/OpenStreetMap 查询,但不会把 `compute_center_locations` 当前坐标当候选返回。用户在前端确认某个候选后,通过保存接口写入维表;之后地图刷新时由 `StoredComputeCenterLocationResolver` 渲染。
手动候选采集链路和渲染链路分开。`collect_location_candidates()` 使用源字段构造 ROR 和 Nominatim/OpenStreetMap 查询,但不会把 `compute_center_locations` 当前坐标当候选返回。如果这些常规候选为空API 层会调用 `LocationLLMFallback`,通过当前默认 AI Provider 进行位置 factcheck并只返回 `source="llm_location_factcheck"``needs_confirmation=true` 的候选。LLM 候选使用“模型自评分 + 后端证据评分”的组合阈值;如果 LLM 只给出可信 city/country 而没有坐标,后端会用 Nominatim 补城市级坐标,但不会因此提高证据分。用户在前端确认某个候选后,通过保存接口写入维表;之后地图刷新时由 `StoredComputeCenterLocationResolver` 渲染。
`resolve_compute_center_location()``resolve_compute_center_location_full()``collect_location_candidates()` 保留为领域 API。`visualization.py` 只消费领域 API不再持有坐标提示常量、国家质心兜底或 Nominatim 细节。
@@ -102,7 +105,7 @@ StoredCollectorLocationResolver()
NominatimResolver(_bgp_collector_query_plan)
```
23 个 RIPE RIS collector 坐标从旧表迁入 `bgp_collector_locations` 维表,默认 `source=legacy_seed``needs_confirmation=true`。旧字典仍由 DB-backed cache 维护,保证下游接口兼容;手动候选采集不会把这份维表坐标当作候选,只用它补齐 site/city/country 查询上下文。
23 个 RIPE RIS collector 坐标从旧表迁入 `bgp_collector_locations` 维表,默认 `source=legacy_seed``needs_confirmation=true`。旧字典仍由 DB-backed cache 维护,保证下游接口兼容;手动候选采集不会把这份维表坐标当作候选,只用它补齐 site/city/country 查询上下文。若 Nominatim 也无法产出城市级候选,采集接口会用当前默认 AI Provider 做 LLM factcheck 兜底,返回待确认候选而不是自动保存。
### BGP 事件
@@ -139,6 +142,26 @@ POST /api/v1/bgp/collectors/{collector_id}/collect-location
}
```
LLM 兜底只发生在用户触发的 `collect-location` 请求中,并且只在常规候选为空时运行。它不会在 `/geo/compute-centers` 启动渲染、定时采集或批量入库流程中自动调用,也不会直接写入 `compute_center_locations``bgp_collector_locations`。LLM 兜底内部不是“一次严格 JSON 成败”的单点链路,而是小型结构化管线:先请求 LLM 做位置 factcheck若返回不是 JSON再发起一次“只从原文抽取、不新增事实”的结构化修复若修复仍失败则只从原文中保守抽取 city/country。随后统一由后端补坐标、算综合分并决定是否生成候选。
这条链路允许 LLM 只给出“DeepL Mercury 位于 Falun, Sweden”这类城市级事实由后端用 Nominatim 补城市坐标;也允许模型第一轮输出自然语言,第二轮再归一化成 JSON。无论哪条路径只有 `precise``site``city` 精度、非零坐标和足够综合分的结果会被转换成候选;失败、低分、只有国家级信息或无法抽出城市的响应会保留为诊断信息。
LLM 返回的 `confidence` 只是模型自评,后端会重新计算综合分并把它作为候选 `confidence`
```text
combined =
0.25 * model_confidence
+ source_quality
+ entity_match
+ geography_match
+ precision_quality
+ name_location_hint
- conflict_penalty
- weak_evidence_penalty
```
当前分项上限:权威/政府/高校来源最高 `0.35`,可信数据库/新闻最高 `0.25`,普通网页最高 `0.15`;证据明确命中实体名最高 `0.25`;城市+国家匹配 `0.20`,只有国家匹配 `0.05`;精度项 `precise=0.15``site=0.12``city=0.08`;实体名与候选城市互相命中时增加 `name_location_hint`,例如 `TAIPEI-1``Taipei`;明确冲突最多扣 `0.45`,普通弱证据措辞最多扣 `0.30`,在实体和城市国家都已命中且无冲突时弱证据扣分封顶 `0.15`。综合分低于 `0.55` 的候选会被拒绝。这样 Alem.Cloud、TAIPEI-1 这类“模型自评分偏低,但实体和城市证据一致”的结果可以被后端公式拉回到可确认候选;真正证据弱或有冲突的结果仍会被拒绝。
`POST /api/v1/visualization/compute-centers/{source_id}/location` 把前端选中的候选 upsert 到 `compute_center_locations`。人工保存默认 `needs_confirmation=false``verification_status="verified"` 并写入 `verified_at`;如果后续接入自动暂存,也可以显式传 `needs_confirmation=true`
前端 [info-card.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/info-card.js) 使用通用候选列表和预览事件渲染对象详情卡。算力中心图层按钮左上角会显示 `unresolved` 数量;点击角标打开待定位列表。列表中的 `采集` 只拉候选,`一键采用` 会逐条调用候选采集接口,选择最高置信且有有效经纬度的候选保存。保存成功一条就从列表移除并重新编号,同时通过 `earth:compute-center-unresolved-count-change` 同步角标;批量结束后再触发 `earth:compute-center-location-saved` 刷新真实图层。

View File

@@ -1,6 +1,6 @@
# Earth 位置候选采集使用手册
位置候选采集用于给 Earth 上的算力中心和 BGP 观测站补齐或核验经纬度。它不会要求用户手工输入坐标,而是把源数据、开放组织注册 API在线地理编码结果整理成候选列表,供用户预览和后续认领。
位置候选采集用于给 Earth 上的算力中心和 BGP 观测站补齐或核验经纬度。它不会要求用户手工输入坐标,而是把源数据、开放组织注册 API在线地理编码结果,以及必要时的 LLM factcheck 兜底结果整理成候选列表,供用户预览和后续认领。
## 适用对象
@@ -18,13 +18,15 @@ BGP 事件的位置默认继承所属 collector。事件本身暂不提供单独
| 字段 | 含义 |
| --- | --- |
| 位置精度 | `精确坐标``站点级位置``城市级位置``位置未确认` |
| 位置来源 | 源数据坐标、ROR 组织注册 API、Nominatim 在线搜索,或已存储的 BGP collector 维表位置 |
| 位置来源 | 源数据坐标、ROR 组织注册 API、Nominatim 在线搜索、LLM factcheck 兜底,或已存储的 BGP collector 维表位置 |
| 位置置信度 | 后端 resolver 给出的相对置信度百分比 |
| 核验状态 | 已确认、估算位置或在线检索结果待确认 |
| 解析依据 | 为什么选择这个位置,例如匹配了哪个站点或城市 |
| 匹配的位置名称 | 开放来源、在线结果或已存储 collector 位置中的规范名称 |
| 位置核验时间 | 已确认位置的核验日期,在线候选通常为空 |
这里的 Nominatim 指 OpenStreetMap 生态中的在线地理编码服务。它会把地点名称、城市、国家、机构或园区查询文本转换为可能的经纬度候选,但结果可能命中同名地点或过宽泛的行政区,因此界面会把这类结果标为待确认。
算力中心 GeoJSON 不再渲染国家质心、未知位置或 `[0, 0]` 占位点。无法达到城市级精度的数据会进入接口的 `unresolved` 列表,并在图层开关左上角显示待定位数量。点击这个通知气泡会打开待定位列表。
地图上带 `?` 的算力中心不是 `unresolved`。它们已经有坐标,只是 `needs_confirmation=true` 或来自在线地理编码,仍需人工核验。真正 `unresolved` 的记录没有可信经纬度,因此不会出现在地球上。
@@ -82,7 +84,7 @@ POST /api/v1/bgp/collectors/{collector_id}/collect-location
}
```
没有候选达到城市级精度时,`success``false`,响应会包含 `failure_reason` 和已尝试的查询文本,便于判断是源数据字段不足、开放来源缺项,还是在线地理编码没有命中。
常规候选为空时,接口会通过当前默认 AI Provider 做一次 LLM factcheck 兜底。LLM 候选始终需要人工确认,不会自动保存;只有达到城市级或更高精度、非零坐标且置信度足够的 JSON 结果才会出现在候选列表中。当仍没有候选达到城市级精度时,`success``false`,响应会包含 `failure_reason``llm_failure_reason` 和已尝试的查询文本,便于判断是源数据字段不足、开放来源缺项在线地理编码没有命中,还是 LLM 返回不可用
## 数据维护建议
@@ -122,6 +124,10 @@ Earth 只渲染达到城市级或更高精度的坐标。源数据没有坐标
Nominatim/OpenStreetMap 结果来自在线地理编码,可能匹配到同名城市、机构或园区。它可以用于快速定位和预览,但在写入已验证位置前应人工确认。
### LLM 兜底会不会直接改地图?
不会。LLM 只在用户点击采集候选且常规来源没有候选时运行并只返回待确认候选。Earth 首屏 GeoJSON、定时采集和批量渲染不会自动调用 LLM只有用户保存候选后位置才会进入维表并参与后续渲染。
### 为什么 BGP 事件没有全部落到 Amsterdam
旧逻辑中,事件可能因为 `operator="RIPE NCC"` 这种通用字段误匹配到 `rrc00`。当前 BGP 事件继承只按所属 collector 在 DB-backed cache 中严格查找,不再用 registry 模糊匹配。

View File

@@ -7,7 +7,7 @@
- 控制台:登录后的管理后台
- Docs后端 Gatekeeper 受控的文档站,基础使用文档公开,开发/运维文档按权限组开放
快速启动路径见 [快速开始](/home/ray/dev/linkong/planet/docs/technical/zh/quickstart.md)。
快速启动路径见 [快速开始](/home/ray/dev/linkong/planet/docs/technical/zh/quickstart.md)。常见排障见 [常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)。
## 入口总览
@@ -17,6 +17,7 @@
| --- | --- | --- | --- |
| Earth | `http://localhost:3000/earth` | 否 | 3D 地球、图层、BGP、卫星、海缆、新闻态势 |
| Docs | `http://localhost:3000/docs` | 部分需要 | 使用手册公开;开发、后端、运维文档按 Gatekeeper 权限组开放 |
| FAQ | `http://localhost:3000/docs/faq` | 否 | Windows / WSL、端口、依赖、动捕、凭证和权限排障 |
| 控制台 | `http://localhost:3000/admin` | 是 | 数据、配置、告警、日志和专题观测 |
| AI Playground | `http://localhost:3000/playground` | 是 | AI Provider 状态和调试 |
| 后端 API 文档 | `http://localhost:8000/docs` | 视接口而定 | FastAPI / OpenAPI 文档 |
@@ -311,7 +312,7 @@ Earth 搜索支持查找当前地球对象,例如:
### 位置候选采集
算力中心和 BGP 观测站详情卡支持自动采集坐标候选。点击对象后,使用详情卡中的 `自动采集坐标候选``重新自动采集坐标` 按钮,后端会从源坐标、开放组织注册 API 和在线地理编码中整理候选位置。BGP 观测站的已存储位置只用于补齐查询上下文,不会作为候选直接返回。
算力中心和 BGP 观测站详情卡支持自动采集坐标候选。点击对象后,使用详情卡中的 `自动采集坐标候选``重新自动采集坐标` 按钮,后端会从源坐标、开放组织注册 API 和在线地理编码中整理候选位置;这些常规来源没有候选时,会使用当前默认 AI Provider 做一次 LLM factcheck 兜底。BGP 观测站的已存储位置只用于补齐查询上下文,不会作为候选直接返回。
候选可以直接在 Earth 上预览。算力中心候选点击 `保存` 后会写入 `compute_center_locations` 维表,并立即刷新图层。算力中心图层左上角的通知气泡显示无法渲染的待定位数量;点击后可查看列表,单条采集候选,或用 `一键采用` 从上到下保存最高置信候选。没有可用候选的记录会留在列表中,不会被国家中心点或硬编码 hint 伪造位置。详细流程见 [Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md)。
@@ -319,11 +320,10 @@ Earth 搜索支持查找当前地球对象,例如:
设置面板包含:
- 旋转模式 / 巡航模式
- 巡航模块BGP、新闻
- 卫星显示风格:自身发光、真实地表覆盖
- 日夜模式
- 面板显示开关
- 旋转模式 / 巡航模式 / 动捕模式
- 巡航模块BGP、新闻、算力中心、船只、海缆、卫星
- 视图设置:卫星显示风格、日夜模式、面板显示开关
- 动捕调试模式、动捕输入源、只显示骨骼
- 地球默认大小
- 地形透明度
- 重置设置
@@ -349,6 +349,30 @@ Earth 支持鼠标、触控板和触屏操作。
拖动灵敏度会根据当前缩放自动调整。默认视角附近保持常规旋转速度;放大后拖动会逐步变细,适合检查某个区域、船只、卫星或 BGP 事件;缩小后拖动会略快,方便快速浏览全球态势。
### 动作捕捉控制
Earth 预留了动作捕捉控制入口,面向大屏和未来 3D 展示。实时链路有两种输入源:默认的 `浏览器摄像头` 会直接用网页 `getUserMedia` 在本机浏览器识别;高级的 `Motion Agent` 会走 `摄像头/RTSP/HTTP -> 本地 Agent -> 本地 WebSocket -> Earth 页面`。两种模式都不会把摄像头帧或实时手势发到云端,也不会复用新闻/RSS 聚合接口。
默认不自动启用。打开设置里的 `动捕调试模式`,或用 `?motion=1` 打开 Earth 动捕连接后,系统会启动当前选择的输入源。输入源默认是 `浏览器摄像头`,无需安装应用,但页面必须运行在 HTTPS 或 localhost且用户需要允许浏览器摄像头权限。需要双摄、USB index、手机/网络摄像头流或客户端/边缘设备时,可在设置中切到 `Motion Agent`。默认 Agent 地址是 `ws://127.0.0.1:8765/ws/gestures`,也可用 URL 参数 `motionAgent` 覆盖。
URL 参数也可以直接指定输入源:`?motion=1&motionProvider=browser` 使用浏览器摄像头;`?motion=1&motionProvider=agent` 使用 Motion Agent传入 `motionAgent=ws://...` 时会自动选择 Motion Agent。
当前手势语义:
| 手势事件 | 作用 |
| --- | --- |
| `rotate_left` | 地球向左旋转 |
| `rotate_right` | 地球向右旋转 |
| `rotate_up` | 地球向上旋转 |
| `rotate_down` | 地球向下旋转 |
| `zoom_in` | 放大视角 |
| `zoom_out` | 缩小视角 |
| `focus_prev` / `focus_next` | 在当前动捕图层内切换可交互目标 |
| `layer_prev` / `layer_next` | 切换动捕候选图层,并巡航到新图层最近目标 |
| `confirm` | 确认当前已选目标;当前浏览器识别暂未启用双手上举确认 |
设置面板中的 `动捕调试模式` 会打开调试面板。浏览器摄像头输入源会在面板内显示本机实时预览,并在其上绘制关节点和连线;`Motion Agent` 输入源只发送归一化骨架事件,不发送原始视频帧。面板里的 `只显示骨骼` 会隐藏视频预览、只保留深色背景和骨架;`停止匹配动作` 会暂停手势触发,但摄像头预览和骨架绘制仍可继续用于调试。未匹配动作时骨架为红色,匹配后变绿并显示当前动作名称。该入口和 `动捕输入源` 控件都已预留 Gatekeeper 权限标记,后续可接入鉴权控制。
### 巡航模式
巡航模式会让 Earth 自动轮播聚焦目标。
@@ -357,6 +381,10 @@ Earth 支持鼠标、触控板和触屏操作。
- BGP
- 新闻
- 算力中心
- 船只
- 海缆
- 卫星
适合演示、监控大屏或无人值守展示。

View File

@@ -155,7 +155,7 @@ wait_for_port_release() {
- `PORT_PRESTART_RETRIES`:默认 3 次。
- `PORT_PRESTART_RETRY_INTERVAL`:默认 2 秒。
`kill_port_if_requested()` 只在当前环境能找到监听 PID 时主动杀进程;如果没有 PID 但端口暂时不可绑定,它会记录诊断并把最终确认交给服务启动流程。`start_frontend_with_retry()` 也只在发现监听 PID 时进入预清理重试,避免在宿主机或外部 network namespace 尚未释放端口时做无意义的“空杀重试”。这意味着第一次重启时看到“未发现监听进程但端口仍不可绑定”通常是外部环境仍在释放端口;脚本不会再把这种情况当成立刻失败的本地进程清理问题
`kill_port_if_requested()` 优先清理当前环境能找到监听 PID;只有检测到当前运行在 WSL 且没有可杀 PID但端口不可绑定时,才会检查 Windows 侧 listener并尝试通过 PowerShell 停止对应服务或强制结束对应进程。若没有权限,或 `iphlpsvc` 这类系统服务拒绝停止,脚本会打印 Windows listener 详情并立即停止启动,不再继续拉起服务碰同一个端口错误。非 WSL 环境不会尝试 Windows 清理路径。此时需要用管理员 PowerShell 清理 portproxy/服务占用,或改用其他端口
## 问题三:端口检测用 Python
@@ -202,6 +202,92 @@ PY
修复戳文件路径后,无参 `restart` 同样使用 `stop + start`fingerprint 检查正常生效,行为与 `restart -b` 完全一致。无需额外代码变更。
## Motion Agent 可选启动
`planet.sh` 现在可以管理本地动作捕捉 Agent但默认不会启动它避免普通开发机因为没有摄像头、OpenCV 或 MediaPipe 而影响后端/前端启动。
启动方式:
```bash
./planet.sh start --motion-agent
```
常用参数:
- `--motion-agent` / `-m`:随本次启动或重启拉起 Motion Agent。
- `--motion-agent-port <端口>`:覆盖默认 WebSocket 端口 `8765`
- `--motion-agent-camera-indexes <indexes>`:覆盖自动发现的摄像头 index例如 `0``0,1`。也可以用环境变量 `MOTION_AGENT_CAMERA_INDEXES=0,1`
- `--motion-agent-camera-urls <urls>`:使用 RTSP/HTTP 摄像头流,适合 WSL、手机摄像头或网络摄像头。也可以用环境变量 `MOTION_AGENT_CAMERA_URLS=...`
- `--motion-agent-dry-run`:不打开摄像头、不加载 CV 依赖,只启动协议服务,适合调试 Web 端连接。
非 dry-run 的 live 模式会在启动前检查 `mediapipe``opencv-python`。如果当前 `.venv` 缺包,脚本会自动执行:
```bash
uv add mediapipe opencv-python
```
如需禁止启动时自动安装,可设置:
```bash
PLANET_MOTION_AGENT_AUTO_INSTALL=0 ./planet.sh start --motion-agent
```
live 模式会自动寻找 `/dev/video*`,优先取前两个 index 传给 Motion Agent。在 WSL 中Windows 摄像头通常不会自动出现在 `/dev/video*`。可先用下面命令看设备:
```bash
ls /dev/video*
```
如需覆盖自动发现结果,可手动指定 index
```bash
./planet.sh start --motion-agent --motion-agent-camera-indexes 1,2
```
WSL 下更通用的方式是把手机摄像头或网络摄像头以 RTSP/HTTP 流接入:
```bash
./planet.sh start --motion-agent --motion-agent-camera-urls http://192.168.1.20:8080/video
```
如果 WSL 中没有发现 `/dev/video*`,且没有提供 `--motion-agent-camera-urls`,脚本会停止 live 启动并提示处理方式,不会自动降级为 dry-run。可选处理
```bash
./planet.sh start --motion-agent --motion-agent-camera-urls http://<手机IP>:8080/video
./planet.sh start --motion-agent --motion-agent-dry-run
```
只有显式设置 `PLANET_MOTION_AGENT_WSL_ALLOW_DRY_RUN_FALLBACK=1`WSL 无摄像头才会自动降级。
也可以用环境变量启用:
```bash
PLANET_START_MOTION_AGENT=1 ./planet.sh start
MOTION_AGENT_DRY_RUN=1 PLANET_START_MOTION_AGENT=1 ./planet.sh start
```
日志入口:
```bash
./planet.sh log -m
```
和前端一起开放局域网时:
```bash
./planet.sh start --allow-lan --motion-agent
```
此时 Motion Agent 会绑定 `0.0.0.0`,启动输出会同时显示本机 WebSocket 地址和推荐局域网 WebSocket 地址。局域网浏览器访问 Earth 时,需要把 `motionAgent` 参数指向这台大屏主机,例如:
```text
http://<LAN_IP>:3000/earth?motion=1&motionAgent=ws://<LAN_IP>:8765/ws/gestures
```
停止时 `./planet.sh stop` 会一并停止已由脚本启动的 Motion Agent。健康检查会显示 `Motion Agent` 的 online/offline 状态。Earth 页面仍需用 `?motion=1` 或浏览器本地存储显式启用 Web 端连接。
如果只是普通网页/WSL/无安装演示场景,可以不启动 Motion Agent直接在 Earth 设置里选择 `浏览器摄像头` 输入源并打开动捕调试模式;该路线使用浏览器 `getUserMedia`,需要 HTTPS 或 localhost 和摄像头权限。
## 其他:移除不必要的 sleep
启动链路中两处 `sleep 3` 在实际已有健康检查覆盖的情况下多余,已移除:

View File

@@ -2,6 +2,8 @@
这份快速开始面向第一次启动 Planet 的开发者或演示操作者。目标是用最短路径把服务跑起来,并知道应该打开哪些入口。
如果遇到端口占用、Windows / WSL 局域网访问、`uv` / `bun`、摄像头或 Docs 权限问题,先看 [常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)。
## 前置条件
推荐在 WSL / Linux shell 中运行。
@@ -64,6 +66,8 @@ export BARENTSWATCH_CLIENT_SECRET="..."
./planet.sh start -f 3001 -b 8001 -a 8101
```
后端 `8000` 被 Windows listener 或旧 portproxy 占用时,排查顺序见 [常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)。
## 2. 创建登录用户
控制台需要登录。首次使用可以执行:
@@ -91,9 +95,9 @@ Earth 是公开页面,不需要登录。
- 地球正常显示
- 右侧图层控制可打开/关闭图层
- 搜索可以查找海缆、卫星、算力中心、BGP 事件
- 算力中心和 BGP 观测站详情卡可以自动采集并预览坐标候选;算力中心待定位气泡可以打开列表并保存候选
- 算力中心和 BGP 观测站详情卡可以自动采集并预览坐标候选;常规来源无候选时会用当前默认 AI Provider 做 LLM factcheck 兜底;算力中心待定位气泡可以打开列表并保存候选
- 鼠标拖动、滚轮缩放和缩放百分比提示正常工作
- 设置面板可以切换巡航模式、日夜模式、卫星显示风格
- 设置面板可以切换旋转 / 巡航 / 动捕模式、日夜模式、卫星显示风格;动捕调试模式下浏览器摄像头可显示本机预览和骨架
## 4. 打开控制台