Semantica · 专题 02
Technical deep-dive · 02

双时态事实与历史修订

Semantica 对“业务世界中何时成立”和“系统何时知道”做了明确分离,并提供时间轴查询、快照、修订、校验和及区间推理。这套语义非常适合补录、更正、政策版本、历史回放和决策复盘。

版本 0.6.6 证据基线 5c6b40f36 分析日期 2026-08-24
Recommendation
参照双时态数据契约;隔离验证查询与修订行为;不要直接把现有接口认作完整时态查询语言。

专题结论

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()(执行点时图重建的方法片段)。

固定提交片段:点时图重建调用 原项目关键片段

python
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. 建议的数据契约

下面是抽象示例(不是原项目原样代码),用于说明业务有效时间与系统记录时间必须分开:

yaml
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. 可借鉴的交互设计

  1. 时间轴顶部提供“业务有效时间 / 系统记录时间”切换,并在双轴模式并排展示。
  2. 补录与更正弹窗同时要求填写有效日期、记录原因、来源证据和替代的旧版本。
  3. 历史快照显示“当时有效”与“当时已知”的标签,防止事后信息污染决策复盘。
  4. 修订差异页按实体、关系和时间边界分类,并突出追溯性更改。
  5. 校验和失败、时间区间重叠和逆序边界进入独立异常队列,而不是只在日志中提示。

7. 引入或参照结论

项目 结论 条件
双时态事实字段 建议仅作设计参照 与现有业务时间、时区和精度规范对齐
追加式修订 建议重点参照 禁止覆盖旧版本并记录修订原因
时态查询器 建议隔离 PoC 验证双轴、范围边界、性能和查询文本语义
图快照与摘要 建议局部验证 增量存储、签名与恢复流程需另行设计
多套历史接口 不建议原样暴露 在统一应用服务后提供单一契约

8. 源码依据

主题 固定版本官方源码 支持的判断
双时态事实字段 双时态事实定义 有效时间和记录时间分别建模
点时、范围和一致性查询 点时重建一致性检查范围查询 查询器提供点时、区间与一致性三类时态能力
图版本、快照与修订 版本管理器定义当前图快照追加式修订 快照保存当前输入图,修订保留旧关系并生成替代版本
区间推理 区间关系、合并、缺口和覆盖实现 区间算法是确定性纯 Python 计算
图构建器时态入口 图构建器的简化时态查询 另有数据形态和时间轴能力较简化的历史入口
上下文图历史状态 上下文图点时状态 上下文图只按有效时间恢复节点和边状态

返回 Semantica 项目分析主报告