AI 元数据管理:自动给表和字段打标签,让数据目录活起来
AI 元数据管理:自动给表和字段打标签,让数据目录活起来
公司数据仓库 3000 张表,新人问"用户流失数据在哪",老员工答"你去
dw.dm_user_churn_v3看看"—— 这种对话每天都在发生。表名和字段名是给机器读的,不是给人理解的。AI 打标签,就是给这些冷冰冰的表名和字段名配上一个"人话翻译器"。
一、元数据目录的"冷尸"困局
提起数据目录,很多团队都有类似经历:老板说搞数据治理,Data Catalog 搭起来,第一批表手工录入了 200 条描述,然后……就没人更新了。三个月后,新增的 80 张表没有描述,改过的 30 个字段注释还停留在旧版本。元数据目录变成了"建完就死"的数字坟场。
问题出在手工业模式。手工录入元数据描述有三个致命缺陷:
一是人不够。3000 张表 × 平均 20 个字段 = 6 万个字段。靠 3 个数据开发手写注释,写到退休也写不完。
二是定义不一致。张三觉得status是"订单状态",李四觉得是"记录有效状态"。同一张表被不同人描述,用词五花八门,搜索时根本找不到。
三是不会更新。表结构变更了(加了个字段、改了类型),手工注释不会跟着改,积攒半年就面目全非了。
AI 打标签的作用就在这里:自动化地、一致地、持续地给每个表和字段贴上语义标签,让数据目录从"静态档案"变成"活地图"。
二、AI 打标签的三级分类体系
先定义清楚"打标签"具体打什么。套用百度谷歌的富媒体搜索思路,给表和字段打三层标签:
graph TD A[元数据标签体系] --> B[L1: 业务域标签] A --> C[L2: 数据特征标签] A --> D[L3: 质量与血缘标签] B --> B1["用户域 / 订单域 / 商品域 / 物流域"] B --> B2["PII / 金融 / 医疗 等合规标签"] C --> C1["主键 / 外键 / 维度 / 指标"] C --> C2["枚举类 / ID类 / 时间类 / 文本类"] D --> D1["时效性: 实时 / 准实时 / T+1"] D --> D2["热度: 过去30天查询次数"] D --> D3["血缘: 上游表 / 下游表"] style B fill:#f96,stroke:#333,stroke-width:2px style C fill:#69f,stroke:#333,stroke-width:2px style D fill:#9f9,stroke:#333,stroke-width:2pxL1 业务域标签回答"这表是干嘛的"。AI 通过表名、字段名和少量数据样本来推断表属于哪个业务域。orders表里有user_id、amount、pay_time,明显是订单域。
L2 数据特征标签回答"这字段怎么用"。字段是维度还是指标,是 ID 还是分类值,这个标签对 BI 自动建模极有用 —- AI 知道user_id是维度、amount是指标,写 SQL 时就能自动做GROUP BY user_id, SUM(amount)。
L3 质量与血缘标签回答"这表可信吗"。更新频率、数据量、热度、血缘链路,这些是运维向的信息,帮人快速评估"这张表值不值得用"。
三、自动标签生成的技术实现
标签的生成分两步走:离线批量打标和在线增量更新。
离线打标的核心是用 LLM 批量处理元数据。对每张表,构造一个包含表名、字段列表、字段类型和少量数据样本的 Prompt:
import json from typing import List, Dict def generate_table_tags( table_name: str, columns: List[Dict], sample_data: Dict[str, List], llm_client ) -> Dict: """ 用 AI 给一张表和它的所有字段自动打标签 设计意图:不给模型全量数据,只传字段名+类型+脱敏样本值。 模型综合这三个维度信息,输出结构化的标签 JSON, 供数据目录前端展示和搜索索引使用。 """ # 构造字段描述摘要 columns_desc = [] for col in columns: col_name = col["name"] col_type = col["type"] # 取前 3 条样本值并脱敏 samples = [str(v)[:20] + ("..." if len(str(v)) > 20 else "") for v in sample_data.get(col_name, [])[:3]] columns_desc.append( f"- {col_name} ({col_type}): 样本={samples}" ) prompt = f"""你是数据治理专家。请为下表生成标签: 表名: {table_name} 字段信息: {chr(10).join(columns_desc)} 为以下三类标签返回 JSON: 1. business_tags: 业务域标签,如"用户域"、"订单域"、"商品域"、"物流域"、"营销域" 2. field_tags: 每个字段的数据特征标签,从以下选项组合: - 角色: "主键"、"外键"、"维度"、"指标"、"时间戳"、"分区键" - 内容: "ID类"、"名称类"、"金额类"、"日期类"、"枚举类"、"文本类" - 敏感度: "PII"、"非敏感"、"待确认" 3. quality_tags: 从字段类型和命名推断的质量标签 - 时效预估: "实时/准实时/T+1" - 置信度: 0-1 输出格式: {{ "table": {{ "business_tags": ["订单域"], "description": "一句话业务描述" }}, "fields": {{ "user_id": {{ "tags": ["维度", "ID类", "PII"], "description": "用户唯一标识" }}, "amount": {{ "tags": ["指标", "金额类", "非敏感"], "description": "订单金额" }} }} }} """ response = llm_client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"} ) return json.loads(response.choices[0].message.content)四、从标签到搜索:让数据目录真正可用
打完标签只是第一步,真正让数据目录"活"起来的是基于标签的语义搜索。
传统数据目录搜索只能做字段名精确匹配。你搜"活跃用户",如果字段叫active_users能搜到;如果叫user_active_flag或者is_user_alive,大概率搜不到。AI 标签解决了这个"同义异名"问题 —-user_active_flag和is_user_alive都被打上了"用户活跃度"的业务标签,语义搜索能命中。
def semantic_search(query: str, tagged_tables: List[Dict]) -> List[Dict]: """ 基于标签的语义搜索:让用户用自然语言找到表 设计意图:传统搜索靠字段名匹配,同义词和近义词完全覆盖不到。 引入标签后,搜索匹配的是"业务语义"而非"字段字面", 用户搜"活跃用户"能命中有 "user_active_flag" 字段且被打上"用户活跃度"标签的表。 """ # Step 1: 将用户的搜索意图也转为标签 intent_prompt = f"""用户搜索: "{query}" 请返回匹配的业务域标签和字段特征标签。 例如: 搜"活跃用户" → 业务标签:["用户域"], 字段标签:["活跃度","用户行为"]""" # Step 2: 用标签做交集匹配 # 计算每张表的标签与搜索意图标签的重合度 scored_tables = [] for table in tagged_tables: score = 0 # 业务域标签匹配 score += len(set(table["business_tags"]) & set(search_tags)) # 字段标签匹配 for field_tags in table["field_tags"].values(): score += len(set(field_tags) & set(field_tags_target)) scored_tables.append((table["name"], score)) # Step 3: 按匹配度排序返回 scored_tables.sort(key=lambda x: x[1], reverse=True) return [t for t, _ in scored_tables[:10]]这其实在模仿一个"老员工介绍表"的过程:老员工脑子里有一张"表→做什么用"的映射,用户问什么,他能快速联想出对应的表。AI 标签就是把这张映射外化、结构化。
五、总结
元数据目录最怕"建完就死"。手工录入解决不了增量问题,建得再好看也是摆设。AI 打标签让标注这件事从"手工填写"变成"自动生成+人工校验",解决了人力和时效性两个核心痛点。
落地路线建议:先从 50 张核心表做起,验证标签准确率 > 90% 再推广;标签体系不用太复杂,L1 业务域 + L2 字段特征就够用了;最后一定要接上搜索接口,标签是为搜索服务的,打完标签没人搜等于白干。
