Files
SuperBizAgent-java/mvp/engineering/harness/Harness 证据安全链学习笔记-从收敛控制到唯一发布点.md
T

165 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Harness 证据安全链学习笔记:从收敛控制到唯一发布点
**更新日期**:2026-08-06
**主题**:progress → guard → release 三域联动——双通道验证架构 + 状态流转全景 + 关键字段来源与使用
**配套**:[progress 代码学习笔记](Harness%20progress%20代码学习笔记-从拦截器五道门到唯一发布点.md)、[Retry 重试机制](Retry重试机制-显式可计量的attempt循环.md)、[执行控制笔记](Harness执行控制笔记-终态检查与取消广播.md)
## 1. 一句话定位
**证据安全链 = progress(执行期收敛控制)→ guard(验证)→ release(唯一发布点)**:
任何对外发布的内容,必须能追溯到 canonical 账本的已验证事实;任何无法证明的内容,只能以有界、诚实的 SafeFallback 降级形态出现。
## 2. 主链路图
```mermaid
flowchart LR
subgraph 执行期["Agent 执行期(core 控资源 + progress 控收敛)"]
TC["HarnessToolInterceptor<br/>工具调用完成"]
TC -->|"完整记录"| CS["Canonical Store<br/>(唯一真相源, TTL 2h)"]
TC -->|"identity"| TR["Progress Tracker<br/>(toolCallId+toolName+scope)"]
end
subgraph 停止["Agent 结束(所有出口触发投影)"]
TR -->|"回读验真"| PP["DiagnosisProgressProjector"]
PP --> PS["ProgressSnapshot<br/>(observedFacts+limitations+stopReason)"]
end
subgraph 裁决["Release 裁决(唯一发布点)"]
EX["DiagnosisAgentExecution<br/>(draft / stopped)"]
EX --> RC["releaseConclusion<br/>(有结论)"]
RC -->|"tool_call_ids"| EG["EvidenceGuard<br/>机械验引用"]
EG -->|"失败"| ER["EvidenceRepair<br/>只修引用→复查"]
EG -->|"通过"| VES["VerifiedEvidenceSnapshot"]
VES --> SG["SemanticGuard<br/>判支持度"]
SG -->|"SUPPORTED"| SUCCESS["SUCCESS<br/>(唯一出口)"]
SG -->|"UNSUPPORTED/不可用"| FB["SafeFallback 降级"]
EG -->|"仍失败"| FB
EX -->|"stopped / 无结论"| FB
PS -->|"降级原料"| FB
end
CS -.->|"回读"| EG
CS -.->|"回读"| PP
```
## 3. 双通道验证架构(核心)
两条并行的「账本背书」通道,合起来覆盖所有结局:
| | progress 快照 | guard 快照 |
|---|---|---|
| 类 | `DiagnosisProgressSnapshot` | `VerifiedEvidenceSnapshot` |
| 组装时机 | agent 结束那一刻(所有出口) | release 验引用通过后 |
| 原料 | Tracker 的调用 identity | draft 里模型写的 tool_call_ids |
| 回读者 | `DiagnosisProgressProjector` | `EvidenceGuard` |
| 需要 draft | **不需要** | **必须** |
| 服务谁 | 受控停止/无结论/非法 draft 降级 | 有结论 draft 证据链 + SemanticGuard |
| 共同点 | 都从 canonical 回读、三重校验、去重有界、绝不输出 raw | 同左 |
**设计意义**:agent 没给出合法 draft(预算打断、输出烂)时,靠 progress 快照降级;给出合法 draft 时,靠 guard 快照支撑。**任何情况下对外发布都有据可依。**
## 4. 状态流转全景(技术终态 vs 用户终态)
### 4.1 六层状态(从内到外)
| 层 | 类型 | 值 | 回答的问题 |
|---|---|---|---|
| core 生命周期 | `RunState` | RUNNING / SUCCESS / FAILED / CANCELLED / TIMED_OUT / BUDGET_EXHAUSTED | Run 技术上是否还允许继续执行 |
| progress 收集停止 | `DiagnosisStopReason` | INFORMATION_SATURATED / BUDGET_LIMIT_REACHED / PROGRESS_PROTOCOL_VIOLATED | 证据收集为何受控停止 |
| release 发布裁决 | `ReleaseOutcome` | SUCCESS / FALLBACK / FAILED / CANCELLED | 用户侧内容结局是什么 |
| release 降级细分 | `FallbackType` | EVIDENCE_VALIDATION_FAILED / SEMANTIC_UNSUPPORTED / SEMANTIC_UNAVAILABLE / BUDGET_EXHAUSTED / INSUFFICIENT_EVIDENCE / MISSING_REQUIRED_CONTEXT | FALLBACK 为什么降级 |
| SSE 进度 | `ChatApplicationStatus` | ROUTING / DIAGNOSIS_RUNNING / SAFETY_VALIDATING ... | 当前走到哪一阶段(不是结局) |
| 对外失败码 | `ChatFailureCode` | RUN_CANCELLED / INTERNAL_FAILURE / ... | 失败时给客户端的粗粒度原因 |
### 4.2 关键映射规则(代码事实)
```text
RunState.BUDGET_EXHAUSTED + progress.hasObservedFacts()==true
→ ReleaseOutcome.FALLBACK(FallbackType.INSUFFICIENT_EVIDENCE)
RunState.BUDGET_EXHAUSTED + 无 facts
→ FAILED(fail closed:没有安全内容可发布)
RunState.CANCELLED → ReleaseOutcome.CANCELLED + ChatFailureCode.RUN_CANCELLED
内部失败(completeFailure)→ RunState.FAILED + ReleaseOutcome.FAILED + INTERNAL_FAILURE
guard 全过 → RunState.SUCCESS + ReleaseOutcome.SUCCESS(唯一出口)
预算耗尽且子路径已产出 FALLBACK → 不二次 completeSuccess
```
### 4.3 两个正交维度的区分(高频面试点)
- **RunState** 回答「Run 技术上是否还在跑、因何技术终态停下」;
- **ReleaseOutcome** 回答「用户侧内容形态:正常报告 / 安全降级 / 失败 / 取消」;
- 常见组合:`RunState=BUDGET_EXHAUSTED` 且有安全进展 → `ReleaseOutcome=FALLBACK`;无进展 → `FAILED`。
### 4.4 终态异常透传
`DiagnosisReleaseUseCase.propagateTerminal`:`RunAbortedException` / `BudgetExceededException` / `RetryFailure.CANCELLED|BUDGET_EXHAUSTED` **原样上抛**,不吞、不伪装成业务 FALLBACK——取消和预算耗尽是 Run 的技术终态事实,用户侧必须知道「被取消了」而不是「诊断结论是不足」。
## 5. 关键字段的来源与使用
### 5.1 CanonicalToolInvocation(唯一真相源,执行时落库)
| 字段 | 来源 | 使用 |
|---|---|---|
| tool_call_id + run_id | ToolBoundary 执行时生成 | key = runId + toolCallId(两个投影器都按它回读) |
| request / raw_response | 工具请求与原始返回 | 审计/验真,不外发 |
| agent_result | Projector 投影后的有界结果 | Agent 可见的唯一形态;EvidenceGuard 重读它 |
| status | PROJECTING → READY / ERROR(单向迁移) | isReferencableBy 要求 READY |
| evidence_status | FOUND / NO_EVIDENCE / ERROR | kind.accepts() 匹配、投影一致性校验 |
| error_code | 仅 ERROR 携带 | 稳定错误码 |
| started_at / completed_at | 生命周期时间戳 | TTL / 审计 |
### 5.2 DiagnosisProgressSnapshot(progress 快照,agent 结束时组装)
| 字段 | 来源 | 使用 |
|---|---|---|
| verifiedSources | Projector 回读 canonical,去重 | 降级时展示「查过哪些来源」 |
| observedFacts | 同上(≤12 条,摘要 320 字,空查询也算) | 「查了查到什么」;`hasObservedFacts()` 安全阀 |
| limitations | 无法验真/截断的诚实说明 | 降级时展示限制 |
| stopReason | Tracker 状态 | release 检查白名单后决定降级 |
### 5.3 VerifiedEvidenceSnapshot(guard 快照,验真通过后组装)
| 字段 | 来源 | 使用 |
|---|---|---|
| analyses[] | EvidenceGuard 重读 canonical agent_result 重建 | SemanticGuard.review 输入 |
| verifiedSources() | 方法去重(sourceType+source+scope) | SUCCESS 的 published_result.source_documents、FALLBACK 的来源 |
### 5.4 SafeFallback(降级载荷,release 降级出口构造)
| 字段 | 来源 | 使用 |
|---|---|---|
| type | SafeFallbackFactory 按场景 | 用户/审计区分降级原因 |
| conclusion | 恒 null | 降级绝不发布根因结论 |
| verified_sources / observed_facts | progress 或 guard 快照投影 | 保留已验证事实供用户继续排查 |
| limitations / next_steps | 工厂按场景拼装 | 诚实说明 + 下一步 |
| failure_stage | DIAGNOSIS_INPUT / DIAGNOSIS_COLLECTION / EVIDENCE_VALIDATION / SEMANTIC_VALIDATION | 定位失败阶段 |
| validation_issues | EvidenceViolation 映射 | EVIDENCE_VALIDATION_FAILED 时的违规明细 |
## 6. 设计要点(贯穿全链的规律)
1. **fail closed 贯穿每一层**:guard 验引用默认拒绝、读投影严格反序列化、release 无 facts 抛异常、SafeFallback 无事实拒绝构造——「不确定 → 默认拒绝,没查到永不伪装成结果」。
2. **负向证据被完整建模**:progress 空查询投影成事实、NEGATIVE_OBSERVATION 配 NO_EVIDENCE、降级诚实声明「查到了但不够」。
3. **canonical 唯一真相源**:链上不存在第二份工具真相;两个投影器共用同一套三重校验。
4. **全链路可审计回放**:EVIDENCE_GUARD_INITIAL/RECHECK、SEMANTIC_ATTEMPT/DECISION、EVIDENCE_REPAIR_ATTEMPT、RELEASE_DECISION 全落 trace。
5. **语义不变性**:EvidenceRepair 只修引用不修结论(prompt 锁死 + hasSameUserVisibleSemantics 校验)。
6. **命名债务**:`FallbackType.BUDGET_EXHAUSTED` 枚举保留,但预算停实际发布 `INSUFFICIENT_EVIDENCE`(注释自认)。
7. **重复验证**:同一 tool_call_id 被多条 analysis 引用会重复验 N 次(引用级独立校验的代价,账本查询便宜可接受)。
## 7. 面试话术(30 秒)
> "Harness 的证据安全链是 progress → guard → release 三段联动。**执行期**:progress 管信息增益收敛(预算归 core),工具调用实时落 canonical 账本、Tracker 只记 identity;**验证期**:agent 结束后 release 编排——有结论的 draft 先进 EvidenceGuard 机械验引用(每个 tool_call_id 从账本回读、READY 且 kind 匹配,失败则 EvidenceRepair 只修引用再验),通过后 SemanticGuard 判结论是否被证据支持;**发布期**:SUPPORTED 是唯一 SUCCESS 出口,其余全部经 SafeFallbackFactory 构造有界诚实的降级。关键设计是**双通道**:没有合法 draft 时靠 progress 快照(observedFacts)降级,有 draft 时靠 guard 快照支撑——任何情况对外发布都有据可依;以及**状态正交**:RunState 回答技术终态(预算耗尽/取消),ReleaseOutcome 回答用户结局(降级/失败),取消和预算耗尽经 propagateTerminal 原样上抛,绝不伪装成业务降级。"
## 8. 代码位置索引
| 组件 | 文件 |
|---|---|
| EvidenceGuard / EvidenceViolationCode | `src/main/java/com/superbiz/agent/harness/guard/evidence/` |
| SemanticGuard / GuardModelCall | `src/main/java/com/superbiz/agent/harness/guard/semantic/` |
| DiagnosisReleaseUseCase / EvidenceRepair / SafeFallbackFactory | `src/main/java/com/superbiz/agent/harness/release/` |
| DiagnosisProgressProjector / Tracker / Snapshot | `src/main/java/com/superbiz/agent/harness/progress/` |
| CanonicalToolInvocation / Store | `src/main/java/com/superbiz/agent/harness/tool/store/` |
| RunState | `src/main/java/com/superbiz/agent/harness/core/RunState.java` |
| DiagnosisStopReason | `src/main/java/com/superbiz/agent/harness/progress/DiagnosisStopReason.java` |
| ReleaseOutcome / FallbackType / SafeFallback | `src/main/java/com/superbiz/agent/harness/contract/` |
| ChatApplicationStatus / ChatFailureCode | `src/main/java/com/superbiz/agent/harness/application/` |