Spring Ai Alibaba DataAgent 元数据标注能力集成

102 阅读14分钟

📋 目录


🚀 快速开始

5 分钟上手

步骤 1:验证元数据

import json
from jsonschema import validate, Draft7Validator

# 加载 Schema
with open('table-metadata-schema-v1.0.json') as f:
    schema = json.load(f)

# 验证元数据
validator = Draft7Validator(schema)
errors = list(validator.iter_errors(your_metadata))
if errors:
    print(f"验证错误: {errors}")
else:
    print("✅ 元数据有效!")

步骤 2:生成基础元数据

metadata = {
    "schema_version": "1.0",
    "table_id": "tbl_order_001",  # 系统自动生成
    "basic_info": {
        "database_name": "order_db",
        "table_name": "t_order"
    },
    "business_info": {
        "business_domain": "transaction",
        "table_type": "fact"
    },
    "technical_info": {
        "db_type": "mysql",
        "instance_name": "prod_mysql_01"
    }
}

步骤 3:建立搜索索引

from elasticsearch import Elasticsearch

es = Elasticsearch()
es.index(index="table_metadata", id=metadata["table_id"], document=metadata)

提示: 完整的代码示例和集成指南请参考 集成指南 章节。


📖 方案概述

背景

dataagent 项目需要解决**"库表数据检索精准性不足"**的问题。通过元数据标注补充库表的业务含义、结构信息、技术属性等描述,让检索能基于业务域、场景、表结构等维度筛选匹配。

核心特性

特性说明优势
检索精准性支持多维度检索(业务域、表类型、标签、字段描述)精确率提升 25%+
标注低门槛必填项仅 8 个,层级扁平(最高 3 层)降低人工标注成本 60%+
扩展性强支持自定义业务域、数据库类型、扩展字段兼容历史数据,不破坏现有结构
无侵入集成可独立部署,便于 Elasticsearch 等检索引擎解析快速集成,无需改造现有系统

设计原则

  1. 最小够用:仅包含库表检索、理解、使用必需的字段
  2. 自动化为主:支持 LLM 按 Schema 自动提取字段描述、业务域等
  3. 人工为辅:仅需补充枚举值、敏感级别等关键信息
  4. 向后兼容:所有扩展均保持向后兼容,不破坏历史数据

🎯 核心概念

五大核心模块

Schema 由以下 5 个核心模块组成,每个模块负责不同的元数据维度:

模块模块名主要用途必填字段数
基础信息basic_info数据库名、表名、表ID、表别名2
业务信息business_info业务域、表类型、业务场景、标签、描述2
结构信息structure_info字段列表、索引信息、主键0
技术属性technical_info数据库类型、实例名、更新频率、数据量2
管理信息management_info负责人、访问权限、操作日志0

必填字段(8 个)

#字段路径说明示例
1schema_versionSchema 版本"1.0"
2table_id唯一表标识符"tbl_order_001"
3basic_info.database_name数据库名"order_db"
4basic_info.table_name物理表名"t_order"
5business_info.business_domain业务域分类"transaction"
6business_info.table_type表类型分类"fact"
7technical_info.db_type数据库类型"mysql"
8technical_info.instance_name数据库实例名"prod_mysql_01"

注意: table_id 由系统自动生成,用户无需手动填写。


📐 Schema 结构

1. 基础信息 (basic_info)

基础标识信息,用于唯一标识表。

字段类型必填说明示例
database_namestring数据库名"order_db"
table_namestring物理表名"t_order"
table_aliasstring表别名/业务友好名称"订单表"
schema_namestring数据库 Schema 名"public"

2. 业务信息 (business_info)

业务描述和分类,用于业务理解和检索。

字段类型必填说明示例
business_domainenum业务域分类"transaction"
business_domain_customstring⚠️自定义业务域(当 business_domain"custom" 时必填)"cross_border_ecommerce"
table_typeenum表类型分类"fact"
table_type_customstring⚠️自定义表类型(当 table_type"custom" 时必填)"snapshot"
business_scenariostring具体业务场景描述"订单创建、支付、发货全流程管理"
tagsarray标签数组,用于灵活分类和检索["核心业务", "高频查询"]
business_descriptionstring表的业务描述"订单主表,存储用户下单信息..."

