RAG Grounding / Faithfulness 校验

从 BodySense 早期动作名 substring/alias checker 进化到 production Grounding Eval:先做确定性的 evidence provenance/contract 校验,再判断完整 InterventionClaim 的语义支持关系,最后只在模糊案例中使用 LLM Judge。

#type / concept #status / growing #tech / ai #resource / bodysense #resource / agent

[!info] related notes

RAG Grounding / Faithfulness 校验

一句话定义

RAG Grounding / Faithfulness 校验回答的是:

模型最终提出的 material claim,是否真的被本轮允许使用的 Evidence 支持?

它不是简单判断“模型有没有引用来源”,也不是判断“动作名有没有在知识库出现”。

在 BodySense 里尤其要区分:

retrieval success
≠ citation exists
≠ evidence admissible
≠ claim supported
≠ business action authorized

Grounding 只解决“claim supported by evidence”这一层;最终是否可以 AUTO / DELIVER / ACCEPT / EXECUTE,仍由更上层 Safety / DecisionAuthority / Treatment Acceptance policy 决定。

为什么有 RAG 仍然会 Hallucinate

RAG 只是把外部内容放进模型可见上下文,并没有强迫模型只能复述这些内容。

模型仍可能:

  • 使用参数知识补充不存在的细节;
  • 错读 Evidence;
  • 把一个动作存在,推成任意剂量都合理;
  • 给正确动作配错误 stop condition;
  • 引用同一身体部位但并不支持该 intervention 的文档;
  • 使用另一个 run 的旧 evidence ID;
  • 把 external knowledge 当成 user fact。

因此:

RAG
= 提供候选证据

Grounding
= 验证最终 claim 是否被合法证据支持

二者是不同阶段。

BodySense v1:Substring / Alias Checker 为什么当时有价值

早期 Treatment checker 的思路:

提取 exercise intervention title
→ 在 RAG result title/body/clips 中 substring match
→ 找不到则查 EXERCISE_ALIASES
→ grounded / ungrounded

例如:

“收下巴”
→ alias “颈部后缩”
→ Evidence content contains “颈部后缩”
→ grounded

这个版本很适合 MVP,因为它:

  • deterministic;
  • 实现简单;
  • 很容易测试;
  • 可以拦住“知识库完全没有出现过的动作”;
  • 没有引入第二个 LLM Judge。

所以 v1 不是“错误设计”,而是验证范围很窄的第一阶段 guardrail

v1 真正验证的是“词出现过”,不是“Claim 被支持”

假设 Evidence:

臀桥可以作为基础训练,建议从低负荷开始;
若出现放射痛加重,应停止并重新评估。

模型输出:

臀桥
- 每天 10 组
- 每组 100 次
- 疼痛加重也继续坚持

Substring checker 会看到:

“臀桥” in evidence

然后判 grounded。

但真正会改变用户行动的 material claims 是:

  • 10 组;
  • 100 次;
  • 每天;
  • 疼痛加重仍继续。

这些并没有被支持,最后一条甚至被 Evidence 明确反对。

所以 production grounding 的判断单元必须从:

Exercise Name

升级为:

InterventionClaim

InterventionClaim 应该包含什么

一个 intervention 的 material claim 可以概念化为:

InterventionClaim
├─ kind
├─ title / action identity
├─ intended goal
├─ dosage
│   ├─ repetitions
│   ├─ sets
│   ├─ intensity
│   ├─ duration
│   └─ frequency
├─ progression / regression rule
├─ contraindications
├─ stop conditions
└─ supporting evidence IDs

不是每个 intervention 都必须拥有所有字段,但 evaluator 应优先验证真正会改变现实行动的字段

例如 education 类 intervention 的 material claim 可能更偏:

  • 内容事实;
  • 风险提示;
  • 下一步建议。

而 exercise 类则特别关心 prescription。

Grounding 之前先做 Provenance / Admissibility

在问:

“Evidence 是否支持 claim?”

之前先问:

“这条 Evidence 有没有资格参与这次判断?”

顺序:

retrieved evidence
→ runtime provenance
→ admissibility
→ semantic support
→ grounding verdict

详见 bodysense-targeted-rag-evidence-provenanceagent-evidence-admissibility

Layer 1:Deterministic Provenance / Contract Checks

任何 semantic Judge 之前,先做机器可以确定回答的问题。

Evidence ID 是否真的被本轮观察

claim.supporting_evidence_ids

