Files
planet/docs/plans/datasource-custom-api-mapping-plan.md
linkong f14ff6ec0f
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / delivery (push) Has been cancelled
release / images (push) Has been cancelled
release: bump version to 0.56.0
2026-05-13 18:21:03 +08:00

427 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 自定义 API 数据源与 LLM 映射系统 — 实施计划
**状态**:规划中
**创建日期**2026-04-28
**核心原则**LLM 辅助生成映射配置;生产采集使用确定性转换引擎
## 已确认决策
| 项目 | 决策 |
|-----|------|
| 自定义 API 的定位 | 作为内置数据源的补充入口,不直接等同于 Earth 新功能 |
| LLM 的职责 | 探索未知 API、分析样本 JSON、生成 mapping 草案 |
| 采集时是否调用 LLM | 不调用;采集链路必须确定性、可审计、可复现 |
| 自定义数据如何进入 Earth | 必须映射到已支持的目标 schema或先进入通用数据沉淀 |
| 外部凭证放置位置 | Settings / 外部集成统一管理 provider tokenDataSources 引用 provider profile |
| TimescaleDB | 高频时序数据稳定后再评估迁移 |
---
## 一、背景与问题
当前系统已经有 `datasource_configs`,可以配置自定义数据源的 endpoint、auth、headers、config也已经有部分 collector 会读取这些配置。但这只能解决“怎么请求数据”,还没有解决以下问题:
- API 返回 JSON 后,如何转换成系统已有领域模型。
- 自定义数据源是补充已有能力,还是全新数据沉淀。
- 转换规则由谁生成、谁校验、谁执行。
- 未知数据是否能自动在 Earth 上展示。
- 外部 token 是放在全局配置中心,还是放在每个 datasource 下。
专业做法是把“请求配置”“外部凭证”“目标 schema”“字段映射”“采集执行”拆开
- Settings 管外部集成凭证,例如 AI Provider、BarentsWatch、未来付费 AIS API。
- DataSources 管具体数据源实例,例如 endpoint、调度频率、目标 schema、mapping 版本。
- LLM 只在配置阶段辅助生成 mapping不进入生产采集链路。
- Earth 只消费明确 schema 的数据,不消费任意未知 JSON。
---
## 二、目标架构
### 2.1 自定义 API 数据源生命周期
```mermaid
flowchart LR
A[配置 endpoint/auth/request] --> B[抓取 sample JSON]
B --> C[选择目标 schema]
C --> D[LLM 生成 mapping 草案]
D --> E[确定性 mapping engine 预览]
E --> F[schema validation]
F --> G[保存 mapping version]
G --> H[scheduler 执行 mapped collector]
H --> I[写入目标表或 generic_records]
```
### 2.2 目标 schema 分层
| schema | 用途 | Earth 可视化 |
|-------|------|-------------|
| `vessel_ais` | 船只 AIS 位置、航速、航向、MMSI 等 | 进入船舶图层 |
| `geo_points` | 通用点位数据,包含经纬度、名称、类型、时间 | 未来进入通用 geo layer |
| `news_events` | 新闻/事件类数据,带时间、地点、摘要、来源 | 复用新闻/事件链路 |
| `compute_centers` | 算力中心、机房、数据中心数据 | 复用算力中心图层 |
| `generic_records` | 未知结构化数据沉淀 | 不直接展示 |
v1 建议优先实现:
- `vessel_ais`
- `geo_points`
- `generic_records`
其他 schema 可先在 registry 中预留名称,但不承诺完整落库与可视化。
### 2.3 LLM 的边界
LLM 可以做:
- 根据 API 文档或 sample JSON 解释字段含义。
- 推荐目标 schema。
- 生成 mapping JSON 草案。
- 给出字段置信度和需要人工确认的字段。
- 帮用户发现分页、数组路径、时间字段、坐标字段。
LLM 不应该做:
- 在正式采集时参与每批数据转换。
- 生成并执行 Python/JavaScript 代码。
- 接触 API key、bearer token、basic auth password。
- 自动创建新的 Earth 图层或数据库表。
---
## 三、后端实施计划
### Phase 1 — Target Schema Registry
新增代码级 registry统一描述系统支持的目标数据类型。
每个 target schema 至少包含:
- `key`:例如 `vessel_ais`
- `label`:前端展示名称。
- `description`:适用场景。
- `fields`:字段名、类型、是否必填、说明、示例。
- `validator`Pydantic 或等价校验器。
- `destination`:写入目标,例如 vessel 表、generic_records、future geo layer。
示例概念:
```json
{
"key": "vessel_ais",
"fields": [
{"name": "mmsi", "type": "integer", "required": true},
{"name": "lat", "type": "float", "required": true},
{"name": "lon", "type": "float", "required": true},
{"name": "sog", "type": "float", "required": false},
{"name": "cog", "type": "float", "required": false},
{"name": "received_at", "type": "datetime", "required": false}
]
}
```
### Phase 2 — Mapping Template Model
新增 mapping 配置持久化表,建议命名为 `datasource_mapping_templates`
关键字段:
- `id`
- `datasource_config_id`
- `target_schema`
- `mapping_json`
- `sample_payload_hash`
- `validation_status`
- `version`
- `is_active`
- `created_at`
- `updated_at`
`mapping_json` 是声明式 DSL不允许任意代码执行。
示例:
```json
{
"source": {
"items_path": "$.data.vessels[*]"
},
"fields": {
"mmsi": {"path": "$.mmsi", "type": "integer"},
"lat": {"path": "$.latitude", "type": "float"},
"lon": {"path": "$.longitude", "type": "float"},
"sog": {"path": "$.speedOverGround", "type": "float", "default": null},
"received_at": {"path": "$.timestamp", "type": "datetime"}
}
}
```
### Phase 3 — Deterministic Mapping Engine
实现独立 mapping engine输入 sample/raw payload 和 mapping JSON输出目标 schema 记录。
v1 支持能力:
- JSONPath/JMESPath 风格路径提取。
- 数组展开。
- 默认值。
- 基础类型转换string、integer、float、boolean、datetime。
- 坐标范围校验。
- 简单枚举映射。
- 错误收集:缺字段、类型转换失败、路径不存在。
明确不支持:
- 任意表达式执行。
- 用户提交脚本。
- LLM runtime 修复。
### Phase 4 — LLM Mapping Assistant API
新增配置阶段 API
- `POST /api/v1/datasources/custom/sample`
- 按 datasource 请求配置抓取 sample JSON。
- `GET /api/v1/datasources/target-schemas`
- 返回可选目标 schema 和字段说明。
- `POST /api/v1/datasources/mappings/propose`
- 输入 sample JSON + target schema调用 AI provider 生成 mapping 草案。
- `POST /api/v1/datasources/mappings/preview`
- 使用确定性 mapping engine 预览转换结果。
- `POST /api/v1/datasources/mappings`
- 保存 mapping 版本。
- `PUT /api/v1/datasources/mappings/{id}`
- 更新 mapping生成新版本或覆盖草稿。
- `POST /api/v1/datasources/{id}/run-mapped`
- 手动触发一次 mapped collector。
安全要求:
- `propose` 请求发送给 LLM 前必须脱敏 sample。
- auth headers、token、password 不进入 prompt。
- LLM 返回结果必须再经过 mapping schema 校验。
### Phase 5 — Generic Mapped HTTP Collector
新增通用 collector
- 读取 `DataSourceConfig` 请求配置。
- 读取 active mapping template。
- 拉取 API 数据。
- 使用 mapping engine 转换。
- 使用 target schema validator 校验。
- 调用 destination handler 写入目标表或 generic storage。
- 将失败记录写入错误日志或 dead-letter 结构。
对于 `generic_records`
- 保存 datasource id。
- 保存 target schema。
- 保存 normalized JSON。
- 保存 raw payload 摘要或 raw reference。
- 保存采集时间、source timestamp、mapping version。
---
## 四、前端实施计划
### Phase 1 — Settings 外部集成
Settings 中保留统一外部集成配置:
- AI Providerbase URL、model、API key。
- BarentsWatchclient id/client secret 或 bearer token。
- 未来付费接口AISHub、MarineTraffic、VesselFinder 等 provider profile。
DataSources 不直接管理全局 secret只引用 provider profile。
### Phase 2 — Settings 自定义源向导
自定义数据源配置入口应放在 `/settings` 的“采集器设置”或后续专门的自定义采集器设置区。`/datasources` 保持数据源目录和采集触发职责,不再承载编辑入口。
自定义数据源配置改成向导或右侧 drawer
1. Request
- endpoint
- method
- auth profile
- headers
- query/body config
- schedule
2. Sample
- 点击抓取 sample
- 展示 JSON tree
- 支持选择数组根路径
3. Target Schema
- 选择 `vessel_ais``geo_points``generic_records`
- 展示该 schema 必填字段
4. Mapping Proposal
- 调用 LLM 生成 mapping 草案
- 显示字段匹配置信度
- 标出需要人工确认的字段
5. Preview
- 用确定性 engine 预览前 N 条转换结果
- 展示校验错误
6. Save & Enable
- 保存 mapping version
- 启用调度或仅保存草稿
### Phase 3 — 运维视图
为 mapped datasource 展示:
- 上次运行时间。
- 成功记录数。
- 失败记录数。
- 当前 mapping version。
- 目标 schema。
- 最近错误。
- 手动运行按钮。
---
## 五、数据库与存储策略
### v1继续使用 PostgreSQL
PostgreSQL 可以承载当前规模的采集、关系查询、JSONB 沉淀和基础时序查询。v1 不必因为“时序数据”立刻引入 TimescaleDB。
适合继续用 PostgreSQL 的场景:
- 数据量可控。
- 最近状态查询为主。
- 历史保留窗口较短。
- 查询模式还没稳定。
- 需要快速迭代 schema 与 mapping。
### TimescaleDB 后续评估
以下条件满足后,再评估 TimescaleDB
- AIS、遥测、轨迹类数据达到高频持续写入。
- 需要按时间窗口做聚合、降采样、retention policy。
- 单表时间序列查询明显成为瓶颈。
- 历史轨迹保留从 24h 扩展到数周或数月。
候选迁移对象:
- `vessel_position`
- future telemetry tables
- future generic time-series records
备选方案:
- PostgreSQL 原生按天/月分区。
- TimescaleDB hypertable。
- 热数据 PostgreSQL冷数据对象存储。
---
## 六、安全与治理
### Secret 管理
- Settings 中保存 provider credentials。
- API 返回配置时必须 mask secret。
- LLM prompt 只能包含脱敏 sample 和 schema 说明。
- 后续可引入字段级加密或 KMS。
### Mapping 治理
- 每次 mapping 变更保留版本。
- active mapping 只能有一个。
- 允许保存 draft mapping。
- 运行记录关联 mapping version。
- 校验失败不能自动启用。
### 错误处理
常见错误类型:
- API 401/403凭证错误或过期。
- API 429限流需要调整 schedule。
- JSON path 不存在:上游结构变化。
- 类型转换失败mapping 规则错误。
- schema validation failed转换结果不满足目标模型。
每次运行需要记录:
- datasource id。
- mapping version。
- started_at / finished_at。
- fetched count。
- mapped count。
- written count。
- failed count。
- error summary。
---
## 七、测试计划
### Backend Unit Tests
- mapping engine
- path 提取。
- 数组展开。
- 默认值。
- 类型转换。
- datetime parse。
- 枚举映射。
- 缺字段错误。
- target schema registry
- `vessel_ais` 必填字段校验。
- `geo_points` 经纬度范围校验。
- `generic_records` 接受未知结构。
- LLM assistant
- mock provider 返回 mapping。
- 验证 secret 不进入 prompt。
- 验证非法 mapping 被拒绝。
### Backend Integration Tests
- sample JSON -> propose mapping -> preview -> save mapping。
- mapped collector 使用保存的 mapping 写入 `generic_records`
- `vessel_ais` sample 写入船舶相关目标结构。
- 上游 JSON 结构变化时,运行失败并记录错误。
### Frontend Tests
- 自定义数据源向导完整流程。
- 未配置 AI Provider 时,提示去 Settings 配置,但允许手写 mapping。
- LLM 返回不完整 mapping 时Preview 阶段显示校验错误。
- 保存 mapping 后展示 active version 和运行状态。
---
## 八、分期工作量
| 阶段 | 内容 | 估算 |
|-----|------|------|
| Phase 0 | 完成本规划、确认 schema registry 设计 | 0.5 天 |
| Phase 1 | target schema registry + mapping template model | 12 天 |
| Phase 2 | deterministic mapping engine | 23 天 |
| Phase 3 | sample/propose/preview/save API | 23 天 |
| Phase 4 | DataSources 自定义源向导 | 35 天 |
| Phase 5 | generic mapped collector + run history | 24 天 |
| Phase 6 | vessel_ais / geo_points destination handler | 24 天 |
---
## 九、当前差距与下一步
当前差距:
- `datasource_configs` 只描述请求配置,不描述目标 schema 和 mapping。
- 自定义源没有 sample -> schema -> mapping -> preview -> save 的闭环。
- 生产采集还没有通用 mapped collector。
- Settings 与 DataSources 的职责边界需要在 UI 上进一步明确。
- Earth 还没有通用 `geo_points` 图层。
下一步建议:
1. 先实现 target schema registry 和 mapping engine不急着接 LLM。
2. 用固定 sample JSON 做 `vessel_ais``generic_records` 的单元测试。
3. 再接 LLM propose API让 LLM 产出的只是 mapping 草案。
4. 最后做前端向导,把人工确认和 preview 放到启用之前。