AI 讨论组State of the Art
全部报告 技术研究 技术研究围绕具体技术问题的调研、方案与故障分析报告,未经讨论组表决。

联合分析数据契约与治理规范

主报告负责方法论与决策依据,本分册负责实现口径。两者的分工:

文档版本
v1.3
文档日期
2026-09-20
站内更新
2026-09-30 17:04
篇幅
1.1 万字,约 28 分钟
文档日期与站内更新时间
文档日期
2026-09-20
站内更新
2026-09-30 17:04
关联分组 可观测信号联合分析第 2 篇,共 2 篇

文档版本:v1.3 final 契约版本:contract_version = 2.0(frozen;序列化载荷中的取值,与文档版本独立,见第 1.2 节) 更新日期:2026-09-20 配套主文档:《Metric、Log、Trace、Profiling 联合分析研究报告(图解与案例版)》v1.6.1 适用对象:联合分析平台实现者、查询适配器开发者、诊断智能体接入方、POC 验收评审人


1. 定位与使用方式

1.1 与主报告的分工

主报告负责方法论与决策依据,本分册负责实现口径。两者的分工:

主报告 本分册
回答 为什么这样设计、有哪些边界和陷阱 字段叫什么、取什么值、怎么算
读者 架构评审、立项决策、跨团队沟通 实现者、接入方、验收人
变更节奏 随方法论认知更新 随实现细节迭代,通常更频繁

两份文档独立版本迭代。本分册中任何与主报告方法论冲突之处,以主报告为准,并应反向修订本分册。

**本分册给出的是字段与口径的建议基线,不是行业标准。**所有阈值均为首轮 POC 的讨论起点,冻结前须结合目标服务、数据规模、故障风险和现有基线调整。

1.2 契约版本与兼容策略

一旦工作台、查询适配器和诊断智能体围绕本契约开发,契约本身就必须可版本化演进。

**文档版本与契约版本相互独立。**本文档为 v1.3 final,其定义的载荷契约为 2.0。文档可因措辞、示例、验收阈值等原因单独修订而不改变契约;契约的 major 变化也不要求文档跟随同号。二者不得混用同一个版本号。

本次升至 2.0 的原因即在于此:Evidence Contract 由单层结构改为 QueryResult + EvidenceBundle 两层,关联状态由记录级下沉至关联边级,来源标识由二元组改为三元组,均属下表中的“层级调整”与“字段改名”,按本节规则必须升 major。

每个顶层序列化载荷必须携带 contract_version(语义化版本,如 "2.0")。嵌套在 EvidenceBundle 内的 QueryResult 继承外层版本,不重复携带;若 QueryResult 独立传输(例如适配器直接返回单源结果),其自身必须携带 contract_version。实现方内部若另有存储结构版本,用 schema_version 单独标识,两者不得混用。

变更分级:

变更类型 版本位 说明
新增可选字段 minor 向后兼容。消费方须忽略未知字段,不得因此报错
新增枚举取值 minor 条件性兼容,见下
字段改名、删除、类型变更 major breaking change
字段语义变更(名称不变但含义变) major 比改名更危险,须强制升 major
必填性变更(可选转必填) major —
层级调整(字段在结构中移位) major 见上文关于 2.0 的说明

枚举扩展的强制约束:新增枚举取值只有在消费方遵守“未知取值一律降级为该枚举的安全兜底值”时才是向后兼容的。因此所有消费方实现必须对下列枚举设置默认分支,不得使用穷尽匹配。未遵守此约束的消费方,任何枚举扩展对它都是 breaking change。

**并非所有枚举都适用同一条兼容规则。**判定标准只有一条:

消费方在不理解某个取值含义的前提下,能否仍然做出安全且不误导的处理?

能,则该枚举可降级,新增取值属 minor;不能,则新增取值本身就是 breaking change。据此分为两类。

**第一类:可降级枚举。**必须定义安全兜底值,消费方必须实现默认分支。新增取值为 minor。

枚举 兜底值 说明
query_status UNKNOWN 与 ERROR 严格区分:ERROR 是“查询确实失败了,原因归入其他”;UNKNOWN 是“无法判断这次查询处于什么状态”,典型来源是收到更高版本生产端的未知取值
data_status UNKNOWN —
completeness UNKNOWN 消费方不得把 UNKNOWN 当作 COMPLETE
correlation_status UNKNOWN —
evidence_level UNASSESSED 哨兵状态,不是第六级
hypothesis.status UNVERIFIED 未知取值按“尚未验证”处理,不得按“已验证”处理
truncation_reason UNKNOWN 可降级:completeness = PARTIAL 已承载可行动信息,不理解具体原因也不会误判
truncation_dimension UNKNOWN 同上,QUERY_BUDGET 已说明截断性质
validation.method OTHER 不理解具体方法仍可如实展示,不影响 status 的判读
generated_by UNKNOWN 未知来源按“血缘不明”处理,属保守方向

第二类:结构性枚举。取值决定了其他字段如何解释,因此不理解取值就无法安全处理。新增取值默认视为 breaking change,须升 major;除非该枚举在定义处明确写明“未知值可安全忽略”的策略。

枚举 为什么不可降级
source_type 决定该记录属于哪类数据、走哪条核验路径与展示逻辑
correlations[].type 直接决定 target 的 Schema;不理解 type 就不知道 target 里的字段该如何解释
target.entity_type 决定 entity_id 指向什么
target.resource_type 决定 resource_id 指向什么

因此不建议机械地给所有枚举都加 UNKNOWN:给 correlations[].type 加兜底值毫无意义,消费方拿到未知 type 时连 target 都无法解析,此时正确行为是拒绝该条边并按 breaking 处理,而不是假装能理解。

兜底方向始终取保守一侧:不确定时降级,不得升级。

兼容窗口建议:major 版本发布后,生产端应在约定期限内同时支持新旧两个 major 版本,消费方完成迁移后再下线旧版本。跨 major 版本的历史诊断快照须保留其原始 contract_version,不得按新契约重新解释(参见主报告附录 A.4 的可复查要求)。


