
关系数据库 Ontology LLM三位一体的落地设计本文的核心命题Ontology 不必是独立的图数据库或 OWL 文件它可以溶解进「关系数据库 LLM」这对现成基础设施形成三位一体的协同架构。全部内容基于 hostdb-query-agent PoC 的真实代码与实测结论召回 100%、SQL 正确率 100%不引用未实现的范式。一、核心命题为什么是「三者协同」而非「三者选一」1.1 三者各自能做什么、不能做什么自然语言查数据库这件事单靠任何一方都不够角色擅长致命短板关系数据库PG结构化存储、毫秒级查询、强一致、千万行聚合不懂自然语言表多了 LLM 找不到该查哪张LLM理解自然语言、生成 SQL、跨语言泛化幻觉编造不存在的列/表、不懂你的私有 schemaOntology定义概念/实体/属性/关系的语义骨架给 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类的具体对象主机node1host_ida1f9c2d7...Property实体字段主机os/ip_addresses进程cpu_percentRelation实体关联「主机_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. 向量标签RAGQdrant payload极快极高中3.2 为什么不选 A/B图库 / OWLpg_notes_ontology_features.md论证、本项目实测验证维度图库 (A)OWL (B)关系向量 (CD) ✅千万行历史聚合性能雪崩性能雪崩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_ddlcolumns_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如domainruntime直接排除web_*TC1.7 验证。这一层的价值没有它LLM 面对万表会迷路有了它LLM 只面对 2-5 张相关表的 DDLtoken 不爆、注意力聚焦。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 幻觉的根源是不知道列的精确含义。DDLhint 把语义边界讲死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.tsexporttypePattern|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 notenote 显式标注反模式如「聚合禁接 LIMIT」。全部在真实 hostdb 验证可执行16/16 通过。动态检索dynamic few-shot「有多少台主机」→ 命中aggregate_count→ 模型照计数模式生成不误接 LIMIT「node1 各磁盘」→ 命中jsonb_object_array→ 模型照 lateral join 生成这一层的价值静态 few-shot 会过度泛化3 条范例全是 latest-row导致 COUNT 误用。动态检索让聚合题拿聚合范例、JSONB 题拿展开范例各取所需。实测修复了 COUNT bugTC8.4DeepSeek 上 5/5 全对。4.5 三层协同的端到端数据流一个完整例子用户问「node1 当前的 CPU 使用率」三层如何接力用户问题 node1 当前的 CPU 使用率 │ ▼ [层① 概念导航] Ontology → 告诉 LLM 该查哪些表 Qdrant 检索 hostdb_schema_catalog → 召回 resources / resources_history向量命中 → 标签确认 domainruntime排除 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_ida1f9c2d7... 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_addressesJSONB当顶层列写h.ip_address不存在幻觉hosts.timestamp实际是last_timestamp高③ 模式误用COUNT 聚合查询误接ORDER BY ... LIMIT 1把取最新行的模式套到计数上中④ 越权写操作生成DELETE/DROP/UPDATE即便概率低后果不可逆致命5.2 四道防线每类幻觉由谁拦、怎么拦幻觉形态第一道生成前约束第二道生成后校验第三道执行前闸门第四道执行时内核① 编造表层①只把 catalog 白名单的表 DDL 注入 promptLLM 根本看不到别的表———② 编造列层②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.4COUNT bug 回归修复「COUNT 误接 LIMIT」DeepSeek 下 5/5 正确guard 闸门TC2.1–2.2121 个注入向量全绿含注释走私、多语句、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 hintsrc/catalog_builder.ts层① 灌入embedding 进 Qdranthostdb_schema_catalogsrc/retriever.ts层① 检索向量召回 标签过滤src/sql_examples.ts层③ 数据源16 条 golden SQL 10 patternsrc/example_builder.ts/example_retriever.ts层③ 灌入检索第二个 Qdrant 集合src/sql_generator.ts三层汇聚组装 DDL 范例进 prompt调 LLMsrc/column_validator.ts层② 反幻觉R1 校验alias-awaresrc/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.26.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%。