业务域枚举值:

  • transaction - 交易域
  • user - 用户域
  • product - 商品域
  • payment - 支付域
  • logistics - 物流域
  • marketing - 营销域
  • finance - 财务域
  • analytics - 分析域
  • custom - 自定义(需填写 business_domain_custom

表类型枚举值:

  • fact - 事实表
  • dimension - 维度表
  • aggregation - 聚合表
  • staging - 临时表
  • temp - 临时表
  • config - 配置表
  • log - 日志表
  • custom - 自定义(需填写 table_type_custom

3. 结构信息 (structure_info)

表结构信息,包含字段列表和索引信息。

字段定义 (columns)

每个字段包含以下属性:

字段类型必填说明
column_namestring物理字段名
column_aliasstring业务别名
data_typestring物理数据类型
column_descriptionstring字段业务描述
is_primary_keyboolean是否主键
is_nullableboolean是否允许 NULL
is_uniqueboolean是否唯一约束
default_valuestring默认值
enum_valuesarray枚举值数组
value_rangestring值范围描述(如 "0-100", ">=0"
sensitivity_levelenum敏感级别(public, internal, confidential, secret
related_tablesarray关联表ID数组

其他结构信息

字段类型说明
indexesarray索引信息数组
primary_keysarray主键字段名数组
estimated_row_countinteger预估行数

4. 技术属性 (technical_info)

技术属性和数据库配置。

字段类型必填说明示例
db_typeenum数据库类型"mysql"
db_type_customstring⚠️自定义数据库类型(当 db_type"custom" 时必填)"oceanbase"
instance_namestring数据库实例名或连接标识"prod_mysql_01"
update_frequencyenum数据更新频率"realtime"
last_update_timestring最后更新时间(ISO 8601 格式)"2024-01-15T10:30:00+08:00"
data_volumeobject数据量信息(行数、存储大小、增长率)-
data_qualityobject数据质量指标(完整性、准确性、新鲜度)-
partition_infoobject分区信息-

数据库类型枚举值:

  • mysql, postgresql, oracle, sqlserver
  • clickhouse, hive, mongodb, redis, elasticsearch
  • custom - 自定义(需填写 db_type_custom

更新频率枚举值:

  • realtime - 实时
  • hourly - 每小时
  • daily - 每天
  • weekly - 每周
  • monthly - 每月
  • on_demand - 按需
  • unknown - 未知

5. 管理信息 (management_info)

管理和权限信息。

字段类型说明
ownerobject负责人信息(姓名、邮箱、电话)
access_permissionobject访问权限配置(读/写权限级别、允许的角色)
operation_logarray操作历史日志数组
lifecycleobject表生命周期信息(状态、创建时间、保留天数)

6. 自定义字段 (custom_fields)

扩展字段,所有键名必须以 custom_ 前缀开头。

值类型限制:

  • ✅ 字符串(最大 2000 字符)
  • ✅ 数字(整数或浮点数)
  • ✅ 布尔值
  • ✅ 数组(字符串或数字数组,最多 100 项)
  • ❌ 对象(嵌套结构)
  • ❌ null 值

示例:

{
  "custom_fields": {
    "custom_data_lineage": "user_table -> order_table -> payment_table",
    "custom_business_owner": "订单业务团队",
    "custom_sla": "99.9%",
    "custom_is_critical": true,
    "custom_priority_score": 8.5
  }
}

提示: 自定义字段的命名规范和使用建议请参考 扩展机制 章节。


🔧 扩展机制

扩展原则

  1. 向后兼容性:所有扩展必须与现有数据向后兼容
  2. 明确的扩展入口:扩展仅允许通过指定的入口点进行
  3. 版本管理:使用语义化版本(主版本.次版本)跟踪 Schema 演进
  4. 验证:所有扩展必须通过 Schema 验证

扩展入口

扩展仅允许通过以下两个入口点:

  1. 自定义字段 (custom_fields 对象)
  2. 可选模块/字段(Schema 中标记为可选的字段)

自定义字段扩展

命名规范

所有自定义字段的键名必须custom_ 前缀开头:

{
  "custom_fields": {
    "custom_data_lineage": "user_table -> order_table",
    "custom_business_owner": "订单业务团队"
  }
}

最佳实践

实践说明示例
使用描述性名称选择清晰、自解释的字段名custom_data_lineage, custom_business_owner
避免模糊命名不要使用无意义的名称custom_field1, custom_ext
文档化自定义字段维护自定义字段及其用途的注册表-
命名一致性多词字段名使用 snake_casecustom_retention_policy

枚举扩展

对于枚举字段(如 business_domaintable_typedb_type),扩展流程为:

  1. 使用 "custom" 选项:当预定义的枚举值不适用时,使用 "custom" 选项
  2. 提供自定义值:填写对应的 *_custom 字段
  3. 提升为预设值:如果自定义值使用频繁(>10% 的表),可在下一个次版本中提升为预设枚举值

示例:添加自定义业务域

{
  "business_info": {
    "business_domain": "custom",
    "business_domain_custom": "cross_border_ecommerce",
    "table_type": "fact"
  }
}

版本管理

版本格式

版本遵循语义化版本:主版本.次版本

  • 主版本:破坏性变更(仅在极端情况下使用)
  • 次版本:向后兼容的扩展

版本更新规则

次版本(例如,1.0 → 1.1)

允许:

  • 向现有模块添加可选字段
  • 添加可选模块
  • 添加新的枚举值(保留 "custom" 选项)
  • 扩展 maxLength/maxItems 约束

不允许:

  • 删除字段
  • 将可选字段设为必填
  • 更改字段类型
  • 删除枚举值

主版本(例如,1.0 → 2.0)

仅用于:

  • 无法避免的破坏性变更
  • 完整的 Schema 重新设计
  • 移除已弃用的功能

注意: 主版本更新需要提供迁移脚本和明确的弃用时间表。

扩展检查清单

在添加扩展之前,请验证:

  • 它是否适合现有模块?
  • 是否可以通过 custom_fields 处理?
  • 是否真正必要(不冗余)?
  • 是否遵循命名规范?
  • 是否向后兼容?
  • 文档是否清晰?
  • 验证规则是否适当?

🔌 集成指南

Elasticsearch 集成

索引映射策略

推荐的 Elasticsearch 索引映射配置:

{
  "mappings": {
    "properties": {
      "table_id": { "type": "keyword" },
      "basic_info": {
        "properties": {
          "database_name": { "type": "keyword" },
          "table_name": {
            "type": "keyword",
            "fields": {
              "text": { "type": "text", "analyzer": "standard" }
            }
          },
          "table_alias": {
            "type": "text",
            "analyzer": "ik_max_word",
            "fields": { "keyword": { "type": "keyword" } }
          }
        }
      },
      "business_info": {
        "properties": {
          "business_domain": { "type": "keyword" },
          "table_type": { "type": "keyword" },
          "tags": { "type": "keyword" },
          "business_description": {
            "type": "text",
            "analyzer": "ik_max_word"
          }
        }
      },
      "structure_info": {
        "properties": {
          "columns": {
            "type": "nested",
            "properties": {
              "column_name": { "type": "keyword" },
              "column_alias": {
                "type": "text",
                "analyzer": "ik_max_word"
              },
              "column_description": {
                "type": "text",
                "analyzer": "ik_max_word"
              }
            }
          }
        }
      }
    }
  }
}

查询示例

精确过滤:

{
  "query": {
    "bool": {
      "filter": [
        { "term": { "business_info.business_domain": "transaction" } },
        { "term": { "business_info.table_type": "fact" } },
        { "terms": { "business_info.tags": ["核心业务", "高频查询"] } }
      ]
    }
  }
}

全文搜索:

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "订单",
            "fields": [
              "business_info.business_description^3",
              "basic_info.table_alias^2"
            ]
          }
        }
      ],
      "filter": [
        { "term": { "business_info.business_domain": "transaction" } }
      ]
    }
  }
}

