用 AI Agent 生成和维护语义视图
语义视图的设计涉及业务理解、表结构分析和语义建模,这类工作非常适合交给 AI Agent 完成。本文从实践角度说明:在动手之前需要完成哪些业务对齐工作,Agent 需要收集哪些信息、如何判断设计质量、以及哪些常见错误会让视图"创建成功但结果错误"。
为什么语义视图适合 Agent 生成
语义视图的创建有两个难点:
- 业务理解:维度和指标的命名、同义词、注释需要贴近业务语言,而不是照搬物理列名
- 表结构分析:外键关系、类型匹配、主键选择需要先读懂数据,再做设计决策
这两件事 Agent 都擅长——它可以同时查询表结构、采样数据、理解业务描述,然后生成一个完整的语义视图定义。但有一件事 Agent 做不到:主动发现业务口径分歧。跳过业务对齐直接让 Agent 建模,等到视图上线后才发现"员工数"在不同报表里定义不一样——这是最难排查的问题类型,也是最容易被忽略的步骤。
业务对齐:在动手之前
技术实现是最简单的部分。 生成一个能运行的语义视图只需要十分钟;生成一个业务上真正有用的语义视图,需要先做好业务对齐。
两类失败模式
| 失败类型 | 症状 | 发现时机 |
|---|---|---|
| 技术失败 | 创建报错(类型不匹配、外键引用错误) | 立即发现 |
| 业务失败 | 创建成功,但查询结果不符合业务预期 | 上线后才发现 |
业务失败更危险:查询不报错,数字看起来合理,但计算口径与业务理解不一致,可能影响决策。
需要收集的五类业务知识
在让 Agent 开始工作之前,先收集以下五类信息:
1. 分析域定义
这个视图要回答哪些核心业务问题?不是"帮我建一个员工视图",而是:
- 场景:按部门、入职年份分析薪资分布
- 使用者:HR 数据分析师、部门经理
- 常用维度:部门、入职时间、在职状态
- 不包含:绩效数据、晋升记录(属于另一个分析域)
明确边界很重要。一个视图覆盖太多主题,不如拆成多个聚焦的视图。
2. 指标口径
同一个指标名称,不同部门可能有完全不同的计算方式:
| 指标名 | HR 口径 | 财务口径 | 管理层口径 |
|---|---|---|---|
| 员工人数 | 在册人数(含试用期) | 在岗人数(已转正) | 全时当量(FTE) |
| 平均薪资 | 全员含离职 | 仅在职员工 | 仅正式员工(排除实习生) |
| 订单金额 | 下单金额 | 实收金额(扣退款) | 确认收入(按财务准则) |
必须在建模前确认每个指标的口径,包括:
- 分子和分母分别是什么
- 包含还是排除哪些数据(离职员工、测试账户、退款订单)
- 按什么时间点统计(下单时间、支付时间、确认时间)
3. 维度粒度
同一个业务概念,可以有不同的粒度级别:
| 维度 | 可选粒度 | 需要确认 |
|---|---|---|
| 时间 | 自然月 / 财季 / 入职年份 | 是否需要多个时间维度? |
| 地理 | 城市 / 省份 / 大区 | 最细粒度是什么?是否需要上卷? |
| 组织 | 自然部门 / 业务线 / 成本中心 | 上卷逻辑在数据库里还是需要表达式实现? |
4. 业务规则和过滤条件
哪些数据在正常分析中应该被排除?这些规则往往是隐性的,需要主动问:
- 测试账户(
)is_test = true - 已删除的记录(
)is_deleted = false - 特殊时间段的异常数据(如系统迁移期间的脏数据)
- 法务和合规要求(某些数据不能出现在报表中)
这些规则可以设计成 FILTERS 子句,也可以直接写入指标的条件聚合里。
5. 术语表
物理列名往往是缩写或技术命名,需要建立业务术语映射:
| 物理列名 | 业务含义 | 常用同义词 |
|---|---|---|
| 所在部门 | 部门、department、team |
| 入职日期 | 入职时间、onboard date、加入日期 |
| 是否在职 | 在职状态、active status、在岗 |
| 月薪(税前) | 薪资、工资、月薪、base salary |
术语表直接影响 Analytics Agent 能否通过自然语言找到正确的维度和指标。
口径文档模板
将以下模板填写完整后交给 Agent,可以显著提升生成质量:
向谁收集、如何收集
| 信息类型 | 找谁 | 有效提问方式 |
|---|---|---|
| 指标口径 | 数据分析师、业务负责人 | "这个数字是怎么算出来的?包含哪些人/订单?" |
| 维度粒度 | 报表使用者 | "你通常按什么维度看这个数据?最细到什么级别?" |
| 业务规则 | 数据工程师、DBA | "这张表里有哪些数据是正常分析不应该包含的?" |
| 术语映射 | 业务用户 | "你们平时说的'在职员工'对应数据库里哪个字段?" |
最实用的方法:拿一份现有报表,逐个数字追问其计算逻辑。这样既能快速发现口径分歧,也能让现有报表成为最好的业务文档参考。
典型口径冲突案例
以下是实际项目中常见的口径分歧,说明为什么业务对齐不能跳过:
案例 1:员工人数
HR 说"我们有 500 人",财务说"在岗 480 人",管理层说"FTE 是 460"——同一时点,三个数字都对,但口径不同。如果语义视图只定义一个"员工总数",三个部门都会觉得数字不对。
解决方案:定义三个独立指标,分别对应三种口径,并在注释中说明差异。
案例 2:订单金额
销售看"下单金额"(GMV),财务看"实收金额"(扣退款),运营看"有效订单金额"(排除测试订单和异常订单)。同一张订单表,三种 WHERE 条件,三个完全不同的数字。
解决方案:建立三个指标,分别命名为
gmv、net_revenue、valid_order_amount,并在同义词中加入各部门的常用叫法。
案例 3:时间维度
"按月分析"可能是自然月(1月1日-1月31日),也可能是财务月(财年第一个月从4月开始),还可能是滚动30天。如果不确认,Agent 会默认用自然月,财务部门的数据就对不上。
解决方案:明确时间维度的定义,如果需要多种时间口径,定义多个时间维度。
识别口径冲突的方法:对同一指标反复追问——"是否包含离职员工?""是否包含实习生?""是否包含未完成状态?"通常在第二或第三个问题时就能暴露分歧。
第一步:收集必要信息
完成业务对齐后,进入技术信息收集阶段。
这是最关键的一步。 信息不足时,Agent 会生成一个"能跑通"但业务上没用的视图。
必须收集的信息
1. 分析目标
不是"帮我建一个语义视图",而是:
- 这个视图要回答什么业务问题?("分析各部门薪资分布" vs "分析员工离职率趋势")
- 主要使用者是谁?(数据分析师、业务经理、还是 AI Agent 自动查询)
- 最常用的查询维度是什么?(按部门、按时间、按地区)
2. 涉及的物理表
让 Agent 先读表结构,不要靠猜:
Agent 需要知道:
- 每张表的主键是什么
- 表之间如何关联(关联列的名称和类型是否一致)
- 哪些列适合做维度,哪些适合做指标
- 数据量级(影响是否需要分区或过滤)
3. 业务术语映射
物理列名往往是缩写或技术命名,需要明确业务含义:
| 物理列名 | 业务含义 | 常用别名 |
|---|---|---|
| 所在部门 | 部门、department |
| 入职日期 | 入职时间、onboard date |
| 是否在职 | 在职状态、active status |
4. 指标定义的口径
同一个"平均薪资"可能有不同口径:
- 是否包含离职员工?
- 是否包含实习生?
- 按自然月还是按财年统计?
这些口径决定了指标的过滤条件和维度设计,必须在建模前确认。
可选但有价值的信息
- 现有的报表或 SQL 查询(帮助 Agent 理解实际使用模式)
- 已知的数据质量问题(某列有大量 NULL、某表有重复数据)
- 下游工具(Analytics Agent、BI 工具、还是直接 SQL 查询)
第二步:让 Agent 分析表结构
在生成语义视图之前,Agent 应该先做一轮表结构分析,而不是直接开始写 CREATE 语句。
Agent 在这一步需要特别检查:
外键类型匹配:这是最常见的创建失败原因。如果
employees.dept(string)要关联 departments.dept_id(int),类型不匹配,创建时会报错:
正确做法是找到类型一致的关联列,或者在设计时明确指定引用列:
主键选择:语义视图的主键不必是物理表的主键,选择能唯一标识业务实体的列即可。如果用
dept_name 作为部门表的主键(而非 dept_id),可以让外键关联更自然。
第三步:生成语义视图
信息收集完毕后,给 Agent 一个结构化的指令。把口径文档直接附在指令里,这是提升生成质量最有效的方式:
第四步:验证生成结果
创建成功不等于可用。 这是最容易被忽略的一步。
必须验证的查询
常见的"静默错误"
以下情况创建时不报错,但查询结果是错的,必须通过验证发现:
算术表达式指标结果错误:
MAX(salary) - MIN(salary) 这类指标定义在查询时只返回第一个操作数(MAX 的值),减法不执行。如果 Agent 生成了这类指标,需要改为在外层 SQL 计算:
外键关联未生效:如果跨表维度查询返回 NULL 或行数异常,说明外键关联没有正确建立。检查
DESC EXTENDED 的输出,确认外键定义是否正确。
维度去重行为:只传 DIMENSIONS 不传 METRICS 时,返回的是去重后的维度值列表,不是原始行数。如果期望看到所有行,需要加上 COUNT 指标。
第五步:迭代优化
语义视图的第一版通常不是最终版。常见的迭代需求:
添加遗漏的维度:发现需要按"薪资等级"分析,但视图里没有这个维度。由于 ALTER 不支持增删维度,需要重建:
修正指标口径:发现"平均薪资"应该只统计在职员工。需要把
AVG(salary) 改为 AVG(CASE WHEN is_active = true THEN salary END):
优化同义词:Analytics Agent 或用户反馈某个维度用自然语言查不到,需要补充同义词。
设计质量检查清单
Agent 生成语义视图后,可以用这个清单做最终检查:
业务对齐
- 每个指标的口径已与业务方确认(包含/排除条件)
- 时间维度的粒度和起止范围已确认
- 已知的口径分歧已通过多个指标分别定义
- 术语表已建立,同义词覆盖主要业务叫法
结构完整性
- 每个逻辑表都有明确的主键
- 外键关联的两端列类型一致
- 被引用的逻辑表在 TABLES 子句中先于引用方定义
语义质量
- 维度和指标名称使用业务术语,而非物理列名缩写
- 关键维度和指标都有中文注释
- 时间类维度设置了
is_time = true - 唯一标识类维度设置了
is_unique = true - 面向 AI Agent 使用时,重要维度添加了同义词
指标正确性
- 没有使用算术表达式指标(
、A - B
)A / B - 没有使用窗口函数指标(
)RANK() OVER - 没有使用派生指标(指标引用指标)
- 条件聚合指标(
)已验证结果正确COUNT(CASE WHEN ...)
查询验证
- 基础维度+指标查询结果符合预期
- 跨表维度查询(外键关联)结果正确
- 计算维度(表达式)结果正确
- 数值量级合理(没有异常的 NULL 或 0)
完整示例:从零生成一个可用的语义视图
以下是一个完整的 Agent 对话流程,展示从需求到可用视图的全过程。
