☰
关系数据库 + Ontology + LLM:三位一体的落地设计
2026/9/27 10:38:36 网站建设 项目流程

关系数据库 + Ontology + LLM:三位一体的落地设计

本文的核心命题:Ontology 不必是独立的图数据库或 OWL 文件,它可以"溶解"进「关系数据库 + LLM」这对现成基础设施,形成三位一体的协同架构。
全部内容基于 hostdb-query-agent PoC 的真实代码与实测结论(召回 100%、SQL 正确率 100%),不引用未实现的范式。


一、核心命题:为什么是「三者协同」而非「三者选一」

1.1 三者各自能做什么、不能做什么

自然语言查数据库这件事,单靠任何一方都不够:

角色擅长致命短板
关系数据库(PG)结构化存储、毫秒级查询、强一致、千万行聚合不懂自然语言;表多了 LLM 找不到该查哪张
LLM理解自然语言、生成 SQL、跨语言泛化幻觉(编造不存在的列/表)、不懂你的私有 schema
Ontology定义"概念/实体/属性/关系"的语义骨架,给 LLM 严格约束传统形态(图库/OWL)重、慢、工程门槛高

三角困局:

  • 只用「PG + LLM」→ LLM 在万表库里迷路、幻觉列名(hostdb 实测 qwen2.5:3b 把ip_addressesJSONB 当顶层列)。
  • 引入「图数据库 Ontology」→ 性能雪崩(千万行聚合)+ LLM 难生成 Cypher + 工程成本爆炸。
  • 只用「OWL Ontology」→ 推理机慢、格式冗长、LLM 难解析。

1.2 本项目的破局思路:让 Ontology「溶解」进现成基础设施

Ontology 不另起炉灶,而是拆成三层,分别长在关系数据库和 LLM 的 prompt 上:

  • 概念分类长在向量库(Qdrant)—— 做 LLM 的「宏观导航」
  • 实体属性长在关系库的 DDL + 注释 —— 做 LLM 的「微观字典」
  • 关系与查询模式长在动态 SQL 范例 —— 做 LLM 的「语法示范」

这样三者的关系不再是"选一个",而是各司其职、闭环协同:

┌─────────────────────────────────────────────┐ │ 用户的自然语言问题 │ └──────────────────────┬──────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ ① Ontology-概念层(Qdrant 向量+标签) │ ← 解决「该查哪些表」 │ 把问题对齐到 hostdb 的概念分类 │ (召回 100%) └──────────────────────┬──────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ ② Ontology-属性层(关系库 DDL+注释) │ ← 解决「这些表有哪些列/含义」 │ 注入候选表的精确 schema + 业务语义 │ (LLM 的字典) └──────────────────────┬──────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ ③ Ontology-关系层(动态 SQL 范例) │ ← 解决「表怎么连/用什么模式」 │ 检索匹配的查询模式范例(COUNT/JOIN/JSONB)│ (防幻觉 + 防模式误用) └──────────────────────┬──────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ LLM 生成 SQL │ ← 三层约束下生成 │ (DeepSeek-v4-pro 实测正确率 100%) │ └──────────────────────┬──────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 关系数据库执行(PG,只读账号 + 熔断) │ ← 落地到真实数据 └─────────────────────────────────────────────┘

关键洞察:Ontology 的价值是"语义约束",而"语义约束"在 LLM 时代最优载体是prompt 里的结构化文本(DDL + 注释 + 范例),不是独立的图数据库。这就是「三位一体」的核心。


二、Ontology 基本原理(背景)

2.1 定义与四要素

Ontology = 一个领域里「概念、实体、属性、关系」的形式化定义,给模糊世界一个机器可读的概念骨架。

要素含义hostdb 例子
Concept/Class抽象类别「主机」「进程」「网络连接」「未知主机」
Entity/Instance类的具体对象主机node1(host_id=a1f9c2d7...)
Property实体字段主机os/ip_addresses;进程cpu_percent
Relation实体关联「主机_contains_进程」(host_id软外键)

