--- layout: default title: "Graph Contexts 技术规范" parent: "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 可以是语句的主语,例如: ``` "2024-01-15" "high" ``` - 注意:命名图是一个与重构分离的功能。 它们除了语句注释之外还有其他用途(分区、访问控制、数据集组织),并且应该被视为一种不同的能力。 3. **匿名节点** (有限支持) - 没有全局 URI 的匿名节点。 - 用于兼容性,以便加载外部 RDF 数据。 - **有限状态**: 对加载后身份的稳定性没有保证。 - 通过通配符查询找到它们(通过连接匹配,而不是通过 ID)。 - 不是首选功能 - 不要依赖于精确的匿名节点处理。 #### 机会性修复 (2.0 破坏性变更) 这些功能与重构目标没有直接关系,但包含在破坏性变更中是有价值的改进: 4. **原始数据类型** - 正确使用 `type` 字段表示 XSD 数据类型。 - 示例:xsd:string, xsd:integer, xsd:dateTime 等。 - 修复当前限制:无法正确表示日期或整数。 5. **语言标签** - 支持字符串原始值上的语言属性 (@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` 模式一致。 单字符类型代码提供紧凑的序列化: ```python 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 ``` 用法示例: ```python # 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` 类获得一个可选的图字段,以成为四元组: ```python @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` = 通配符 / `*`**: 查询所有图 (相当于 SPARQL `GRAPH ?g { ... }`) 这保持简单查询的简单性,并使命名图查询成为可选。 完全支持跨图查询 (g=通配符)。 Cassandra 模式包含专门的表,其中 g 是一个聚类列,而不是分区键,从而实现高效的跨所有图的查询。 #### 时间查询 **查找在特定日期之后发现的所有事实:** ``` S: ? # 任何引用三元组 P: O: > "2024-01-15"^^xsd:date # 日期比较 ``` **查找何时认为特定事实成立:** ``` S: << >> # 引用三元组作为主语 P: O: ? # 返回日期 ``` **查找被发现为错误的 facts:** ``` S: ? # 任何引用三元组 P: O: ? # 具有任何值 (存在) ``` #### 溯源查询 **查找由特定来源支持的所有事实:** ``` S: ? # 任何引用三元组 P: O: ``` **查找哪些来源支持特定事实:** ``` S: << >> # 引用三元组作为主语 P: O: ? # 返回来源 IRI ``` #### 真实性查询 **查找 Person 声明为真的断言:** ``` S: ? # 任何引用三元组 P: O: ``` **查找冲突的断言 (相同的 facts,不同的真实性):** ``` # 第一个查询:声明为真的事实 S: ? P: O: ? # 第二个查询:声明为假的 fact S: ? P: O: ? # 应用程序逻辑:查找主语的交集 ``` **查找信任评分低于阈值的 facts:** ``` S: ? # 任何引用三元组 P: 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 等)。 实施将分阶段进行: 1. **第一阶段:Cassandra** - 在完全控制的后端上验证设计,然后再承诺在所有存储系统中的实现。 2. **第二阶段+:其他后端** - 在后续阶段实施 Neo4j 和其他存储系统。 此方法通过在所有系统上承诺实现之前,在完全受控的后端上验证设计,从而降低风险。 #### `Value` → `Term` 重命名 `Value` 类将被重命名为 `Term`。 这会影响代码库中的约 78 个文件。 重命名充当强制函数:任何仍然使用 `Value` 的代码都将立即显示为需要审查/更新以获得 2.0 兼容性。 ## 安全注意事项 命名图不是安全功能。 用户和集合仍然是安全边界。 命名图纯粹用于数据组织和重构支持。 ## 性能注意事项 - 引用三元组会增加嵌套深度,这可能会影响查询性能。 - 需要命名图索引策略以实现高效的范围查询。 - Cassandra 模式设计需要适应四元组存储。 ### 向量存储边界 向量存储始终只引用 IRI: - 永远不要边(引用三元组)。 - 永远不要原始值。 - 永远不要匿名节点。 这使向量存储保持简单 - 它处理命名实体语义相似性。 图结构处理关系、重构和元数据。 引用三元组和命名图不会使向量操作复杂化。 ## 测试策略 使用现有的测试策略。 由于这是一个破坏性版本,因此需要重点关注端到端测试套件,以验证新的结构是否在所有组件中都正确工作。 ## 迁移计划 - 2.0 是一个破坏性版本;不需要向后兼容性。 - 现有数据可能需要迁移到新的模式(基于最终设计的确定)。 - 考虑迁移工具,用于转换现有三元组。 ## 开放问题 - **匿名节点**: 确认有限支持。 可能需要决定采用 Skolem 化策略(在加载时生成 IRI,或保留匿名节点 ID)。 - **查询语法**: 引用三元组在查询中的具体语法是什么? 需要定义查询 API。 - **谓词词汇表**: 已解决。 允许任何有效的 RDF 谓词,包括自定义的用户定义的谓词。 尽量减少对任何事情的锁定(例如,在某些地方使用 `rdfs:label`)。 策略:除非绝对必要,否则避免锁定任何内容。 - **向量存储影响**: 已解决。 向量存储始终仅指向 IRI - 永远不要边、原始值或匿名节点。 引用三元组和重构不会影响向量存储。 ## 参考文献 - [RDF 1.2 概念](https://www.w3.org/TR/rdf12-concepts/) - [RDF-star 和 SPARQL-star](https://w3c.github.io/rdf-star/) - [RDF 数据集](https://www.w3.org/TR/rdf11-concepts/#section-dataset)