Files
SuperBizAgent-java/mvp/architecture/stategraph-runtime-architecture.md

200 lines
9.5 KiB
Markdown
Raw Permalink 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.
# 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`