Files
SuperBizAgent-java/mvp/issues/active/ISS-011-chat-diagnosis-stategraph-orchestration.md
T

771 lines
27 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.
# ISS-011 Chat 诊断 StateGraph 编排改造
**状态**:待实现
**严重程度**:高
**发现时间**:2026-07-16
**来源**:OnCall / Agent 编排模拟面试、当前 Chat 复杂诊断调用链复核
**预计实施周期**:2–3 个工作日
---
## 1. 背景
当前复杂 Chat 诊断在 `ChatService.executeChatComplex(...)` 中采用两层编排:
```text
SequentialAgent
-> Planner
-> Executor
-> Verifier
ChatService 外层循环
-> 解析 Verifier PASS / LOW_CONFID / REJECT
-> 决定 Composer、补证据或安全降级
```
这种实现已经具备 Planner、Executor、Gatekeeper、Verifier、Composer 的职责拆分,但流程控制分散在:
- `SequentialAgent` 固定顺序。
- `VerifierInputHook` 内的 Gatekeeper。
- `ChatService` 外层最多两轮循环。
- Composer 和固定降级逻辑。
随着 no-evidence、工具能力阻断、Executor 非法输出、Gatekeeper REJECT、Verifier LOW_CONFID 等状态增加,当前高层 Flow 抽象已经无法清晰表达阶段短路和定向重试。
---
## 2. 当前问题
### 2.1 Executor 语义失败后仍可能继续 Pipeline
如果 Executor 抛出异常,当前外层 `catch` 可以终止 Run;但如果 Executor 正常返回一段错误文本、非法结构或工具阻断结果,`SequentialAgent` 仍会继续调用 Verifier。
这会造成:
- Verifier 消费无效输入。
- 增加无意义模型调用和 Token。
- Trace 中难以区分执行失败与证据不足。
- 最终降级发生得过晚。
### 2.2 不能按失败阶段精确重试
当前 LOW_CONFID 重试会重新运行:
```text
Planner -> Executor -> Verifier
```
但真实需求可能是:
| 失败位置 | 期望恢复位置 |
|---|---|
| Planner 输出非法 | 重试 Planner |
| Executor 输出结构非法 | 保留计划,只重试 Executor |
| Gatekeeper 引用验真失败 | 直接进入固定安全降级 |
| Verifier LOW_CONFID | 将 missing evidence 返回 Planner 进行有限补证据 |
| 工具权限或能力阻断 | 不重试,直接降级 |
当前 `SequentialAgent + 外层 round` 无法自然表达这些回边。
### 2.3 Gatekeeper 藏在 Verifier Hook 中
当前链路是:
```text
Executor
-> VerifierInputHook
-> ExecutorGatekeeperService
-> Verifier
```
Hook 适合加工和拦截 Verifier 输入,但不适合根据 Gatekeeper 结果跳回 Executor。Gatekeeper 作为诊断质量门禁,应该成为显式编排节点。
### 2.4 编排逻辑已经形成隐式状态机
`ChatService` 当前同时负责:
- 构建 Agent。
- 执行 SequentialAgent。
- 控制 LOW_CONFID 轮次。
- 构造 retry context。
- 调用 Composer。
- 固定模板降级。
- 持久化 Run、self_evaluation 和汇总指标。
继续增加 `if/else` 会进一步扩大 `ChatService` 职责,降低流程可读性和可测试性。
---
## 3. 改造目标
使用 Spring AI Alibaba `StateGraph` 接管跨 Agent 的状态转换,现有 ReactAgent、Prompt、工具、证据协议和持久化能力继续复用。
目标职责:
```text
StateGraph
-> 控制顺序、条件边、重试、终止和降级
ReactAgent
-> 完成 Planner、Executor、Verifier、Composer 节点内部语义任务
Java Node
-> 完成 Gatekeeper、重试判断、固定降级等确定性任务
```
本次不使用 SupervisorAgent 替代固定诊断 Pipeline。SupervisorAgent 留给未来多个专科 SubAgent 之间的动态路由。
---
## 4. 目标流程
```mermaid
flowchart TD
Start["START"] --> Planner["Planner"]
Planner -- "成功" --> Executor["Executor"]
Planner -- "失败" --> Fallback["Fallback"]
Executor -- "结构有效" --> Gatekeeper["Gatekeeper"]
Executor -- "失败或阻断" --> Fallback
Gatekeeper -- "PASS" --> Verifier["Verifier"]
Gatekeeper -- "LOW_CONFID 且存在已验真 binding" --> VerifiedInput["Build Verified Verifier Input"]
Gatekeeper -- "LOW_CONFID 且零条已验真 binding" --> Fallback
Gatekeeper -- "REJECT" --> Fallback
VerifiedInput --> Verifier
Verifier -- "PASS" --> Composer["Composer"]
Verifier -- "REJECT" --> Composer
Verifier -- "LOW_CONFID 且有预算" --> EvidenceRetry["Prepare Evidence Retry"]
Verifier -- "LOW_CONFID 且无预算" --> Composer
Verifier -- "执行失败" --> Fallback
EvidenceRetry --> Planner
Composer --> End["END"]
Fallback --> End
```
### 4.1 本期只保留 Verifier LOW_CONFID 补证据
Gatekeeper REJECT 本期不重试,直接进入 Fallback。
Verifier LOW_CONFID 保留当前有限补证据能力:
```text
目标:补充缺失证据
返回:Planner
默认上限:1 次
```
只有同时满足以下条件时才允许补证据:
- Verifier 提供了可执行的 missing evidence。
- LOW_CONFID 不是由 Gatekeeper verdict ceiling 导致。
- 所需工具存在且当前 Agent 有权限。
- 仍有 Run 级预算。
- 本 Run 尚未执行过补证据轮次。
Prepare Evidence Retry Node 由代码实现,负责把已确认事实、证据缺口、已调用工具、已执行 Query、当前 Skill 和剩余预算整理为受限 retry context,然后返回 Planner。
Planner 第二轮使用 `EVIDENCE_GAP_ONLY` 模式,只生成增量补证据计划,不允许重新开始完整诊断、扩大服务范围或重复已经成功执行的查询。
---
## 5. Gatekeeper REJECT 策略
**决策状态**:已确认,2026-07-16。
本期不增加 EvidenceRepairNode,也不让 Gatekeeper REJECT 返回 Executor 重试。任何 Gatekeeper REJECT 都直接进入固定安全降级。
原因:
- 第一版先验证显式 Graph 编排和阶段短路,不同时引入新的模型节点。
- 证据引用错误不一定可以安全修复,自动重新绑定可能制造第二次幻觉。
- 当前最重要的是保证不可信 Executor 输出不能进入 Verifier,而不是提高 REJECT 的自动恢复率。
- 直接 Fallback 的状态语义简单,便于先建立稳定的路由和测试基线。
处理流程:
```text
Executor
-> Gatekeeper
-> PASS / LOW_CONFID:进入 Verifier
-> REJECT:直接 Fallback
```
Fallback 最终表达只保留:
最终表达只保留:
- 已确认且能够独立验证的事实。
- 无法验证的证据引用问题。
- 当前诊断限制。
- 建议人工检查的下一步。
---
### 5.1 Executor INVALID_OUTPUT 策略
**决策状态**:已确认,2026-07-16。
`INVALID_OUTPUT` 定义为 Executor Agent 调用已经返回,但无法解析为最小 `executor_evidence_v2` 结构。它对应当前解析状态中的 `missing` 或 `malformed`,包括:
- 输出为空。
- 输出不是 JSON。
- JSON 被截断或语法非法。
- JSON 根节点不是对象。
- `claims` 不是数组。
以下情况不属于 `INVALID_OUTPUT`:
- 合法的空 claims 和 missing info。
- 合法 no-evidence。
- 结构可解析但 evidence binding 错误,此类进入 Gatekeeper。
- 引用真实但证据无法支持 claim,此类进入 Verifier。
本期处理方式:
```text
Executor INVALID_OUTPUT
-> 不重试 Executor
-> 不调用 Gatekeeper
-> 不调用 Verifier
-> 不调用模型 Composer
-> 固定安全 Fallback
```
原因:
- 当前没有可信结构化结果可供后续门禁消费。
- 重试有工具权限的 Executor 可能重复调用工具并产生第二套证据。
- 本期优先建立清晰、可验证的控制流,不同时引入格式修复模式。
Trace 至少记录:
- `executor_status = INVALID_OUTPUT`。
- missing / malformed 及解析错误摘要。
- 当前 Run 已发生的工具调用数量和成功情况。
- 跳转 Fallback 的原因。
- Gatekeeper、Verifier 未执行的原因。
Executor 原始输出只允许保留在受控审计中,不得直接作为用户答案。
---
### 5.2 Gatekeeper LOW_CONFID 策略
**决策状态**:已确认,2026-07-16。
Gatekeeper LOW_CONFID 表示 Executor 输出存在非致命结构或引用缺口,但不代表所有 evidence binding 都不可信。本期按已验真 binding 数量处理:
```text
Gatekeeper LOW_CONFID
-> 至少一条 checked binding 为 pass
-> 代码过滤失败 binding
-> 构造 verified executor output
-> Verifier
-> 最终 verdict 最高为 LOW_CONFID
-> 零条 checked binding 为 pass
-> 固定 Fallback
```
Verifier Input Builder 必须:
- 只保留 Gatekeeper `checked_bindings.status=pass` 对应的 evidence binding。
- 删除失败 binding。
- 没有有效 binding 的 claim 不得作为确认性 claim 进入 Verifier。
- 不向 Verifier 传递 Executor 未经验真的自由文本作为事实来源。
- 将 `verifier_verdict_ceiling` 设置为 `LOW_CONFID`。
即使模型 Verifier 返回 PASS,编排层也必须将有效 verdict 限制为 LOW_CONFID。
LOW_CONFID 进入 Verifier 的目标是保留部分真实证据,而不是让 Verifier 修复 Gatekeeper 失败。
---
## 6. Graph State 最小契约
Graph State 保存跨节点需要的结构化状态,不复制完整工具原文和模型思考过程。
| 状态 | 作用 | 策略 |
|---|---|---|
| `diagnosis_context` | 当前 Query、history、sessionId/runId 等统一上下文 | Replace |
| `planner_plan` | Planner 结构化计划 | Replace |
| `planner_status` | Planner 执行状态 | Replace |
| `planner_mode` | NORMAL / EVIDENCE_GAP_ONLY | Replace |
| `executor_output` | `executor_evidence_v2` | Replace |
| `executor_status` | COMPLETED / INVALID_OUTPUT / TOOL_BLOCKED / FAILED | Replace |
| `gatekeeper_result` | 当前轮验真结果 | Replace |
| `gatekeeper_status` | PASS / LOW_CONFID / REJECT | Replace |
| `verified_executor_output` | 只保留 Gatekeeper 通过 binding 的 Verifier 输入 | Replace |
| `verified_binding_count` | 当前可供 Verifier 使用的 binding 数量 | Replace |
| `verifier_verdict_ceiling` | PASS 或 LOW_CONFID | Replace |
| `verifier_output` | Verifier 结构化结果 | Replace |
| `verdict` | PASS / LOW_CONFID / REJECT / FAILED | Replace |
| `evidence_retry_count` | 补证据轮次 | Replace |
| `retry_context` | missing evidence 和补查约束 | Replace |
| `final_answer` | 最终用户表达 | Replace |
| `failure_reason` | 当前确定性失败原因 | Replace |
说明:
- `agent_step` 和 `tool_invocation` 继续作为完整 Trace 数据源。
- Graph State 只保存控制流程所需的最新状态。
- `no_evidence` 属于合法 Executor 输出,不等于 `FAILED`,仍然进入 Gatekeeper 和 Verifier。
---
## 7. 与当前代码的关系
### 7.1 继续复用
- Planner、Executor、Verifier、Composer Prompt。
- Skill Registry、Planner Skill metadata 和 Executor `read_skill`。
- `ExecutorGatekeeperService` 现有规则。
- `ToolTraceSummaryService`。
- Executor、Verifier、Composer 结构化解析逻辑。
- `diagnosis_run`、`agent_step`、`tool_invocation` 和 `self_evaluation`。
- Token、耗时和工具调用数回填。
- 当前 API 请求和响应协议。
### 7.2 需要调整
- `ChatService.executeChatComplex(...)` 不再创建 `SequentialAgent`。
- Gatekeeper 从 `VerifierInputHook` 的隐式执行迁为显式 Graph Node。
- LOW_CONFID 外层 `for round` 迁入 Graph 条件边。
- Composer 与固定 Fallback 成为独立节点。
- ChatService 只负责 Run 生命周期和调用 Graph,不继续承载细粒度状态机。
### 7.3 ReactAgent 接入策略
第一阶段使用适配 Node 显式调用当前 ReactAgent,不直接全面使用 `ReactAgent.asNode(...)`。
原因:
- 当前 Agent 根据 history 和 retry context 动态构造 Prompt。
- 当前使用自定义 outputKey 和解析逻辑。
- Hook、ThreadLocal 和父子 Graph `messages` 需要先验证。
Graph State 和 Agent 输入契约稳定后,再评估直接使用 `asNode(false, false)`。
### 7.4 已确认:父子状态使用输入白名单隔离
**决策状态**:已确认,2026-07-16。
外层 Graph 维护完整工作流状态,但每个 ReactAgent 不直接接收 `parentState.data()`。每个 Adapter Node 必须完成一次显式状态投影:
```text
父 Graph Shared State
-> Adapter Node 选择允许字段
-> Agent 专用 Input DTO
-> ReactAgent 私有执行上下文
-> Parser 提取标准输出
-> 只更新父 Graph 指定状态
```
各节点输入边界:
| 节点 | 允许读取 | 不允许直接读取 |
|---|---|---|
| Planner | query、history、retry context、Skill metadata | Executor、Gatekeeper、Verifier 的历史输出 |
| Executor | query、planner plan、selected skill、executor retry context | Verifier 结论、其他轮次未筛选 messages |
| Gatekeeper | executor structured output、当前 run 的 tool invocation | Planner 思考、其他 run 工具记录 |
| Verifier | query、executor structured output、gatekeeper result、verified tool trace | Planner 计划、Executor 思考、未经 Gatekeeper 验真的自由文本 |
| Composer | allowed claims、missing info、recommended actions | 原始工具结果、Executor 原始答案和未允许 claims |
实现约束:
- 第一阶段不使用 `asNode(true, true)`。
- `asNode(false, false)` 也不作为严格隔离手段,因为它主要减少 `messages` 传播,不能替代字段白名单。
- 每个 Adapter Node 使用专用 Input DTO,不复用一个包含所有字段的通用 AgentInput。
- ReactAgent 只向父 Graph 返回结构化 Node Output,不回传内部完整 `messages` 和推理过程。
- 子 Agent 的执行标识按 `runId + agentName + attempt` 隔离,避免不同 Agent 和重试轮次复用内部状态。
- 数据隔离由代码保证,Prompt 约束只作为补充。
### 7.5 已确认:编排审计使用独立 `orchestration_trace`
**决策状态**:已确认,2026-07-16。
Graph 路由记录不写入 `self_evaluation`。本期在 `diagnosis_run` 新增 nullable JSON 字段 `orchestration_trace`,用于保存当前 run 的紧凑编排摘要。
职责边界:
```text
self_evaluation
-> 结果质量、证据可信度以及 Gatekeeper / Verifier 等评估结果
orchestration_trace
-> 节点跳转、条件边原因、重试、降级和终止摘要
agent_step
-> 真实模型 Agent 调用
tool_invocation
-> 真实工具调用
```
最小结构:
```json
{
"version": "stategraph-v1",
"transitions": [
{
"from": "gatekeeper",
"to": "fallback",
"reason_code": "gatekeeper_reject",
"attempt": 1
}
],
"final_node": "fallback",
"termination_reason": "gatekeeper_reject",
"degraded": true,
"evidence_retry_count": 0
}
```
约束:
- 只写入 `diagnosis_run`,不写入会话级 `diagnosis_session`,因为 Graph 执行边界是 `runId`。
- 使用稳定的 `reason_code`,不保存完整 Prompt、模型思考、工具原文或 Graph State 快照。
- `transitions` 受 Graph 最大循环次数约束,不作为无限增长的事件日志。
- Trace API 将其作为与 `self_evaluation` 平级的可选字段返回;历史 run 可以为 `null`。
- 第一版不新增 orchestration 明细表,后续只有在需要跨 run 检索单次节点事件时再单独评估。
---
## 8. 分阶段实施计划
## 阶段 0:设计冻结
**预计时间**:1–2 小时
**目标**:完成讨论,不修改运行时实现。
任务:
- 确认 Graph State 最小契约。
- 确认所有条件边和最大重试次数。
- 确认 Fallback 用户表达。
- 确认旧 Sequential 测试的替换范围。
完成标准:
- 本 issue 中所有“待讨论决策”已有明确结论。
- 不存在未定义的循环和终止路径。
## 阶段 1:Graph 骨架和路由测试
**预计时间**:2–3 小时
**目标**:使用 Fake Node 验证 Graph API 和所有路径,不接真实模型。
任务:
- 创建诊断 Graph State 和状态常量。
- 创建 Graph 拓扑。
- 创建 Fake Planner、Executor、Gatekeeper、Verifier、Composer。
- 为所有条件边编写路由测试。
完成标准:
- Executor FAILED 后不调用 Gatekeeper、Verifier。
- Executor INVALID_OUTPUT 直接进入固定 Fallback,不触发任何模型重试。
- 任意 Gatekeeper REJECT 直接进入 Fallback,不调用 Verifier。
- LOW_CONFID 只允许一次 Planner 补证据。
- Graph 不存在无限循环。
## 阶段 2:接入真实节点
**预计时间**:3–4 小时
**目标**:将现有 Agent 和代码服务接入 Graph。
任务:
- 创建 Planner、Executor、Verifier、Composer Node Adapter。
- 创建显式 Gatekeeper Node。
- 创建 Verifier Input Builder Node,过滤未通过的 binding。
- 创建 Evidence Retry Prepare Node。
- 创建固定 Fallback Node。
- 保持现有 Prompt、工具和证据协议不变。
完成标准:
- Agent Hook 和 ToolCallback 正常工作。
- Gatekeeper 只执行一次,不再由 Verifier Hook 重复触发。
- no-evidence 继续进入 Gatekeeper 和 Verifier。
- Gatekeeper LOW_CONFID 只向 Verifier 提供已验真 binding,并限制 verdict 上限。
- Verifier LOW_CONFID 只有存在可执行缺口时才返回 Planner。
- 第二轮 Planner 只生成 `EVIDENCE_GAP_ONLY` 增量计划。
## 阶段 3:替换 ChatService 编排
**预计时间**:2–3 小时
**目标**:复杂 Chat 诊断正式调用 StateGraph。
任务:
- 将 `executeChatComplex(...)` 改为构造初始 Graph State 并执行 CompiledGraph。
- 使用 `runId` 作为 Graph `threadId`,`sessionId` 作为 metadata。
- 增加数据库迁移,为 `diagnosis_run` 添加 nullable JSON 字段 `orchestration_trace`。
- 将 Graph 的节点跳转、reason code、重试和终止摘要持久化到当前 run。
- 保留 Run 创建、状态更新、耗时、Token、工具数和 Eval 调用。
- 将 Graph 最终状态映射为现有 `ChatResult`。
完成标准:
- `/api/chat` 请求和响应协议不变。
- `diagnosis_run.agent_flow` 仍为 `CHAT`。
- Trace 明细继续归属于当前 runId。
- Trace API 将 `orchestration_trace` 作为与 `self_evaluation` 平级的可选字段返回。
- Executor 失败路径不产生 Verifier Agent step。
## 阶段 4:创建新测试体系
**预计时间**:3–4 小时
**目标**:以 Graph 路径和外部行为为中心创建测试,不迁移旧固定顺序断言。
新测试:
- `DiagnosisGraphWorkflowTest`:纯路由测试。
- `DiagnosisGraphNodeContractTest`:节点输入输出契约。
- `ChatServiceGraphIntegrationTest`:ChatService、Run、Trace、自评估集成。
必须覆盖:
- PASS 正常路径。
- Planner 失败。
- Executor FAILED / TOOL_BLOCKED / INVALID_OUTPUT。
- 合法 no-evidence。
- Gatekeeper REJECT 直接降级。
- Gatekeeper LOW_CONFID 且存在已验真 binding。
- Gatekeeper LOW_CONFID 且不存在已验真 binding。
- Verifier LOW_CONFID 补证据。
- Gatekeeper ceiling 导致的 LOW_CONFID 不触发补证据。
- LOW_CONFID 缺少可执行 missing evidence 时不触发补证据。
- 第二次 LOW_CONFID 不再补证据。
- Verifier REJECT 安全表达。
- Composer 失败固定降级。
- 同 session 多 run 隔离。
旧测试处理:
- `ChatServiceSequentialAgentTest` 不作为迁移约束,可以由新测试整体替换。
- `VerifierInputHookTest` 根据 Gatekeeper 迁移结果删除或改写。
- `ExecutorGatekeeperServiceTest`、Controller、Trace 和 Eval 契约测试继续保留。
## 阶段 5:回归、清理和文档
**预计时间**:1–2 小时
**目标**:完成行为确认并删除旧编排结构。
任务:
- 运行新的单元和集成测试。
- 运行相关 diagnosis eval baseline。
- 对比关键 Trace 路径。
- 删除 `SequentialAgent` 复杂诊断编排和旧外层 round 状态机。
- 删除不再需要的 Gatekeeper Hook 隐式执行逻辑。
- 更新架构文档和 issue 状态。
完成标准:
- 新测试全部通过。
- 关键 Eval 没有非预期退化。
- ChatService 不再维护隐式诊断状态机。
- 不存在新旧两套长期并行的重复实现。
---
## 9. 测试策略
本改造允许忽略并替换与 SequentialAgent 强绑定的历史测试,但不允许丢失已经建立的安全边界。
测试分层:
```text
Graph 路由测试
-> 不调用模型,验证条件边和循环上限
Node 契约测试
-> 验证 Agent / Java Node 的状态映射
Chat 集成测试
-> 验证外部协议、Run、Trace、orchestration_trace 和 self_evaluation
Eval baseline
-> 验证最终证据表达没有退化
```
不再把“所有 Agent 固定按顺序调用”作为正确性标准。正确性标准改为:
> 根据当前节点状态进入预期路径,并且所有安全门禁和外部协议保持成立。
---
## 10. 行为与协议影响
### 外部协议
保持不变:
- `/api/chat` 请求和响应结构。
- `sessionId/runId` 语义。
- `executor_evidence_v2`。
- Verifier 和 Composer 输出契约。
### Trace API 加法式变化
- Trace 聚合响应新增与 `self_evaluation` 平级的可选字段 `orchestration_trace`。
- 现有字段语义不变,历史 run 或未经过 StateGraph 的 run 返回 `null`。
- 这是有意的内部审计持久化和 Trace 查询协议扩展,不影响 `/api/chat` 消费方。
### 明确的内部行为变化
- Executor 失败后不再调用 Verifier。
- Executor INVALID_OUTPUT 不重试,直接进入固定 Fallback。
- Agent 调用顺序不再固定。
- Gatekeeper REJECT 直接安全降级,不进行自动修复和重试。
- Gatekeeper LOW_CONFID 只在存在已验真 binding 时进入 Verifier,且 verdict 最高为 LOW_CONFID。
- LOW_CONFID 根据 missing evidence 返回 Planner,而不是无差别完整重跑。
- 第二轮 Planner 使用增量补证据模式,不重新执行完整 Playbook。
- Agent step 数量、Token 和耗时可能减少。
- Trace 需要能解释条件边选择和终止原因。
这些是有意的编排行为变化,不是对外协议变化。
---
## 11. 验收标准
### 编排
- [ ] Executor FAILED / TOOL_BLOCKED 后不会执行 Gatekeeper 和 Verifier。
- [ ] Executor INVALID_OUTPUT 不重试,不执行 Gatekeeper、Verifier 和模型 Composer。
- [ ] Executor 合法 no-evidence 会继续执行 Gatekeeper 和 Verifier。
- [ ] Gatekeeper REJECT 直接进入 Fallback,不执行 Verifier。
- [ ] Gatekeeper LOW_CONFID 且零条已验真 binding 时直接进入 Fallback。
- [ ] Gatekeeper LOW_CONFID 且存在已验真 binding 时,Verifier 只接收通过校验的 binding。
- [ ] Gatekeeper LOW_CONFID 路径的最终 verdict 不得升级为 PASS。
- [ ] Verifier LOW_CONFID 最多触发一次 Planner 补证据。
- [ ] LOW_CONFID 补证据循环受次数和 Run 总预算限制。
- [ ] Gatekeeper verdict ceiling 导致的 LOW_CONFID 不触发补证据。
- [ ] 不存在可执行 missing evidence 时不触发补证据。
- [ ] 第二轮 Planner 只输出增量计划,不扩大诊断范围或重复成功查询。
- [ ] Composer 失败使用固定模板结束。
### 证据和安全
- [ ] Gatekeeper 规则语义不放宽。
- [ ] Verifier 只消费已验真证据。
- [ ] no-evidence 不得表达为已排除或问题不存在。
- [ ] REJECT 降级不泄漏 Executor 原始答案和未验证根因。
### 数据与审计
- [ ] Graph 使用 runId 作为 threadId。
- [ ] Agent step、tool invocation 和 self_evaluation 仍绑定正确 runId。
- [ ] `orchestration_trace` 只写入当前 diagnosis run,不污染其他 run 或 session 级数据。
- [ ] `orchestration_trace` 不包含 Prompt、模型思考、工具原文和 Graph State 快照。
- [ ] Trace 能展示实际节点路径、重试原因和终止原因。
- [ ] 历史 run 的 `orchestration_trace=null` 时 Trace API 仍能正常返回。
- [ ] Run 最终状态、答案、耗时、Token 和工具调用数正确回填。
### 工程质量
- [ ] 新 Graph 测试覆盖所有分支。
- [ ] `ChatServiceSequentialAgentTest` 已由新测试替换。
- [ ] 不保留长期重复的 Sequential 和 Graph 两套实现。
- [ ] 数据库 schema 仅新增 `diagnosis_run.orchestration_trace` nullable JSON 字段。
- [ ] `/api/chat` 和证据协议不变;Trace API 仅新增可选的 `orchestration_trace` 字段。
---
## 12. 风险与缓解
### ReactAgent 父子 Graph 状态污染
风险:直接使用 `asNode(...)` 可能导致 `messages`、outputKey 或 checkpoint 传播不符合预期。
缓解:第一阶段使用适配 Node 显式调用 Agent;完成契约测试后再考虑直接子图节点。
### Gatekeeper 重复执行
风险:显式 Gatekeeper Node 与现有 `VerifierInputHook` 同时执行。
缓解:迁移时明确 Gatekeeper 只有一个入口;Verifier Hook 只负责构造输入或被替换。
### LOW_CONFID 循环失控
风险:Verifier LOW_CONFID 持续返回 Planner,形成重复规划和工具调用。
缓解:保留当前最多一次补证据约束,并设置 Run 级总预算与 Graph recursion limit。
### Trace 与 Graph Checkpoint 语义混淆
风险:把当前数据库 Trace 当作 Graph 恢复检查点,或把 `MemorySaver` 当成持久化。
缓解:本期 Graph 只负责控制流程,不声明跨重启恢复;HITL 和持久 Checkpointer 单独立项。
---
## 13. Out of scope
本 issue 暂不包含:
- AIOps 迁移到公共 Graph。
- Chat 和 AIOps 入口统一。
- SupervisorAgent 和专科 SubAgent。
- 人工中断、审批和恢复。
- 持久化 Checkpointer。
- 并行工具或并行 Agent。
- EvidenceRepairNode 和 Gatekeeper REJECT 自动修复。
- Gatekeeper REJECT 返回 Executor 的重试回边。
- 修改 Prompt 业务语义。
- 修改 `executor_evidence_v2`、Verifier、Composer 协议。
- 除 `diagnosis_run.orchestration_trace` 外的其他数据库表或字段。
这些能力应在本 issue 完成后根据实际收益单独讨论。
---
## 14. 已冻结决策
以下决策均已确认,不再作为开放问题:
- 第一阶段保留现有 ReactAgent,通过 Adapter Node 调用。
- 父 Graph State 不直接传给 ReactAgent,使用每个 Agent 独立的 Input DTO 做白名单投影。
- 第一阶段不直接依赖 `ReactAgent.asNode(...)` 实现父子编排。
- Gatekeeper REJECT 本期不重试,直接进入 Fallback。
- 本期不增加 EvidenceRepairNode。
- Executor INVALID_OUTPUT 本期不重试,直接进入固定 Fallback。
- Gatekeeper LOW_CONFID 有已验真 binding 时进入 Verifier,零条时直接 Fallback。
- Gatekeeper LOW_CONFID 路径的最终 verdict 上限为 LOW_CONFID。
- Verifier LOW_CONFID 的补证据路径返回 Planner,并使用 `EVIDENCE_GAP_ONLY` 增量规划模式。
- Gatekeeper ceiling、无可执行缺口、无预算或已经补查时不触发 LOW_CONFID 重试。
- Graph 路由摘要写入独立的 `diagnosis_run.orchestration_trace`,不耦合进 `self_evaluation`。
- 不保留 Sequential / StateGraph 双链路配置开关;在专用 Git 分支完成实现和验收后,直接以 StateGraph 替换旧复杂诊断编排。
- 实现期间允许代码处于分支内的阶段性状态,但合并前必须删除旧 Sequential 编排和不再使用的迁移代码,不形成长期双轨维护。
---
## 15. 相关文件
- `src/main/java/com/superbiz/agent/service/ChatService.java`
- `src/main/java/com/superbiz/agent/service/ExecutorGatekeeperService.java`
- `src/main/java/com/superbiz/agent/hook/VerifierInputHook.java`
- `src/main/java/com/superbiz/agent/service/ToolTraceSummaryService.java`
- `src/main/java/com/superbiz/agent/hook/AgentLoggingHook.java`
- `src/test/java/com/superbiz/agent/service/ChatServiceSequentialAgentTest.java`
- `src/test/java/com/superbiz/agent/service/ExecutorGatekeeperServiceTest.java`
- `src/test/java/com/superbiz/agent/hook/VerifierInputHookTest.java`
- `mvp/architecture/agent-orchestration.md`
- `mvp/architecture/harness-quality-gates.md`
- `knowledge_20260716_Spring_AI_Alibaba_Graph_诊断编排改造/`
## 16. 参考文档
- https://java2ai.com/docs/frameworks/graph-core/core/core-library
- https://java2ai.com/docs/frameworks/graph-core/quick-start
- 当前依赖:`spring-ai-alibaba-graph-core:1.1.2.0`
- 当前依赖:`spring-ai-alibaba-agent-framework:1.1.2.0`