# Chat StateGraph 运行时架构 **更新日期**:2026-07-20 **状态**:当前复杂 Chat 诊断的权威运行时架构 **适用范围**:`POST /api/chat` 的复杂诊断路径;简单 Chat 和 AIOps 使用各自链路 ## 1. 架构定位 复杂 Chat 已单轨切换为 Spring AI Alibaba bounded `StateGraph`。`ChatService` 负责 Run 生命周期和持久化,`ChatDiagnosisGraphRuntime` 负责执行 Graph,`DiagnosisGraphFactory` 负责声明 Node 与条件边,Agent/Java Node 负责各自的语义任务或确定性校验。 ```mermaid flowchart LR API["POST /api/chat"] --> Chat["ChatService.executeChatComplex"] Chat --> Session["chat_session"] Chat --> Run["diagnosis_run: RUNNING"] Chat --> Actions["DiagnosisRealGraphActionsFactory"] Actions --> Runtime["ChatDiagnosisGraphRuntime"] Runtime --> Factory["DiagnosisGraphFactory"] Factory --> Graph["Compiled StateGraph"] Graph --> Planner["PlannerNodeAdapter"] Graph --> Executor["ExecutorNodeAdapter"] Graph --> Gatekeeper["GatekeeperNode"] Graph --> Projection["VerifiedInputNode"] Graph --> Verifier["VerifierNodeAdapter"] Graph --> Retry["EvidenceRetryPrepareNode"] Graph --> Composer["ComposerNodeAdapter"] Graph --> Fallback["FallbackNode"] Executor --> Tools["lookup_knowledge / logs / metrics"] Tools --> Invocations["tool_invocation"] Planner --> Steps["agent_step"] Executor --> Steps Verifier --> Steps Composer --> Steps Graph --> Mapper["DiagnosisGraphResultMapper"] Graph --> TraceBuilder["DiagnosisOrchestrationTraceBuilder"] Mapper --> SelfEval["diagnosis_run.self_evaluation"] TraceBuilder --> RouteTrace["diagnosis_run.orchestration_trace"] Chat --> RunDone["diagnosis_run: SUCCESS / FAILED"] RunDone --> TraceAPI["exact Run Trace API"] SelfEval --> TraceAPI RouteTrace --> TraceAPI Steps --> TraceAPI Invocations --> TraceAPI ``` ## 2. 运行生命周期 一次复杂 Chat 运行按以下顺序执行: 1. `ChatService` 解析或创建 `sessionId`,生成唯一 `runId`。 2. 确保 `chat_session` 元数据存在,并创建 `diagnosis_run`,初始状态为 `RUNNING`、`agent_flow=CHAT`。 3. 构建 Planner、Executor、Verifier、Composer 四个 `ReactAgent`,再由 `DiagnosisRealGraphActionsFactory` 组合 Java Nodes。 4. `ChatDiagnosisGraphRuntime` 以 `runId` 作为 Graph `threadId`,将 `sessionId/runId` 放入 `RunnableConfig.metadata`。 5. `DiagnosisGraphFactory` 编译 StateGraph 并执行,Graph recursion limit 固定为 32。 6. Graph 返回非空 `final_answer` 后,`DiagnosisGraphResultMapper` 生成 verifier evaluation,`DiagnosisOrchestrationTraceBuilder` 压缩路由摘要。 7. `ChatService` 保存答案、耗时、步骤数、工具数、自评估和编排摘要,将 Run 标记为 `SUCCESS`。 8. 未处理异常会尽力保存 partial state/partial trace,再将 Run 标记为 `FAILED`;能够生成安全 Fallback 的路径仍是 `SUCCESS`,并通过 `degraded=true` 表达质量降级。 9. `finally` 清理本轮检索追踪和 session/run ThreadLocal,避免跨 Run 污染。 ## 3. Graph 拓扑 ```mermaid flowchart TD Start([START]) --> Planner[Planner] Planner -->|COMPLETED| Executor[Executor] Planner -->|technical retry once| Planner Planner -->|non-retryable / exhausted| Fallback[Fallback] Executor -->|COMPLETED| Gatekeeper[Gatekeeper] Executor -->|INVALID_OUTPUT / TOOL_BLOCKED / FAILED| Fallback Gatekeeper -->|PASS| VerifiedInput[Verified Input] Gatekeeper -->|LOW_CONFID + verified bindings| VerifiedInput Gatekeeper -->|REJECT / no verified binding| Fallback VerifiedInput --> Verifier[Verifier] Verifier -->|technical retry once| Verifier Verifier -->|LOW_CONFID + critical gap + retry allowed| EvidenceRetry[Evidence Retry] EvidenceRetry -->|EVIDENCE_GAP_ONLY| Planner Verifier -->|completed and no retry| Composer[Composer] Verifier -->|non-retryable / exhausted| Fallback Composer -->|COMPLETED| End([END]) Composer -->|technical retry once| Composer Composer -->|non-retryable / exhausted| Fallback Fallback --> End ``` 路由规则: | 节点 | 继续条件 | 重试 | 安全终止 | |---|---|---|---| | Planner | `COMPLETED` 进入 Executor | `INVALID_OUTPUT` / `RETRYABLE_FAILED` 最多一次技术重试 | `NON_RETRYABLE_FAILED` 或重试耗尽进入 Fallback | | Executor | 只有 `COMPLETED` 进入 Gatekeeper | 不做 Graph 技术重试 | 非法输出、工具阻断或执行失败进入 Fallback | | Gatekeeper | `PASS`,或 `LOW_CONFID` 且至少一个 verified binding | 不重试 | `REJECT` 或零 verified binding 进入 Fallback | | Verifier | 完成后由 `effective_verdict` 决定 Composer 或补证据 | 技术失败最多一次;证据补查最多一次 | 不可重试失败或技术重试耗尽进入 Fallback | | Composer | `COMPLETED` 结束 | 技术失败最多一次 | 不可重试失败或重试耗尽进入 Fallback | | Fallback | 生成非空确定性安全答复 | 不重试 | 直接结束并标记 `degraded=true` | Evidence retry 只有同时满足以下条件才发生: - `evidence_retry_count < 1`。 - Gatekeeper 给出的 verifier verdict ceiling 仍允许 `PASS`。 - Verifier 输出包含可提取的 critical evidence gap。 补证据时 Planner 进入 `EVIDENCE_GAP_ONLY`,`planner_retry_count` 重置;Executor 只执行增量查询,但重新输出完整 `executor_evidence_v2` 快照。 ## 4. 状态与执行边界 ### Graph State Graph State 只保存跨 Node 的控制信息和结构化结果: - `diagnosis_context`、`planner_plan`、`executor_output`。 - `gatekeeper_result`、`verified_executor_output`、`verified_evidence`。 - `verifier_output`、`composer_output`、`final_answer`。 - Planner/Verifier/Composer 技术重试计数和 `evidence_retry_count`。 - `orchestration_events` 有界追加事件。 默认状态键使用 replace strategy,只有 `orchestration_events` 使用 append strategy。事件在 Graph 边界存为 classloader-neutral Map:`node/outcome/reason_code/attempt`,避免 DevTools restart classloader 造成 record 类型身份不一致。 ### RunnableConfig 外层 Graph config 使用: - `threadId = runId`。 - metadata 包含 `sessionId` 和 `runId`。 调用 nested `ReactAgent` 时,`ReactAgentDiagnosisInvoker` 创建独立 config,只保留业务身份与 store,不向子 Agent 传播外层 Graph 的 human-feedback、state-update、checkpoint/resume 控制 metadata,避免父 Graph 恢复语义污染子 Graph。 ## 5. 证据信任边界 ```text Executor output -> source_invocation_id + raw_path + evidence_excerpt -> GatekeeperNode / ExecutorGatekeeperService -> 按当前 runId 读取 tool_invocation -> 验证 invocation ownership、raw_path、excerpt -> VerifiedInputNode -> 只投影通过的 claims/bindings/evidence -> VerifierNodeAdapter -> 只判断已验真证据是否支持 claim -> ComposerNodeAdapter -> 只表达允许输出的结论、限制和建议 ``` Verifier 不读取完整工具 Trace,不执行新检索,也不读取 Skill 正文。当前版本不生成或读取 `tool_trace_summary`。 ## 6. Run 级审计模型 | 审计层 | 存储/API | 回答的问题 | |---|---|---| | 执行明细 | `agent_step`、`tool_invocation` | 模型和工具实际做了什么? | | 证据与答案质量 | `diagnosis_run.self_evaluation` | 引用是否真实、claim 是否可推导、Prompt/Gatekeeper 版本是什么? | | Graph 路由 | `diagnosis_run.orchestration_trace` / `run.orchestrationTrace` | 走了哪些 Node、为何重试或降级、在哪里结束? | `orchestration_trace` 当前结构: ```json { "version": "stategraph-v1", "transitions": [ {"from": "planner", "to": "executor", "reason_code": "completed", "attempt": 1} ], "final_node": "composer", "termination_reason": "composer_completed", "degraded": false, "evidence_retry_count": 0 } ``` 该字段只属于 exact Run 投影,响应不提供兼容 `session` 投影;非 StateGraph Run 可以为空。 ## 7. 验收层次 | 测试层 | 权威测试 | 覆盖 | |---|---|---| | Workflow | `DiagnosisGraphWorkflowTest` | 全部分支、有限重试、补证据和 Fallback | | Node Contract | `DiagnosisGraphNodeContractTest` | 真实 Node 的输入投影、输出状态和证据边界 | | Runtime | `ChatDiagnosisGraphRuntimeTest` | config、最终状态、partial failure/trace | | Chat Integration | `ChatServiceGraphIntegrationTest` | Run 生命周期、答案、自评估、编排摘要和失败持久化 | | Trace Contract | `DiagnosisTraceServiceTest` | exact run ownership 和 `run.orchestrationTrace` 投影 | | Demo Contract | `InterviewDemoScriptContractTest` | exact runId、Graph 字段和 summary 输出 | ## 8. 关键代码 - `src/main/java/com/superbiz/agent/service/ChatService.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/ChatDiagnosisGraphRuntime.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/DiagnosisGraphFactory.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/DiagnosisGraphRouter.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/DiagnosisGraphState.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/DiagnosisRealGraphActionsFactory.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/ReactAgentDiagnosisInvoker.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/DiagnosisGraphResultMapper.java` - `src/main/java/com/superbiz/agent/graph/diagnosis/DiagnosisOrchestrationTraceBuilder.java` - `src/main/java/com/superbiz/agent/service/DiagnosisTraceService.java`