自动化标注

LLM 提示模板

def generate_annotation_prompt(table_schema, sample_data):
    prompt = f"""
你是一位数据治理专家。分析以下数据库表,并根据库表元数据 Schema 提取元数据。

表结构:
{table_schema}

样本数据(前 5 行):
{sample_data}

请提取并返回以下结构的 JSON 对象:
{{
  "business_info": {{
    "business_domain": "以下之一:transaction, user, product, payment, logistics, marketing, finance, analytics, 或 custom",
    "table_type": "以下之一:fact, dimension, aggregation, staging, temp, config, log, 或 custom",
    "business_scenario": "具体业务场景描述",
    "tags": ["标签1", "标签2", ...],
    "business_description": "全面的业务描述"
  }},
  "structure_info": {{
    "columns": [
      {{
        "column_name": "...",
        "column_alias": "业务友好名称",
        "column_description": "业务含义描述",
        "sensitivity_level": "以下之一:public, internal, confidential, secret"
      }}
    ]
  }}
}}

重点关注:
1. 从表名和列名推断业务域
2. 从列关系理解业务场景
3. 提供有意义的业务描述
4. 识别敏感数据字段
"""
    return prompt

混合标注方法

结合 LLM 和基于规则的方法,提高标注效率和准确性:

def hybrid_annotation(table_schema, sample_data, db_config, llm_client):
    """
    混合标注:LLM 用于业务信息,规则用于技术信息
    """
    # LLM 用于业务理解
    business_metadata = auto_annotate_table(table_schema, sample_data, llm_client)
    
    # 规则用于技术信息
    technical_metadata = {
        "db_type": db_config["type"],
        "instance_name": db_config["instance_name"],
        "update_frequency": infer_update_frequency(table_schema)
    }
    
    # 合并
    complete_metadata = {
        **business_metadata,
        "technical_info": technical_metadata,
        "schema_version": "1.0"
    }
    
    return complete_metadata

