Agent 的 Historical Replay 与 Counterfactual Replay
区分历史回放、反事实回放与当前重新分析,并以冻结的输入/证据版本和行为不变量而非逐 token 一致作为主要验证目标。
[!info] related notes
- 所属 MOC: agent-evals-moc、agent-runtime-moc
- 相关概念: trace、agent-testing-and-evals、eval-dataset、agent-decision-trace、agent-configuration-and-execution-provenance
- 易混淆概念: Current Re-analysis
- 相关资源: bodysense-diagnosis-agent-architecture
Agent 的 Historical Replay 与 Counterfactual Replay
范围
Agent replay 至少有两个真正的 replay 目标:Historical Replay 与 Counterfactual Replay。另外还要明确区分第三种行为:Current Re-analysis。
如果不先区分目的,很容易把“解释历史”“比较新策略”和“重新分析用户现在状态”混为一谈。
为什么 Replay 不是“重新跑一次”这么简单
真正 replay 的核心不是调用模型,而是控制变量。
每一次 Agent 结果都可以粗略看成:
Result
=
Input World
× Configuration
× Execution Environment/Observations
× Policy
如果你“重跑”时同时改变:
- BodyState;
- Prompt;
- Model;
- Evidence snapshot;
- DecisionPolicy;
然后发现结果不同,你几乎无法知道差异来自哪里。
所以 Replay 的第一原则是:
先明确哪些变量应该冻结,哪些变量是本次实验故意改变的。
Historical Replay
Historical replay 回答:
按当时的输入、配置、策略和可用证据,系统为什么做出了那个决策?
它依赖:
- 当时的 configuration identity;
- pinned business-data revision;
- execution provenance;
- evidence/source versions 或 snapshot;
- policy versions;
- DecisionTrace;
- 必要的 frozen replay input。
最重要的不是“重新问一次模型”,而是尽量恢复当时的 epistemic world:
BodyState R42
Configuration C9
Evidence E17@v3
Policy v1
当时真实 tool observations
Historical Replay 可以有不同深度
Level 1 · Authority Replay
只验证 deterministic shell:
historical DecisionFacts
+ historical Policy v1
→ original Decision?
不需要模型。
用途:
- 验证历史 policy implementation;
- 验证 migration 后 authority 没漂;
- audit。
Level 2 · Runtime Replay
恢复:
frozen input
configuration
tool/evidence observations
让 Agent runtime 重走语义路径。
用途:
- 检查 runtime/compiler/framework migration;
- behavioral contract 回归。
Level 3 · Full External Re-execution
重新调用外部 provider/tools。
它最不稳定,因为外部世界已经可能变化。
所以 production historical replay 往往更依赖冻结 observations,而不是强行实时重做所有外部调用。
Historical Replay 不能偷用今天的新 Evidence
假设历史 D100 当时看到:
E17@v3
今天知识库已经更新为:
E17@v8
如果直接用 v8 重跑,问题已经变成:
“如果当时拥有今天的新知识,会怎样?”
这属于 counterfactual variable,而不是严格 historical replay。
如果历史版本无法获取,正确做法是:
replay fidelity = incomplete
missing artifact = E17@v3 snapshot
而不是静默替换。
Counterfactual Replay
Counterfactual replay 回答:
如果把同一个冻结历史案例交给另一个 configuration / policy,会发生什么?
例如:
same R42 / frozen case
├─ C9 → ABSTAIN
└─ C15 → ALLOW_DEGRADED
这非常适合:
- configuration comparison;
- policy change analysis;
- regression discovery;
- Challenger offline validation;
- production incident 回流 Eval。
关键是明确哪些变量被冻结、哪些变量故意改变。
Counterfactual Replay 最好一次只改一个主要变量
如果想回答:
Prompt v8 是否比 v7 好?
应该尽量保持:
same model
same evidence snapshot
same dataset
same schema/tools/policy
只改 Prompt。
如果同时:
Model A→B
Prompt v7→v8
最终差异无法直接归因给 model 或 prompt。
这就是为什么 L1 学习里会引出 factorial / interaction thinking:
Model × Prompt
可能存在组合 interaction。
Current Re-analysis 不是 Replay
如果用户今天已经是:
BodyState R55
而系统用当前 production configuration 重新做一次 Diagnosis:
R55 × current config
→ new DiagnosisAnalysis
这叫新的业务分析,不应该叫 Historical Replay。
一个很实用的区分:
R42 + original C9
→ historical replay
R42 + candidate C15
→ counterfactual replay
R55 + current production config
→ current re-analysis / new Diagnosis
为什么 Current Re-analysis 必须产生新的业务历史
用户世界已经变化时:
R42 → R55
系统不是在解释旧决策,而是在基于新事实做新决策。
所以应产生:
new DiagnosisAnalysis
new DecisionTrace
new execution provenance
不能“更新旧 Analysis 让它看起来更正确”。
这保护了:
Past knowledge != current knowledge
为什么不能要求逐 Token 一致
LLM 本身具有随机性,provider 与模型实现也可能变化。即使 temperature 很低,也不能把“每个 token 完全相同”作为长期可靠的 replay contract。
更稳健的是验证 Behavioral Contract:
同样的 critical gap
→ 不得越过 hard blocker
同样的 evidence IDs / versions
→ provenance 必须可追溯
同样的 policy facts + policy version
→ authority transition 保持一致
所以:
Replay 的关键不是复刻模型私有文本轨迹,而是恢复可审计世界并验证关键业务不变量。
Replay Comparison 的三类 Drift
Hard Drift
例如:
baseline: critical gap → ABSTAIN
candidate: critical gap → ALLOW_NORMAL
这是 contract-level regression。
Semantic Drift
例如:
candidate ranking 变化
confidence HIGH→MEDIUM
summary 重点变化
需要 semantic evaluator 判断是否可接受。
Presentation Drift
例如同义改写、语序变化。
通常不应该阻断 promotion。
这三层比“全文 diff”更适合 Agent replay。
Deterministic Shell + Stochastic Core
可以把系统理解成:
Deterministic shell
├─ pinned input revisions
├─ immutable configuration identity
├─ policy versions
├─ hard blockers
├─ tool/evidence identity
├─ runtime fact extraction
└─ authority transitions
Stochastic / semantic core
├─ LLM wording
├─ candidate ranking
└─ semantic judgment
Replay 越依赖 deterministic shell,就越可长期验证。
Frozen Input 应该包含什么
“保存 user prompt”通常不够。
一个 production case 的 frozen input 可能包括:
BodyState revision/snapshot
profile
relevant history
candidate assessment state
conversation/context summary
expected configuration ID
allowed tool policy
runtime business context
如果这些字段不是 exact snapshot,未来 replay 可能拿到“同名但已经变化”的 current state。
Evidence Snapshot 是 Replay Fidelity 的关键
如果外部 Evidence 真正影响了历史 Decision,只记录 URL 或当前 source key 往往不够。
至少应尽量有:
evidence_id
source_key
source_version
retrieved_at
relevant snapshot / excerpt
否则未来来源站删除、索引重建或内容更新后,历史世界无法恢复。
详见 agent-configuration-and-execution-provenance 与 agent-evidence-admissibility。
Replay Fidelity 应该是一等结果
不要只有:
replay passed / failed
还应该能表达:
fidelity = exact | degraded | approximate
以及:
missing dimensions
├─ provider revision unavailable
├─ E17 historical snapshot missing
└─ external tool state unavailable
这样 Replay 的结论才有解释边界。
Replay 与 External Side Effects
Counterfactual replay 绝不能轻易重放真实 side effect。
例如 Agent tool:
send_message
create_order
write_record
activate_treatment
Replay 应该:
use recorded observation / fake executor / side-effect sandbox
而不是再次执行现实动作。
这也是 Agent replay 比普通 pure-function replay 更复杂的地方。
Historical Replay 与 Counterfactual Replay 不应该改写历史
假设:
D100
R42 × C9
Decision = ABSTAIN
今天用 C15 counterfactual replay 得到:
ALLOW_DEGRADED
也不能把 D100 改掉。
D100 记录的是:
当时真实 production configuration C9 在当时世界下作出的历史结果。
Counterfactual result 是比较产物,不是对历史的“纠错写回”。
Replay Result 应该有独立 Identity
如果 counterfactual replay 产生新结果,可以保存:
ReplayRun ID
source historical case ID
baseline configuration ID
candidate configuration ID
frozen input fingerprint
comparison result
但不要把它冒充新的 production DiagnosisAnalysis,除非系统明确执行了 current re-analysis。
这保护“实验产物”和“真实业务历史”的边界。
与 Eval 的关系
真实 production failure 可以被冻结成 replayable regression case:
incident
→ capture pinned inputs + provenance + DecisionTrace
→ reviewed regression case
→ baseline vs candidate replay/eval
于是线上异常真正进入持续质量闭环,而不是只留在日志里。
Replay 不是 Qualification 的全部
Historical cases 有真实价值,但可能有分布偏差:
- 只覆盖过去遇到过的 case;
- rare safety slice 样本少;
- historical production policy 本身可能过滤掉某些 case。
所以 qualification 仍需要:
curated holdout
challenge slices
critical safety cases
production replay regressions
一起组成证据。
Paired Comparison 为什么最好使用相同 Case Fingerprint
比较 baseline/challenger 时:
same frozen input fingerprint
same dataset fingerprint
才能减少 case composition 差异。
否则:
baseline 跑了一批简单案例
challenger 跑了另一批困难案例
再比较 pass rate 没有意义。
与 Fault Localization 的关系
Historical Replay 也可以帮助验证故障到底来自:
- semantic reasoning;
- evidence environment;
- policy revision;
- provider/model execution;
- delivery path。
但 replay 前一定要明确 fidelity,否则“复现失败”可能只是因为历史 world 没有真正被冻结。
用 Replay 做逐层故障实验
一个案例线上失败,可以依次做:
1. Historical authority replay
→ policy 是否稳定?
2. Same frozen input + same config + recorded evidence
→ semantic runtime 是否仍违反 contract?
3. Same frozen input + candidate config
→ 新 config 是否修复?
4. Current re-analysis
→ 今天用户状态是否仍存在同类问题?
每一步改变变量不同,因此能更好定位根因。
BodySense Diagnosis 例子
历史:
D100
R42 × C9
G8 critical unresolved
Decision = ABSTAIN
Historical Replay
R42 snapshot
C9
historical evidence snapshot
policy v1
→ expect hard boundary still ABSTAIN
Counterfactual Replay
same R42 snapshot
C15 challenger
same replay dataset
→ ALLOW_DEGRADED
这说明 C15 改变了行为,需要进一步 qualification,不代表应该修改 D100。
Current Re-analysis
R55 current BodyState
production C15
→ D220 new Analysis
这是新的业务事实。
Treatment 中 Replay 的额外难点
Treatment 有 action lifecycle:
proposal
→ acceptance
→ intervention
→ outcome
Counterfactual replay 可以问:
“如果当时用新 config,会提出什么 proposal?”
但不能自动推导:
“用户真实执行以后会得到什么 Outcome”
现实结果不是模型可 replay 的变量。
所以 Treatment counterfactual 必须区分:
proposal counterfactual
vs
real-world causal outcome
Consultation 中 Replay 的额外难点
多轮 Agent 有:
stream events
interrupt
user answer
resume
checkpoint state
冻结 case 时要保存 turn input 和重要 interaction observations。
但 public live stream 的每个 chunk 不一定是 replay 核心;更重要的是 stable semantic/runtime events 和 control state。
测试 Replay 系统应覆盖什么
Historical fidelity
historical evidence missing
→ explicit degraded fidelity
Variable control
counterfactual changes only intended configuration
No side effect
replay cannot trigger real write/action tool
Hard contract comparison
critical blocker behavior classified as hard drift
Historical immutability
counterfactual result never rewrites source analysis
Current re-analysis
new BodyState → new business Analysis identity
自测题
- Historical Replay、Counterfactual Replay、Current Re-analysis 分别回答什么?
- 为什么 Replay 的第一件事是定义冻结变量?
- 为什么 historical replay 不能偷偷使用今天的 Evidence v8?
- Authority Replay 为什么可以完全不调用模型?
- Hard / Semantic / Presentation drift 有什么区别?
- Replay fidelity 为什么应该显式记录?
- 为什么 replay tool side effects 必须 sandbox/fake?
- Counterfactual result 为什么不能修改历史 DiagnosisAnalysis?
- Production incidents 为什么适合转成 replay regression case?
- Treatment replay 为什么不能证明真实 Outcome 的因果结果?
常见误解
- Replay 就是把旧 prompt 再发一次:缺少配置、证据和 policy identity 时无法解释差异。
- 输出文字不同就说明 replay 失败:首先看关键 behavioral invariants 是否变化。
- Historical replay 可以直接证明新配置安全:它解释过去;新配置资格仍需要 counterfactual/offline qualification 与 rollout evidence。
- 用最新知识重跑历史就是更准确的 Historical Replay:那已经改变了历史 epistemic state。
- 今天重新分析最新 BodyState 也叫 replay:那应该产生新的 immutable Analysis。
- Replay 越接近真实越应该重新执行所有 side effects:相反,真实副作用通常必须被隔离。
- Historical replay cases 足够代表未来分布:仍需要 challenge/holdout/critical slices。