BodySense Targeted RAG 与 Evidence Provenance

把 BodySense 的 EvidenceGap、targeted retrieval、normalized Evidence、admissibility、citation 与 provenance 放进同一条取证链,解释为什么外部 RAG 不能补成用户事实,以及 retrieved/admissible/resolved 必须分层。

#type / synthesis #status / growing #tech / ai #tech / architecture #resource / bodysense #resource / agent

[!info] related notes

  • 所属 MOC:
  • 相关概念:
  • 易混淆概念:
  • 相关资源:

BodySense Targeted RAG 与 Evidence Provenance

核心结论

BodySense 更成熟的 RAG 心智不是:

“用户问了问题
→ 先搜几条知识
→ 全塞进 Prompt”

而是:

当前决策出现明确 uncertainty
→ typed EvidenceGap
→ policy 选择 acquisition channel
→ targeted retrieval
→ runtime 记录 EvidenceAttempt
→ normalized Evidence
→ provenance / admissibility
→ gap resolved or unresolved

这把 RAG 从“Prompt 增强技巧”升级成一个有原因、有预算、有 identity、有 provenance、有停止条件的证据获取过程

Broad Preloaded RAG 为什么在决策 Agent 中不够好

传统 RAG:

request
→ search(query)
→ top 5 docs
→ concatenate rag_context
→ LLM

在普通问答里完全可以工作,但 Diagnosis/Treatment 这种 decision system 会遇到几个问题。

1. 不知道为什么搜

结果里有 citation,但无法回答:

“这条 Evidence 是为哪个 decision-relevant uncertainty 获取的?”

2. 不知道不搜是否合理

如果已有信息足够,继续 broad search 只会增加:

  • latency;
  • token;
  • irrelevant context;
  • conflicting facts。

3. User Fact 与 External Knowledge 容易混淆

外部 RAG 能告诉系统:

“某类症状通常与哪些机制相关?”

不能告诉系统:

“这个用户本人是否有该症状?”

4. 无法定义停止原因

只写:

search until model feels enough

不能审计:

  • 为什么继续;
  • 为什么停止;
  • budget 是否越界;
  • gap 是否真的解决。

5. Replay 难解释

如果只保存最终 prompt/citation,未来很难恢复:

当时缺什么
→ 为什么搜
→ 搜了什么
→ 哪些结果可用
→ 为什么最后仍 ABSTAIN

Targeted RAG 就是为这些生产问题增加控制面。

EvidenceGap 是 Retrieval 的上游语义

一个真正可执行的 Gap 至少表达:

EvidenceGap
├─ stable identity
├─ kind / source kind
├─ missing fact/question
├─ rationale
├─ criticality
└─ targeted query(只有 external knowledge 适用)

重点是:

先知道为什么缺,再决定怎么找。

不是先有一个 search tool,再让模型所有不确定性都扔进去。

user_informationexternal_knowledge 必须分开

User Information Gap

“这个用户是否出现进行性肌力下降?”

合适来源:

  • ask_user;
  • measurement;
  • user-owned durable record;
  • observation。

External Knowledge Gap

“进行性肌力下降在当前风险判断里意味着什么?”

合适来源:

  • RAG;
  • guideline;
  • domain knowledge tool。

这两个问题看起来相关,但 epistemic role 完全不同。

为什么 External RAG 绝不能补成 User Fact

知识库:

“C6 神经根受累可能伴随拇指感觉异常。”

用户只说:

“右肩痛。”

错误:

RAG says C6 often has thumb numbness
→ user has thumb numbness

正确:

External Evidence:
thumb numbness would be informative for C6

Current User Fact:
UNKNOWN

Gap:
ask whether this user actually has thumb numbness

这是一个非常重要的 epistemic invariant:

population/general knowledge

individual observed fact

LLM、Runtime、Policy 三种角色

成熟 Targeted RAG 可以分:

LLM
= proposer / semantic reasoner
→ identify a useful Gap
→ formulate a targeted query
→ interpret semantic support

Runtime
= recorder / verifier
→ execute actual retrieval
→ assign attempt identity
→ record returned evidence IDs
→ enforce budget

Policy
= authority
→ which channel/source is allowed
→ admissibility
→ consequence of unresolved critical gap

压缩成一句:

LLM proposes; Runtime records; Policy authorizes.

如果 LLM 同时负责“说自己搜过”“说这条证据能用”“说 gap 已解决”“说可以 AUTO”,就失去了独立控制面。

EvidenceAttempt:为什么 Tool Log 还不够

普通 tool trace:

search_knowledge(query="...")
→ 200 OK

缺少业务信息:

为哪个 Gap?
当时预算多少?
返回哪些 Evidence?
是否 admissible?
是否真正解决 Gap?
为什么之后停止?

所以可以有:

EvidenceAttempt
├─ attempt_id
├─ gap_id
├─ channel
├─ query
├─ requested_top_k
├─ returned_evidence_ids
├─ outcome
├─ stopping_reason
├─ latency
└─ budget before/after

它把一个低层 ToolCall 提升成 decision-relevant execution fact。

EvidenceBudget 只控制资源,不证明知识充分

例如:

max_searches = 2
max_results_per_search = 5

只表示:

最多允许消耗多少 retrieval resource

它不表示:

两次搜索后 Gap 一定 resolved

完全可能:

budget exhausted
+
critical Gap unresolved
→ ABSTAIN / ESCALATE

所以:

budget exhausted
≠ evidence sufficient

Targeted Query 的真正价值

Broad query:

“颈椎 神经 症状 治疗 训练 风险”

很容易返回:

  • definition;
  • exercise;
  • warning;
  • unrelated body region;
  • general education。

Targeted Gap:

G7:
“某 intervention 在神经症状加重时的 stop condition 是什么?”

query 就可以围绕:

specific intervention + stop condition + relevant context

这样:

Gap → Attempt → Evidence

的因果关系更清晰,context pollution 更少。

Retrieved、Admissible、Resolved 三层

Retrieved Evidence

含义:

Retriever 返回了它

Admissible Evidence

含义:

当前 source/version/fact-type/policy 允许用于这次 decision

可能检查:

  • source status;
  • source version;
  • run/source set;
  • gap kind;
  • evidence identity;
  • review/quality status。

Gap Resolved

含义:

可采纳 Evidence 在语义上已经足够消除这条 uncertainty

所以必须直接记住:

retrieved
≠ admissible
≠ sufficient
≠ resolved

Partial Support

Gap:

“这个 intervention 的动作、剂量和 stop condition 是否都有支持?”

Evidence:

action supported ✅
dosage supported ✅
stop condition absent ❌

这条 Evidence 完全可以:

admissible = true

但 Gap 仍:

partial / unresolved

不要为了状态简单,把“有一篇相关文章”自动压成 resolved=true

Conflicting Evidence

可能:

E31 admissible → supports A
E32 admissible → contradicts A

这不是 admissibility failure;相反,系统得到了合法冲突证据

后续可能需要:

  • source hierarchy;
  • recency;
  • evidence quality;
  • conflict policy;
  • keep Gap unresolved;
  • human review。

不要因为系统想要一个确定答案,就静默丢掉不喜欢的 Evidence。

Normalized Evidence Contract

Raw SearchResult 服务 retrieval/UI,可以有:

title
summary
body_markdown
similarity
source title/author
clips

但治理层更需要稳定 Evidence:

Evidence
├─ evidence_id
├─ source_id / source key
├─ source version/snapshot
├─ kind
├─ observed excerpt/content
├─ acquired_for_gap_id
├─ attempt_id
├─ retrieval score/rank(若需要)
└─ policy metadata

Normalized 的价值在于隔离 retriever 实现。

未来即使从:

pgvector
→ hybrid BM25 + vector + reranker

上层仍然消费同一个 Evidence contract。

Runtime-known Facts 不应该让模型重新抄

Tool 实际返回:

E31@v7

模型最终 output 里又写:

used_evidence = [E31]

只能证明:

model claims it used E31

不能替代:

runtime actually observed E31

模型可能:

  • 忘抄;
  • 抄错;
  • hallucinate E99;
  • 引用另一个 run 的 evidence。

所以:

Runtime Evidence Trail

Model Evidence Claim

二者可以比较,但不能合并。

Cross-run Evidence 为什么危险

Run A retrieved E31
Run B did not

Run B 模型/缓存却引用:

supporting_evidence_ids = [E31]

如果 validator 只检查:

database contains E31

就会错误通过。

真正应该检查:

E31 ∈ Run B observed/admissible evidence set ?

如果不是:

invalid provenance

这属于 deterministic check,不需要 LLM Judge。

Citation 与 Provenance

Citation

面向用户/解释:

“这条建议参考了哪里?”

可以展示:

  • source title;
  • timestamp;
  • excerpt;
  • clip。

Provenance

面向 audit/replay/governance:

“这次 run 实际观察了哪个版本的哪条 Evidence?为哪个 Gap?来自哪个 Attempt?”

漂亮 citation UI 不自动意味着 provenance 足够。

Query 也属于 Acquisition Provenance

同一 Evidence 可能被不同 query 召回。

Q1: “梨状肌 坐骨神经 禁忌”
Q2: “小腿放射痛 怎么训练”

它们代表不同 acquisition intent。

保存 query / gap relation 有助于:

  • retriever debugging;
  • query eval;
  • replay;
  • 发现模型搜索方向错误;
  • 评估 context engineering。

这不要求保存所有私有 chain-of-thought,只保存 decision-relevant acquisition fact。