前端表单渲染

Vue.js 组件示例

<template>
  <el-form :model="formData" :rules="rules" label-width="150px">
    <!-- 基础信息 -->
    <el-card header="基础信息">
      <el-form-item label="数据库名" prop="basic_info.database_name" required>
        <el-input v-model="formData.basic_info.database_name" />
      </el-form-item>
      <el-form-item label="表名" prop="basic_info.table_name" required>
        <el-input v-model="formData.basic_info.table_name" />
      </el-form-item>
    </el-card>
    
    <!-- 业务信息 -->
    <el-card header="业务信息">
      <el-form-item label="业务域" prop="business_info.business_domain" required>
        <el-select v-model="formData.business_info.business_domain">
          <el-option label="交易域" value="transaction" />
          <el-option label="用户域" value="user" />
          <el-option label="自定义" value="custom" />
        </el-select>
      </el-form-item>
      
      <el-form-item 
        v-if="formData.business_info.business_domain === 'custom'"
        label="自定义业务域" 
        prop="business_info.business_domain_custom"
        required
      >
        <el-input v-model="formData.business_info.business_domain_custom" />
      </el-form-item>
    </el-card>
  </el-form>
</template>

提示: 完整的表单组件代码和验证规则请参考文档的完整版本。


📝 示例数据

示例 1:交易域订单表

