Evidence Acquisition Policy

根据决策相关证据缺口、风险、获取成本与预算选择是否继续搜索、询问、观察或停止,使信息获取成为受控策略而非模型自由探索。

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

[!info] related notes

Evidence Acquisition Policy

一句话定义

Evidence Acquisition Policy 是在 Agent 已识别证据缺口后,决定是否值得继续取证、从哪里取证、最多投入多少预算,以及何时停止的控制策略。

[!important] 核心区分 Tool capability ≠ Acquisition policy

模型“想搜索”不等于系统“允许搜索”。

为什么 Acquisition 是 Policy 问题,不只是 Tool Calling 技巧

如果 Agent 只有:

search_knowledge
ask_user
measure
lookup_profile

这些只是“能做什么”。

真正的生产问题是:

什么时候值得做?
做哪一个?
最多做几次?
如果失败怎么办?
如果用户不回答怎么办?
如果搜到了不允许使用的来源怎么办?
什么时候应该停止而不是继续烧 token?

这些问题已经超出 Tool API,本质上是在设计一个有限资源下的信息获取控制器

可以类比数据库查询优化:

SQL capability

Query planner

同样:

Tool capability

Acquisition planner/policy

为什么不能只给模型一个搜索工具

searchask_user 或 measurement tool,只说明 Agent 有能力取证;它不等于系统已经规定:

  • 什么 gap 值得取证;
  • 应该搜索知识还是询问用户;
  • 一次失败后能重试几次;
  • 什么来源/版本允许使用;
  • 什么时候收益已经低于成本;
  • critical gap 无法关闭时最终怎么办。

如果这些决定全部交给 LLM,自由 tool calling 很容易演变成:

模型觉得不确定
→ 搜一堆东西
→ 上下文越来越大
→ 模型觉得差不多了
→ 自己宣布 resolved

这不是一个可审计的控制系统。

基本决策链

Accepted EvidenceGap

判断 decision relevance / criticality

选择 acquisition channel
  ├─ knowledge retrieval
  ├─ ask_user
  ├─ measurement / observation
  └─ domain tool

Runtime 执行真实 Tool Action

EvidenceAttempt

Evidence identity + admissibility validation

重新评估 gap

RESOLVED / continue / stop

其中“真实执行”很关键:模型不能靠一句“我已经搜索了”制造 execution fact。

Acquisition Channel 必须匹配 Gap 类型

User-information gap

例如:

“这个用户本人的肱二头肌反射是否减弱?”

合适渠道:

  • ask_user;
  • measurement;
  • observation;
  • 未来真实业务数据。

不合适渠道:

generic medical RAG

因为一般知识只能告诉你“某类患者通常如何”,不能告诉你“这个用户本人实际如何”。

External-knowledge gap

例如:

“C6 神经根受累通常与哪些感觉分布相关?”

这才适合 targeted retrieval。

[!warning] 一条非常重要的 epistemic boundary external knowledge ≠ user fact

Channel Selection 可以被看成一个 Capability Filter

不要一开始就把所有 tools 暴露给模型。

可以先由 gap/policy 决定:

AllowedCapabilities(Gap)

例如:

user_information
→ {ask_user, read_user_profile, measurement}

external_knowledge
→ {search_knowledge, guideline_lookup}

conflict
→ {ask_user, compare_history, human_review}

然后模型只在允许集合里做 semantic choice。

这比:

20 个 tools 全部给模型
prompt 写“请不要乱用”

更接近真正权限系统。

EvidenceAttempt:把“尝试取证”变成可审计事实

一次真正的 acquisition 应产生 typed attempt,而不是只保留 tool log。

典型字段:

EvidenceAttempt
├─ attempt_id
├─ gap_id
├─ strategy / channel
├─ query / request
├─ requested_top_k
├─ returned_evidence_ids
├─ admissibility / outcome
├─ stopping_reason
├─ latency
├─ cost / token / user burden
└─ budget_before / budget_after

这样以后可以明确回答:

  • 为什么搜?
  • 为哪个 gap 搜?
  • 真正返回了什么?
  • 为什么这些结果没有关闭 gap?
  • 为什么停止?