2. 查询结果状态契约

对应主报告 6.2 节。四个维度彼此正交,必须分别返回,不得合并为单一枚举。

归属层级(决定第 4 章的结构分层):

维度 归属对象 出现位置
query_status 一次对某个数据源的查询 QueryResult
data_status 一次对某个数据源的查询 QueryResult
completeness 一次对某个数据源的查询 QueryResult
correlation_status 一条关联边(一条证据与某个目标之间的一条关系) Evidence.correlations[]

一次跨源诊断会产生多条 QueryResult、多条 Evidence 和更多条关联边,三者数量互不相等:一次查询可能产出多条证据也可能一条都没有;一条证据通常同时参与多条关联边。

**确定性属于关系,不属于记录。**同一条日志可以精确绑定到某个 Span(EXACT),而该 Span 归属哪个部署仍然只是候选(CANDIDATE)。给整条记录贴一个 correlation_status 无法表达这种情况,详见 2.4 节。

2.1 query_status:这次查询本身成功了吗

取值 含义 使用约束
OK 查询正常完成 —
TIMEOUT 超出该源的超时预算 completeness 置为 PARTIAL;若已获得结果则一并返回,若超时发生在首条结果之前则 data_status = UNKNOWN
UNAVAILABLE 数据源不可达或拒绝服务 不得降级表达为“无记录”
PERMISSION_DENIED 使用方对该源或该范围无权限 必须与 NO_MATCH 严格区分,否则使用方无法判断是系统没有还是自己看不到
ERROR 其他查询失败 须附带来源侧错误标识,便于排查
UNKNOWN 无法判断查询状态 兜底值。与 ERROR 区分:ERROR 表示确定失败,UNKNOWN 表示状态不可判定。消费方不得视为 OK

2.2 data_status:目标数据存在吗

取值 含义 使用约束
FOUND 查到目标记录 —
NO_MATCH 查询成功且范围完整,确实无匹配记录 表示“查到了,没有”;仍不能推出“系统没问题”
EXPIRED 目标已超出保留期 须有保留策略或保留审计作为依据,不得由查不到推断
SAMPLED_OUT 目标在采样阶段被丢弃 仅当来源提供明确采样决策审计证据时才可填写,否则返回 UNKNOWN
NOT_COLLECTED 该字段/信号在该对象上未采集 仅当来源提供采集配置审计证据时才可填写,否则返回 UNKNOWN
UNKNOWN 无法区分上述情况 默认值。不确定时必须落在此项

硬约束:绝大多数数据源不记录“这条我采样丢弃了”“这个字段我没采集”。SAMPLED_OUT 与 NOT_COLLECTED 若无审计证据支撑,就是带确定性外观的猜测。实现方在接入每一个数据源时,须先确认该源是否具备提供这两类证据的能力,并在适配器配置中显式声明;未声明的源一律只能返回 UNKNOWN。

2.3 completeness:拿到的是全部吗

取值 含义
COMPLETE 查询范围内结果完整
PARTIAL 因分页、预算、超时或源侧限制被截断
UNKNOWN 无法判断结果是否完整(兜底值)

消费方不得把 UNKNOWN 当作 COMPLETE:在诊断语境下,“不知道是否完整”必须与“确认完整”分开处理,否则会退化为“没查到异常即无异常”。

PARTIAL 必须附带截断原因。由于一次查询可能同时触发多个限制(例如既超时又触及扫描预算),truncation_reason 定义为数组:

取值 含义
PAGE_LIMIT 分页上限
TIMEOUT 超时预算
SOURCE_LIMIT 源侧自身限制
QUERY_BUDGET 触及第 7 章定义的查询预算
UNKNOWN 已截断但原因不明,或消费方对未知取值的降级结果(1.2 节)

出现 QUERY_BUDGET 时必须同时给出 truncation_dimension,取值为触顶的预算参数名:max_time_range / max_entities / max_sources / max_scan_bytes / max_results / max_recursive_depth / UNKNOWN;多个维度同时触顶时该字段亦为数组。

两处的 UNKNOWN 是 1.2 节兜底规则的合法落点:消费方执行降级后写回的值必须仍然符合本 Schema,否则就会出现“规范允许降级,Schema 不接受降级结果”的自相矛盾。生成端不应主动使用 UNKNOWN,除非确实无法判定截断原因。

这样设计是因为预算参数会随实现演进增减。把每个参数都做成一个 truncation_reason 取值会导致枚举频繁扩张,而 QUERY_BUDGET 加维度名的组合可以扩展而不破坏兼容。

2.4 correlation_status:这条关联关系确定吗

对应主报告 6.2、6.3 节与附录 B.1 的验收口径。

**该状态标注在关联边上,不标注在证据记录上。**一条证据同时参与多条关联,各边的确定性可以不同:

证据 trace-span-S2  →  T7 / S2      (REQUEST_SPAN)      EXACT
证据 trace-span-S2  →  实例 I17      (ENTITY_RELATION)   CANDIDATE

若只给这条证据一个状态,EXACT 和 CANDIDATE 都是错的。因此 Schema 中采用 correlations[] 数组,逐边标注(见 4.3 节)。

边的 source 语义

一条边的 source 恒为其所属的父 Evidence,不在边内显式声明。target 只允许一个明确目标。这条规则必须定死,否则实现者会在两种理解之间分裂:一种认为 source 永远是父 Evidence,另一种认为 source 可以是前一条边的 target(即把 correlations[] 当成链式关系包)。

由此得出一条推论:**边不可传递复合。**若要表达跨多跳的关系(例如“该日志所属实例的部署版本”),必须显式生成新的关联边,且:

复合边的 status 不得高于链路上最弱的一环。链路最弱环节是确定性的上限,而不是充分条件。

具体说:EXACT 加 CANDIDATE 的上限只能是 CANDIDATE;即使上游各边均为 EXACT,仍须确认该关系具备可传递语义、各跳处于一致的事件时间与有效期区间,并由明确规则重新判定后,复合边才可标记为 EXACT。不得仅以“上游边都是 EXACT”为由自动推导出复合边为 EXACT。

