trustgraph/docs/tech-specs/graph-contexts.zh-cn.md
Alex Jenkins 8954fa3ad7 Feat: TrustGraph i18n & Documentation Translation Updates (#781)
Native CLI i18n: The TrustGraph CLI has built-in translation support
that dynamically loads language strings. You can test and use
different languages by simply passing the --lang flag (e.g., --lang
es for Spanish, --lang ru for Russian) or by configuring your
environment's LANG variable.

Automated Docs Translations: This PR introduces autonomously
translated Markdown documentation into several target languages,
including Spanish, Swahili, Portuguese, Turkish, Hindi, Hebrew,
Arabic, Simplified Chinese, and Russian.
2026-04-14 12:08:32 +01:00

14 KiB
Raw Blame History

layout title parent
default Graph Contexts 技术规范 Chinese (Beta)

Graph Contexts 技术规范

Beta Translation: This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.

概述

本规范描述了 TrustGraph 核心图结构体的变更,以符合 RDF 1.2 标准并支持完整的 RDF 数据集语义。 这对 2.x 版本系列是一个破坏性变更。

版本控制

  • 2.0: 早期采用版本。核心功能可用,可能尚未完全达到生产级别。
  • 2.1 / 2.2: 生产版本。稳定性和完整性已验证。

关于成熟度的灵活性是故意的 - 早期采用者可以访问新的功能,而所有功能尚未经过生产环境的验证。

目标

本次工作的首要目标是启用关于事实/声明的元数据:

  • 时间信息: 将事实与时间元数据关联

    • 确定一个事实何时被认为是正确的。
    • 确定一个事实何时开始成立。
    • 确定一个事实何时被发现是错误的。
  • 来源/溯源: 跟踪哪些来源支持一个事实

    • “这个事实由来源 X 支持”。
    • 将事实链接回其原始文档。
  • 真实性/信任度: 记录对真实性的断言

    • “Person P 声明这是真的”。
    • “Person Q 声称这是假的”。
    • 启用信任评分和冲突检测。

假设: 重构RDF-star / 引用三元组)是实现这些目标的关键机制,因为所有这些都要求对声明进行声明。

背景

为了表达“事实Alice 知道 Bob于 2024-01-15 被发现”或“来源 X 支持Y 导致 Z的声明”您需要引用一个边作为可以进行声明的对象。 标准的三元组不支持这种情况。

当前限制

trustgraph-base/trustgraph/schema/core/primitives.py 中的当前 Value 类可以表示:

  • URI 节点 (is_uri=True)
  • 原始值 (is_uri=False)

type 字段存在,但未用于表示 XSD 数据类型。

技术设计

需要支持的 RDF 功能

核心功能(与重构目标相关)