2.2 Ontology 解决的语义鸿沟

  • 用户说「node1 的 CPU」→ 机器怎么知道指向resources.cpu_usage_percent?
  • 用户说「未知主机」→ 怎么区分是unknown_hosts(未纳管)而非hosts(受控)?
  • 用户说「每台主机的进程数」→ 怎么知道要走hosts _contains_ processes关系?

没有 Ontology,这些全靠人工 hardcode;有了它,概念结构化、可检索、可被 LLM 理解。

2.3 传统形态 vs 本项目形态

传统 Ontology本项目形态
载体OWL/RDF 文件 或 Neo4j 图关系库 DDL + 向量库 + prompt
形态显式图/三元组隐式三层
严格度★★★★★★★★(够用)
性能大数据慢毫秒级
LLM 友好低(Cypher/OWL 难生成)极高(DDL 即 prompt)

传统 OWL 形态(<owl:Class>/<owl:ObjectProperty>)语义最严格,但重、慢、LLM 难消化——这是本项目不走该路的根本原因。


三、Ontology 实现模式分类与对比

3.1 四类模式总览

模式载体性能LLM 友好工程成本
A. 图数据库(Neo4j)节点+边大数据慢低(Cypher 难)极高
B. OWL/RDF三元组中低(冗长)高
C. 关系型 DDL+元数据PG Schema极快高(DDL 即提示词)低
D. 向量+标签(RAG)Qdrant payload极快极高中

3.2 为什么不选 A/B(图库 / OWL)

pg_notes_ontology_features.md论证、本项目实测验证:

维度图库 (A)OWL (B)关系+向量 (C+D) ✅
千万行历史聚合性能雪崩性能雪崩PG 毫秒级
LLM Text-to-SQL翻译成 Cypher,幻觉重OWL 冗长难解析DDL 进 prompt,召回 100%
工程成本ETL + 图运维推理机 + 专家DBA 写注释
多跳推理强强弱(hostdb 单跳够用)

结论:hostdb 是监控分析库(非社交网络),查询以host_id单跳 + 时间窗为主。上图库是把简单问题复杂化,DDL 注入远比 Cypher 生成可靠。

3.3 选定:C + D 混合(关系库提供属性,向量库提供路由)

本项目把 C 和 D 组合成三层隐式 Ontology,下一章详述。


四、三位一体的落地设计(核心)

4.1 三层 Ontology 的分工

Ontology 层对应要素载体代码/集合解决的问题
① 概念分类层Concept/ClassQdrant 向量+标签schema_catalog.ts+ 集合hostdb_schema_catalog该查哪些表
② 实体属性层Entity/Property关系库 DDL+注释catalog 的columns_ddl+columns_hint表有哪些列、什么含义
③ 关系/模式层Relation+查询模式动态 SQL 范例sql_examples.ts+ 集合hostdb_sql_examples表怎么连、用什么 SQL 套路

4.2 层 ① 概念分类层 —— Ontology 给 LLM 做「宏观导航」

关系数据库的角色:提供 18 张表的真实结构。
Ontology 的角色:给每张表打两个维度的概念标签。
LLM 的角色:通过向量召回 + 标签过滤,把自然语言对齐到正确的表。

// src/schema_catalog.ts(实测代码)exportinterfaceCatalogEntry{table:string;domain:"inventory"|"runtime"|"security"|"app";// ← 业务域分类entity_type:"entity"|"history"|"link"|"meta";// ← 时态分类description:string;columns_ddl:string;columns_hint:string;}
  • domain(业务域):inventory(受控主机)/runtime(进程连接资源告警)/security(未知实体)/app(应用自身)
  • entity_type(时态):entity(当前态)/history(时序)/link(关联)/meta(元数据)

双重定位(向量 + 标签):

  • 向量召回(bge-m3 + Qdrant cosine):自然语言 → Top-K 相似表,实测命中率100%(AC1)。
  • 标签过滤(Qdrant filter):如domain=runtime直接排除web_*(TC1.7 验证)。

这一层的价值:没有它,LLM 面对万表会迷路;有了它,LLM 只面对 2-5 张相关表的 DDL,token 不爆、注意力聚焦。hostdb 仅 18 表看似不需要,但这是 pg_notes「万表两级路由」的最小可验证切片。