type 与 target Schema

type 是结构性枚举(见 1.2 节),它直接决定 target 的字段结构:

type 含义 target 必填字段 典型判定依据
REQUEST_SPAN 请求/执行关联:该记录属于某一次执行 trace_id 必填;span_id 条件必填(关联到整条 Trace 而非具体 Span 时可省略) Trace/Span 绑定或其他确定性执行键
ENTITY_RELATION 实体历史关系:该记录归属哪个逻辑实体 entity_type + entity_id 带有效期的历史关系 + 可信事件时间
RESOURCE_CONTEXT 资源上下文关联:该记录产生于哪个承载资源 resource_type + resource_id 进程身份、容器与主机关系

两个 target 枚举同样是结构性枚举:

枚举 取值 边界
entity_type SERVICE / DEPLOYMENT / INSTANCE 指向逻辑实体
resource_type POD / CONTAINER / HOST / PROCESS 指向承载资源

ENTITY_RELATION 与 RESOURCE_CONTEXT 的分界即在于此:前者回答“属于哪个服务/部署/实例”,后者回答“跑在哪个 Pod/容器/主机/进程上”。二者不重叠,也不可互相替代。

RESOURCE_CONTEXT 对应 OTel Profiles 概念页区分的 resource-context correlation,使 Profile 到进程、容器、Pod、主机等承载资源的关联纳入同一模型,不必另设字段。注意逻辑实例 INSTANCE 属于 entity_type,不得放入 resource_type。

取值 含义 判定要求
EXACT 确定性关联 依据请求上下文或唯一身份键直接命中;不确定时必须降级,不得凑数
CANDIDATE 启发式候选 由时间窗口、实体范围、耗时特征等推出;界面与契约中必须标明为候选
AMBIGUOUS 存在多个候选且无法区分 例如误差窗口内有两个 Pod 候选、新旧身份空间无法判等
UNKNOWN 不具备判定依据 默认值

核心取舍:对诊断系统而言,错误地声称 EXACT 比返回 UNKNOWN 危险得多。宁可不知道,也不能精确地关联错。

不同 type 的误判后果不同,验收时须分别统计(第 11.1 节):REQUEST_SPAN 误判会把不相干的日志或样本塞进本次诊断;ENTITY_RELATION 误判会把证据归到错误的版本或实例上,进而误导版本对照。

2.5 典型组合

字段名使用第 4 章的扁平形式。注意 correlation_status 归属于关联边而非查询记录,此处并列仅为便于对照;实际载荷中它出现在 Evidence.correlations[] 内。

场景 query_status data_status completeness correlation_status
查询成功,范围完整,确实无记录 OK NO_MATCH COMPLETE —
Trace 保留审计确认已过期 OK EXPIRED COMPLETE —
日志源超时,返回部分结果 TIMEOUT UNKNOWN PARTIAL —
误差窗口内两个 Pod 候选 OK FOUND COMPLETE AMBIGUOUS
扫描预算触顶 OK FOUND PARTIAL EXACT
使用方无权限 PERMISSION_DENIED UNKNOWN — —
Exemplar 环形缓冲已覆盖 OK UNKNOWN COMPLETE UNKNOWN

3. 证据等级

对应主报告 4.4 节。与 correlation_status 是两个不同维度:后者描述一条关联边的身份与关系确定性,前者描述整组证据的支撑程度。

取值 含义 上升到下一级所需的额外证据
ENTITY_RELATED 同属一个实体 事件时间 + 历史生命周期与资源关系(该实例当时运行在哪台主机、属于哪个部署)
WINDOW_RELATED 同一时间窗口及相关资源 请求上下文:Trace/Span 绑定,或其他确定性执行键
EXECUTION_RELATED 同一次执行 代码与版本差异分析
MECHANISM_HYPOTHESIS 形成可解释观测的机制假设 对照实验
MECHANISM_VERIFIED 控制条件下复现并验证 —
UNASSESSED 哨兵值,不是第六级:尚无法评估证据等级 兜底值。证据包不含任何证据、或收到未知取值降级时使用

**每一级都不能由前一级自动推导。**输出诊断结论时必须标注当前等级;停在 MECHANISM_HYPOTHESIS 并说明还缺什么,优于直接输出 MECHANISM_VERIFIED。

注意前两级跃迁所需的证据类型不同,容易混淆:从 ENTITY_RELATED 到 WINDOW_RELATED,靠的是时间与历史资源关系;请求上下文属于再下一级的跃迁条件。在尚无请求身份时以“有 Trace 在同一窗口”为由标注 EXECUTION_RELATED,是本模型最常见的误用。

另有一条强制规则:

evidence_level 不得高于该证据包实际携带的证据所能支撑的等级。

也就是说,若 evidence[] 为空,evidence_level 只能是 UNASSESSED。如果窗口级判断来自 K8s 历史关系、实体注册表或其他上下文事实,那么这些事实本身就是证据,必须作为条目进入 evidence[],而不是以“背景信息”的名义支撑一个更高的等级。


4. 证据契约 Evidence Contract

统一的机器可读结构,人机双接口共用(主报告 7.4 节)。三条核心设计:

  1. 分两层:QueryResult 描述“对某个源的一次查询发生了什么”,EvidenceBundle 描述“这次诊断收集到的跨源证据整体”。
  2. 确定性属于关系:关联状态标注在 Evidence.correlations[] 的每条边上,不标注在证据记录上。
  3. 事实与推断分离:evidence 只承载观测到的记录,hypothesis 承载推断且带独立验证状态。

4.1 序列化约定

