知识图谱把实体、关系和主张组织成相互连接的模型。当 AI 应用需要遍历显式关系、保留证据谱系、执行领域约束或聚合跨文档事实时,它才具备独特价值。知识图谱不等于图数据库,GraphRAG也不是关键词、向量或混合检索的通用替代品。
本文把图谱定义为受治理的派生视图:每条主张回指原始来源片段与版本,每条检索路径继承授权边界,每种 GraphRAG 模式都必须在目标工作负载上击败更简单的基线。
目录
- 核心要点
- 知识图谱、图数据库与本体
- 判断是否需要知识图谱
- 生产架构
- 以主张和来源为建模核心
- 约束关系抽取与实体消歧
- 选择 RDF、属性图或关系存储
- 按查询类型路由 GraphRAG
- 安全执行图查询
- 统一授权与证据边界
- 分层评估知识图谱
- 交付最小可行知识图谱
- 运行增量更新、删除与回滚
- 常见失败模式
- 常见问题
- 参考资料
核心要点
- 知识图谱是一种知识表示;图数据库只是一种实现选择。
- 从反复出现的业务问题和证据路径出发,不要从数据库产品或“大而全”本体出发。
- 把抽取结果存为带来源、版本和状态的主张,不要当作永恒事实。
- 关系抽取和实体消歧都是可测量、可回滚的数据流水线。
- 只有图上下文优于关键词、向量或混合检索基线时才采用 GraphRAG。
- 禁止执行不受约束的 LLM 生成 Cypher,也不能信任查询携带的授权字段。
- 图路径说明检索用了什么证据,不揭示模型隐藏推理,也不证明结论正确。
- 抽取、消歧、图质量、检索、生成、安全和生命周期必须分层评测。
知识图谱、图数据库与本体
知识图谱是实体与主张的连接式表示,图数据库则是存储和查询图结构的软件。分清二者,才能避免让某个数据库产品反向决定知识模型。
| 概念 | 定义什么 | 不保证什么 |
|---|---|---|
| 知识图谱 | 实体、主张、关系、标识符与语义 | 真实性、完整性或特定数据库 |
| 图数据库 | 存储、索引、事务与遍历查询 | 本体质量或来源可靠性 |
| RDF 图 | 由 IRI 标识的主语-谓语-宾语三元组集合 | 未配置蕴涵机制时的丰富推理 |
| 属性图 | 带标签和属性的节点与关系 | 跨系统共享语义 |
| 本体 | 词汇、类、属性以及部分约束或规则 | 实例数据正确 |
| GraphRAG | 使用图派生上下文的检索架构族 | 每类查询都更优 |
稳定的 W3C RDF 1.1 Concepts Recommendation 将 RDF 图定义为三元组集合,将 RDF Dataset 定义为一个默认图和零个或多个命名图。RDF 1.2 Concepts目前是 Candidate Recommendation Snapshot,并增加了 Triple Term 等能力。除非所有生产者和消费者都明确支持所用的 RDF 1.2 特性,否则仍应以 RDF 1.1 作为互操作基线。
属性图便于表达面向应用的关系遍历;RDF 强调全局标识、图交换和显式语义;关系数据库仍擅长事务、约束和有界 JOIN。生产系统可以组合多种模型,但实体身份、来源谱系和删除语义必须一致。
判断是否需要知识图谱
只有当具名关系、共享身份或证据路径本身就是产品需求时,知识图谱才值得引入。语料规模大或系统使用了 LLM,都不能单独证明需要图谱。
| 用户任务 | 起始方案 | 何时增加图谱 |
|---|---|---|
| 查询实时账户余额或订单状态 | 权威 API 或关系查询 | 答案还需要关联方或依赖路径 |
| 查找标识符、原文或政策条款 | 关键词检索 | 别名和关联记录能显著补充召回 |
| 在文档中查找改写表达 | 向量或混合检索 | 显式实体关系能补齐缺失证据 |
| 追踪所有权、血缘、影响范围或欺诈网络 | 先基准测试关系 JOIN 与图查询 | 可变深度路径是反复出现的核心负载 |
| 归纳整个语料库的主题 | 层级摘要或 Map-Reduce 基线 | 图社区能以可接受成本提高有证据的覆盖率 |
在设计实体前,先为每类重要问题写一份查询契约:
- 答案支持用户做出什么决策。
- 哪些记录是权威来源,允许多长刷新延迟。
- 需要哪些实体、关系和证据路径。
- 遍历深度、扇出、时延和成本上限是多少。
- 适用什么授权范围,必须返回哪些引用。
- 非图基线是什么,验收指标是什么。
这会扭转一种常见失败模式:不要先把所有名词都导入图谱,再寻找用途;只构建已被真实问题证明必要的身份层和关系层。
生产架构
生产级知识图谱应拆分来源记录、抽取、消歧、图发布、检索和答案生成。分层后,团队才能重跑某一环节,而不是在无感知状态下改变全部下游答案。
离线路径负责生成派生制品,在线路径只能检索调用方有权访问的制品。每个生成主张都应回答四个问题:
- 哪些原始来源片段支持它?
- 哪个抽取器和消歧器版本生成了图制品?
- 哪次授权决策允许召回?
- 当时启用了哪个图快照和索引快照?
任何答案缺失,代表系统存在可观测性缺口,而不是具备了解释能力。
以主张和来源为建模核心
更稳健的图模型把抽取边视为有证据支持的主张,而不是无条件事实。当来源冲突、随时间变化或只在特定范围内成立时,这个边界至关重要。
{
"claim_id": "clm_01J...",
"subject_id": "org:acme",
"predicate": "HEADQUARTERED_IN",
"object_id": "place:singapore",
"source_document_id": "doc_842",
"source_revision": "sha256:8f1...",
"source_span": {"start": 418, "end": 476},
"extractor_version": "relations-2026-08-01",
"valid_from": "2026-04-01",
"valid_to": null,
"tenant_id": "tenant_17",
"policy_scopes": ["research"],
"state": "candidate"
}
原始文档及其版本才是引用边界。社区摘要、Embedding、消歧后的实体和图边都是派生辅助信息,必须回指原始边界,不能互相循环引用。对需要 RDF 互操作的系统,PROV-O提供跨系统交换来源信息的词汇,SHACL则校验 RDF Data Graph 是否满足结构约束。两项标准都不能证明现实主张为真,来源审核与领域控制仍需独立负责。
以下无第三方依赖的校验器展示了最小摄入契约:
package main
import (
"fmt"
"strings"
)
var allowedRelations = map[string]struct{}{
"HEADQUARTERED_IN": {},
"OWNS": {},
"DEPENDS_ON": {},
}
type Claim struct {
SubjectID string
Predicate string
ObjectID string
SourceDocumentID string
SourceRevision string
SpanStart int
SpanEnd int
ExtractorVersion string
TenantID string
}
func (c Claim) Validate(sourceLength int) error {
if _, ok := allowedRelations[c.Predicate]; !ok {
return fmt.Errorf("relationship %q is not in the versioned vocabulary", c.Predicate)
}
if c.SpanStart < 0 || c.SpanStart >= c.SpanEnd || c.SpanEnd > sourceLength {
return fmt.Errorf("source span [%d,%d) is outside revision length %d",
c.SpanStart, c.SpanEnd, sourceLength)
}
required := []string{
c.SubjectID,
c.ObjectID,
c.SourceDocumentID,
c.SourceRevision,
c.ExtractorVersion,
c.TenantID,
}
for _, value := range required {
if strings.TrimSpace(value) == "" {
return fmt.Errorf("claim lineage and tenant scope are required")
}
}
return nil
}
func main() {
claim := Claim{
SubjectID: "org:acme",
Predicate: "HEADQUARTERED_IN",
ObjectID: "place:singapore",
SourceDocumentID: "doc_842",
SourceRevision: "sha256:8f1",
SpanStart: 10,
SpanEnd: 42,
ExtractorVersion: "relations-v3",
TenantID: "tenant_17",
}
if err := claim.Validate(100); err != nil {
panic(err)
}
fmt.Println("valid")
}
// 输出:valid
生产字段还应包含置信度、审核状态、时间范围、摄入时间、策略标签和被取代关系。置信度只能用于排序,不能成为发布无来源主张的许可。
约束关系抽取与实体消歧
关系抽取和实体消歧都是含噪推断任务,需要显式 Schema、标注测试集、审核队列和回滚能力。通用预训练语言模型加一组临时编造的标签,并不会自动变成关系分类器。
采用受约束的抽取契约:
- 定义版本化关系词表及合法的主客体类型。
- 每个候选实体和关系必须保留来源片段。
- 拒绝未知谓词,禁止运行时随意创建新边类型。
- 使用稳定标识符和可审计特征解析实体身份。
- 将低置信度或高影响合并送入人工审核。
- 分离候选、已接受和已拒绝主张。
实体消歧必须拥有独立发布门禁。有害合并会把两个不同实体污染到大量路径;有害拆分会制造重复身份并隐藏证据。除 pairwise precision/recall 外,还应按实体类型和语言统计有害合并率与有害拆分率。
不要覆盖冲突。保留主张级来源与时间范围,让检索能够显式暴露分歧,或选择某个时间点有效的主张。
选择 RDF、属性图或关系存储
存储模型应由工作负载与治理要求决定,而不是按厂商或数据规模套用一句口号。选型前要用代表性数据、遍历、更新和授权过滤执行基准测试。
| 决策因素 | RDF 存储 | 属性图 | 关系或混合存储 |
|---|---|---|---|
| 共享标识和标准化交换 | 适合 | 需要自定义约定 | 需要映射 |
| 本体和显式蕴涵 | 结合指定语义机制时适合 | 通常由应用管理 | 通常由应用管理 |
| 关系遍历型应用查询 | 可行,需实测 SPARQL 负载 | 通常表达自然 | 适合有界关系 |
| 事务记录和严格约束 | 取决于具体产品 | 取决于具体产品 | 通常是首选 |
| 复用现有运维平台 | 可能增加新技术栈 | 可能增加新技术栈 | 增量成本通常较低 |
| 细粒度授权 | 必须设计并验证 | 必须设计并验证 | 方案成熟度取决于模型 |
| 可移植性 | RDF 标准利于交换 | 查询方言与特性不同 | SQL 广泛,但扩展不同 |
数据库选型需要评估查询语言兼容性、事务与一致性、索引行为、遍历扇出、批量与增量摄入、备份恢复、可观测性、策略执行、托管或自建约束,以及实测总体成本。只列产品名无法完成这些判断。
按查询类型路由 GraphRAG
GraphRAG 是一组图增强检索架构,不同查询模式服务于不同任务。系统应按已评测的问题类型路由,而不是把所有请求都送入成本最高的路径。
Microsoft 的 GraphRAG 查询文档区分:
- Basic Search:向量 RAG 基线路径。
- Local Search:组合文本块、图实体、关系与相关报告。
- Global Search:围绕社区报告执行 map-reduce,回答全语料问题。
- DRIFT Search:利用社区信息扩展局部搜索。
原始 GraphRAG 论文在特定语料和评价标准下评估全局意义归纳,并未证明图检索对所有任务占优。独立的 WildGraphBench也表明收益依赖问题类型:图方法可能改善多事实聚合,BM25 对直接查找仍有竞争力,图聚合还可能丢失细节。
| 查询类型 | 起始基线 | 何时升级为图检索 |
|---|---|---|
| 精确标识符或原文事实 | 关键词/BM25 | 实体别名或关联记录提高召回 |
| 局部语义问题 | 向量或混合检索 | 邻接关系增加有来源证据 |
| 关联多事实问题 | 混合检索基线 | 有界遍历提高证据覆盖 |
| 全语料主题 | 聚合基线 | 社区报告在可接受成本下提高完整性 |
| 事务查询 | 权威数据库/API | 通常不经过 GraphRAG |
路由器应优先使用确定性特征,例如操作类型、识别出的实体、预期聚合范围和授权策略。LLM 可以参与意图分类,但输出仍需通过 Schema 校验并提供安全回退。
安全执行图查询
安全图检索应把已校验意图映射到预审查询模板,绝不能把模型生成的任意查询文本直接发送到数据库。
package main
import (
"fmt"
"strings"
)
type Intent string
const (
EntityProfile Intent = "entity_profile"
DependencyNeighbors Intent = "dependency_neighbors"
)
type QueryPlan struct {
Cypher string
Parameters map[string]any
}
var queryTemplates = map[Intent]string{
EntityProfile: `
MATCH (e:Entity {tenant_id: $tenant_id, id: $entity_id})
WHERE any(scope IN e.policy_scopes WHERE scope IN $allowed_scopes)
RETURN e.id AS id, e.name AS name, e.type AS type
LIMIT 1`,
DependencyNeighbors: `
MATCH (e:Entity {tenant_id: $tenant_id, id: $entity_id})
-[r:DEPENDS_ON {tenant_id: $tenant_id}]->(n:Entity {tenant_id: $tenant_id})
WHERE any(scope IN e.policy_scopes WHERE scope IN $allowed_scopes)
AND any(scope IN r.policy_scopes WHERE scope IN $allowed_scopes)
AND any(scope IN n.policy_scopes WHERE scope IN $allowed_scopes)
RETURN n.id AS id, n.name AS name, r.claim_id AS claim_id
ORDER BY n.id
LIMIT $row_limit`,
}
func buildPlan(
intent Intent,
entityID string,
tenantID string,
allowedScopes []string,
requestedLimit int,
) (QueryPlan, error) {
query, ok := queryTemplates[intent]
if !ok {
return QueryPlan{}, fmt.Errorf("unsupported query intent %q", intent)
}
if strings.TrimSpace(entityID) == "" || len(entityID) > 128 {
return QueryPlan{}, fmt.Errorf("invalid entity identifier")
}
if strings.TrimSpace(tenantID) == "" || len(allowedScopes) == 0 {
return QueryPlan{}, fmt.Errorf("authoritative tenant and policy scope are required")
}
rowLimit := requestedLimit
if rowLimit < 1 {
rowLimit = 1
}
if rowLimit > 100 {
rowLimit = 100
}
return QueryPlan{
Cypher: query,
Parameters: map[string]any{
"entity_id": entityID,
"tenant_id": tenantID,
"allowed_scopes": append([]string(nil), allowedScopes...),
"row_limit": rowLimit,
},
}, nil
}
func main() {
plan, err := buildPlan(
DependencyNeighbors,
"service:checkout",
"tenant_17",
[]string{"operations"},
500,
)
if err != nil {
panic(err)
}
fmt.Println(plan.Parameters["row_limit"])
}
// 输出:100
Neo4j Cypher 注入防护文档解释了为什么字面值必须参数化:查询文本与参数会分离编译。但这只是必要控制,不是完整安全方案。
生产系统必须同时执行:
- 从可信身份和策略服务取得租户、对象与目的范围。
- 使用只读、最小权限数据库角色。
- Allowlist 查询模板、标签、关系类型和可排序属性。
- 限制遍历深度、扇出、返回行数、时间和内存。
- 对字面值进行参数化。
- 数据库错误进入模型或客户端前必须脱敏。
- 记录模板 ID、策略决策、快照、脱敏参数、时延和结果行数。
参数化可以阻断字面值注入,不能完成授权。动态标签、关系类型、属性名与查询子句也不能因为放进参数就自动安全。
统一授权与证据边界
授权必须让原始文本、向量块、图主张和生成摘要得到同一个访问结论,否则图索引会成为绕过文档权限的侧信道。
授权应在检索前和检索中执行:
- 从权威服务解析调用方身份、租户、用途和对象权限。
- 按这些权限过滤候选索引。
- 在图查询模板内强制租户和策略范围。
- 组装 Prompt 前重新校验每个来源片段。
- 拒绝指向授权证据集之外的生成引用。
- 记录策略决策与图/索引快照以供审计。
禁止让模型生成 tenant_id、allowed_scopes 或访问控制谓词。查询文本不是身份来源。
社区报告等图摘要必须继承源文档的权限。一个混合了允许和禁止文档的摘要,不能通过隐藏引用变成安全内容;它必须针对当前授权证据重新构建,否则就应排除。
分层评估知识图谱
单一答案分数无法定位回归来自抽取、消歧、检索、生成还是策略,因此需要分层门禁,并在每次发布评测中保留更简单的检索基线。
| 层级 | 指标示例 | 严重失败 |
|---|---|---|
| 抽取 | 实体/关系 precision、recall、F1,来源片段有效率,词表违规率 | 无来源或不可追踪主张 |
| 消歧 | Pairwise precision/recall/F1,有害合并率,有害拆分率 | 跨实体污染 |
| 图质量 | 来源覆盖率、过期边率、孤立率、重复实体率 | 已接受边没有有效证据 |
| 检索 | 证据 Recall@K、路径/证据覆盖、引用覆盖 | 漏掉授权证据或返回越权证据 |
| 生成 | 正确性、主张支持、完整性、拒答、冲突处理 | 关键主张无证据支持 |
| 安全 | 越权内容召回率、跨租户泄漏、模板绕过攻击 | 任何未授权披露 |
| 运维 | p50/p95 时延、索引成本、刷新延迟、更新放大 | 违反 SLO 或删除期限 |
以下无依赖示例分别计算证据召回率与引用精度,避免把两者混为一个指标:
package main
import "fmt"
type RetrievalMetrics struct {
EvidenceRecall float64
CitationPrecision float64
}
func toSet(values []string) map[string]struct{} {
set := make(map[string]struct{}, len(values))
for _, value := range values {
set[value] = struct{}{}
}
return set
}
func overlapCount(left, right map[string]struct{}) int {
count := 0
for value := range left {
if _, ok := right[value]; ok {
count++
}
}
return count
}
func retrievalMetrics(required, retrieved, cited []string) RetrievalMetrics {
requiredSet := toSet(required)
retrievedSet := toSet(retrieved)
citedSet := toSet(cited)
requiredCount := len(requiredSet)
if requiredCount == 0 {
requiredCount = 1
}
citedCount := len(citedSet)
if citedCount == 0 {
citedCount = 1
}
return RetrievalMetrics{
EvidenceRecall: float64(overlapCount(requiredSet, retrievedSet)) /
float64(requiredCount),
CitationPrecision: float64(overlapCount(citedSet, retrievedSet)) /
float64(citedCount),
}
}
func main() {
metrics := retrievalMetrics(
[]string{"span:A", "span:B"},
[]string{"span:A", "span:C"},
[]string{"span:A", "span:X"},
)
fmt.Printf("evidence_recall=%.3f citation_precision=%.3f\n",
metrics.EvidenceRecall, metrics.CitationPrecision)
}
// 输出:evidence_recall=0.500 citation_precision=0.500
结果应按问题类型、语言、租户、实体类型、图深度和来源新鲜度切片,并把质量、时延和成本一起报告。全语料综合有所提升,并不代表直接事实查询也应该走更慢、更不精确的路径。
生产级 RAG 评估指南提供更完整的发布门禁设计;GraphRAG 高级工程指南深入讲解抽取契约和基线实验;语义搜索指南覆盖混合检索和授权过滤。
交付最小可行知识图谱
最小可上线的知识图谱只需端到端支持一类边界清楚的查询。团队应先证明检索收益和生命周期控制,再扩展本体或导入整个企业目录。
| 交付步骤 | 必备制品 | 发布证据 |
|---|---|---|
| 1. 固定负载 | 版本化问题、预期证据和无答案样本 | 评审者确认每个问题对应真实用户决策 |
| 2. 定义身份 | 稳定实体 ID、别名、合并/拆分策略和关系词表 | 标注消歧集通过约定的有害合并门禁 |
| 3. 发布主张 | 来源版本、片段、抽取器版本、策略范围和主张状态 | 每条已接受主张都可追溯到当前授权证据 |
| 4. 保留基线 | 同一问题上的关键词、向量、关系查询或 API 结果 | 图路径赢得目标切片,且不损害直接点查 |
| 5. 影子验证 | 版本化图/索引快照和分层遥测 | 质量、时延、成本与越权测试同时通过 |
| 6. 开启单路由 | 功能开关、回滚快照、删除演练和责任人 | 上线前证明可以回滚且删除能完整传播 |
后续扩展应由失败或新增的高价值问题切片驱动。没有查询、责任人、来源契约和删除路径的新实体类型,只会扩大维护面,不能证明用户价值。
运行增量更新、删除与回滚
生产图谱是版本化派生视图,因此更新和删除必须传播到所有衍生物。只更新来源文档,会让旧主张、Embedding、社区报告和缓存继续生效。
维护完整依赖清单:
来源版本
-> 文本分段
-> 候选主张
-> 消歧实体
-> 已接受图快照
-> 关键词/向量索引
-> 社区划分
-> 生成摘要
-> 检索与答案缓存
每次来源变更应执行:
- 创建不可变的新来源版本。
- 重新抽取受影响片段并比较主张差异。
- 只对受影响候选重新执行实体消歧。
- 原子发布新的图与索引快照。
- 失效依赖已变主张的摘要和缓存。
- 保留上一快照用于回滚。
删除时应立即 Tombstone 来源并阻止召回,删除或撤回依赖主张,重建受影响摘要,清除缓存,并在约定期限内验证传播完成。删除覆盖率和传播延迟都应进入发布指标。
常见失败模式
危害最大的故障通常跨越多个层级,因此单一答案质量指标看不到它们。
| 失败 | 根因 | 生产控制 |
|---|---|---|
| 把知识图谱当事实库 | 抽取边丢失来源语境 | 主张节点、来源片段、审核状态、时间范围 |
| 不同实体被合并 | 身份特征弱或全局阈值粗糙 | 分类型阈值、审核队列、可回滚 |
| 同一实体被拆分 | 别名和多语言匹配缺口 | 稳定 ID、别名来源、pairwise 评测 |
| GraphRAG 替代所有基线 | 先选架构、后评工作负载 | 查询类型路由与基线门禁 |
| 把路径当解释 | 混淆检索产物与推理 | 路径标记为证据,并引用原始片段 |
| 执行生成 Cypher | 模型输出越过信任边界 | 预审模板与严格参数 |
| 租户过滤来自 Prompt | 把查询数据误当授权 | 权威身份与策略服务 |
| 删除来源仍影响答案 | 派生制品缺少依赖谱系 | 删除清单、传播 SLO、结果核验 |
| 社区摘要成为权威来源 | 引用生成文本而非原文 | 摘要到片段谱系与引用校验 |
常见问题
所有知识图谱都基于 RDF 吗?
不是。RDF 是基于三元组和 IRI 的标准化图数据模型,知识图谱也可以使用属性图、关系模型、搜索索引或它们的组合。无论选择哪种存储,都应保留实体身份、语义、来源与生命周期边界。
构建知识图谱必须先有本体吗?
不一定。小型应用可以从受约束的实体和关系 Schema 起步。当团队需要共享语义、互操作、推理规则或形式化约束时,本体更有价值,但它不能验证来源真实性,也不会消除实体消歧错误。
GraphRAG 能减少幻觉吗?
它可能为部分任务提供更完整的证据,但不能保证答案真实。风险仍取决于抽取质量、检索覆盖、授权、Prompt 组装、模型行为和主张级核验。应测量主张支持率与拒答能力,而不是假设有图就不会幻觉。
图遍历应该设置多深?
没有通用深度。针对产品真正需要的关系编写固定 Allowlist 模板,再评测覆盖、扇出、时延和错误关联。无界或由模型自由选择的深度会增加成本、泄漏风险和无关路径。
什么情况下不应采用 GraphRAG?
当权威数据库、BM25、向量或混合检索已经满足质量与时延目标;当源文档权限无法传播到图制品;或团队无法维护抽取、消歧、更新、删除和分层评测时,都不应引入 GraphRAG。
参考资料
- RDF 1.1 Concepts and Abstract Syntax — W3C Recommendation
- RDF 1.2 Concepts and Abstract Data Model — W3C Candidate Recommendation
- Shapes Constraint Language (SHACL) — W3C Recommendation
- PROV-O: The PROV Ontology — W3C Recommendation
- GraphRAG Query Overview — Microsoft
- From Local to Global: A Graph RAG Approach to Query-Focused Summarization
- WildGraphBench: Benchmarking Graph-Based Retrieval-Augmented Generation
- Protecting against Cypher Injection — Neo4j
总结
知识图谱只有把身份、关系、来源、策略和生命周期显式化,才会形成长期 AI 工程价值。将图谱构建成权威来源的版本化派生视图,让抽取与消歧可逆,只在评测证明收益时路由 GraphRAG,并通过有界模板执行图查询。最终得到的不是自动真实,也不是隐藏推理的窗口,而是一套证据和治理契约可测量的检索系统。