Files
SuperBizAgent-java/mvp/engineering/harness/CONTEXT.md

17 KiB
Raw Permalink Blame History

Harness Context:统一术语与命名边界

更新日期:2026-07-29 状态:当前实现口径 适用范围:com.superbiz.agent.harness、Chat SSE、Diagnosis Run 持久化与相关工程文档

本文是术语词典,不建议第一次接触 Harness 时顺序阅读。入门请从 README.md 开始,遇到名词歧义时再回到本文查询。

1. 为什么需要这份 Context

当前系统同时存在 Run 状态、发布结果、Tool 状态、证据状态、收集状态、停止原因和 Fallback 原因。它们都使用了 SUCCESS、ERROR、FAILED、READY 等相近词汇,但回答的是不同问题。

如果把这些词排成一条“大状态机”,会产生错误理解,例如:

  • NO_EVIDENCE 被理解为 Tool 调用失败;
  • FALLBACK 被理解为 Run 执行失败;
  • SATURATED 被理解为预算耗尽;
  • READY 被理解为证据足以支持根因;
  • 数据库 status=SUCCESS 被理解为已经找到根因。

本文件是 Harness 工程文档的术语入口。阅读其他文章前,先以这里的定义区分身份、数据、状态和组件责任。代码与现行架构文档仍是最终事实来源;本文件不创建新的运行协议。

2. 一句话定义 Harness

Harness 是包围非确定性模型执行的确定性控制边界:Agent 负责业务推理和 Draft,Harness 负责 Run 身份、生命周期、预算、取消、Tool 门禁、证据验真、停止控制、发布和审计。

Harness 不是:

  • 业务工作流引擎;
  • Planner / Executor / Verifier / Composer 编排图;
  • 框架 ReAct loop 的第二份实现;
  • 判断业务根因的规则引擎;
  • 用于存放所有 Agent 相关代码的泛化名称。

3. 三层范围:不要把 Harness、Core 和 Application 当成同义词

名称 定义 包含 不包含
Chat Application 一次 Chat 请求的应用用例 Session/Run 创建、路由、分支执行、持久化、公开结果 HTTP/SSE 连接本身、业务推理细节
Diagnosis Harness Diagnosis Agent 外部的确定性控制系统 Core、Interceptor、ToolBoundary、Progress、Guard、Release、Audit 根因推理和 ReAct 规划
Harness Core 最小运行控制内核 RunContext、deadline、budget、cancel、lifecycle、retry policy 路由、Tool backend、Guard、持久化、SSE

代码包 com.superbiz.agent.harness 同时包含 Chat Application 和 Diagnosis Harness 的实现,这是代码组织范围,不代表所有类都属于 Harness Core。

DiagnosisHarnessCore 目前也被 System Chat、Knowledge Query 和 Router 复用预算与生命周期能力。类名前缀保留了演进历史,概念上应理解为当前 Chat Run 的 Harness Core。

4. 身份术语

flowchart TB
    S["Chat Session<br/>sessionId,多轮容器"] -->|"1:N"| R1["Run<br/>runId,一次请求"]
    S -->|"1:N"| R2["Run<br/>下一次请求"]

    R1 -->|"1:N"| AS["Agent Step<br/>一次模型步骤"]
    R1 -->|"1:N"| TC["Tool Call / Invocation<br/>framework tool_call_id"]
    R1 -->|"1:N"| TE["Trace Event<br/>sequence_no"]

    TC --> CI["Canonical Invocation<br/>Run 内短期 Tool 真相"]
    AS --> TR["Diagnosis Trace<br/>按 exact Run 聚合"]
    TC --> TR
    TE --> TR

    R1 -.->|"SUCCESS diagnosis only"| PT["PublishedResult<br/>可投影为下一轮 PreviousTurn"]

图中的所有明细都必须绑定 exact runId。Session 只负责组织多轮,不能替代 Run 归属;Trace 是聚合视图,不能反过来成为执行身份。

4.1 Chat Session

一次多轮对话容器,由 sessionId 标识。同一个 Session 可以包含多次 Run。

Session 用于:

  • 组织多轮请求;
  • 查找安全的 PreviousTurn;
  • 查询历史 Run。

Session 不代表一次执行,不拥有 Tool Call 或模型步骤的终态。

4.2 Run

一次独立的 Chat Application 执行,由 runId 标识。每次请求创建新 Run,无论 intent 是 System Chat、Knowledge Query 还是 Diagnosis。

代码和表名中仍大量使用 DiagnosisRun / diagnosis_run,但当前 Chat Application 会为三种 intent 都创建该记录。因此文档中优先使用 Run;只有引用 Java 实体或数据库表时才写 DiagnosisRun。

4.3 Agent Step