约定 规则
契约版本 顶层载荷必须带 contract_version;嵌套的 QueryResult 继承外层版本,独立传输时自身必须携带
字段命名 统一使用扁平字段名(query_status、data_status、completeness、correlation_status),与第 2 章一致;不使用 query.status 这类嵌套形式
时间戳 RFC 3339,含时区,如 2026-09-20T10:04:00+08:00。主报告的教学案例可继续显示短时间,实现必须用完整格式
记录标识 统一为 source_type + source_system + source_record_id 三元组(第 5 章),不使用跨源拼接的裸字符串
空值语义 数组字段无内容时返回空数组,不得省略;省略表示“未检查”,空数组表示“已检查且无内容”
未知字段 消费方必须忽略并继续处理
未知枚举值 消费方必须降级为该枚举的兜底值(见 1.2 节),不得升级

4.2 QueryResult:单源查询结果

query_id: q-20260920-100501-log-01     # 指向 9.3 节审计记录中的实际查询条件
source_type: LOG
source_system: es-prod-cluster-a
query_status: OK
data_status: FOUND
completeness: COMPLETE
truncation_reason: []
effective_time_range:                   # 该源实际使用的窗口,可能因时钟偏差宽于 bundle 级 time_range
  start: "2026-09-20T10:03:30+08:00"
  end: "2026-09-20T10:06:30+08:00"
time_quality:
  clock_offset_estimate: "+120ms"
result_count: 3

effective_time_range 与 bundle 级 time_range 并存且可以不同。第 6 章规定“不得在扩大窗口后直接宣称精确关联”,若实际使用的窗口不落到 QueryResult 上,该规则事后无法审计——审计者看不到当时用的是哪个窗口。

4.3 EvidenceBundle:一次诊断的跨源证据包

contract_version: "2.0"

subject:
  service_id: svc-042
  deployment_id: dep-240
  instance_id: I17

time_range:
  start: "2026-09-20T10:04:00+08:00"
  end: "2026-09-20T10:06:00+08:00"

query_results:
  - query_id: q-...-log-01
    source_type: LOG
    source_system: es-prod-cluster-a
    query_status: OK
    data_status: FOUND
    completeness: COMPLETE
  - query_id: q-...-trace-01
    source_type: TRACE
    source_system: apm-new-prod
    query_status: OK
    data_status: FOUND
    completeness: COMPLETE
  - query_id: q-...-profile-01
    source_type: PROFILE
    source_system: pyroscope-prod
    query_status: OK
    data_status: UNKNOWN
    completeness: COMPLETE

evidence:
  - source_type: LOG
    source_system: es-prod-cluster-a
    source_record_id: log-123
    correlations:
      - type: REQUEST_SPAN
        target:
          trace_id: T7
          span_id: S2
        status: EXACT
        rule_version: correlation-v3
      - type: RESOURCE_CONTEXT
        target:
          resource_type: CONTAINER
          resource_id: C17
        status: EXACT
        rule_version: entity-v7
  - source_type: TRACE
    source_system: apm-new-prod
    source_record_id: trace-span-S2
    correlations:
      - type: REQUEST_SPAN
        target:
          trace_id: T7
          span_id: S2
        status: EXACT
        rule_version: correlation-v3
      - type: ENTITY_RELATION
        target:
          entity_type: INSTANCE
          entity_id: I17
        status: CANDIDATE
        rule_version: entity-v7
        time_quality:
          time_uncertainty: "±300ms"

evidence_level: EXECUTION_RELATED

limitations: []

hypothesis:
  statement: "请求执行期间发生规则重新解析"
  status: UNVERIFIED

要点说明:

  • query_results 中出现 PROFILE 且 data_status = UNKNOWN,而 evidence 中没有对应条目——这正是“查了但没拿到”与“拿到了证据”的区分,两者必须能分别表达。
  • 每条边的 source 都是它所属的那条证据:log-123 的两条边分别断言“这条日志属于 T7/S2”和“这条日志产生于容器 C17”;trace-span-S2 的两条边分别断言“它就是 T7/S2”和“它当时归属实例 I17”。没有任何一条边以另一条边的 target 为起点。
  • trace-span-S2 的两条边状态不同:请求身份是 EXACT,实体归属只到 CANDIDATE。这正是 2.4 节要解决的情况。
  • 若要表达“这条日志归属哪个部署”,必须显式建一条 log-123 → DEPLOYMENT dep-240 的边,其状态按最弱环节取 CANDIDATE,不得由前两条边复合推出 EXACT。
  • time_quality 出现在关联边上而非证据记录上,因为时间误差影响的是具体某条关系的判定(第 6 章)。
  • evidence_level 与 hypothesis 属于整个包,描述这组证据整体支撑到了哪一级。

4.4 hypothesis.status 与状态迁移

hypothesis.status 为四值枚举:

取值 含义 允许的 evidence_level
UNVERIFIED 尚未做对照验证 最高 MECHANISM_HYPOTHESIS
VERIFIED 对照验证通过 MECHANISM_VERIFIED
REFUTED 对照验证做了,假设被推翻 不得为 MECHANISM_VERIFIED,应回落至 EXECUTION_RELATED
INCONCLUSIVE 验证做了但结果不确定 保持 MECHANISM_HYPOTHESIS,并在 limitations 中说明缺口

只有 UNVERIFIED 与 VERIFIED 两个值时,对照实验失败后契约只能停在 UNVERIFIED,无法区分“还没验证”和“验证后被否定”——两者对下一步排查的指导完全相反。

**REFUTED 是有诊断价值的结论,不是失败。**它排除了一条机制假设,与 11.2 节“拒答不计为错误”属同一逻辑:REFUTED 不得计入错误结论分子。若不明确这一点,实现方会倾向于把被推翻的假设留在 UNVERIFIED 以免“显得做错了”,这恰好是该枚举要消除的行为。

状态迁移时,hypothesis.status 与 evidence_level 必须同时更新。单独出现 VERIFIED 而证据等级未升,或 REFUTED 而等级仍为 MECHANISM_VERIFIED,均视为契约违例。

validation:验证过程与结论范围

仅有 status 无法满足主报告附录 A.4 的可复查要求——该节要求每份判断保存机制假设、支持与反证、缺口、验证结果及结论范围。若只记录 VERIFIED,系统可以声称已验证,却无法复现为什么已验证。因此 hypothesis 下增加 validation:

evidence:
  # ...前述证据条目...
  - source_type: METRIC              # 验证实验本身也是证据,必须在包内
    source_system: prom-prod
    source_record_id: exp-run-01
    correlations: []

hypothesis:
  statement: "请求执行期间发生规则重新解析"
  status: VERIFIED
  validation:
    method: CONTROLLED_COMPARISON
    conditions: "同一输入、同一流量、同一资源规格;对比 v2.3 / v2.4 / 修复版"
    evidence_refs:
      - source_type: METRIC
        source_system: prom-prod
        source_record_id: exp-run-01
    result_summary: "仅 v2.4 复现,修复版恢复至基线"
    conclusion_scope: "订单服务 v2.4 优惠计算路径;未覆盖其他调用路径与其他服务"

引用闭环是强制的:

validation.evidence_refs 中的每一项,必须引用同一 EvidenceBundle.evidence[] 中存在的记录。

若验证所依据的实验记录不在证据包内,就会出现“status = VERIFIED,但支撑它的实验记录不可访问甚至已过期”的情况,这正好抵消了 validation 要解决的可复查问题。因此验证实验本身必须作为证据条目进入 evidence[](如上例的 exp-run-01),即使它没有任何关联边。

若将来确需引用包外证据,应单独定义 external_evidence_refs 字段,并强制携带快照、内容哈希与保留期约定;不得让 evidence_refs 同时承担包内引用和包外引用两种语义。该字段不在 2.0 范围内。

必填性规则:

hypothesis.status validation
UNVERIFIED 可为空
VERIFIED 必填
REFUTED 必填
INCONCLUSIVE 必填

validation.method 为可降级枚举(1.2 节),兜底值 OTHER:CONTROLLED_COMPARISON / ROLLBACK / FIX_VERIFICATION / LOAD_REPLAY / CONFIG_TOGGLE / OTHER。

只要 validation 存在,conditions 一律必填,不区分 method 取值。原因是兼容性:未来 2.x 生产端若新增 CHAOS_EXPERIMENT,旧消费方会把它降级为 OTHER;若 conditions 仅在 OTHER 时必填,生产端并不知道自己会被降级,自然可能不发送该字段,于是一个声称 minor 兼容的枚举扩展经 fallback 后反而违反旧 Schema。统一必填既消除这个冲突,也让 VERIFIED / REFUTED / INCONCLUSIVE 三种结果都带有可复现的实验条件。

conclusion_scope 是其中最容易被省略、也最容易被误用的字段:它划定结论的适用边界。上例中验证只覆盖了优惠计算路径,不能据此断言该服务其他路径无同类问题。缺少这一字段时,一次局部验证很容易在传播中被当作全局结论。

REFUTED 同样必须填写 validation——被推翻的假设需要记录“用什么方法、在什么条件下推翻的”,否则下一次排查会重复同样的实验。

4.5 异常返回示例

contract_version: "2.0"

query_results:
  - query_id: q-...-log-02
    source_type: LOG
    source_system: es-prod-cluster-a
    query_status: TIMEOUT
    data_status: UNKNOWN
    completeness: PARTIAL
    truncation_reason: [TIMEOUT, QUERY_BUDGET]
    truncation_dimension: [max_scan_bytes]

evidence: []

evidence_level: UNASSESSED

limitations:
  - "日志源超时且触及扫描预算,仅返回部分结果"
  - "时间误差窗口内存在两个 Pod 候选"
  - "Exemplar 留存窗口已过,无法反查指标样本"

hypothesis: null

此例中 evidence[] 为空,因此 evidence_level 只能是 UNASSESSED(第 3 章的等级上限规则)。若要声称已达 WINDOW_RELATED,支撑它的 K8s 历史关系或注册表事实必须作为证据条目出现在 evidence[] 中。

limitations 为空数组与不返回该字段含义不同:前者表示已检查且无限制,后者表示未检查。evidence 同理。

4.6 字段必填性

QueryResult:

字段 必填性 说明
query_id 必填 审计与复查的锚点
source_type / source_system 必填 —
query_status / data_status / completeness 必填 —
truncation_reason 条件必填 completeness = PARTIAL 时必填,否则返回空数组
truncation_dimension 条件必填 truncation_reason 含 QUERY_BUDGET 时必填
effective_time_range 条件必填 与 bundle 级 time_range 不同时必填;相同时可省略
time_quality 可选 源端能提供时钟偏差估计时填写
result_count 可选 —
contract_version 条件必填 独立传输时必填;嵌套于 bundle 时省略

EvidenceBundle:

字段 必填性 说明
contract_version 必填 —
subject / time_range 必填 —
query_results 必填 无查询时返回空数组
evidence 必填 无证据时返回空数组
evidence_level 必填 无证据时为 UNASSESSED
limitations 必填 无限制时返回空数组
hypothesis 可选 未形成假设时为 null

Evidence 条目:

字段 必填性 说明
source_type / source_system / source_record_id 必填 三元组缺一不可
correlations 必填 无关联边时返回空数组(此时该证据只能支撑 ENTITY_RELATED)
correlations[].type / target / status 必填 target 的字段结构由 type 决定,见 2.4 节
correlations[].rule_version 必填 诊断可复现的前提
correlations[].time_quality 条件必填 该边的判定依赖时间时必填(典型为 ENTITY_RELATION)

hypothesis:

字段 必填性 说明
statement / status 必填 hypothesis 非 null 时
validation 条件必填 status 为 VERIFIED / REFUTED / INCONCLUSIVE 时必填
validation.method / result_summary / conclusion_scope 必填 validation 存在时
validation.conditions 必填 不区分 method 取值,见 4.4 节的兼容性说明
validation.evidence_refs 必填 每项必须命中同一 bundle 的 evidence[];无支撑证据时返回空数组,但此时 status 不应为 VERIFIED

4.7 智能体输出的强制字段

诊断智能体基于上述证据包形成结论时,输出必须包含:

conclusion          结论陈述
evidence_refs       引用的证据(source_type + source_system + source_record_id 三元组列表)
evidence_level      当前证据等级(第 3 章)
completeness        数据完整性汇总
counter_evidence    反证(观察到但与结论不符的证据)
missing_evidence    缺失证据及其影响
next_verification   下一步验证动作

evidence_refs 中的每一项必须能在同一证据包的 evidence 数组中找到对应记录;引用不存在的记录,计入主报告附录 B.1 的“智能体错误证据引用率”。

并强制区分四类陈述,不得混用:

类别 说明 反例
事实 直接观测到的数据 —
关联 某条关联边所断言的关系,须带该边的 status 把 CANDIDATE 的实体归属陈述为确定
假设 能解释观测的机制推断 把“同一窗口观察到 CPU 热点”写成“CPU 热点导致请求变慢”
验证结论 经对照实验确认的机制 把未做对照的假设标为已验证

5. 血缘与来源字段

对应主报告附录 A.1。实体关系、别名映射和精确关联均须携带:

记录的全局引用由三元组 source_type + source_system + source_record_id 承担。拆分的原因是:log、trace 这类值描述的是数据类型而非来源系统;企业同时运行两个日志集群时,log + log-123 并不唯一。

字段 说明 取值约束
source_type 数据类型 封闭枚举(结构性,新增即 breaking):METRIC / LOG / TRACE / PROFILE / CHANGE / SERVICE_CATALOG / CMDB / K8S / RELEASE / CONFIG / RUNTIME / REGISTRY
source_system 提供该记录的具体系统实例 开放取值,填企业注册的稳定系统标识(如 es-prod-cluster-a、apm-new-prod);不是封闭枚举,新增系统不构成契约变更
source_record_id 在该系统中的原始记录标识 须可回溯查询;仅在同一 source_system 内保证唯一
observed_at 该事实被观察到的时间 与 valid_from 区分,观察时间可晚于生效时间
valid_from 关系生效时间 必填
valid_to 关系失效时间 未失效为空;不得用当前时间填充
rule_version 产生该关系的规则或映射版本 诊断可复现的前提
confidence 确定性等级 复用 correlation_status 取值
generated_by 生成方式 auto_rule / manual_fix / source_direct / UNKNOWN(血缘不明,亦为 1.2 节降级的合法落点)

**关于变更事件的归类。**主报告 4.2 节把变更事件列为一级诊断维度,其来源涵盖发布、配置、扩缩容、路由流量调整、数据库与中间件变更、基础设施迁移等。这些记录必须有确定归属,否则各适配器会各自发明分类。规则如下,按优先级从上到下:

变更来源 source_type
应用发布、依赖升级(制品变更随发布记录) RELEASE
配置项变更、灰度配置调整 CONFIG
扩缩容、编排控制面内的路由与流量调整 K8S
其余变更记录:数据库与中间件变更单、基础设施迁移、网关或网格平台的独立变更单 CHANGE

即:若变更由发布、配置或编排平台直接产生,用对应的具体类型;其余变更记录统一归入 CHANGE,具体领域由开放取值的 source_system 区分。

这里没有采用"全部映射到已有类型、不设 CHANGE"的方案,原因是数据库变更单、基础设施迁移等确实在现有类型中无自然归属,强行映射到 CMDB 会把"资产登记"与"变更记录"混为一谈,反而制造新的语义争议。由于 source_type 是结构性枚举,此项必须在 2.0 冻结前定下——冻结后再加就是 breaking change。

关于人工修订:旧版本把 manual 放在来源枚举中并不合适——人工修订是生成方式而非数据源系统。正确表达是 source_type = REGISTRY(实体注册表自身)、source_system 填治理入口的系统标识,由 generated_by = manual_fix 承担“人工”语义。两个字段各司其职,不重叠。


6. 时间质量与误差模型

对应主报告附录 C.1。仅靠扩大查询窗口不足以支撑精确关联。

字段 说明
event_time 事件实际发生时间
observed_time 采集端观察到的时间(对应 OTel ObservedTimestamp)
ingest_time 入库时间
clock_offset_estimate 该来源相对基准时钟的偏差估计
time_uncertainty 综合误差边界

判定规则建议:

需要区分两类关联,它们对时间质量的依赖完全不同:

关联类型 回答的问题 对时间的依赖
请求/Span 身份关联 这条日志是不是属于这个 Span 有请求上下文直接绑定时不依赖时间
实体关系关联 这个 Span 当时属于哪个部署、哪个 Pod、哪个版本 始终依赖时间,因为实体关系带有效期
条件 correlation_status 上限
有请求上下文直接绑定(仅限请求/Span 身份关联) 可为 EXACT,不因时钟误差降级
无请求上下文,time_uncertainty 小于目标 Span 时长的约定比例 最高 CANDIDATE
无请求上下文,误差窗口内存在多个候选 AMBIGUOUS
时间源不可信或偏差未知 UNKNOWN

误差边界必须随结果返回,不得在扩大窗口后直接宣称精确关联。

即使请求身份关联已达 EXACT,涉及部署、实例生命周期和历史拓扑的实体关系仍须独立考虑时间质量:请求上下文能证明“这条日志属于 T7/S2”,但不能证明“S2 当时跑在 dep-240 的 I17 上”——后者只能由带有效期的历史关系加上可信的事件时间共同确定。两类关联应分别标注 correlation_status,不得用前者的确定性覆盖后者。


7. 查询预算 Query Budget

对应主报告附录 C.1 与 7.4 节。应作为统一契约而非各适配器内部参数。

参数 说明 智能体额外约束
max_time_range 单次查询的最大时间跨度 自主模式下应显著收紧
max_entities 单次查询涉及的最大实体数 未获对应策略授权时禁止自动横向扩展;获得目的绑定的授权后,仅允许在本预算范围内扩展
max_sources 单次查询涉及的最大数据源数 —
max_scan_bytes 各源扫描量上限 触顶即 PARTIAL,不得静默继续
max_results 返回记录数上限 —
timeout 各源超时预算 —
max_recursive_depth 自动下钻/展开的递归深度 必填,防止一次告警触发跨四平台的大范围扫描