4.3 层 ② 实体属性层 —— 关系库 DDL 即 Ontology 的「微观字典」

关系数据库的角色:DDL 本身就是最权威的实体-属性定义。
Ontology 的角色:用columns_hint(列注释)补充业务语义,把 OWL 要写 10 倍长的话用一行中文讲清。
LLM 的角色:读 DDL + hint,理解每个列的精确含义与边界。

例如resources表:

{table:"resources",columns_ddl:"CREATETABLEresources(id bigint,host_id varchar,timestamp timestamptz,cpu_usage_percent double,mem_used_percent double,disks jsonb)",columns_hint:"cpu_usage_percent:CPU使用率0-100;mem_used_percent:内存使用率0-100;disks:JSONB数组,含 mount_point/used_percent,用 jsonb_array_elements 展开.",}

columns_hint是关键 —— 它直接进 prompt 喂给 LLM。这是符号主义本体论在 LLM 时代的演进:不靠推理机,靠 prompt 注入实现"严格约束"。

这一层的价值:LLM 幻觉的根源是"不知道列的精确含义"。DDL+hint 把语义边界讲死,DeepSeek-v4-pro 在此约束下达成 SQL 正确率 100%(不再把disks内部键当顶层列)。

4.4 层 ③ 关系/模式层 —— 动态 SQL 范例做「语法示范 + 反幻觉」

这是本项目超出 pg_notes 原设计、根据实测增补的层(Phase 4b / T8)。

问题:光有 DDL 不够 —— 模型不知道"表怎么连"、“什么场景用什么 SQL 套路”。qwen2.5:3b 实测因此把 COUNT 题误接 LIMIT 1、漏 JSONB lateral join。

解法:把"关系 + 查询模式"作为第三层 Ontology,灌入第二个 Qdrant 集合,按问题动态检索。

10 种查询模式(src/sql_examples.ts):

exporttypePattern=|"aggregate_count"// 聚合计数(对冲 LIMIT 误用)|"jsonb_string_array"// JSONB 字符串数组展开(IP)|"jsonb_object_array"// JSONB 对象数组展开(disks)|"latest_row"|"time_window"|"join"|"group_by"|"top_n"|"history_trend"|"unknown_entity";

16 条范例,每条含question + sql + pattern + note,note 显式标注反模式(如「聚合禁接 LIMIT」)。全部在真实 hostdb 验证可执行(16/16 通过)。

动态检索(dynamic few-shot):

  • 「有多少台主机」→ 命中aggregate_count→ 模型照计数模式生成(不误接 LIMIT)
  • 「node1 各磁盘」→ 命中jsonb_object_array→ 模型照 lateral join 生成

这一层的价值:静态 few-shot 会过度泛化(3 条范例全是 latest-row,导致 COUNT 误用)。动态检索让"聚合题拿聚合范例、JSONB 题拿展开范例",各取所需。实测修复了 COUNT bug(TC8.4),DeepSeek 上 5/5 全对。

4.5 三层协同的端到端数据流(一个完整例子)

用户问「node1 当前的 CPU 使用率」,三层如何接力:

用户问题 "node1 当前的 CPU 使用率" │ ▼ [层① 概念导航] Ontology → 告诉 LLM 该查哪些表 Qdrant 检索 hostdb_schema_catalog → 召回 resources / resources_history(向量命中) → 标签确认 domain=runtime(排除 web_*) │ ▼ [层② 属性字典] 关系库 DDL → 告诉 LLM 这些表有什么列 注入 resources 的 columns_ddl + columns_hint → LLM 看到「cpu_usage_percent: CPU使用率0-100」「disks 是 JSONB 数组」 │ ▼ [层③ 模式示范] 动态范例 → 告诉 LLM 用什么 SQL 套路 Qdrant 检索 hostdb_sql_examples(独立集合) → 命中 latest_row 范例(ORDER BY timestamp DESC LIMIT 1) → 命中 aggregate_count 的 note(聚合禁 LIMIT,防误用) │ ▼ LLM 生成 SQL(三层约束下,DeepSeek-v4-pro 100% 正确) SELECT cpu_usage_percent FROM resources WHERE host_id='a1f9c2d7...' ORDER BY timestamp DESC LIMIT 1; │ ▼ 关系库执行(PG 只读账号 ontology_ro + 熔断 + guard 闸门) → 返回结果 + 执行轨迹