为什么普通 Tool Log 不足以替代 EvidenceAttempt

普通 trace 可能只显示:

search_knowledge(query="C6 thumb numbness")
200 OK

但它没有表达业务语义:

这个 search 属于哪个 Gap?
当时 budget 剩多少?
返回 Evidence 是否 admissible?
是否解决了 Gap?
为什么后面没继续搜?

EvidenceAttempt 把低层 tool execution 提升成:

decision-relevant execution fact

这也是为什么它值得进入 DecisionTrace / durable audit,而不仅是 observability log。

Targeted Acquisition

成熟策略优先寻找最可能改变当前决策的下一条证据,而不是 broad retrieval:

不是:还能搜什么?
而是:哪条新证据最可能关闭当前关键 gap?

这有三个直接收益:

  1. 减少无意义 token 与成本;
  2. 减少上下文污染;
  3. 让每次 acquisition 都能归因到一个明确的 Gap。

例如:

G3 = “C6 是否通常影响拇指感觉?”

比起:

search("颈椎病 神经 症状 治疗 肌力 感觉 预后")

更合理的是围绕 G3 生成狭窄 query。

为什么 Broad Retrieval 会增加“看起来更聪明但更难治理”的风险

Broad query 往往返回很多主题相近但决策价值不同的内容:

定义
原因
治疗
预后
风险
运动建议

模型拿到大量 context 后可能:

  • 从无关段落补出 user fact;
  • 把治疗知识混进 Diagnosis;
  • 因 token 太多忽略真正 critical evidence;
  • 无法追踪哪一条 Evidence 是为哪个 Gap 获取的。

Targeted Retrieval 的价值不只是省 token,更重要的是建立:

Gap → Attempt → Evidence

的可解释关系。

EvidenceBudget:资源上限,不是风险证明

Evidence budget 可以限制:

  • 最大检索次数;
  • 每次最大 top_k;
  • 最大询问轮数;
  • token;
  • latency;
  • monetary cost;
  • user burden;
  • 某类高成本工具调用次数。

但必须记住:

Budget exhausted ≠ evidence sufficient,也 ≠ risk LOW。

预算耗尽只说明:

不能继续按当前方式取证

如果 critical gap 仍然 OPEN,后续应交给 SafetyEnvelopeDecisionAuthority 决定 ABSTAIN / ESCALATE / BLOCK,而不是把未知自动解释成安全。

为什么 Budget 需要由 Runtime 持有

如果只在 prompt 写:

“最多搜索两次”

模型仍可能:

  • 第三次 tool call;
  • 重试时忘记前面已消耗;
  • interrupt/resume 后重新计数;
  • 多个 gap 并行时各自认为还有 2 次。

Runtime-owned budget 可以做到:

before attempt: check
on attempt: decrement atomically
on exhaustion: reject future acquisition
persist usage / stopping reason

这就是:

Prompt asks
Runtime enforces

的区别。

Budget 可以有多维度,而不只是“搜索次数”

一个成熟系统可能同时有:

SearchBudget
TokenBudget
LatencyBudget
MoneyBudget
UserBurdenBudget
RiskBudget

例如:

搜索还可以继续
但用户已经被连续追问 4 次

此时 user burden 可能要求停止当前路径,转为:

degraded / save and continue later / human review

所以 acquisition optimization 是多目标问题,不是简单的 max_searches。

Run Budget 与 Per-Gap Budget

可以同时存在:

Run max_searches = 3

G1 max_searches = 2
G2 max_searches = 1

这样可以防止一个低价值 Gap 把整轮资源吃光。

更进一步可以按 criticality 分配:

critical gap
→ higher priority / reserved budget

non-critical gap
→ stop earlier

但仍然要记住:priority 只控制资源,不能把 budget 用完等价成安全。

Stopping Reason 也是一等事实

常见停止理由:

gap_resolved
budget_exhausted
source_unavailable
marginal_value_too_low
user_fact_unavailable
permission_boundary
unresolvable

停止原因应该进入 EvidenceAttempt / DecisionTrace,因为:

“为什么没继续搜?”

本身就是未来 audit / replay 需要回答的问题。

为什么 Stop 不是 Failure

很多 Agent 会陷入“只要还不确定就继续工具调用”的循环。

实际上受控停止可能是正确决策:

critical user fact 无法获取
→ stop acquisition
→ ABSTAIN

或者:

non-critical external gap
marginal value low
→ stop
→ ALLOW_DEGRADED

生产系统的目标不是“永远找出答案”,而是:

在有限资源与安全边界下,知道什么时候继续、什么时候停止、停止后允许做什么。

Marginal Value:下一次取证值不值得

可以概念化:

Expected Value of Information

Probability that new evidence changes decision
×
Importance of that decision change
-
Acquisition cost/risk

不一定真的计算数学期望值,但这个心智很重要。

例如:

再搜一次可能只是多一个同义解释
→ marginal value low

确认是否存在新的进行性无力
→ 可能直接改变 ESCALATE/AUTO
→ marginal value high

这就是 decision-relevant acquisition。

Acquisition 与 Evidence Admissibility 分开

工具成功返回 Evidence,并不等于这条 Evidence 可以进入 Decision。

例如:

A2 retrieves E8

但 E8 的 source version 不符合当前 configuration 的 evidence policy,则:

retrieved = true
admissible = false
G3 remains unresolved

详见 Agent Evidence Admissibility

这说明 acquisition loop 中至少有两类成功:

mechanical success
→ 工具成功返回结果

business success
→ 返回结果合法且足以改变/关闭当前 Gap

二者不能混为一谈。

Acquisition Failure 也要分类

ToolFailure
→ timeout / 500 / connection error

NoResult
→ tool 正常,但 0 hit

InadmissibleResult
→ 有结果,但 policy 不允许用

InsufficientResult
→ 合法结果,但不足以解决 Gap

PermissionDenied
→ Gap 不允许这个 channel

BudgetDenied
→ 资源已耗尽

这些 failure 对后续策略完全不同。

如果统一压成:

search_failed

就无法做合理 retry、degradation 和 incident analysis。

Retry 与 New Attempt 的关系

网络层 retry:

HTTP timeout
→ retry same tool request

和业务层第二次 acquisition:

A1 结果不足
→ reformulate query
→ A2

语义不同。

建议区分:

transport retry
vs
semantic acquisition attempt

否则 budget 会被混乱计算:一次语义 attempt 可能内部有 infrastructure retry,但不一定应算成两次业务搜索。

LLM、Runtime 与 Policy 的 ownership

一个成熟结构可以这样划分:

LLM
→ propose gap / targeted semantic query
→ judge semantic relevance

Runtime
→ own budget
→ execute tool
→ create EvidenceAttempt
→ record actual evidence IDs
→ enforce no-search-after-exhaustion

Policy
→ authorize channel/source/version
→ decide consequences of unresolved critical gap

因此:

Prompt constraint 只能告诉模型“应该怎么做”;Runtime enforcement 才能保证系统“不能越界做”。

Query Generation:模型可以提出,但 Runtime 要约束形状

对 external knowledge gap,LLM 很适合把自然语言 gap 变成检索 query。

但可以有结构约束:

query non-empty
max length
no user-sensitive leakage
linked gap_id required
top_k bounded
source filters controlled by policy

也就是说:

LLM owns semantics of query
Runtime owns execution envelope

不要让模型通过 query 参数偷偷扩大 source scope 或 top_k budget。

BodySense 例子

G1
kind = external_knowledge
critical = false
→ policy allows search
→ A1 retrieves E31
→ admissible + relevant
→ G1 RESOLVED

G2
kind = user_information
critical = true
→ generic search forbidden
→ measurement unavailable
→ G2 UNRESOLVED
→ stop_reason = required_user_fact_unavailable
→ DecisionAuthority = ABSTAIN

即使 Python Candidate confidence = HIGH,G2 的状态也不会因此消失。

一个完整的 Acquisition Loop 例子

G7
kind = external_knowledge
critical = true
question = “当前干预在症状加重时应该停止吗?”