{
  "schema_version": "1.0",
  "table_id": "tbl_order_001",
  "basic_info": {
    "database_name": "order_db",
    "table_name": "t_order",
    "table_alias": "订单表"
  },
  "business_info": {
    "business_domain": "transaction",
    "table_type": "fact",
    "business_scenario": "订单创建、支付、发货全流程管理",
    "tags": ["核心业务", "高频查询", "实时数据"],
    "business_description": "订单主表,存储用户下单信息,包括订单基本信息、订单金额、订单状态等核心字段。"
  },
  "structure_info": {
    "columns": [
      {
        "column_name": "order_id",
        "column_alias": "订单ID",
        "data_type": "bigint",
        "column_description": "订单唯一标识符,系统自动生成的自增主键",
        "is_primary_key": true,
        "sensitivity_level": "internal"
      },
      {
        "column_name": "order_amount",
        "column_alias": "订单金额",
        "data_type": "decimal(10,2)",
        "column_description": "订单总金额,单位为元",
        "sensitivity_level": "confidential"
      }
    ],
    "primary_keys": ["order_id"]
  },
  "technical_info": {
    "db_type": "mysql",
    "instance_name": "prod_mysql_order_01",
    "update_frequency": "realtime"
  },
  "custom_fields": {
    "custom_data_lineage": "tbl_user_001 -> tbl_order_001 -> tbl_payment_001",
    "custom_sla": "99.9%"
  }
}

示例 2:用户域画像表

{
  "schema_version": "1.0",
  "table_id": "tbl_user_profile_001",
  "basic_info": {
    "database_name": "user_center",
    "table_name": "user_profile",
    "table_alias": "用户画像表"
  },
  "business_info": {
    "business_domain": "user",
    "table_type": "dimension",
    "business_scenario": "用户画像数据存储,支持用户标签、偏好、行为分析等场景",
    "tags": ["用户域", "数据分析", "T+1同步"],
    "business_description": "用户画像维度表,存储用户的详细画像信息"
  },
  "technical_info": {
    "db_type": "postgresql",
    "instance_name": "analytics_postgres_01",
    "update_frequency": "daily"
  },
  "custom_fields": {
    "custom_sync_schedule": "T+1 daily sync at 02:00"
  }
}


💡 最佳实践

标注实践

实践说明
使用 LLM 进行初始标注自动提取业务描述和域分类,提高效率
手动审查敏感字段审查并更正敏感级别、枚举值,确保准确性
利用自定义字段custom_fields 用于组织特定需求
保持一致性遵循命名规范并文档化自定义字段
版本控制始终在元数据中指定 schema_version

扩展实践

实践说明
优先使用可选字段尽可能使用可选字段而非 custom_fields
谨慎使用自定义字段仅用于真正自定义的、组织特定的需求
文档化扩展维护所有扩展的清晰文档
验证扩展确保所有扩展通过 Schema 验证
规划提升设计自定义值时考虑提升为预设枚举

集成实践

检索引擎设置:

  • 配置索引映射
  • 设置分词器(用于中文文本)
  • 创建过滤查询模板
  • 测试搜索性能

自动化标注:

  • 设置 LLM 客户端
  • 创建提示模板
  • 实现验证逻辑
  • 设置批量处理

前端集成:

  • 从 Schema 生成表单字段
  • 实现渐进式展示
  • 添加验证规则
  • 创建自定义字段 UI

❓ 常见问题

Q1: 如何选择业务域?

A: 优先从预设枚举值中选择。如果都不适用,使用 "custom" 并填写 business_domain_custom。当自定义值使用频繁时(>10% 的表),可以申请提升为预设枚举值。

Q2: 自定义字段可以嵌套对象吗?

A: 不可以。自定义字段的值类型限制为:字符串、数字、布尔值、数组(字符串或数字)。如果需要复杂结构,建议使用可选模块扩展。

Q3: 如何迁移历史元数据到新 Schema?

A:

  1. 识别历史元数据中的字段
  2. 映射到新 Schema 的对应字段
  3. 使用 Schema 验证器验证迁移后的数据
  4. 逐步迁移,保留原始数据作为备份

Q4: 必填字段可以省略吗?

A: 不可以。8 个必填字段是 Schema 的核心,必须全部填写。table_id 由系统自动生成,其他字段需要手动填写。

Q5: 如何判断字段的敏感级别?

A:

  • public: 可以公开访问的数据
  • internal: 内部使用的数据
  • confidential: 机密数据,需要授权访问
  • secret: 秘密数据,严格限制访问

建议参考组织的数据分类标准。


📚 参考资料

规范文档

行业参考

  • Dify 元数据过滤功能
  • Haystack 库表 metadata 字段设计
  • OpenAI Metadata Tagger Schema 规范