举个简单的例子。
用户说"帮我推荐武汉的旅游攻略",背后至少需要四步,查天气、根据天气推荐游玩项目、根据项目推荐美食、把所有结果整合成一篇图文。
四步分别需要不同的提示词和工具,硬塞进一个 Agent 里,提示词很容易就膨胀到没办法维护。
这篇内容用一个旅游推荐的案例,演示怎么用 LangGraph4j + Spring AI 把四个 Agent 编排成一张有向图。
01、为什么需要多 Agent?
先看一个具体的需求。
用户输入一个地址,系统先查询当地天气。如果用户还要求做旅游推荐,就继续调用旅游 Agent 和美食 Agent,最后生成一篇小红书风格的图文攻略;如果只是问天气,直接返回天气预报就结束了。

这个需求拆下来有四个 Agent。
- 天气 Agent 通过 Function Call 调用天气工具,拿到实时天气数据
- 旅游 Agent 根据天气推荐适合当前天气的游玩项目
- 美食 Agent 根据游玩项目推荐附近美食,用结构化输出返回 Java 对象
- 图文 Agent 把前面所有结果整合成一篇小红书风格的内容

02、LangGraph4j 把 Agent 变成了一张图
LangGraph4j 是 LangGraph 的 Java 实现,它提供了一种编排多个 Agent 的方式,把协作关系描述成一张有向图。

State 是图的全局共享状态。所有 Node 共享同一份 State 实例,每个 Node 执行完之后把结果写回 State,下一个 Node 从 State 里读取前置数据。
Node 是处理节点,每个 Node 对应一个 Agent。它接收当前的 State,执行自己的逻辑(通常是调用一次大模型),返回一个 Map<string, object=""> 写回 State。
Edge 是节点之间的连线,决定了执行顺序。A → B 表示 A 执行完之后自动轮到 B。
ConditionalEdge 是条件分支,根据 State 中的内容决定走哪条路。比如"用户要推荐就走旅游 Agent,不要推荐就直接跳到图文 Agent"。
new StateGraph<>(TravelState.serializer())
.addNode("weatherAgent", node_async(weatherAgent::callWeatherAgent))
.addNode("travelAgent", node_async(travelAgent::callTravelAgent))
.addNode("foodAgent", node_async(foodAgent::callFoodAgent))
.addNode("xhsAgent", node_async(xhsBlogAgent::callResponseAgent))
.addEdge(START, "weatherAgent")
.addConditionalEdges("weatherAgent", edge_async(shouldContinue), ...)
.addEdg...</string,>
回复