预算触顶必须体现在 completeness 与 truncation_reason 中(QUERY_BUDGET 加 truncation_dimension,见 2.3 节),不得以静默截断的方式返回看似完整的结果。

智能体的横向扩展遵循主报告 9.2 节的原则:默认禁止,按需开通,目的绑定,范围受控。这里的“受控”不等于“绝对禁止”——跨多应用巡检的诊断账号本就可能需要更大的横向范围,关键是该范围必须来自显式授权策略,并落在本章预算之内。


8. 权威源与冲突裁决

对应主报告 7.3 节。治理形态为统一治理入口 + 多权威事实源:注册表负责模型、规则版本、冲突裁决、历史快照与查询输出,不负责生产所有事实。

8.1 按字段划分权威

**不使用“业务归属”这类笼统说法,一律拆到字段。**笼统表述是跨文档矛盾的主要来源。

字段 权威源 说明
service_identity 服务目录 逻辑服务身份
business_service_owner 服务目录 业务服务责任人
asset_owner CMDB 资产责任人
cost_center CMDB 成本中心
physical_location CMDB 机房与网络位置
Pod/容器/节点生命周期与有效期 编排控制面 时序信息,多数 CMDB 不保存
部署批次、版本、灰度范围 发布平台 —
配置项版本与生效时间 配置中心 —
process_identity 运行时 进程身份与启动时间
running_artifact 运行时 实际加载的制品,对“实际运行什么”强于登记信息

8.2 冲突裁决

**冲突不一定意味着数据错误。**它可能来自权威级别差异、数据新鲜度、迟到数据、配置偏差,也可能确实是真实的数据错误。裁决规则只负责给出当前应采信的值,不代表其余来源都无需修复。

需要先区分两类,处理方式完全不同。

**第一类:表面冲突。**看起来矛盾,拆到字段后自然消失。

CMDB:   该实例的资产责任人属于 A 团队      (asset_owner)
运行时: 该进程实际加载 service-A 的构建产物 (running_artifact)

这两条根本没有冲突,只是回答了不同字段。大量所谓的“数据不一致”属于这一类,根因是用了“业务归属”这种笼统说法而非字段名。8.1 节把权威性拆到字段,正是为了消除这类伪冲突。

**第二类:真实冲突。**同一字段,两个来源给出不同值。

service_catalog.service_identity = service-A
k8s.annotation.service_identity  = service-B

这才需要裁决。裁决规则按以下顺序应用:

  1. 按字段确定权威源(8.1 节表)——service_identity 的权威源是服务目录,服务目录胜出;K8s annotation 在此属于登记信息,对该字段不具权威性。
  2. 同权威级别时按发生时间——较新的事实优先,但须检查是否为迟到数据。
  3. 仍无法裁决时置为 AMBIGUOUS,不得任选其一。此项仅适用于两个同等权威级别来源相持不下的情形,权威级别明确时不得以 AMBIGUOUS 回避。
  4. 无论裁决结果如何,保留冲突记录,包含各来源取值、裁决依据与规则版本,供事后复查。

上例中虽然服务目录胜出,但 annotation 与服务目录长期不一致本身就是一个需要修复的配置问题,冲突记录是发现它的唯一途径。

禁止“谁先写谁赢”。


9. 数据新鲜度

实体映射不仅要正确,还要及时。“映射逻辑正确但事实已过时”是一类不易察觉的误诊来源。

各权威源须定义:

字段 说明
freshness_sla 约定的最大同步延迟
max_acceptable_lag 超过即触发告警并在查询结果中提示的阈值
last_updated_at 该源最近一次成功同步时间

超出 max_acceptable_lag 时,基于该源的关联结果应降级(correlation_status 不高于 CANDIDATE),并在 limitations 中说明。


10. 联合分析平台自身的可观测性

对应主报告附录 B.1。平台本身必须可观测,不能只依赖被它查询的四类系统。

指标 说明
查询成功率 按源、按使用方类型分别统计
查询时延 P95 / P99 按查询类型和负载分别统计
实体服务可用性 不可用时下游应按设计降级而非整体失败
映射同步延迟 按权威源分别统计,对应第 9 章
PARTIAL 返回率 持续升高通常意味着预算设置不合理或源侧劣化
AMBIGUOUS 比例 持续升高通常意味着实体模型或时间质量出现问题
错误关联数量 经事后核验发现的 EXACT 误判,应为零容忍项
查询超时率 按源统计
权威源数据新鲜度 对应 last_updated_at
智能体错误证据引用率 引用了不存在或不相关证据的结论占比

11. POC 验收指标清单

拆为两组分别统计。两组不得混合报告,技术质量达标不等于运维价值实现。

11.1 技术质量组

指标 计算方法 讨论起点
实体映射覆盖率 正确且唯一映射对象数 / 应覆盖对象数;另报流量加权 ≥95%,关键对象单列
EXACT 准确率 核验正确的 EXACT 关联边数 / 已核验 EXACT 关联边总数,按 type 分别统计 任一 false positive 为阻断项;须报样本量与统计不确定性
CANDIDATE 质量 Precision、Recall、Top-K 命中率,同样按 type 分别统计 单独统计,不与 EXACT 混合
请求上下文覆盖率 具备可用关联上下文的适用请求日志 / 适用请求日志 ≥95%,不把系统日志混入分母
关联实际命中率 成功取得目标证据的关联尝试 / 全部合法关联尝试 原始与条件命中率须一起报告;Exemplar 留存作为独立变量
Completeness COMPLETE 返回占比 按源统计
查询时延 代表性并发与窗口下的 P95、超时率 P95 ≤5 秒,须限定查询类型与负载
可用性 平台自身可用性与降级表现 与既有告警主路径解耦
采集与平台开销 应用 CPU/RSS/延迟、网络、存储、扫描量、运维工时 必须实测,不得引用宣传值

