为何RAG不够用:面向图查询、SQL查询和向量查询的语义层
RAG在多跳查询、数值型查询以及含义模糊的企业级查询中表现不佳。语义层负责查询分解、路由处理和模式映射,同时借助Apache Ossie来实现跨平台兼容性。
语言模型使得用通俗语言表达企业需求变得十分容易。但获得答案与在多个数据系统中理解问题的含义是两回事。以这个例子为例:
想象一位分析师在提问:哪些交易所交易基金持有与英伟达有战略合作关系的公司、管理规模超过10亿美元,且在最近的研究报告中获得了正面评价?
这看起来像是一个问题,但实际上它包含了三类工作:
- 英伟达、战略合作伙伴、ETF持有情况:在图表中梳理这些关系。
- 管理规模超过10亿美元:进行精确的数值筛选。
- 最新的正面研究:理解非结构化文本。
其背后存在更根本的问题:在底层数据模型中,AUM的含义是什么?又以哪个来源作为其权威依据?系统要能够给出正确答案,就必须理解数据的含义而不仅仅是数据本身。语义工程正是为填补这一空白而存在的。
RAG的局限性
典型的RAG流程会检索出相关段落,再让模型基于这些段落进行回答。当任务仅仅是查找相关文本并据此回应时,这种方法非常有效。但企业级问题往往需要的不仅仅是相似度判断,而纯向量检索会在四个明显方面出现缺陷。
碎片化的检索
想象一份产品手册被分割成了三部分:
Chunk 1: Atlas Enterprise — vendor, category
Chunk 2: Pricing — base fee, usage fee
Chunk 3: Risks — lock-in, migration, data residency
有人询问Atlas Enterprise的定价与风险情况。产品名称可能仅出现在第一部分中,第二部分和第三部分则包含答案,但经过分割后已不再保留实体上下文。元数据增强、父子关系检索以及重新排序等功能虽能有所帮助,但信息碎片化仍是其根本缺陷。
无法进行关系遍历
现在试问哪些ETF持有与NVIDIA有合作关系的公司?其推理路径并非简单的关键词匹配:
NVIDIA
↓ HAS_STRATEGIC_PARTNER
Company
↓ HELD_BY
ETF
向量搜索能够找到提及 NVIDIA、其合作伙伴或 ETF 的文档,但它无法可靠地判定这些提及之间是否存在特定的多跳关系。图结构可以明确地遍历这些路径:
?nvidia corp:hasStrategicPartner ?company .
?etf etf:hasConstituent ?company .
相似的文本并不等同于实体之间的关联。
实体歧义
像“NVIDIA”这样的名称可能指代多个不同的事物:
NVIDIA → Company
NVIDIA International → Subsidiary
NVIDIA AI Enterprise → Product
尽管它们的嵌入向量可能彼此接近,但它们仍是不同类型的独立实体。本体论能够提供实体身份、类型及关联关系,而文本相似度则无法做到这一点。
没有精确的数值过滤功能
像“年度收入超过100万美元且流失概率低于5%的客户”这样的查询实际上就是普通的SQL语句:
SELECT customer_id
FROM customer_metrics
WHERE annual_revenue > 1000000
AND churn_probability < 0.05;
嵌入模型能够捕捉相似性,但无法可靠地执行大于、小于、介于之间、聚合或排序等操作。
一个问题,多种引擎
这个初始问题需要多种检索策略,而每种引擎适用于不同类型的推理:
Vector → meaning and unstructured text
BM25 → exact lexical matching
Graph → relationships and multi-hop traversal
SQL → filters, numbers and aggregation
该任务已从检索模式转变为联合查询执行模式。联合查询带来了三个更为棘手的问题:分解、路由和映射。
分解
系统必须将自然语言问题拆分成可执行的单元:
1. Resolve NVIDIA as a Company
2. Find its strategic partners
3. Find ETFs holding those companies
4. Filter AUM > $1B
5. Retrieve the latest research reports
6. Identify positive views
路由
每个单元都需要前往对其而言具有权威性的源地址:
relationships → Graph
AUM → SQL
research view → Vector Search
仅仅连接数据库是不够的。系统必须知道哪个数据源负责回答哪部分问题。
映射
这往往是难度最大的部分。用户输入AUM,而数据库中可能存储着这样的字段:
NET_ASSET_AMT
AUM_USD
FUND_NET_ASSET
哪个是受约束的概念?类似地,ETF在图中可能表现为fund:ETF,在SQL中为dim_fund.fund_id,而在向量索引中则为metadata.product_id。系统需要一种将业务术语与实际数据结构相连的桥梁,这就是模式对齐机制;没有它,大型语言模型可能会针对并不存在的列编写看似合理的SQL语句。
语义层
语义层介于人们的表达意图与数据存储方式之间。与其让大型语言模型面对数百个原始表和属性,不如直接呈现概念:
Company
Strategic Partner
ETF
Constituent
Assets Under Management
Research Report
并为每一个赋予意义:
Assets Under Management
├─ business definition
├─ currency / unit
├─ effective date
├─ authoritative source
└─ physical column
该层随后可以直接参与查询生命周期。这改变了本体的作用——它不再仅仅是静态文档,而是成为人工智能系统的可执行上下文。
可能的组织结构
对于同时使用关系数据库、知识图谱和向量搜索的系统,该层可以按如下方式构建:
semantic_layer/
├── ontology/
│ ├── tbox.ttl # classes and relationships
│ └── vocabulary.yaml # business terms and synonyms
├── schemas/
│ ├── rdb.yaml # tables, columns, types
│ ├── graph.yaml # entities, predicates, graph paths
│ └── vector.yaml # indexes and document metadata
├── semantics/
│ ├── metrics.yaml # governed metrics such as AUM
│ ├── mappings.yaml # concept → physical source mapping
│ └── relationships.yaml # cross-domain relationships
├── query/
│ ├── routing.yaml # Graph vs SQL vs Vector routing
│ └── examples.yaml # representative query plans
└── validation/
└── rules.yaml # allowed fields and business rules
在那种架构中,tbox.ttl用于声明诸如Company和ETF之类的类别,以及它们之间的HAS_STRATEGIC_PARTNER关联关系,而rdb.yaml则记录实际的表和列信息。mappings.yaml将“管理资产”这一概念与fund_metrics.net_asset_amt列关联起来。最后,routing.yaml让规划器决定某个步骤是发送到图数据库、SQL还是向量搜索引擎。
具体的文件取决于实现方式。关键在于明确写出含义、物理映射关系以及有效的执行路径,而不是让大型语言模型在每次查询时都重新发现这些信息。有四项任务能直接从中受益:
- 消歧义:名称相似的公司和产品属于不同的实体类别。
fund_metrics.net_asset_amt。这就是为什么语义工程的范围比构建本体更广。其目标是通过共享词汇表、本体、指标定义、关系、模式映射、业务规则、源元数据以及验证检查,让业务含义在运行时能够被使用。从这个角度看,语义层更像是企业数据的编译阶段,而非单纯的词汇表。
从层次结构到运行时
如今许多智能体设计都是这样的:
User → LLM → Tools
大语言模型接收工具描述并决定其名称。而语义架构则可能受到更多限制:
User
↓
Semantic Resolution
↓
Logical Query Plan
↓
Validated Execution
↓
Evidence
↓
LLM
该模型无需逐个猜测表格、指标、图表谓词及业务规则的内容,它在受限的语义环境中运行。其目标是在模型与企业数据之间建立更好的接口,而非仅仅打造更大的模型。
为何开放交换格式如此重要
语义定义本身往往容易出现碎片化。一家公司可能在数据平台、BI工具、产品目录、分析应用和AI代理中分别定义“净收入”这一概念,随着时间推移这些定义会逐渐出现差异。
开放语义交换标准(OSI)旨在解决这一问题。该计划于2026年6月加入Apache孵化器,现以Apache Ossie的名称继续发展中。它的目标是让系统能够以中性方式交换语义元数据。核心规范采用YAML格式编写,涵盖了数据集、字段、关系、指标以及AI相关内容。简化后的模型结构如下:
version: "0.2.0.dev0"
semantic_model:
- name: investment_products
datasets:
- name: etf
source: analytics.dim_etf
fields:
- name: aum
datatype: Decimal
ai_context:
synonyms: ["assets under management", "net assets"]
metrics:
- name: total_aum
expression:
dialects:
- dialect: ANSI_SQL
expression: SUM(etf.aum)
语法并不重要。关键在于aum拥有一个完整的定义,包括其物理来源、数据类型、度量逻辑以及面向人工智能的同义词,而且这个定义会以可移植的元数据形式存在,而无需在每个工具中重新编写。
┌→ BI
├→ Analytics
Semantic Model ───┼→ AI Agents
├→ Data Catalogs
└→ Data Applications
目录可以显示AUM的规范定义及其来源,AI代理可以读取相同的元数据,从而将“管理资产”这一表述准确映射到对应字段,而无需根据原始架构进行猜测。
除此之外,Ossie还能依据JSON Schema验证模型,支持多种表达方式,并定义了用于在不同供应商格式之间转换的模型。未来的计划还包括更丰富的指标、更好的组合性、目录集成、更精细的关系语义以及本体表示。
对于AI而言,本体方向尤其具有意义,因为仅靠指标和维度无法让代理了解这类事实信息:
Customer is an Organization
Company HAS_SUBSIDIARY Company
Company OWNS_PRODUCT Product
Document DESCRIBES Entity
如果语义模型与更丰富的本体论相融合,人工智能系统就能获得可移植的业务含义,而不仅仅是可移植的架构。
回到 NVIDIA 的问题
语义查询系统可以逐步处理初始问题,每一项决策都有明确的元数据作为依据。没有语义层的话,大型语言模型必须在每一步都自行推断含义、来源、架构及关联关系,而一个错误的假设就可能导致整个流程崩溃。
更宏观的变革
企业级人工智能已经经历了多个发展阶段:
LLM + Prompt
↓
LLM + RAG
↓
LLM + Tools
↓
LLM + Federated Data
↓
Semantic Layer + Federated Execution + LLM
检索功能用于判断哪些文档具有相关性。图结构则展示实体之间的关联方式。SQL用于确定哪些记录符合精确条件。语义层则处理首要问题:如何将这个问题转化为我们数据中的词汇表达?
系统会不断接入更多的数据库、图结构、文档、API以及工具,但仅仅连接数据是不够的,还必须建立数据的意义关联。企业级人工智能或许会减少向模型提供额外数据的方式,转而让模型更深入地理解这些数据的含义。