this run's observed evidence set

不能只查:

数据库里历史上存在 E31

必须确认:

本轮真的 retrieval/observed E31

Evidence 是否属于正确 Run / Snapshot

防止:

  • cross-run contamination;
  • stale cache;
  • wrong source revision;
  • historical replay 偷用 current version。

Source / Version 是否 Admissible

例如:

unpublished draft
withdrawn source
unapproved version
wrong jurisdiction

即使语义支持,也可能无权用于当前决策。

user_fact 来源是否合法

External RAG 不能证明:

“这个用户有/没有某症状”

如果 claim 是 user-specific fact,应验证来源来自:

  • user input;
  • durable BodyState;
  • measurement;
  • approved observation。

Acquisition Policy 是否被绕过

如果 EvidenceBudget 只允许两个 targeted search,模型不能在最终 output 中凭空引用十条从未 acquisition 的 Evidence。

Structured Prescription 是否满足最小 Contract

例如:

  • title 非空;
  • kind 合法;
  • required stop condition 存在;
  • dosage schema 合法。

这些问题不需要 LLM Judge。

[!important] 机器已经确定知道的事实,不要再交给 LLM 猜。

Layer 2:Structured Semantic Support

通过 Layer 1 只表示:

Evidence identity 合法

还要问:

Evidence 内容是否真的支持这个 material claim?

可以先 canonicalize:

Claim
→ normalized action + dosage + goal + stop condition

Evidence
→ normalized excerpt + metadata

再组合:

  • exact structured match;
  • alias/synonym;
  • canonical action identity;
  • semantic similarity;
  • contradiction detector;
  • structured support rules。

为什么 Embedding Similarity 不能直接等于 Support

例子:

Evidence:
“疼痛加重时停止臀桥”

Claim:
“疼痛加重时继续臀桥”

两句话 embedding 可能非常接近,因为:

  • 同一个动作;
  • 同一个症状;
  • 大量相同词。

但逻辑关系是:

contradiction

所以:

semantic similarity
≠ entailment
≠ support

Embedding 更适合:

candidate support signal

而不是最终 truth gate。

Support 最好按字段/子 Claim 分解

不要只有:

grounded = true/false

可以:

Action supported?       yes
Goal supported?         yes
Dose supported?         partial
Frequency supported?    no
Progression supported?  unknown
Stop condition?         contradicted

这样 evaluator 能准确指出:

“这个动作本身有依据,但处方细节没有依据。”

这比一句 ungrounded 更有诊断价值。

Layer 3:Optional LLM Judge,只处理模糊语义

有些支持关系很难靠简单规则:

Evidence:
“隔日进行,每次 2~3 组”

Claim:
“每周 3 次,每次 2 组”

它们可能相容,但需要上下文推理。

这时可以用固定 rubric 的 LLM Judge:

Input
├─ canonicalized claim
├─ only admissible evidence excerpts
└─ fixed support rubric

Output
├─ supported
├─ partial
├─ unsupported
├─ contradicted
└─ uncertain

Judge 的职责应该限定在语义 support

不应该让它重新决定:

  • evidence ID 是否存在;
  • 是否属于本轮;
  • source version 是否 approved;
  • user fact 是否可以来自 RAG;
  • safety override;
  • Treatment 是否最终能执行。

这些属于 deterministic policy / authority。

为什么不能“一把梭”全部交给 Judge

如果只问:

“下面 Treatment 是否有依据?YES/NO”

会失去:

  • stable reason code;
  • deterministic audit;
  • 可重复 regression test;
  • cross-run evidence hard check;
  • evaluator 本身漂移的可见性。

Judge 自己也有:

  • nondeterminism;
  • prompt sensitivity;
  • model revision drift;
  • latency/cost。

所以推荐层次:

Hard deterministic facts
→ structured semantic support
→ Judge only uncertain slice

Verdict 不应该只剩 faithful: bool

更丰富:

{
  "verdict": "degraded",
  "claims": [
    {
      "intervention": "臀桥",
      "support": "partial",
      "evidence_ids": ["E31"],
      "reasons": [
        "action_supported",
        "dose_not_supported_by_cited_evidence"
      ]
    }
  ]
}

至少可以区分:

supported
partial
unsupported
contradicted
uncertain
invalid_provenance

Reason codes:

evidence_id_not_observed
cross_run_evidence
source_not_admissible
action_not_supported
dose_not_supported
frequency_not_supported
progression_not_supported
stop_condition_not_supported
contraindicated_by_evidence
user_fact_wrong_source

这样结果能被:

  • qualification;
  • dashboard;
  • human review;
  • failure analysis;
  • dataset slicing;

直接消费。

Citation 与 Grounding 不能混为一谈

Citation 回答:

“输出指向哪条来源?”

Grounding 回答:

“这条来源的内容是否支持输出的 material claim?”

完全可能:

citation exists = yes
grounding = unsupported

例如引用一篇“腰痛训练总览”,却提出文中完全没有的高剂量 prescription。

所以 UI 显示引用卡片是透明度能力,不是 correctness proof。

Admissibility 与 Grounding 也不同

一篇 Evidence 可能语义上非常支持 claim,但它是:

  • withdrawn;
  • unpublished;
  • wrong source set;
  • historical replay 中版本不匹配。

那么:

semantic support = yes
admissibility = no

它仍不能进入生产决策。

所以顺序必须是:

provenance
→ admissibility
→ support

而不是把所有文档都丢给 Judge 再问“能不能用”。

Grounding 与 Safety 也不同

一个 Treatment 可能 fully grounded,但当前用户状态出现 red flag。

Grounding = supported
Safety = blocked

完全合理。

所以:

Grounding

Safety

DecisionAuthority

更清楚:

Semantic Proposal
→ Evidence admissibility
→ Grounding
→ current safety/freshness/authority policy
→ Authorized Business Result

Grounding 与 Temporal Validity

Proposal 在 T1:

Evidence 支持 ✅

用户在 T2 才接受,BodyState 已变化。

历史 Grounding 仍然可以是真的:

“当时 Evidence 支持这个 proposal”

但:

“现在仍允许执行”

是新的 Acceptance/Temporal Authority 问题。

所以:

grounded at source context

still authorized at current context

这直接连接 treatment-temporal-validity-and-reauthorization

Grounding Eval v2 为什么不能写完就直接替换 Production Gate

Evaluator 自己也是 behavior-significant system。

如果 v2 太严格:

safe Treatment 大量误判 unsupported
→ automation rate 崩

如果太宽松:

危险 dosage 继续通过

因此更稳的上线流程:

build evaluator dataset
→ run v1
→ run v2
→ collect disagreement
→ manually inspect disagreement slices
→ define thresholds
→ qualification-only first
→ decide promotion to production governance separately

这和 Agent Configuration promotion 思想一致:

Evaluator 也需要证据,而不是因为“看起来更智能”就获得 authority。

v1/v2 Disagreement Dataset 为什么重要

如果两版都对 90% case 同意,真正有价值的是剩下 10%:

v1 pass / v2 fail
v1 fail / v2 pass

人工查看这些 slice 可以回答:

  • v1 false positive 在哪里;
  • v1 false negative 在哪里;
  • v2 是否过度保守;
  • semantic matcher/Judge 是否稳定。

比只比较总 pass rate 更有诊断价值。

Required Dataset Slices

1. Exact supported exercise

Evidence 与 action/prescription 一致。

2. Alias / synonym

Evidence 写“颈部后缩”,claim 写“收下巴”。

3. Action supported, dosage unsupported

动作有依据,但组数/频率没有。

4. Contradicted stop condition

Evidence 要求疼痛加重停止,claim 要求继续。

5. Same body part, wrong intervention

都谈肩部,但 Evidence 并没有支持该动作。

6. Multiple evidence, only one supports

明确真正 support 的 evidence identity。

7. No evidence

不得默认相信模型参数知识完成 production grounding。

8. Misleading lexical overlap

大量相同词但逻辑无关/相反。

9. Chinese short-token false positive

单个“臀”不能因为出现在“臀桥/臀肌/臀部”里就算 action match。

10. Progression / stop-condition support

动作正确但 progression/stop condition 不正确。

11. Cross-run evidence

模型引用一个全局存在但本轮未观察的 Evidence。

12. Inadmissible source

语义支持但 source/version 不允许。

中文 Substring 为什么特别危险

中文没有天然空格边界。

例如:

“臀”

会出现在:

臀部
臀肌
臀桥
臀中肌

单字符 substring 几乎没有 discriminative value。

早期 checker 对短 token 做 guard 是合理防御,但无法从根本上完成 semantic grounding。

更成熟:

canonical action identity
+ structured unit type
+ phrase/alias normalization
+ semantic candidate match
+ support/contradiction evaluation

EXERCISE_ALIASES 仍然有价值

v2 不是“删掉所有字符串逻辑”。

Exact/alias match 仍然可以作为:

high-confidence deterministic fast path

合理演进:

v1 reliable local rules
+
provenance
+
structured claims
+
semantic support
+
contradiction
+
reason codes
+
optional Judge

而不是:

all deterministic logic deleted
→ one expensive Judge call

Grounding Result 与 Treatment DecisionTrace 的关系

Grounding 可以成为 Treatment proposal/qualification 的一个 policy fact:

grounding.verdict = supported / partial / ...

但 DecisionTrace 还要结合:

  • Safety;
  • temporal validity;
  • candidate assessment;
  • current BodyState;
  • policy revision。

所以 Grounding 是 decision input,不是完整 DecisionAuthority。

Grounding Failure 如何进入 Failure Attribution

假设 UI 最终没有显示 Treatment。

不要只写:

faithfulness failed

更精确:

Evidence acquisition success ✅
Evidence provenance valid ✅
Action supported ✅
Dose supported ❌
Grounding verdict = partial
Decision policy → degraded/block

或:

DB timeout ❌
→ no actual evidence
→ grounding unavailable

这样根因可以落在:

  • knowledge coverage;
  • retrieval;
  • async infrastructure;
  • claim generation;
  • evaluator。

Production Metrics

可以统计:

grounding_verdict_total{verdict=...}
grounding_reason_total{reason=...}
judge_invocation_total
grounding_disagreement_v1_v2
ungrounded_claim_field_total{field=dose|progression|...}
invalid_provenance_total

这些指标能帮助回答:

  • v2 是否过严;
  • 哪类 Treatment 最常缺依据;
  • Judge 调用率是否太高;
  • 知识库缺的是动作还是 prescription 细节;
  • 某 configuration 是否突然增加 grounding failure。

Testing 不要只断言最终 Bool

除了:

assert result.faithful is False

更重要:

  • 哪个 claim 失败;
  • 哪个 evidence ID 被拒绝;
  • reason code;
  • 哪个 field unsupported;
  • contradiction;
  • Judge 是否只在 uncertain case 被调用;
  • deterministic failure 时 Judge 根本不应执行。

例如:

claim action exists
+ evidence ID invalid

应该在 Layer 1 fail,不能把非法 Evidence 交给 Judge 后得到“语义上支持”。

一个完整例子

Treatment proposal:

Intervention: 颈部后缩
Frequency: 每天 5 次
Stop condition: 麻木加重也继续
Supporting IDs: [E31]

Evidence E31:

颈部后缩可作为低负荷练习;
若出现神经症状加重,应停止并重新评估。

Evaluator:

Layer 1
E31 observed this run ✅
E31 admissible ✅

Layer 2
Action = supported
Frequency = not supported
Stop condition = contradicted

Verdict
= contradicted / rejected
Reason codes
= [frequency_not_supported, stop_condition_contradicted]

这里 substring v1 很可能 pass,但 claim-level v2 能发现真正风险。

自测题

  1. 为什么“臀桥”出现在 Evidence 中,仍不能证明“每天 10 组 × 100 次臀桥” grounded?
  2. 为什么 supporting evidence ID 的合法性不能交给 LLM Judge?
  3. Embedding similarity 为什么不能直接等价 support?
  4. Citation exists 与 Claim grounded 有什么区别?
  5. Admissibility 与 Grounding 有什么区别?
  6. 为什么 fully grounded Treatment 仍可能被 Safety/DecisionAuthority block?
  7. Grounding at T1 为什么不等于 T2 acceptance 仍 authorized?
  8. v2 evaluator 为什么应该先做 disagreement dataset/qualification?
  9. 为什么 v1 exact/alias rules 不应该全部删除?
  10. 为什么测试要断言 reason code/field,而不只 faithful=false

最终心智

Production Grounding 不应该问:

“知识库里有没有出现这个动作名字?”

而应该问:

“本轮允许使用的、版本正确的 Evidence,是否支持这个具体 Intervention 的关键行动声明;哪些字段被支持、哪些只是部分支持、哪些被 Evidence 否定?”

当系统能结构化回答这个问题时,Faithfulness 才从一个字符串防幻觉补丁升级为 production Agent 的证据质量门。

创建于 2026/6/25 更新于 2026/8/23