统计单位必须是关联边而非证据记录,且按 type 分开:REQUEST_SPAN 误判会把不相干的日志或样本塞进本次诊断,ENTITY_RELATION 误判会把证据归到错误的版本或实例上并误导版本对照。两者的后果、排查路径和阻断条件不同,混在一个比率里等于抹掉了 2.4 节建立的区分。

11.2 运维价值组

指标 说明 归因要求
MTTD 故障发现时间 —
MTTI 定位时间中位数与 P90 必须同案例集对照,控制人员熟练度与案例记忆
MTTR 恢复时间 受修复方案影响大,不可单独归因本平台
跨平台跳转次数 单次排障中的平台切换次数 仅减少跳转不构成价值证明
人工查询次数 单次排障中的手工查询次数 —
错误结论率 错误根因结论占比 在已知真值且不向诊断者泄露的案例上评估
无法判断率(abstention rate) 明确拒答占比 不计入“错误根因”分子,但必须单独统计并与有效回答覆盖率同时验收;不得通过扩大拒答比例换取表面准确率
假设推翻率 hypothesis.status = REFUTED 的占比 不计入错误结论分子(4.4 节)。推翻一条假设是有效的排除结论,不是诊断失败
有效回答覆盖率 给出明确结论(无论对错)的案例占比 与无法判断率互补,两者须成对报告

归因约束:定位与恢复时间受人员熟练度、故障类型、当班经验影响很大。若未采用同案例集对照设计,改善不得归因于本平台。


12. 必测反例

实现方须对下列情形逐条执行并记录结果。用例表齐全不构成通过依据,执行记录与回归结果才是。

用例 期望表现
不同租户/环境同名服务 不串联、不泄露
Pod 重建、IP 复用、PID 复用 旧数据仍关联原对象
服务改名、滚动发布、新旧版本并存 服务历史连续,部署与进程正确区分
CMDB 与运行时冲突或迟到 按第 8 章裁决并保留冲突记录
日志乱序、时钟偏差、采集延迟 返回误差边界,不用到达顺序伪造执行顺序
消息重试、批处理、异步跨线程 不混淆尝试,不强拼单父链
Trace 采样但日志保留 有 ID 无 Trace 时返回有依据的状态
Exemplar 存在但 Trace 过期 EXPIRED,不跳到其他 Trace
Exemplar 环形缓冲被覆盖 区分“无 Exemplar”与“有 Exemplar 但目标不可得”
新旧 APM 身份空间无法判等 AMBIGUOUS,不做截断或补零匹配
跨 Canonical Trace Context 切换点 提示关联降级,不把旧身份空间记录当 canonical 命中
使用方无权限 PERMISSION_DENIED,不与无记录合并
数据源无采样审计能力 UNKNOWN,不得推断为 SAMPLED_OUT
同一条证据的两类关联状态不同 correlations[] 中 REQUEST_SPAN 为 EXACT、ENTITY_RELATION 为 CANDIDATE 时可分别表达,界面与智能体输出不得取其一代表整条证据
消费方收到未知枚举值 按 1.2 节兜底表降级(query_status/completeness→UNKNOWN,evidence_level→UNASSESSED),不得报错中断,也不得升级为确定状态
证据包不含任何证据 evidence_level 只能为 UNASSESSED,不得声称已达窗口级或更高
对照实验推翻假设 hypothesis.status = REFUTED,validation 必填,evidence_level 回落至 EXECUTION_RELATED,且不计入错误结论
声称 VERIFIED 但未提供 validation 拒绝该载荷为契约违例,不得接受
validation.evidence_refs 指向包外记录 拒绝该载荷为契约违例;验证实验记录必须作为证据条目进入 evidence[]
validation 存在但缺 conditions 拒绝该载荷为契约违例,不区分 method 取值
消费方降级后写回 truncation_reason / generated_by 写回 UNKNOWN 必须仍通过 Schema 校验
上游各边均为 EXACT 的多跳复合 不得自动判为 EXACT;须确认可传递语义与时间区间一致后由明确规则重新判定
跨两跳的关联需求(日志→实例→部署) 必须显式建边,状态按最弱环节取值;不得由两条边复合推出 EXACT
收到未知的 correlations[].type 或 source_type 按结构性枚举处理:拒绝该条边或该条证据并上报版本不兼容,不得降级为 UNKNOWN 后继续解析 target
两个同等权威来源对同一字段给出不同值 置 AMBIGUOUS 并保留冲突记录;权威级别明确时不得以 AMBIGUOUS 回避
某源实际查询窗口宽于 bundle 级窗口 QueryResult.effective_time_range 如实记录,不得仅上报 bundle 级 time_range
智能体自主模式跨应用查询 无对应授权策略时拒绝或转人工确认;有目的绑定授权时仅在 Query Budget 范围内执行
递归深度触顶 停止下钻并返回 PARTIAL
Profile 有标记无样本、符号不全 显示限制,不输出虚假 Span 级归因
指标重置、单位差异、P99 跨实例聚合 正确处理或拒绝无效比较
Collector 或实体服务不可用 原有监控继续运行,新增能力按设计降级

13. 与主报告的对应关系

本分册章节 主报告出处
第 1.2 节 契约版本 本分册独有,主报告不涉及
第 2 章 状态契约 6.2 节
第 3 章 证据等级 4.4 节、图 6
第 4 章 证据契约 6.2 节、7.4 节、附录 A.4
第 5 章 血缘字段 附录 A.1
第 6 章 时间质量 附录 C.1
第 7 章 查询预算 附录 C.1、7.4 节
第 8 章 权威源与冲突 7.3 节、2.3 节
第 9 章 数据新鲜度 7.3 节
第 10 章 平台自观测 附录 B.1
第 11 章 验收清单 附录 B.1
第 12 章 必测反例 附录 B.2

涉及 Canonical Trace Context 的迁移策略见主报告 6.3 节与图 9,本分册不重复。安全、权限与审计要求见主报告第 9 章。