Diagnosis ReAct Agent 的一次模型步骤。多个 Agent Step 属于一个 Run,用于记录每轮模型调用的有界元数据和 Token。

Agent Step 不是 Run,也不是 retry attempt。ReAct 的下一轮模型调用是业务循环;retry 是同一技术操作的再次 attempt。

4.4 Tool Call / Tool Invocation

  • Tool Call:模型通过框架产生的调用请求,由 framework tool_call_id 标识。
  • Tool Invocation:该请求进入 ToolBoundary 后的一次实际执行记录。
  • Tool Request Rejection:在 progress、重复或停止门禁处被拒绝,backend 没有执行,不算 Tool Invocation。

Harness 不生成第二套 Tool Call ID。

4.5 Trace

按 exact sessionId + runId 聚合的可回放观察视图,包含 Run、Agent Step、Tool metadata 和统一 Timeline。

Trace 是观察结果,不是新的执行上下文或状态所有者。TraceEventStatus 只描述单个事件,不能替代 RunState 或 ReleaseOutcome。

5. 核心执行术语

5.1 RunContext

一次 Run 的显式执行上下文。结构不可变地携带:

sessionId
runId
deadline
RunCancellation
RunBudget
ModelCallLedger
HarnessRetryPolicies
RunLifecycle
DiagnosisProgressTracker

“结构不可变”表示 record 字段引用不变化;预算、取消、生命周期和进展通过各自线程安全句柄在 Run 内变化。

5.2 Run Lifecycle

Run 的内存执行终态,由 RunLifecycle 所有,状态类型是 RunState。它采用 first-terminal-wins,后到达的成功、失败或取消不能覆盖第一个终态。

5.3 Run Cancellation

请求停止 Run 的协作机制,由 RunCancellationReason 记录第一个原因。取消会阻止后续边界和迟到发布,但不承诺一定能立即物理中断已发送给 Provider 的同步请求。

5.4 Run Budget

单 Run 的资源账本和门禁,包括模型调用、Tool 调用、单 Tool 次数、输入/输出/总 Token 和 Run bytes。

Budget 只回答“还能不能消耗资源”,不回答“继续诊断是否有价值”。后者属于 Information Gain 和 Collection State。

5.5 Retry Attempt

同一个技术操作因允许的技术失败而再次执行。当前 Router 和 SemanticGuard 最多 2 次 attempt,Diagnosis Agent、Tool 和 EvidenceRepair 只有 1 次。

以下不是 retry:

  • ReAct Agent 的下一轮思考;
  • 改用另一个 Tool;
  • NO_EVIDENCE 后继续查询;
  • 用户发起下一次 Run。

6. Agent 与输出术语

6.1 Diagnosis Agent

唯一拥有业务 ReAct Tool loop 的 Agent,负责提出假设、选择 Tool、评价非空结果的信息增益并生成 DiagnosisDraft。

它不负责 Run 生命周期、Tool 授权、证据物理验真、SemanticGuard 或最终发布。

6.2 DiagnosisDraft

Diagnosis Agent 的结构化草稿,是发布链输入,不是已经发布的报告。Draft 可以有结论,也可以 conclusion=null。

Draft 中的 Tool 引用和结论必须经过 Release Pipeline 后才能成为公开内容。

6.3 Agent Result

当前 Tool 代码中的 agent_result 指 Tool-specific Projector 生成、存入 canonical invocation 的标准化有界结果。

它不是:

  • Diagnosis Agent 的最终 Draft;
  • Chat Application 的最终结果;
  • 直接进入模型上下文的完整内容。

更准确的理解是 Canonical Projected Tool Result。当前字段名因协议兼容保留。

6.4 Model Observation

从 canonical agent_result 再次白名单投影后,真正作为 Tool Response 进入 Diagnosis Agent 上下文的内容。

预算、阈值、重复指纹、raw response 和完整 Harness 控制状态不进入 Model Observation。

6.5 PreviousTurn 与 PublishedResult

  • PublishedResult:只有 DIAGNOSIS + ReleaseOutcome.SUCCESS 才能持久化的安全诊断结果。
  • PreviousTurn:从 PublishedResult 生成的有界下一轮上下文。

Fallback、失败、取消、raw evidence 和完整历史不会进入 PreviousTurn。

PublishedResult 不等于当前请求直接返回的 ChatApplicationResult。

7. Tool 与证据术语

7.1 ToolBoundary

所有业务 Tool 的统一执行边界,负责 Run/ID/授权/只读校验、预算、bytes、canonical 状态迁移和 metadata audit。

ToolBoundary 不判断信息增益或业务根因。

7.2 Canonical Invocation

Redis TTL 内的完整 Tool 调用真相,包含 request、raw response、标准化 agent_result、调用状态和证据状态。

