【Spring AI Graph:从0到Supervisor·预告】动手之前,先定好3个架构决策

起因

我的代码审查Agent跑了两个月,单链路一直没问题。直到需要加RAG查最佳实践------同一个入口要走不同检索路径,单链路搞不定,必须上Graph。

但Spring AI Graph的资料太少了,官方文档偏概念,社区文章偏Demo。我花了2周从零啃到能写出第一个子图,这里先说整体架构和技术亮点,周末发完整代码。

最终形态:三层拼装的Supervisor Graph

我要搭的不是"一个Graph",而是一个三层拼装系统

plaintext

yaml 复制代码
Layer 3: Supervisor Graph(底层StateGraph手写)
         意图识别 → 条件路由 → 子图分发
              ↓
Layer 2: SubGraph(高层API快搭 / 底层手写,按需选择)
         ├─ RAG问答子图:意图分类 → 条件路由 → keyword/hybrid双路 → rerank → 生成
         ├─ 代码审查子图:解析 → 并行扫描 → 风险评估 → HITL → 报告
         └─ 通用对话子图:简单链路
              ↓
Layer 1: Node(最小执行单元,实现NodeAction/EdgeAction接口)
         IntentAnalyzeNode / KeywordSearchNode / HybridSearchNode / ...

为什么要分三层?因为不同层的关注点不同

  • Layer 3 关心路由和编排,必须灵活,所以用底层StateGraph
  • Layer 2 关心业务流程,能用高层API就别手写
  • Layer 1 关心单一职责,每个Node只做一件事

这三层不是我自己发明的------LangGraph的图编排、Spring的DI分治、Erlang的Supervisor Tree,思想来源是这些。但用Spring AI Graph落地的时候,怎么拼、在哪层用什么API,没有现成答案。

3个架构亮点

亮点1:两层API混搭------不是全底层也不是全高层

Spring AI Alibaba提供两层API:

  • 高层:SequentialAgent / ParallelAgent / LlmRoutingAgent
  • 底层:StateGraph + Node + Edge

社区文章要么全用高层(搭个Demo没问题,复杂场景撑不住),要么全用底层(能干但开发慢)。

我的做法:Supervisor用底层手写,子图内部用高层快搭

为什么?因为Supervisor需要两样东西,高层API给不了:

  1. 条件路由:根据意图动态分发到不同子图,LlmRoutingAgent只能做一次路由,不支持多级条件判断
  2. HITL中断恢复:高风险代码暂停等人工确认,高层API没有"暂停→等人→继续"的机制

java

dart 复制代码
// Supervisor必须底层手写
StateGraph supervisor = new StateGraph(OverAllState.class)
    .addNode("intent", intentRouterNode)
    .addNode("code_review", codeReviewSubGraph)
    .addNode("rag_qa", ragQaSubGraph)
    .addNode("human_review", humanReviewNode)
    .addConditionalEdge("intent", this::routeByIntent,
        Map.of("code_review", "code_review", "rag_qa", "rag_qa"))
    .addConditionalEdge("code_review", this::needHumanReview,
        Map.of("yes", "human_review", "no", END));

但子图内部没必要全手写。代码审查的质量检查+安全扫描,ParallelAgent两行搞定。按需选择API层级,才是工程化的思路

亮点2:有状态编排------从"一次性调用"到"可恢复流程"

大多数Agent Demo是这样的:输入 → 模型 → 输出,无状态,跑完就完了。

但真实场景不是一次调用。代码审查需要:解析→并行扫描→风险评估→可能要等人确认→生成报告。中间任何一步都可能失败,需要从断点恢复而不是从头重跑。

StateGraph的OverAllState就是这个问题的解法------每个Node执行完,状态持久化到共享容器。下一个Node从容器读状态,不依赖上游传递。

java

ini 复制代码
// 每个子图注册自己需要的key,全部ReplaceStrategy
KeyStrategyFactory keyStrategyFactory = () -> {
    HashMap<String, KeyStrategy> strategies = new HashMap<>();
    strategies.put(DreamSaaSOverAllState.userInput, new ReplaceStrategy());
    strategies.put(DreamSaaSOverAllState.queryIntent, new ReplaceStrategy());
    strategies.put(DreamSaaSOverAllState.searchResult, new ReplaceStrategy());
    strategies.put(DreamSaaSOverAllState.finalAnswer, new ReplaceStrategy());
    return strategies;
};

Replace策略保证下游读到的始终是最新值。子图按需注册key,不跨层------RAG子图不需要riskLevel,代码审查子图不需要searchResult

这和Java里的Event Sourcing是同一个思路:状态是第一公民,流程是状态驱动的

亮点3:HITL不是confirm,是架构级的断点设计

"Human-in-the-Loop"很容易被理解成"弹个确认框"。但HITL在Graph架构里不是确认框,是架构级的断点

区别在哪?

  • 确认框:流程继续跑,弹个框让人点一下
  • 架构断点:流程暂停,状态持久化,等人回复后从断点恢复

这意味着:

  1. Agent不会在等人的时候占着资源
  2. 人工确认的结果会写回State,影响后续路由
  3. 断点可以跨Session------今天确认不了,明天接着来

代码审查场景:检测到SQL注入风险 → 暂停 → 等安全工程师确认 → 确认后才进报告生成。不是AI说了算,架构层面保证人可控

这个设计目前Spring AI Graph的Checkpoint机制还在完善中,我用的是手动实现的State快照方案,中篇会详细展开。

技术栈版本

spring-ai-bom 1.1.6 + spring-ai-alibaba 1.1.2.2。API还在迭代,跟着做的话版本对齐是前提。

连载计划

  • 上篇(本周末):【Spring AI Graph:从0到Supervisor·上】条件路由与RAG子图
  • 中篇(下周末):【Spring AI Graph:从0到Supervisor·中】HITL与并行执行
  • 下篇(6/6):【Spring AI Graph:从0到Supervisor·下】Supervisor三层拼装

每篇都放完整代码,不是snippet也不是伪代码。读者看完能直接写出同样的东西。

相关推荐
Terrence Shen2 分钟前
Hermes agent的tools是怎么落地应用的系列
人工智能·llm·agent·hermes
x***r1519 分钟前
jdk-11.0.16.1_windows使用步骤详解(附JDK 11环境变量配置与验证教程)
java·开发语言·windows
弹简特44 分钟前
【Java项目-轻聊】01-项目演示+项目介绍+准备工作+项目源码
java
Cosolar1 小时前
2026年AI Agent技术生态开源项目合集
人工智能·开源·agent·智能体
luck_bor1 小时前
File类&递归作业
java·开发语言
武子康1 小时前
Java-07 深入浅出 MyBatis数据库一对多关系模型实战:表结构设计与查询实现
java·后端
花椒技术2 小时前
企业内部 Agent 落地复盘:Gateway、Skill 和二次确认如何串起受控业务执行
后端·agent·ai编程
冬奇Lab2 小时前
Agent系列(六):记忆管理——让 Agent 记住重要的事
人工智能·agent
七牛云行业应用3 小时前
OpenHuman、OpenClaw、Hermes Agent 傻傻分不清楚?一篇说清三者定位
ai·agent·hermes agent
REDcker3 小时前
Linux OverlayFS详解
java·linux·运维