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.
14 KiB
| 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 功能
核心功能(与重构目标相关)
这些功能与时间、溯源和真实性目标直接相关:
-
RDF 1.2 引用三元组 (RDF-star)
- 指向其他边的边。
- 三元组可以作为另一个三元组的主语或宾语。
- 启用关于声明的声明(重构)。
- 注释单个事实的核心机制。
-
RDF 数据集 / 命名图
- 支持数据集中的多个命名图。
- 每个图由 IRI 标识。
- 从三元组 (s, p, o) 转换为四元组 (s, p, o, g)。
- 包含一个默认图以及零个或多个命名图。
- 图 IRI 可以是语句的主语,例如:
<graph-source-A> <discoveredOn> "2024-01-15" <graph-source-A> <hasVeracity> "high" - 注意:命名图是一个与重构分离的功能。 它们除了语句注释之外还有其他用途(分区、访问控制、数据集组织),并且应该被视为一种不同的能力。
-
匿名节点 (有限支持)
- 没有全局 URI 的匿名节点。
- 用于兼容性,以便加载外部 RDF 数据。
- 有限状态: 对加载后身份的稳定性没有保证。
- 通过通配符查询找到它们(通过连接匹配,而不是通过 ID)。
- 不是首选功能 - 不要依赖于精确的匿名节点处理。
机会性修复 (2.0 破坏性变更)
这些功能与重构目标没有直接关系,但包含在破坏性变更中是有价值的改进:
-
原始数据类型
- 正确使用
type字段表示 XSD 数据类型。 - 示例:xsd:string, xsd:integer, xsd:dateTime 等。
- 修复当前限制:无法正确表示日期或整数。
- 正确使用
-
语言标签
- 支持字符串原始值上的语言属性 (@en, @fr 等)。
- 注意:一个原始值要么有一个语言标签,要么有一个数据类型,两者不能同时存在(除了 rdf:langString)。
- 对于 AI/多语言用例非常重要。
数据模型
Term (重命名自 Value)
Value 类将被重命名为 Term,以更好地反映 RDF 术语。
此重命名有两个目的:
- 与 RDF 概念对齐命名(“Term”可以是 IRI、原始值、匿名节点或引用三元组,而不仅仅是“值”)。
- 在破坏性变更接口强制代码审查 - 任何仍然引用
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用于与s、p、o一致。 - 可选:
None表示默认图(无命名)。 - 类型: 纯字符串 (IRI),而不是 Term
- 图名始终是 IRI。
- 匿名节点作为图名被排除(过于混乱)。
- 不需要完整的 Term 机制。
注意:类名保持为 Triple,即使它现在实际上是一个四元组。
这避免了变更,并且术语“三元组”仍然是常见的术语。 图上下文是关于三元组存储位置的元数据。
候选查询模式
当前查询引擎接受 S、P、O 项的组合。 使用引用三元组时,一个三元组本身可以成为这些位置上的有效项。 以下是支持原始目标的候选查询模式。
图参数语义
遵循 SPARQL 的约定以实现向后兼容:
g被省略 / None: 仅查询默认图。g= 特定 IRI: 仅查询该命名图。g= 通配符 /*: 查询所有图 (相当于 SPARQLGRAPH ?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)Value→Term重命名。- 具有类型区分器的新的
Term结构。 Triple获得g字段以进行图上下文。
-
消息翻译器 (
trustgraph-base/trustgraph/messaging/translators/)- 更新以适应新的
Term和Triple结构。 - 用于新字段的序列化/反序列化。
- 更新以适应新的
-
网关组件
- 处理新的
Term和四元组结构。
- 处理新的
-
知识核心
- 支持四元组和重构的核心更改。
-
知识管理器
- 模式更改会在此处传播。
-
存储层
- Cassandra: 重新设计模式(参见“实施详细信息”)。
- 其他后端:推迟到后续阶段。
-
命令行工具
- 更新以适应新的数据结构。
-
REST API 文档
- 更新 OpenAPI 规范。
外部仓库
-
Python API (此仓库)
- 更新客户端库以匹配新的结构。
-
TypeScript API (单独仓库)
- 平行于 Python API 的更改。
- 分离的发布协调。
-
Workbench (单独仓库)
- 状态管理方面的重大更改。
- 用于图上下文功能的 UI 更新。
API
REST API
- 在 OpenAPI 规范中记录。
- 需要更新以适应新的
Term和Triple结构。 - 可能需要新的端点来处理图上下文操作。
Python API (此仓库)
- 客户端库更改以匹配新的原始数据类型。
Term(以前是Value) 和Triple的破坏性更改。
TypeScript API (单独仓库)
- 与 Python API 平行的更改。
- 分离的发布协调。
Workbench (单独仓库)
- 状态管理方面的重大更改。
- 用于图上下文功能的 UI 更新。
实施细节
分阶段的存储实施
存在多个图存储后端(Cassandra、Neo4j 等)。 实施将分阶段进行:
-
第一阶段:Cassandra
- 在完全控制的后端上验证设计,然后再承诺在所有存储系统中的实现。
-
第二阶段+:其他后端
- 在后续阶段实施 Neo4j 和其他存储系统。
此方法通过在所有系统上承诺实现之前,在完全受控的后端上验证设计,从而降低风险。
Value → Term 重命名
Value 类将被重命名为 Term。 这会影响代码库中的约 78 个文件。
重命名充当强制函数:任何仍然使用 Value 的代码都将立即显示为需要审查/更新以获得 2.0 兼容性。
安全注意事项
命名图不是安全功能。 用户和集合仍然是安全边界。 命名图纯粹用于数据组织和重构支持。
性能注意事项
- 引用三元组会增加嵌套深度,这可能会影响查询性能。
- 需要命名图索引策略以实现高效的范围查询。
- Cassandra 模式设计需要适应四元组存储。
向量存储边界
向量存储始终只引用 IRI:
- 永远不要边(引用三元组)。
- 永远不要原始值。
- 永远不要匿名节点。
这使向量存储保持简单 - 它处理命名实体语义相似性。 图结构处理关系、重构和元数据。 引用三元组和命名图不会使向量操作复杂化。
测试策略
使用现有的测试策略。 由于这是一个破坏性版本,因此需要重点关注端到端测试套件,以验证新的结构是否在所有组件中都正确工作。
迁移计划
- 2.0 是一个破坏性版本;不需要向后兼容性。
- 现有数据可能需要迁移到新的模式(基于最终设计的确定)。
- 考虑迁移工具,用于转换现有三元组。
开放问题
- 匿名节点: 确认有限支持。 可能需要决定采用 Skolem 化策略(在加载时生成 IRI,或保留匿名节点 ID)。
- 查询语法: 引用三元组在查询中的具体语法是什么? 需要定义查询 API。
- 谓词词汇表: 已解决。 允许任何有效的 RDF 谓词,包括自定义的用户定义的谓词。 尽量减少对任何事情的锁定(例如,在某些地方使用
rdfs:label)。 策略:除非绝对必要,否则避免锁定任何内容。 - 向量存储影响: 已解决。 向量存储始终仅指向 IRI - 永远不要边、原始值或匿名节点。 引用三元组和重构不会影响向量存储。