它用于当前 Run 的 EvidenceGuard 和 ProgressSnapshot,不是长期审计记录。

7.3 Durable Audit

长期保存的有界元数据:Run/Tool identity、状态、耗时、bytes、模型步骤和 Token。它不保存 Prompt、完整 Tool 参数、raw response 或 canonical record。

7.4 Evidence

Tool 在特定 scope 下返回、经过 Projector 标准化并能由当前 Run canonical record 验真的事实或负向观察。

EVIDENCE_FOUND 只代表存在候选内容,不代表它支持根因。

7.5 Negative Observation

READY + NO_EVIDENCE 形成的限定范围事实,例如“在时间窗 T、服务 S、查询 Q 下没有匹配日志”。

它不能被解释为“故障不存在”或“系统健康”。Draft 中使用 AnalysisKind.NEGATIVE_OBSERVATION 表达这种分析。

7.6 VerifiedEvidenceSnapshot

EvidenceGuard 从 canonical invocation 中投影出的已验真、最小证据集合,供 SemanticGuard 使用。它不包含 raw response。

7.7 ProgressSnapshot

Tool loop 结束后,根据已完成 Tool Call identity 回读 canonical records 生成的有界过程视图,用于受控停止或无结论 Fallback。

VerifiedEvidenceSnapshot 面向“有结论报告的语义审查”;ProgressSnapshot 面向“没有可发布结论时说明已经检查了什么”,两者用途不同。

8. Guard 与发布术语

8.1 EvidenceGuard

确定性引用验真器。检查 Draft 结构、analysis 引用闭包、当前 Run 所有权、READY 状态、EvidenceStatus 和 typed projection 自洽性。

不调用模型,不判断结论是否被证据支持。

8.2 EvidenceRepair

一次性的模型修复步骤,只修结构和引用。修复前后 SemanticDraftView 必须保持用户可见语义一致,之后重新执行 EvidenceGuard。

它不是新的报告作者,也不是 retry Agent。

8.3 SemanticGuard

隔离的单轮语义审查器,只判断 verified evidence 是否支持 Draft,输出 SUPPORTED / UNSUPPORTED。

它使用模型,但无 Tool、无记忆、无 ReAct loop、无报告改写权,因此文档中不要称它为第二个业务 Agent。

8.4 Release Pipeline

从 DiagnosisDraft 或受控停止输入,到 DiagnosisReleaseResult 的安全决策链:EvidenceGuard、可选 Repair/Recheck、SemanticGuard 和 SafeFallback。

8.5 ReleaseOutcome

应用层最终处理结果:

  • SUCCESS:发布安全正常内容;
  • FALLBACK:请求已被安全处理,但没有发布正常诊断结论;
  • FAILED:无法形成安全业务结果;
  • CANCELLED:Run 被取消。

ReleaseOutcome 不等于 RunState。尤其 FALLBACK 不是 RunState。

8.6 SafeFallback 与 FallbackType

SafeFallback 是确定性公开内容;FallbackType 解释为什么没有发布正常诊断结论,例如:

  • EVIDENCE_VALIDATION_FAILED;
  • SEMANTIC_UNSUPPORTED;
  • SEMANTIC_UNAVAILABLE;
  • INSUFFICIENT_EVIDENCE;
  • MISSING_REQUIRED_CONTEXT。

FallbackType 是 ReleaseOutcome.FALLBACK 的原因,不是新的生命周期状态。

9. 状态维度速查

