Files
planet/docs/plans/datasource-custom-api-mapping-plan.md
2026-04-29 17:27:44 +08:00

13 KiB
Raw Blame History

自定义 API 数据源与 LLM 映射系统 — 实施计划

状态:规划中 创建日期2026-04-28 核心原则LLM 辅助生成映射配置;生产采集使用确定性转换引擎

已确认决策

项目 决策
自定义 API 的定位 作为内置数据源的补充入口,不直接等同于 Earth 新功能
LLM 的职责 探索未知 API、分析样本 JSON、生成 mapping 草案
采集时是否调用 LLM 不调用;采集链路必须确定性、可审计、可复现
自定义数据如何进入 Earth 必须映射到已支持的目标 schema或先进入通用数据沉淀
外部凭证放置位置 Settings / 外部集成统一管理 provider tokenDataSources 引用 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 layerTODO
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:字段名、类型、是否必填、说明、示例。
  • validatorPydantic 或等价校验器。
  • 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

关键字段:

  • id
  • datasource_config_id
  • target_schema
  • mapping_json
  • sample_payload_hash
  • validation_status
  • version
  • is_active
  • created_at
  • updated_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 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_aisgeo_pointsgeneric_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。

TODOTimescaleDB

以下条件满足后,再评估 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_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_aisgeneric_records 的单元测试。
  3. 再接 LLM propose API让 LLM 产出的只是 mapping 草案。
  4. 最后做前端向导,把人工确认和 preview 放到启用之前。