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