Attempt A1

query = broad phrase
returned = [E10, E11]
E10 inadmissible
E11 relevant but no stop condition
→ unresolved
budget 2 → 1

Attempt A2

模型根据缺失部分 reformulate:

query = targeted stop-condition query
returned = [E20]
E20 admissible
semantic support = sufficient
→ resolved
budget 1 → 0
stop_reason = gap_resolved

这里每一步都能解释:

为什么继续?
为什么改 query?
为什么 E11 不够?
为什么最终停止?

这就是受控 acquisition,而不是“模型多搜了两次”。

与 Configuration 的关系

Evidence tool surface、budget、source policy、gap schema 都属于 behaviorally significant configuration。

例如:

C9
→ evidence-policy-v2
→ max_search = 2

C12
→ evidence-policy-v3
→ new approved source + different acquisition rule

这种变化可能改变最终 decision,因此应该形成新的 configuration identity,并重新 qualification。

为什么 Tool Schema 变化也可能是 Configuration 变化

例如 v1 tool:

search_evidence(query)

v2 tool:

acquire_evidence(EvidenceGap)

后者强制绑定:

gap identity
source kind
rationale
criticality

这不仅是 API refactor,而是改变 Agent 可执行行为边界,因此是 behavior-significant change。

与 L4 Async/RAG 的关系

Acquisition policy 假设底层 tool 能在合理时间内完成。

如果:

sync psycopg blocks event loop
local embedding blocks event loop

可能出现:

Attempt timeout
→ budget consumed
→ critical Gap unresolved
→ ABSTAIN

表面上像“证据不足”,根因却可能是 runtime resource boundary。

所以 EvidenceAttempt 应记录:

latency
error/stopping reason

这样 Failure Attribution 才能区分:

knowledge unavailable
vs
infrastructure blocked

测试 Acquisition Policy 应覆盖什么

Channel policy

user_information → generic RAG forbidden
external_knowledge → targeted search allowed

Budget

max_search=2
third search rejected by runtime

Stopping

gap resolved → no more search
budget exhausted → no more search

Admissibility

retrieved but inadmissible
→ gap remains unresolved

Retry semantics

infrastructure retry
≠ semantic attempt count

Critical consequence

critical gap unresolved after stop
→ normal AUTO forbidden

Traceability

每个 attempt 必须能关联:

gap_id
query/channel
returned evidence IDs
budget before/after
stop reason

自测题

  1. 为什么 Tool capability 不等于 Acquisition policy?
  2. Gap kind 应怎样限制可用工具集合?
  3. 为什么 Prompt 中写“最多两次”不足以真正 enforce budget?
  4. Budget exhausted 为什么不能解释为 risk LOW?
  5. Tool 200 OK 与 business acquisition success 有什么区别?
  6. Broad retrieval 为什么会增加 context pollution 和 provenance 难题?
  7. transport retry 与 semantic EvidenceAttempt 为什么要区分?
  8. 为什么 stopping reason 是审计事实?
  9. Expected Value of Information 的心智如何帮助决定是否继续搜索?
  10. L4 的 Event Loop blocking 为什么可能最终表现成 EvidenceGap unresolved?

常见误解

  • 检索越多越安全:更多上下文也可能引入噪声、冲突和错误来源。
  • 模型自己最清楚何时停:高风险路径的预算和停止规则应由 runtime/policy 持有。
  • 获取失败后继续 AUTO:是否还能 AUTO 取决于剩余 gap 与 SafetyEnvelope。
  • Budget 用完就代表尽力了,所以可以继续:尽力程度不是安全证明。
  • Tool 返回 200 就算 Evidence 成功:还要做 identity、admissibility 和 semantic usefulness 判断。
  • Prompt 写了“最多搜索两次”就够了:真正的次数上限应该由 runtime 强制执行。
  • 停止取证就是系统失败:受控停止 + abstain/escalate 往往是正确的 production behavior。
  • 所有 retry 都应该消耗一次业务 budget:先区分 infrastructure retry 与 semantic acquisition attempt。
创建于 2026/8/19 更新于 2026/8/23