13 KiB
自定义 API 数据源与 LLM 映射系统 — 实施计划
状态:规划中 创建日期:2026-04-28 核心原则:LLM 辅助生成映射配置;生产采集使用确定性转换引擎
已确认决策
| 项目 | 决策 |
|---|---|
| 自定义 API 的定位 | 作为内置数据源的补充入口,不直接等同于 Earth 新功能 |
| LLM 的职责 | 探索未知 API、分析样本 JSON、生成 mapping 草案 |
| 采集时是否调用 LLM | 不调用;采集链路必须确定性、可审计、可复现 |
| 自定义数据如何进入 Earth | 必须映射到已支持的目标 schema,或先进入通用数据沉淀 |
| 外部凭证放置位置 | Settings / 外部集成统一管理 provider token;DataSources 引用 provider profile |
| TimescaleDB | 放入 TODO;高频时序数据稳定后再评估迁移 |
一、背景与问题
当前系统已经有 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 数据源生命周期
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(TODO) |
news_events |
新闻/事件类数据,带时间、地点、摘要、来源 | 复用新闻/事件链路 |
compute_centers |
算力中心、机房、数据中心数据 | 复用算力中心图层 |
generic_records |
未知结构化数据沉淀 | 不直接展示 |
v1 建议优先实现:
vessel_aisgeo_pointsgeneric_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。
示例概念:
{
"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。
关键字段:
iddatasource_config_idtarget_schemamapping_jsonsample_payload_hashvalidation_statusversionis_activecreated_atupdated_at
mapping_json 是声明式 DSL,不允许任意代码执行。
示例:
{
"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 Provider:base URL、model、API key。
- BarentsWatch:client id/client secret 或 bearer token。
- 未来付费接口:AISHub、MarineTraffic、VesselFinder 等 provider profile。
DataSources 不直接管理全局 secret,只引用 provider profile。
Phase 2 — Settings 自定义源向导
自定义数据源配置入口应放在 /settings 的“采集器设置”或后续专门的自定义采集器设置区。/datasources 保持数据源目录和采集触发职责,不再承载编辑入口。
自定义数据源配置改成向导或右侧 drawer:
- Request
- endpoint
- method
- auth profile
- headers
- query/body config
- schedule
- Sample
- 点击抓取 sample
- 展示 JSON tree
- 支持选择数组根路径
- Target Schema
- 选择
vessel_ais、geo_points、generic_records - 展示该 schema 必填字段
- 选择
- Mapping Proposal
- 调用 LLM 生成 mapping 草案
- 显示字段匹配置信度
- 标出需要人工确认的字段
- Preview
- 用确定性 engine 预览前 N 条转换结果
- 展示校验错误
- Save & Enable
- 保存 mapping version
- 启用调度或仅保存草稿
Phase 3 — 运维视图
为 mapped datasource 展示:
- 上次运行时间。
- 成功记录数。
- 失败记录数。
- 当前 mapping version。
- 目标 schema。
- 最近错误。
- 手动运行按钮。
五、数据库与存储策略
v1:继续使用 PostgreSQL
PostgreSQL 可以承载当前规模的采集、关系查询、JSONB 沉淀和基础时序查询。v1 不必因为“时序数据”立刻引入 TimescaleDB。
适合继续用 PostgreSQL 的场景:
- 数据量可控。
- 最近状态查询为主。
- 历史保留窗口较短。
- 查询模式还没稳定。
- 需要快速迭代 schema 与 mapping。
TODO: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 说明。
- 后续 TODO:引入字段级加密或 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_aissample 写入船舶相关目标结构。- 上游 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 | 1–2 天 |
| Phase 2 | deterministic mapping engine | 2–3 天 |
| Phase 3 | sample/propose/preview/save API | 2–3 天 |
| Phase 4 | DataSources 自定义源向导 | 3–5 天 |
| Phase 5 | generic mapped collector + run history | 2–4 天 |
| Phase 6 | vessel_ais / geo_points destination handler | 2–4 天 |
九、当前差距与下一步
当前差距:
datasource_configs只描述请求配置,不描述目标 schema 和 mapping。- 自定义源没有 sample -> schema -> mapping -> preview -> save 的闭环。
- 生产采集还没有通用 mapped collector。
- Settings 与 DataSources 的职责边界需要在 UI 上进一步明确。
- Earth 还没有通用
geo_points图层。
下一步建议:
- 先实现 target schema registry 和 mapping engine,不急着接 LLM。
- 用固定 sample JSON 做
vessel_ais和generic_records的单元测试。 - 再接 LLM propose API,让 LLM 产出的只是 mapping 草案。
- 最后做前端向导,把人工确认和 preview 放到启用之前。