专题结论
Semantica 对“业务世界中何时成立”和“系统何时知道”做了明确分离,并提供时间轴查询、快照、修订、校验和及区间推理。这套语义非常适合补录、更正、政策版本、历史回放和决策复盘。
建议:参照双时态数据契约;隔离验证查询与修订行为;不要直接把现有接口认作完整时态查询语言。
1. 双时态模型
semantica.kg.temporal_model(定义双时态事实及开放时间边界的模块)中的 BiTemporalFact(包装关系数据并同时保存有效时间和记录时间的事实模型,约第 28 行)包含四个关键时间字段:
| 重要字段 | 中文简介 | 回答的问题 |
|---|---|---|
valid_from(事实在业务世界开始有效的时间,约第 34 行) |
有效时间起点 | 事实从什么时候成立? |
valid_until(事实在业务世界停止有效的时间,约第 35 行) |
有效时间终点 | 事实到什么时候为止? |
recorded_at(系统首次记录该事实版本的时间,约第 36 行) |
记录时间起点 | 系统从什么时候知道? |
superseded_at(该记录版本被新版本替代的时间,约第 37 行) |
记录时间终点 | 这个版本何时不再是系统当前认知? |
这一分离避免了用单一更新时间覆盖两种语义。例如,合同从 7 月 1 日生效但 8 月 22 日才补录:有效时间起点应为 7 月 1 日,记录时间起点应为 8 月 22 日。
2. 查询语义
TemporalGraphQuery(按有效时间或记录时间过滤关系并重建图的查询器,约第 41 行)提供三个重要方向:
query_at_time()(按指定时间点和时间轴筛选活动关系的方法,约第 107 行)用于点时查询;query_time_range()(查询与指定时间范围相交或覆盖关系的方法,约第 359 行)用于区间查询;validate_temporal_consistency()(检查图中时间边界和重叠问题的方法,约第 211 行)用于一致性报告。
需要特别注意:点时查询接收的查询文本目前没有被真正解释,实际行为是“按轴过滤关系并重建图”。因此产品文档应称它为“时态图过滤器”或补齐查询解析,不能直接宣传为完整查询语言。
原始调用链与关键片段
TemporalGraphQuery.query_at_time()(点时查询入口)先解析时间,再调用 TemporalGraphQuery.reconstruct_at_time()(按所选时间轴重建图的方法);后者通过 TemporalGraphQuery._relationship_active_at_time()(判断单条关系在目标时刻是否活动的内部方法)完成过滤。输入是图、查询文本、时间点和时间轴;输出是重建后的实体与关系集合。查询文本只被原样放回响应,没有进入重建调用。
原项目关键片段——TemporalGraphQuery.query_at_time()(执行点时图重建的方法片段)。
固定提交片段:点时图重建调用 原项目关键片段
self.logger.info(f"Querying graph at time: {at_time}")
# Parse time
query_time = self._parse_time(at_time)
reconstructed_graph = self.reconstruct_at_time(
graph,
query_time,
time_axis=time_axis,
)
这段代码证明点时查询的主行为是时间解析与图重建;结合参数说明明确标注查询文本尚未使用,可确定它不是完整查询语言。可借鉴的是显式时间轴与独立重建步骤;不能照搬的是保留一个看似可执行、实际只回显的查询文本参数。
仓库还有两条并行历史入口:GraphBuilder.query_temporal()(图构建器上的简化时态查询入口,约第 1110 行)与 ContextGraph.state_at()(上下文图按有效时间恢复状态的方法,约第 2590 行)。它们的数据形态和时间轴能力不完全相同,生产接入应在应用层统一接口。
3. 版本与修订
TemporalVersionManager(生成图版本、快照、修订、差异和校验和的管理器,约第 1149 行)包含以下关键动作:
| 方法 | 中文简介 | 采用判断 |
|---|---|---|
create_version()(创建并返回带标签和时间戳的图副本、但不负责持久化或计算摘要的方法,约第 1217 行) |
生成可比较的版本对象 | 调用方需另行保存;它不会自行建立审计检查点 |
create_snapshot()(为调用方传入的当前图附加当前时间、作者、说明和校验和并持久化的方法,不会按任意历史时刻重建图,约第 1326 行) |
保存当前输入图的审计快照 | 历史视图需先由时态查询重建;仍需验证大图性能 |
apply_revision()(以追加替代方式应用追溯修订的方法,约第 1391 行) |
保留旧版本并产生新版本 | 值得重点参照 |
verify_checksum()(验证快照摘要是否匹配的方法,约第 1586 行) |
发现意外修改 | 不能代替数字签名和外部时间戳 |
修订的关键价值不是“可以改历史”,而是“修改系统对历史的认知,同时保留系统曾经知道什么”。这正是决策复盘中区分合理决策与事后信息的基础。
4. 区间推理
TemporalReasoningEngine(计算区间关系、合并、缺口、覆盖率和时间线的纯 Python 推理器,约第 43 行)提供确定性的区间计算,不依赖 LLM。
可参照能力包括:
- 判断两个区间先后、相交、包含或相等;
- 合并相接或重叠的区间;
- 找出覆盖缺口并计算覆盖率;
- 把事实版本投影为实体时间线;
- 识别补录信息对历史区间的追溯覆盖。
这部分比通用“时间字符串过滤”更适合作为领域规则的底层工具,但需先确定时区、精度、开放边界和结束时间的统一约定。
5. 建议的数据契约
下面是抽象示例(不是原项目原样代码),用于说明业务有效时间与系统记录时间必须分开:
fact_version_id: contract-status-v2
subject: contract-17
predicate: status
object: active
valid_time:
from: 2026-07-01T00:00:00Z
until: null
system_time:
recorded_at: 2026-08-22T09:30:00Z
superseded_at: null
revises: contract-status-v1
reason: late-arriving-source-document
对应的查询接口至少要显式要求调用方选择有效时间轴、记录时间轴或双轴快照,避免默认值隐藏语义差异。
6. 可借鉴的交互设计
- 时间轴顶部提供“业务有效时间 / 系统记录时间”切换,并在双轴模式并排展示。
- 补录与更正弹窗同时要求填写有效日期、记录原因、来源证据和替代的旧版本。
- 历史快照显示“当时有效”与“当时已知”的标签,防止事后信息污染决策复盘。
- 修订差异页按实体、关系和时间边界分类,并突出追溯性更改。
- 校验和失败、时间区间重叠和逆序边界进入独立异常队列,而不是只在日志中提示。
7. 引入或参照结论
| 项目 | 结论 | 条件 |
|---|---|---|
| 双时态事实字段 | 建议仅作设计参照 | 与现有业务时间、时区和精度规范对齐 |
| 追加式修订 | 建议重点参照 | 禁止覆盖旧版本并记录修订原因 |
| 时态查询器 | 建议隔离 PoC | 验证双轴、范围边界、性能和查询文本语义 |
| 图快照与摘要 | 建议局部验证 | 增量存储、签名与恢复流程需另行设计 |
| 多套历史接口 | 不建议原样暴露 | 在统一应用服务后提供单一契约 |
8. 源码依据
| 主题 | 固定版本官方源码 | 支持的判断 |
|---|---|---|
| 双时态事实字段 | 双时态事实定义 | 有效时间和记录时间分别建模 |
| 点时、范围和一致性查询 | 点时重建、一致性检查、范围查询 | 查询器提供点时、区间与一致性三类时态能力 |
| 图版本、快照与修订 | 版本管理器定义、当前图快照、追加式修订 | 快照保存当前输入图,修订保留旧关系并生成替代版本 |
| 区间推理 | 区间关系、合并、缺口和覆盖实现 | 区间算法是确定性纯 Python 计算 |
| 图构建器时态入口 | 图构建器的简化时态查询 | 另有数据形态和时间轴能力较简化的历史入口 |
| 上下文图历史状态 | 上下文图点时状态 | 上下文图只按有效时间恢复节点和边状态 |