五、反幻觉体系:三位一体的纵深防御(关键设计)

这一章单独成篇,因为反幻觉是整个三位一体架构存在的根本理由。前面的三层设计(概念/属性/关系)最终都服务于一个目标:让 LLM 在生成 SQL 时不犯错,即便犯了也被拦下。
设计哲学是纵深防御(defense in depth):不指望任何单一环节 100% 可靠,而是让幻觉在「生成前约束 → 生成后校验 → 执行前闸门 → 执行时内核」四个关卡逐层被拦。任何一层失效,数据仍安全。

5.1 LLM 幻觉的四种形态(实测归纳)

在 hostdb PoC 的实测中,qwen2.5:3b 表现出四类典型幻觉,每一类都需要专门的拦截手段:

幻觉形态真实案例(实测)危险等级
① 编造表(弱模型罕见,但万表场景必然)LLM 引用了 schema 里不存在的表中
② 编造列把ip_addresses(JSONB)当顶层列;写h.ip_address(不存在);幻觉hosts.timestamp(实际是last_timestamp)高
③ 模式误用COUNT 聚合查询误接ORDER BY ... LIMIT 1(把取最新行的模式套到计数上)中
④ 越权写操作生成DELETE/DROP/UPDATE(即便概率低,后果不可逆)致命

5.2 四道防线:每类幻觉由谁拦、怎么拦

幻觉形态第一道(生成前约束)第二道(生成后校验)第三道(执行前闸门)第四道(执行时内核)
① 编造表层①:只把 catalog 白名单的表 DDL 注入 prompt,LLM 根本看不到别的表———
② 编造列层②:DDL 列出真实列 + hint 讲清 JSONB 边界R1 列校验(column_validator.ts):按information_schema验证 LLM 引用的表.列/别名.列真实存在,不存在即拒绝并触发重试——
③ 模式误用层③:动态范例注入正确模式 +note标注反模式(如「聚合禁接 LIMIT」)B 错误回筒:执行失败时把 PG 错误喂回模型自纠(最多 3 次)——
④ 越权写——guard 闸门:正则黑名单(drop/delete/insert/…)+ 必须 SELECT 起头 + 拒绝分号多语句ontology_ro只读账号:内核物理拒绝任何写操作(双保险)

5.3 为什么需要纵深防御(不能只靠一层)

每一道防线都有失效的可能,只有多层叠加才能保证「总有一层兜得住」:

  • 只靠 LLM 自觉(生成前约束)?不够。qwen2.5:3b 在三层 prompt 约束下仍会幻觉h.ip_address(层② DDL 明明写了ip_addresses)。
  • 只靠生成后校验(R1)?不够。校验器只验「列存在」,验不出「列语义对」(如把disks.used_percent当mem_used_percent)。这是诚实的残留边界。
  • 只靠 guard 闸门?不够。guard 是正则,理论上可能被绕过(注释走私、编码 trick)。
  • 只靠内核只读?够安全但不够友好——靠内核拒意味着 SQL 已经跑到数据库,浪费一次往返,且错误信息可能泄露 schema。

所以四层叠加:层①②③在「生成前/后」把绝大多数幻觉消灭在 LLM 层面(DeepSeek 下 100% 不触发后两层);guard 作为执行前最后过滤;ontology_ro作为不可绕过的物理底线。

5.4 实测:四道防线各自被验证过

防线验证用例实测结果
层① 白名单万表场景模拟(catalog 仅注入相关表)bge-m3 召回 100%,不相关表不进 prompt
层② R1 列校验TC3.2 /column_validator.ts的 alias-aware 测试拦下h.ip_address、hosts.timestamp等幻觉列,触发重试
层③ 动态范例TC8.4(COUNT bug 回归)修复「COUNT 误接 LIMIT」,DeepSeek 下 5/5 正确
guard 闸门TC2.1–2.21(21 个注入向量)全绿,含注释走私、多语句、DROP/DELETE/INSERT 等
内核只读TC3.2 双保险绕过 guard 直接喂 INSERT,被ontology_ro内核拒绝,行数不变

