trustgraph/docs/tech-specs/graph-contexts.zh-cn.md

426 lines
14 KiB
Markdown
Raw Normal View History

---
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 可以是语句的主语,例如:
```
<graph-source-A> <discoveredOn> "2024-01-15"
<graph-source-A> <hasVeracity> "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: <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 等)。
实施将分阶段进行:
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)