Knowledge Snapshot 与 Evidence Version

知识库持续更新时,同一个 source key 的内容可能变化。

Historical Replay 需要回答:

当时模型看到的是 E31@v3,还是今天的 E31@v8?

所以真正影响 decision 的 Evidence 应有:

  • stable ID;
  • version/snapshot; -必要 excerpt。

如果历史版本找不到,replay 应标记:

fidelity degraded

不能偷偷替换成最新版并称为 exact historical replay。

Targeted RAG 与 Top-k Vector Search 并不冲突

Targeted RAG 没有否定底层:

query embedding
→ pgvector cosine search
→ filters
→ intent boost
→ top_k

变化的是上层 orchestration:

Traditional:
每次都搜,因为“这是 RAG 应用”

Targeted:
只有 explicit decision-relevant external gap 时搜,
并把 search 绑定 gap/budget/provenance

所以它是Evidence acquisition policy 的升级,不一定要求换向量数据库。

RAG Infrastructure Failure 为什么必须进入 Attempt Provenance

假设:

Gap G7 correct
query correct

但:

sync DB blocks loop
→ query timeout

或:

local embedding executor saturated
→ acquisition timeout

最终:

Gap unresolved

如果 Attempt 只记录:

no evidence

会把 infrastructure failure 误认为 knowledge absence。

所以要区分:

success-empty
infrastructure-error
inadmissible-result
insufficient-result
budget-denied
permission-denied

这直接连接 L4 Async 与 L1 Failure Attribution。

Grounding 是 Acquisition 之后的下一道门

即使 targeted retrieval 正确返回 Evidence,还要问:

最终 Diagnosis/Treatment material claim
真的被这些 admissible Evidence 支持吗?

所以:

Evidence acquisition
→ Evidence set
→ Model claim
→ Grounding evaluator

不能简化成:

有 citation
→ faithful

详见 RAG Grounding / Faithfulness 校验

一个完整 BodySense 例子

用户已确认:

久坐后臀部紧张,偶有向小腿后外侧放射感

Treatment 前出现:

G17
kind = external_knowledge
question = 某个神经相关动作的 stop conditions 是什么?
critical = true

Attempt A1

query = targeted stop-condition query
→ E41, E42

Policy:

E41 reviewed source / approved version
→ admissible

E42 unpublished draft
→ inadmissible

Semantic support:

E41 mentions action
but not all stop conditions
→ partial

最终:

retrieved = 2
admissible = 1
resolved = false
criticalGapCount = 1
DecisionAuthority → ABSTAIN / ESCALATE / safer path

整个过程中,没有因为 external article 写了某症状,就偷偷给用户新增 user fact。

测试 Targeted RAG 应覆盖什么

No-gap

信息充分:

no unnecessary retrieval

User-fact Gap

kind=user_information
→ generic RAG forbidden

External Gap

kind=external_knowledge
→ targeted search allowed

Budget

max searches reached
→ later attempt denied
→ gap does not auto-resolve

Provenance

returned Evidence IDs = runtime observed set

Cross-run

model references E31 not observed in this run
→ invalid

Inadmissible

retrieved unapproved source
→ gap remains unresolved

Partial support

some subclaims supported
→ critical gap still open if required subclaim missing

Infrastructure error

DB/Embedding failure:

must not be represented as successful empty retrieval

Historical version

replay 使用 exact source version;缺失则显式 degraded fidelity。

自测题

  1. 为什么 broad preloaded RAG 在 decision Agent 中不够可治理?
  2. EvidenceGap 为什么应该在 search 之前出现?
  3. User-information 与 external-knowledge gap 的 acquisition channel 有什么根本区别?
  4. Tool log 为什么不能替代 EvidenceAttempt?
  5. Budget exhausted 为什么不能把 Gap 自动标 resolved?
  6. retrieved / admissible / resolved 分别是哪一层事实?
  7. Runtime Evidence Trail 与模型 used_evidence 声明有什么区别?
  8. Cross-run Evidence 为什么可以 deterministic 拦截?
  9. Citation 与 Provenance 分别回答什么?
  10. 为什么 knowledge source version 对 Historical Replay 很重要?
  11. Targeted RAG 是否要求放弃 pgvector top-k?为什么?
  12. 为什么 DB timeout 必须和“0 search result”区分?

最终不变量

Gap decides WHY to acquire
Kind decides WHERE to acquire
Budget limits HOW MUCH
Runtime records WHAT happened
Evidence identity tells WHICH evidence
Admissibility decides CAN it be used
Resolution decides DID uncertainty disappear
Citation explains WHERE it came from to users
Provenance makes it replayable/auditable

Targeted RAG 的本质,是把“搜索知识”从一个无上下文 tool call,升级成 production Agent 的受控证据获取过程。

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