AI 数据字典自动生成:从字段注释到业务口径的智能补全

📅 2026/7/16 17:44:09
AI 数据字典自动生成:从字段注释到业务口径的智能补全
AI 数据字典自动生成从字段注释到业务口径的智能补全接手的表有 200 个字段注释全是 NULL让 AI 帮你从字段名和数据值里推断含义自动补齐数据字典。一、数据字典是最大的技术债如果你在大厂做过数据开发一定经历过这个噩梦接了个需求要用某张表打开一看——200 个字段150 个没有注释剩下 50 个的注释是用户标识金额状态这种说了等于没说的废话。更要命的是业务口径。活跃用户在这张表里是过去 7 天有登录在另一张表里是过去 30 天有下单。没有一个统一的数据字典每次写 SQL 都要先花半天搞清楚这个字段到底是什么意思。数据字典的维护在大多数团队里都是重要但不紧急的事。开发忙着上线谁会专门花时间去补 50 张表的注释结果就是技术债越滚越大。AI 数据字典的思路是不要指望人手动填让 AI 从数据的表面信息和内在规律自动推断字段的业务含义。为什么三层推断要分步走而不是让 AI 一步完成如果你直接把表名字段名200 行样例数据扔给 LLM 让它生成注释它的成功率大概只有 60%。不是 LLM 不行而是你把太多不确定性一次塞给了它。分三步走的好处是每一步的输入都是确定的、可验证的。字段名解析是纯规则——order_amt_7d一定拆成[order, amt, 7d]零概率出错。数据值推断是统计——唯一值 95% 就是 ID枚举值在 {0,1} 就是布尔准确率 85% 以上。前两步已经把这个字段大概率是什么确定了 80%第三步 LLM 只是把结论润色成自然语言。这种规则统计AI的三段式 pipeline准确率能到 90% 以上比一步到位的 LLM 高 30 个百分点。这就是为什么在 AI 落地场景里永远不要让 LLM 从零开始——先给它确定性信号再让它发挥语言能力。二、字段名解析从命名约定推断含义第一步最简单但最有效——从字段名本身提取信息。大多数团队的字段命名是有规律的只是没人整理成文档import re from collections import defaultdict class FieldNameAnalyzer: 从字段名自动推断字段含义 利用命名约定驼峰/下划线/前缀反向推导 # 常见缩写映射表 —— 这是领域知识需要持续积累 ABBREVIATIONS { amt: 金额(amount), cnt: 计数(count), qty: 数量(quantity), dt: 日期(date), ts: 时间戳(timestamp), uid: 用户ID(user_id), sku: 商品编码(stock keeping unit), cvr: 转化率(conversion rate), ctr: 点击率(click through rate), uv: 独立访客(unique visitor), pv: 页面浏览(page view), gmv: 成交总额(gross merchandise volume), arpu: 每用户平均收入(average revenue per user), dau: 日活跃用户(daily active users), mau: 月活跃用户(monthly active users), } # 常见前后缀含义 PREFIX_SUFFIX { _id: 标识符/主键, _name: 名称, _time: 时间, _date: 日期, _status: 状态, _type: 类型, _flag: 布尔标记(0/1), _rate: 比率/比例, _ratio: 比率, _rank: 排名, is_: 是否(布尔值), has_: 是否有(布尔值), total_: 总计, avg_: 平均值, max_: 最大值, min_: 最小值, } def parse_field_name(self, field_name): 解析单个字段名拆成有意义的部分 比如 parse_field_name(total_order_amt_7d) → [total, 总计], [order, 订单], [amt, 金额], [7d, 近7天] tokens [] # 按驼峰或下划线拆分 # 处理驼峰orderStatus → [order, status] words re.findall(r[A-Z]?[a-z]|[A-Z](?[A-Z][a-z]|\d|\b), field_name) # 处理下划线order_status → [order, status] if len(words) 1: words field_name.split(_) for word in words: word_lower word.lower() # 先查缩写表 if word_lower in self.ABBREVIATIONS: tokens.append((word, self.ABBREVIATIONS[word_lower])) else: tokens.append((word, word)) return tokens def analyze_table_fields(self, table_fields): 分析整张表的字段发现命名模式 比如所有以 _7d 结尾的字段都是近7天指标 results {} patterns defaultdict(list) for field_name in table_fields: tokens self.parse_field_name(field_name) results[field_name] { tokens: tokens, description: | .join(f{t}→{d} for t, d in tokens) } # 发现模式查找共享后缀的字段组 suffix field_name.split(_)[-1] if _ in field_name else if suffix.isdigit() or suffix.endswith(d): patterns[suffix].append(field_name) return results, dict(patterns) # 使用示例 # analyzer FieldNameAnalyzer() # fields [order_amt_7d, order_amt_30d, user_cnt_7d, cvr_7d, is_paid_user] # results, patterns analyzer.analyze_table_fields(fields) # for field, info in results.items(): # print(f{field}: {info[description]}) # 输出 # order_amt_7d: order→order | amt→金额(amount) | 7d→7d # order_amt_30d: order→order | amt→金额(amount) | 30d→30d # 发现模式: {7d: [order_amt_7d, user_cnt_7d, cvr_7d], ...}为什么缩写映射表是活的领域知识而不是一劳永逸的字典同一个缩写在不同业务线可能有不同含义——你从支付团队学到的amt是金额但到了广告团队amt可能是amount投放量。如果你把缩写映射表写死在代码里换一个团队就得重写一份。更好的做法是把映射表做成可配置的 YAML 文件每个业务线维护自己的缩写映射。更关键的是PREFIX_SUFFIX里的模式发现——你通过分析整张表发现了所有以_7d结尾的字段是一组近 7 天指标这个发现本身比任何预设的映射表都更有价值。AI 的价值不在于它背下了多少缩写而在于它从一张新表里自动发现模式的能力。三、数据值推断从实际数据反推含义光看字段名不够有些字段名太简洁或者命名不规范。这时候就要看数据本身来推断。import pandas as pd import numpy as np from datetime import datetime class DataValueAnalyzer: 从数据值推断字段的语义类型 核心思路不同类型的数据有不同的分布特征 - ID 类唯一值多接近行数 - 枚举类几个固定值反复出现 - 时间类数字在合理范围内时间戳/日期 - 金额类正数有小数点 # 常见枚举值的语义映射 ENUM_MAPPINGS { frozenset([0, 1]): 布尔标记(是/否), frozenset([0, 1, 2]): 三态状态(待处理/进行中/已完成), frozenset([0, 1, 2, 3]): 四态状态(未开始/进行中/已完成/已取消), } def infer_field_type(self, series, field_name): 根据数据分布推断字段的语义类型 series_clean series.dropna() if len(series_clean) 0: return {type: 空字段, confidence: 1.0} result {field_name: field_name} # 唯一值占比 —— ID 类字段的核心特征 unique_ratio series_clean.nunique() / len(series_clean) if unique_ratio 0.9: result[type] ID标识符 result[confidence] min(unique_ratio, 1.0) result[note] f{series_clean.nunique()} 个唯一值 # 枚举类唯一值少重复多 elif unique_ratio 0.05 and series_clean.nunique() 20: unique_vals sorted(series_clean.unique()) result[type] 枚举/状态码 result[values] unique_vals # 尝试匹配已知的枚举模式 val_set frozenset(unique_vals[:4]) # 取前4个看模式 for pattern, meaning in self.ENUM_MAPPINGS.items(): if val_set.issubset(pattern) or pattern.issubset(val_set): result[semantic_hint] meaning break result[confidence] 0.85 # 时间戳10 位且都在合理范围 elif ( series_clean.dtype in [int64, float64] and series_clean.min() 1000000000 and series_clean.max() 2000000000 and field_name.endswith((_time, _ts, timestamp)) ): result[type] Unix时间戳 result[confidence] 0.9 # 用 min/max 的 datetime 作为提示方便人确认 result[time_range] f{datetime.fromtimestamp(series_clean.min())} ~ {datetime.fromtimestamp(series_clean.max())} result[note] result[time_range] # 比率类值在 0~1 之间 elif series_clean.between(0, 1).all() and field_name.endswith((_rate, _ratio)): result[type] 比率/概率 result[confidence] 0.8 else: result[type] 数值/文本 result[confidence] 0.3 return result # 使用示例 # analyzer DataValueAnalyzer() # 用户状态字段值全是 0/1/2 # s1 pd.Series([0, 1, 2, 1, 0, 2, 1, 0, 0, 1] * 100) # result analyzer.infer_field_type(s1, user_status) # print(result) # → {type: 枚举/状态码, values: [0, 1, 2], # semantic_hint: 三态状态(待处理/进行中/已完成), confidence: 0.85}为什么数据值推断的置信度不是 100%一个字段的值全是 0 和 1你推断它是布尔标记——但实际可能是是否 VIP布尔也可能是支付方式0微信 1支付宝枚举。一个字段的唯一值占比 95%你推断它是 ID——但实际可能是一个高度随机化的设备指纹字段不是业务 ID。数据值推断的本质是模式匹配而模式匹配永远有误判的情况。这就是为什么infer_field_type返回的每个结果都带了confidence字段——0.85 表示大概率对但需要人看一眼。反过来说如果一个推断工具告诉你 100% 确定那才是真的不靠谱。信任度评分是 AI 系统对自己的诚实度——高置信度的自动接受低置信度的提交人工审核这个人机协同的机制比全自动更可靠。四、AI 综合推理把碎片信息拼成完整描述字段名解析给了一些线索数据值推断给了另一些线索。但要把这些线索拼成一句完整准确的字段描述还得靠 LLM。def generate_field_description(field_name, field_type, analysis_result, context): 用 LLM 将分析结果转为自然语言描述 输入字段名 分析结果 表级上下文 输出自然的字段注释 业务口径说明 prompt f你是资深数据分析师。请为以下数据库字段生成标准的字段注释。 ## 字段信息 - 字段名{field_name} - 字段类型数据库{field_type} - 自动分析结果{analysis_result} ## 表级上下文 {context} ## 输出要求 请按以下格式输出 1. 字段注释20字以内一句说清楚 2. 业务口径这句话在业务上怎么理解的 3. 取值范围说明如果是枚举列出各值的含义 ## 示例 字段名order_amt_7d 输出 1. 近7天订单金额 - 滚动窗口汇总 2. 口径过去7个自然日含当日内用户完成的订单总金额含运费不含退款 3. 取值范围浮点数 ≥ 0单位为元 # 实际使用时调用 LLM API # response call_llm_api(prompt) return prompt这套流程整合起来的数据字典生成 pipeline为什么 LLM 在这一层只做润色而不做发现这是整个 pipeline 架构最关键的决策。如果让 LLM 负责推断字段含义它就会靠经验来猜——看到user_type就猜用户类型0普通 1VIP——但这个枚举值映射是完全错误的因为你们公司的 user_type 可能是 0个人 1企业。LLM 在推断任务上不可靠的原因在于它依赖的是训练数据里的普遍模式而不是你公司数据库里的实际数据分布。所以正确的职责分配是让规则和统计做推断因为它们依赖事实让 LLM 做润色因为它擅长语言组织。规则告诉 LLM 这个字段是布尔类型、值域 0/1LLM 把它写成是否标记0否 1是——推断是规则做的文字是 LLM 写的。混淆了这两个角色整个系统的准确率就会从 90% 掉到 60%。踩坑提醒不要用生产库的全量数据跑数据值推断——DataValueAnalyzer.infer_field_type需要扫描字段的所有值来计算唯一值占比在生产库的千万级表上跑一次SELECT DISTINCT可能直接把库拖慢。正确做法是只抽样比如 10000 行做推断然后把结果标记为基于抽样而非全量准确。对于抽样结果置信度低的字段再用离线表的全量数据跑一次不要在生产主库上跑分析查询。字段名解析无法处理中文字段名和拼音混合命名——如果你的 Hive 表里有用户年龄、zhifu_jine、order_金额这种混搭命名FieldNameAnalyzer的正则拆分会全部失效。这种情况目前只能用 LLM 直译把中文片段送给 LLM 翻译但准确率会降到 60% 左右。团队里规范字段命名语言要么全英文要么全中文拼音转写比写一个万能的解析器更实际。数据字典生成之后必须配过期检测——你花两天跑完了 50 张表的字典三个月后 20% 的表结构变了加了字段、改了类型、删了旧字段但你没有任何机制检测这些变化。最简单的方案是加一个定时任务每天对核心表的 DDL 做一次快照对比昨天的快照有变化就触发字典更新——不需要人工盯着表结构变化。五、总结AI 自动生成数据字典的思路是先让机器做 80%人复核 20%。机器擅长从字段名规律和数据分布里找线索但最终的语义理解和业务口径确认还是需要人来把关。实际落地时建议分步走先从核心表开始挑 3-5 张最重要、使用最频繁的表先跑一遍验证效果建立缩写/枚举知识库把团队内部的命名约定沉淀下来AI 推断会越来越准保持 human-in-the-loopAI 生成的结果标记置信度置信度低的主动提示人工审核数据字典做好了新人 onbarding 效率直接提升 50%——再也不用追着老员工问这个字段啥意思了。本文由朱大喜原创如果你也被数据字典问题折腾过欢迎评论区吐槽~