这篇是上篇,聊清楚语义层是什么、里面有什么、有哪些方案选。下篇接着讲 API 设计和内部流转,两篇一起读效果最佳。
先给你讲个让人沮丧的故事
某团队花了三个月,把 LLM 接入了自己的广告投放数据平台。演示那天,产品经理当场提问:
"上周各品牌的消耗和 CPM 是多少?"
AI 给了一个数。大家鼓掌。
然后有人拿着报表比对了一下——数字对不上。
不是差一点点,是差了一个数量级。
问题出在哪?AI 生成了 SQL,表名没错,字段也认识,但 <code>fee</code> 字段它当成"预估消耗"算了,而系统里 <code>fee</code> 其实是"聚光实际扣费",两者统计口径差了 30% 以上。
AI 不知道这件事。它为什么会知道呢?你没告诉它。
这就是语义层要解决的问题。
你以为 LLM 很聪明,其实它是个文盲
对,LLM 能写诗、能翻译、能讲笑话。但面对你公司的数据库,它跟门外汉没什么两样。
数据库里存的是什么?是 <code>fee</code>、<code>imp</code>、<code>ctr</code>、<code>stat_date</code>,还有大量类似 <code>A00293847XQ</code> 这样的 ID。这些字段名对 LLM 来说和天书差不多——它不知道 <code>fee</code> 是扣费还是预算,不知道 <code>stat_date</code> 是投放日期还是数据更新日期,也不知道"效果好"在你们公司到底是 CTR 高、还是 ROI 高、还是老板拍板说好就是好。
研究数据摆在这里:没有任何业务语义辅助,Text-to-SQL 准确率上限约 70%。 遇到稍复杂一点的业务指标,直接跌到 50% 以下。
你雇了个聪明绝顶的实习生,但他第一天上班,什么背景都没交代就让他去查数据、做分析。翻车了怨谁?
语义层就是给 LLM 准备的"入职培训材料"。
语义层是什么
定义一句话说完:语义层是数据仓库和上层应用之间的业务翻译官,负责把底层的技术语言(表名、字段名、join 逻辑)翻译成业务能理解的概念(消耗、CPM、点击率)。
它解决的核心矛盾是:
- 底层数据说的是技术语言:<code>SELECT SUM(fee) FROM ad_stat WHERE stat_date BETWEEN...</code>
- 业务用户说的是人话:"上周花了多少钱"
- LLM 需要在两者之间搭桥,但没人给它画地图
语义层就是那张地图。
更重要的是,它让"定义一次,全局复用"成为可能。<code>CPM</code> 的计算公式只写一次,所有报表、所有工具、所有 AI Agent 用的都是同一个口径。不会再出现"财务报表的消耗和投放系统的消耗对不上"这种经典问题——那种情况通常意味着两个地方各自写了一套 SQL,某一个人某一天改了一个条件,然后谁也不知道哪个是对的。
语义层里面放什么
聊完是什么,来说说里面装了啥。语义层不是一个单一文件,它通常包含几类内容:
第一类:指标定义
这是最核心的。每个业务指标要说清楚四件事:叫什么、怎么算、正常范围是多少、有什么口径要注意。举个例子:
指标:CPM
中文别名: ["千次展示费用", "cpm", "千次费用"]
计算公式: SUM(fee) / SUM(impression) * 1000
单位: 元
正常区间: 20 ~ 200
口径说明: 超过 200 通常意味着定向范围过窄,建议排查
注意"口径说明"这一块——这不是技术信息,是业务经验的沉淀。这类知识如果不显式写进语义层,LLM 永远猜不到,人也容易忘。
第二类:维度定义
用于分组和筛选的属性,比如"品牌"、"广告计划"、"时间粒度"。维度定义里要写清楚字段映射和别名,比如用户说"品牌",系统字段其实叫 <code>brand_name</code>,这个对应关系要有。
第三类:业务规则
这是大多数团队最容易忽略的,但对 AI 来说最有价值的部分:
- "自然流消耗"和"付费消耗"不是一回事,不能加总
- "消耗"默认用聚光扣费口径,T+1 更新,不含退款
- CPM 超过 200 属于异常,需要主动提示用户
如果不写,AI 只会给你算一个数,不会告诉你这个数有没有问题。
第四类:词汇映射表
专门给 LLM 注入上下文用的字典,是整个语义层最"接地气"的部分:
"消耗" / "花了多少钱" / "花费" → fee
"点击率" → ctr = click / impression
"ROI" → 需澄清:广告 ROI 还是品效 ROI?
有了这张表,LLM 遇到"上周花了多少"就知道去查 <code>fee</code>,而不是去猜半天。"ROI"有歧义?语义层可以提前标记,让 AI 主动来问用户。
五种方案,选哪个
知道要建语义层之后,接下来的问题是怎么建。业界目前有五条路:
| 方案 | 核心思路 | 准确率上限 | 维护成本 |
|---|---|---|---|
| 裸 Schema 注入 | 把表结构直接塞进 Prompt | ~70% | 极低 |
| Metric 层 | 预定义指标 + 计算公式 | ~80% | 中 |
| RAG 词汇表 | 向量化业务术语,动态检索 | ~85% | 低-中 |
| 语义模型(YAML) | 结构化描述字段/关系/指标 | ~90% | 中-高 |
| 知识图谱/本体 | 实体+关系+约束的完整图结构 | ~95-99% | 极高 |
裸 Schema 注入就是把 <code>SHOW COLUMNS</code> 的结果粘进 Prompt,简单粗暴,70% 的准确率勉强够演示,上了生产基本翻车。
知识图谱/本体准确率最高,但工程量巨大,没有专职团队别碰。
对于大多数中等规模的业务 AI 产品来说,"语义模型 + RAG 示例"的组合是最划算的——准确率能到 90% 以上,工程复杂度可控,不需要养一个专门的知识图谱团队。
语义模型负责稳定的核心知识(指标定义、字段映射),RAG 负责动态的补充(从历史查询示例里检索出最相似的几条,一起喂给 LLM)。两者结合,效果比单独用任何一个都好。
可以直接参考的开源项目:
- Vanna.ai:RAG + SQL 生成,最容易上手,适合快速验证想法
- Wren AI:有完整的语义层建模 UI,类似完整产品形态,可以直接参考它的设计
- dbt MetricFlow:指标定义的 YAML 规范做得最规范,2025 年已开源
- Snowflake Cortex Analyst:AI + 语义模型的最佳工程实践之一,值得仔细读
小结
语义层这件事说起来不复杂:你要让 AI 读懂业务数据,就得先把业务知识整理清楚,告诉它"消耗是什么"、"效果好怎么算"、"哪些数字超出正常范围"。
麻烦的地方在于,这些知识大多数团队从来没有系统梳理过,分散在各个 SQL 文件、各个报表配置、各个老员工的脑子里。建语义层的过程,某种意义上是一次业务知识的大扫除。
痛,但必要。
下篇会接着讲:有了语义层之后,怎么设计对外暴露的 API?一次查询在语义层内部是怎么流转的?MQL 是什么,为什么不直接让 LLM 写 SQL?
→ 接续阅读:语义层(下篇):一次查询的奇妙旅程