这些功能与时间、溯源和真实性目标直接相关:

  1. RDF 1.2 引用三元组 (RDF-star)

    • 指向其他边的边。
    • 三元组可以作为另一个三元组的主语或宾语。
    • 启用关于声明的声明(重构)。
    • 注释单个事实的核心机制。
  2. RDF 数据集 / 命名图

    • 支持数据集中的多个命名图。
    • 每个图由 IRI 标识。
    • 从三元组 (s, p, o) 转换为四元组 (s, p, o, g)。
    • 包含一个默认图以及零个或多个命名图。
    • 图 IRI 可以是语句的主语,例如:
      <graph-source-A> <discoveredOn> "2024-01-15"
      <graph-source-A> <hasVeracity> "high"
      
    • 注意:命名图是一个与重构分离的功能。 它们除了语句注释之外还有其他用途(分区、访问控制、数据集组织),并且应该被视为一种不同的能力。
  3. 匿名节点 (有限支持)

    • 没有全局 URI 的匿名节点。
    • 用于兼容性,以便加载外部 RDF 数据。
    • 有限状态: 对加载后身份的稳定性没有保证。
    • 通过通配符查询找到它们(通过连接匹配,而不是通过 ID
    • 不是首选功能 - 不要依赖于精确的匿名节点处理。

机会性修复 (2.0 破坏性变更)

这些功能与重构目标没有直接关系,但包含在破坏性变更中是有价值的改进:

  1. 原始数据类型

    • 正确使用 type 字段表示 XSD 数据类型。
    • 示例xsd:string, xsd:integer, xsd:dateTime 等。
    • 修复当前限制:无法正确表示日期或整数。
  2. 语言标签

    • 支持字符串原始值上的语言属性 (@en, @fr 等)。
    • 注意:一个原始值要么有一个语言标签,要么有一个数据类型,两者不能同时存在(除了 rdf:langString
    • 对于 AI/多语言用例非常重要。

数据模型

Term (重命名自 Value)

Value 类将被重命名为 Term,以更好地反映 RDF 术语。 此重命名有两个目的:

  1. 与 RDF 概念对齐命名“Term”可以是 IRI、原始值、匿名节点或引用三元组而不仅仅是“值”
  2. 在破坏性变更接口强制代码审查 - 任何仍然引用 Value 的代码都会立即显示为已损坏,并且需要更新。

一个 Term 可以表示:

  • IRI/URI - 命名节点/资源。
  • 匿名节点 - 具有本地作用域的匿名节点。
  • 原始值 - 具有以下之一的数据值:
    • 数据类型 (XSD 类型),或
    • 语言标签。
  • 引用三元组 - 用作项的三元组 (RDF 1.2)。
选定的方法:具有类型区分器的单个类

序列化要求驱动结构 - 无论 Python 表示形式如何,都需要类型区分器。 具有类型字段的单个类是最佳选择,并且与当前的 Value 模式一致。

单字符类型代码提供紧凑的序列化:

from dataclasses import dataclass

# Term 类型常量
IRI = "i"      # IRI/URI 节点
BLANK = "b"    # 匿名节点
LITERAL = "l"  # 原始值
TRIPLE = "t"   # 引用三元组 (RDF-star)

@dataclass
class Term:
    type: str = ""  # 之一: IRI, BLANK, LITERAL, TRIPLE

    # 对于 IRI 项 (type == IRI)
    iri: str = ""

    # 对于匿名节点 (type == BLANK)
    id: str = ""

    # 对于原始值 (type == LITERAL)
    value: str = ""
    datatype: str = ""   # XSD 数据类型 URI (与语言互斥)
    language: str = ""   # 语言标签 (与数据类型互斥)

    # 对于引用三元组 (type == TRIPLE)
    triple: "Triple | None" = None

用法示例:

# IRI 项
node = Term(type=IRI, iri="http://example.org/Alice")

# 带数据类型的原始值
age = Term(type=LITERAL, value="42", datatype="xsd:integer")

# 带语言标签的原始值
label = Term(type=LITERAL, value="Hello", language="en")

# 匿名节点
anon = Term(type=BLANK, id="_:b1")

# 引用三元组 (关于声明的声明)
inner = Triple(
    s=Term(type=IRI, iri="http://example.org/Alice"),
    p=Term(type=IRI, iri="http://example.org/knows"),
    o=Term(type=IRI, iri="http://example.org/Bob"),
)
reified = Term(type=TRIPLE, triple=inner)
考虑的替代方案

选项 B专用类的联合 (Term = IRI | BlankNode | Literal | QuotedTriple)

  • 拒绝:仍然需要类型区分器进行序列化,增加了复杂性。

选项 C具有子类的基本类

  • 拒绝:与序列化问题相同,此外还有 dataclass 继承的复杂性。

Triple / Quad

Triple 类获得一个可选的图字段,以成为四元组:

@dataclass
class Triple:
    s: Term | None = None    # 主语
    p: Term | None = None    # 谓词
    o: Term | None = None    # 宾语
    g: str | None = None     # 图名 (IRI)None = 默认图

设计决策:

  • 字段名称: g 用于与 spo 一致。
  • 可选: None 表示默认图(无命名)。
  • 类型: 纯字符串 (IRI),而不是 Term
    • 图名始终是 IRI。
    • 匿名节点作为图名被排除(过于混乱)。
    • 不需要完整的 Term 机制。

注意:类名保持为 Triple,即使它现在实际上是一个四元组。 这避免了变更,并且术语“三元组”仍然是常见的术语。 图上下文是关于三元组存储位置的元数据。

候选查询模式

当前查询引擎接受 S、P、O 项的组合。 使用引用三元组时,一个三元组本身可以成为这些位置上的有效项。 以下是支持原始目标的候选查询模式。

图参数语义

遵循 SPARQL 的约定以实现向后兼容:

  • g 被省略 / None: 仅查询默认图。
  • g = 特定 IRI: 仅查询该命名图。
  • g = 通配符 / *: 查询所有图 (相当于 SPARQL GRAPH ?g { ... })

这保持简单查询的简单性,并使命名图查询成为可选。

完全支持跨图查询 (g=通配符)。 Cassandra 模式包含专门的表,其中 g 是一个聚类列,而不是分区键,从而实现高效的跨所有图的查询。

时间查询

查找在特定日期之后发现的所有事实:

S: ?                                    # 任何引用三元组
P: <discoveredOn>
O: > "2024-01-15"^^xsd:date             # 日期比较

查找何时认为特定事实成立:

S: << <Alice> <knows> <Bob> >>          # 引用三元组作为主语
P: <believedTrueFrom>
O: ?                                    # 返回日期

查找被发现为错误的 facts

S: ?                                    # 任何引用三元组
P: <discoveredFalseOn>
O: ?                                    # 具有任何值 (存在)

溯源查询

查找由特定来源支持的所有事实:

S: ?                                    # 任何引用三元组
P: <supportedBy>
O: <source:document-123>

查找哪些来源支持特定事实:

S: << <DrugA> <treats> <DiseaseB> >>    # 引用三元组作为主语
P: <supportedBy>
O: ?                                    # 返回来源 IRI

真实性查询

查找 Person 声明为真的断言:

S: ?                                    # 任何引用三元组
P: <assertedTrueBy>
O: <person:Alice>

查找冲突的断言 (相同的 facts不同的真实性)

# 第一个查询:声明为真的事实
S: ?
P: <assertedTrueBy>
O: ?

# 第二个查询:声明为假的 fact
S: ?
P: <assertedFalseBy>
O: ?

# 应用程序逻辑:查找主语的交集

查找信任评分低于阈值的 facts

S: ?                                    # 任何引用三元组
P: <trustScore>
O: < 0.5                                # 数值比较

架构

需要对多个组件进行重大更改:

此仓库 (trustgraph)

  • 模式原始数据类型 (trustgraph-base/trustgraph/schema/core/primitives.py)

    • ValueTerm 重命名。
    • 具有类型区分器的新的 Term 结构。
    • Triple 获得 g 字段以进行图上下文。
  • 消息翻译器 (trustgraph-base/trustgraph/messaging/translators/)

    • 更新以适应新的 TermTriple 结构。
    • 用于新字段的序列化/反序列化。
  • 网关组件

    • 处理新的 Term 和四元组结构。
  • 知识核心

    • 支持四元组和重构的核心更改。
  • 知识管理器

    • 模式更改会在此处传播。
  • 存储层

    • Cassandra: 重新设计模式(参见“实施详细信息”)。
    • 其他后端:推迟到后续阶段。
  • 命令行工具

    • 更新以适应新的数据结构。
  • REST API 文档

    • 更新 OpenAPI 规范。

外部仓库

  • Python API (此仓库)

    • 更新客户端库以匹配新的结构。
  • TypeScript API (单独仓库)

    • 平行于 Python API 的更改。
    • 分离的发布协调。
  • Workbench (单独仓库)

    • 状态管理方面的重大更改。
    • 用于图上下文功能的 UI 更新。

API

REST API

  • 在 OpenAPI 规范中记录。
  • 需要更新以适应新的 TermTriple 结构。
  • 可能需要新的端点来处理图上下文操作。

Python API (此仓库)

  • 客户端库更改以匹配新的原始数据类型。
  • Term (以前是 Value) 和 Triple 的破坏性更改。

TypeScript API (单独仓库)

  • 与 Python API 平行的更改。
  • 分离的发布协调。

Workbench (单独仓库)

  • 状态管理方面的重大更改。
  • 用于图上下文功能的 UI 更新。

实施细节

分阶段的存储实施

存在多个图存储后端Cassandra、Neo4j 等)。 实施将分阶段进行:

  1. 第一阶段Cassandra

    • 在完全控制的后端上验证设计,然后再承诺在所有存储系统中的实现。
  2. 第二阶段+:其他后端

    • 在后续阶段实施 Neo4j 和其他存储系统。

此方法通过在所有系统上承诺实现之前,在完全受控的后端上验证设计,从而降低风险。

ValueTerm 重命名

Value 类将被重命名为 Term。 这会影响代码库中的约 78 个文件。 重命名充当强制函数:任何仍然使用 Value 的代码都将立即显示为需要审查/更新以获得 2.0 兼容性。

安全注意事项

命名图不是安全功能。 用户和集合仍然是安全边界。 命名图纯粹用于数据组织和重构支持。

性能注意事项

  • 引用三元组会增加嵌套深度,这可能会影响查询性能。
  • 需要命名图索引策略以实现高效的范围查询。
  • Cassandra 模式设计需要适应四元组存储。

向量存储边界

向量存储始终只引用 IRI

  • 永远不要边(引用三元组)。
  • 永远不要原始值。
  • 永远不要匿名节点。

这使向量存储保持简单 - 它处理命名实体语义相似性。 图结构处理关系、重构和元数据。 引用三元组和命名图不会使向量操作复杂化。

测试策略

使用现有的测试策略。 由于这是一个破坏性版本,因此需要重点关注端到端测试套件,以验证新的结构是否在所有组件中都正确工作。

迁移计划

  • 2.0 是一个破坏性版本;不需要向后兼容性。
  • 现有数据可能需要迁移到新的模式(基于最终设计的确定)。
  • 考虑迁移工具,用于转换现有三元组。

开放问题

  • 匿名节点: 确认有限支持。 可能需要决定采用 Skolem 化策略(在加载时生成 IRI或保留匿名节点 ID
  • 查询语法: 引用三元组在查询中的具体语法是什么? 需要定义查询 API。
  • 谓词词汇表: 已解决。 允许任何有效的 RDF 谓词,包括自定义的用户定义的谓词。 尽量减少对任何事情的锁定(例如,在某些地方使用 rdfs:label)。 策略:除非绝对必要,否则避免锁定任何内容。
  • 向量存储影响: 已解决。 向量存储始终仅指向 IRI - 永远不要边、原始值或匿名节点。 引用三元组和重构不会影响向量存储。

参考文献