类型 所有者 回答的问题 不能回答的问题
RunState RunLifecycle Run 的内存执行是否终止、如何终止 发布了正常内容还是 Fallback
RunCancellationReason RunCancellation 谁首先请求取消、为什么 最终公开结果是什么
ChatApplicationStatus Application Observer 当前向用户展示哪个处理阶段 Run 是否已经终止
InvocationStatus Canonical Invocation Tool 调用记录是否完成 是否找到候选证据
EvidenceStatus Tool Projector 当前 scope 是否有候选证据 是否支持根因
InformationGain Harness/Diagnosis Agent 结果是否推进当前诊断 Tool 是否技术成功
DiagnosisCollectionState ProgressTracker 是否允许继续调用证据 Tool Run 是否终止
DiagnosisStopReason ProgressTracker 为什么停止继续收集 对外发布什么内容
SemanticVerdict SemanticGuard 已验真证据是否支持 Draft Run 是否成功执行
ReleaseOutcome Application/Release 对外处理结果属于成功、降级、失败还是取消 Tool 或收集过程的内部状态
FallbackType SafeFallbackFactory FALLBACK 的业务/安全原因 整个 Run 的执行终态
TraceEventStatus 单个 Trace Event 某条事件的局部结果 全局生命周期
SSE Session State ChatSseSession 连接能否继续发送事件 Harness Run 的业务结果
flowchart LR
    subgraph Execution["执行控制维度"]
        RS["RunState<br/>RUNNING -> terminal"]
        CS["CollectionState<br/>COLLECTING / SATURATED"]
        SR["StopReason<br/>停止收集原因"]
    end

    subgraph Tool["单次 Tool 维度"]
        IS["InvocationStatus<br/>PROJECTING / READY / ERROR"]
        ES["EvidenceStatus<br/>FOUND / NO_EVIDENCE / ERROR"]
        IG["InformationGain<br/>GAINED / NO_GAIN"]
    end

    subgraph Validation["验证维度"]
        EV["EvidenceGuardResult<br/>valid / violations"]
        SV["SemanticVerdict<br/>SUPPORTED / UNSUPPORTED"]
    end

    subgraph Publication["发布与观察维度"]
        RO["ReleaseOutcome<br/>SUCCESS / FALLBACK / FAILED / CANCELLED"]
        FT["FallbackType<br/>FALLBACK 原因"]
        SSE["SSE Session State<br/>连接发送状态"]
        DB["diagnosis_run.status<br/>持久化通用状态"]
    end

    IS --> ES
    ES --> IG --> CS
    CS --> SR
    ES --> EV --> SV
    SR --> RO
    SV --> RO
    RS --> RO
    RO --> FT
    RO --> SSE
    RO --> DB

箭头表示信息参与后续决策,不表示枚举之间一一转换。例如 READY + EVIDENCE_FOUND 仍可能得到 NO_GAIN,RunState.SUCCESS 也可能对应 ReleaseOutcome.FALLBACK。

完整状态转换和跨层映射见Harness生命周期与状态.md。

10. 命名规则

后续代码和文档遵守以下用词:

  1. 说“Run 成功/失败/取消/超时/预算耗尽”时,明确写 RunState。
  2. 说“发布正常内容/Fallback/失败/取消”时,明确写 ReleaseOutcome。
  3. 不单独写“Tool 成功”,改写为 InvocationStatus=READY,并同时说明 EvidenceStatus。
  4. 不写“找到有效证据”,除非已经说明是候选内容、已验真事实还是足以支持结论。
  5. NO_EVIDENCE 必须附带 scope,不得写成全局否定。
  6. SATURATED 只用于 Collection State;预算耗尽使用 BUDGET_LIMIT_REACHED 或 RunState.BUDGET_EXHAUSTED。
  7. Fallback 只指安全发布降级,不用来泛指异常兜底代码。
  8. Agent 默认指 Diagnosis Agent;SemanticGuard 和 EvidenceRepair 分别称“语义审查器”和“引用修复步骤”。
  9. agent_result 引用字段名时保留原名,概念说明使用“canonical projected Tool result”。
  10. status 单独出现没有意义,必须注明所属类型或存储字段。

11. 已知命名债务

11.1 DiagnosisRun 名称大于实际诊断范围

当前 Chat Application 对三种 intent 都写入 diagnosis_run。文档统一称 Run;是否重命名实体和表属于单独的协议/迁移决策,本次不修改代码。

11.2 SseOutcome 当前未被运行时使用

SseOutcome 枚举存在,但当前 ChatSseEvent.Done 直接携带 ReleaseOutcome,并禁止公开 CANCELLED。因此当前 SSE 真理源是 ReleaseOutcome,不要再基于 SseOutcome 推导协议。

11.3 FallbackType.BUDGET_EXHAUSTED 不是当前诊断发布主路径

枚举值仍存在,但当前 Diagnosis Release 对预算受控停止的行为是:有已验真进展时发布 INSUFFICIENT_EVIDENCE,无安全进展时保持失败。文档不能仅因枚举存在就声称系统会发布 BUDGET_EXHAUSTED Fallback。

11.4 数据库 status=SUCCESS 不等于找到根因

JpaChatRunStore 将 ReleaseOutcome.SUCCESS 和 FALLBACK 都映射为数据库 status=SUCCESS,表示请求被正常处理。是否发布根因必须结合 release_outcome、content_type 和 FallbackType 判断。

11.5 RunState 没有直接作为独立字段持久化

当前持久化主记录保存通用 status 和 release_outcome,Trace 保存阶段事件;内存 RunTermination.state/reason 不是独立数据库字段。排查时不能只靠数据库 status 反推 TIMED_OUT 或 BUDGET_EXHAUSTED 的精确内部终态。

12. 如何使用本文

本文不是必读的第一章,而是遇到名词歧义时使用的词典。第一次接触 Harness,请先读 README.md 建立最小心智模型;需要理解某个状态或概念时,再回到本文对应章节查询。