5.5 诚实的残留边界

反幻觉体系覆盖了语法层和结构层的幻觉,但有一类目前无法自动拦截:

  • 语义层幻觉:SQL 语法对、列也存在、也执行成功,但取错了语义。例如 qwen3b 把内存题的mem_used_percent取成了disks[0].used_percent(磁盘使用率)—— 列校验验不出,因为它只查"列存不存在",不查"列对不对"。

要拦这类需要结果层合理性校验(如检查 SELECT 的列名与问题关键词的相关性),属进阶工作。好消息:DeepSeek-v4-pro 在三层约束下不再犯这类错(5/5 语义全对),说明强模型 + 三层约束已足够,结果层校验是给弱模型的额外补丁。


六、实现索引

6.1 关键文件

文件三位一体中的角色关键内容
src/schema_catalog.ts层①+② 数据源18 表的 domain/entity_type 标签 + DDL + hint
src/catalog_builder.ts层① 灌入embedding 进 Qdranthostdb_schema_catalog
src/retriever.ts层① 检索向量召回 + 标签过滤
src/sql_examples.ts层③ 数据源16 条 golden SQL + 10 pattern
src/example_builder.ts/example_retriever.ts层③ 灌入+检索第二个 Qdrant 集合
src/sql_generator.ts三层汇聚组装 DDL + 范例进 prompt,调 LLM
src/column_validator.ts层② 反幻觉R1 校验(alias-aware)
src/executor.ts关系库执行只读 + 熔断
src/pipeline.ts编排串联三层 + guard + CRAG 降级

6.2 实测验证(三位一体有效性的证据)

验证项结果证据
层① 召回准不准bge-m3 命中率100%tests/output/recall_report.json
层② DDL 注入够不够DeepSeek SQL 正确率100%(5/5,含语义)tests/output/sql_eval_report.json
层③ 模式覆盖10 pattern 检索覆盖100%TC8.5
层③ COUNT bug 修复动态范例让模型不再误接 LIMITTC8.4
层② 列校验alias-aware 校验器拦幻觉列column_validator.tsparseAliases
关系库只读写操作被内核拒(双保险)TC3.2

6.3 模型对比(证明架构对强模型是充分支撑)

模型可执行率语义正确说明
qwen2.5:3b(本地)80%~60%JSONB 幻觉、模式误用
deepseek-v4-pro(云端)100%100%三层约束下完全正确

含义:pipeline(三层 Ontology + guard + CRAG)对强模型已是生产级支撑。qwen3b 的失败是模型能力问题,非架构问题——换强模型后,所有脚手架正常工作且不再需"救火"。


七、总结

7.1 核心论点

Ontology 不必是独立的图数据库或 OWL 文件。把它拆成三层(概念分类 / 实体属性 / 关系模式),分别长在向量库、关系库 DDL、动态范例上,就能与 LLM 形成三位一体的闭环——既享受 Ontology 的"零幻觉严格约束"红利,又复用关系库与向量库的成熟性能,无需引入新的图数据库栈。

7.2 三位的职责一句话

  • 关系数据库:数据的家 + DDL 即最权威的实体属性定义。
  • Ontology(溶解态):给 LLM 提供"该查哪些表/列什么含义/怎么连"的三层语义约束。
  • LLM:在三层约束下把自然语言翻译成精确 SQL。

7.3 边界(诚实)

本模式不是万能:

  • 复杂多跳推理(≥3 跳):需建视图固化为宽表(Dev Plan R3 决策点)。
  • 严格逻辑推断(子类继承/逆关系):需上 OWL。
  • 万表规模:需两级路由(Qdrant 类目 + 视图),属后续。

但 hostdb(监控分析库、单跳关系、18 表)完全在本模式的甜区,实测召回 100% + SQL 正确率 100%。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询