跳过正文
Java Agentic AI 框架选型:同一业务下的三种编排路径
  1. 文章/

Java Agentic AI 框架选型:同一业务下的三种编排路径

·6106 字·13 分钟
NeatGuyCoding
作者
NeatGuyCoding

Java Agentic AI 框架选型:同一业务下的三种编排路径
#

在 JVM 上落地 Agentic 应用,难点往往不在「能不能调 LLM」,而在谁来决定下一步:是 Java 代码写死的流程,还是模型在运行时选工具、选子 Agent。Spring AI、LangChain4jEmbabel 代表三种不同的抽象层级——底层原语、声明式 Agent 组合、目标驱动规划。

对照场景是 Nutrition Planner:并行拉取用户档案与当季食材,生成符合过敏与卡路里约束的周餐计划,再用 Evaluator-Optimizer 循环做营养校验。三个框架实现同一业务语义,但编排责任落在不同层——手写 Java 并发、AgenticServices builder、或 GOAP 自动 replan。本文梳理机制差异与工程取舍;能力矩阵、版本时间线、token 定量估算等未独立 benchmark 验证的部分会单独标注。读者可 clone ai-nutrition-planner 本地跑通三模块后再做选型。


Agentic 演进与 Workflow 取舍
#

为什么:LLM 应用演进路径大致是:Prompt Engineering → RAG 接地 → Tool Calling → 多模态 → Agentic Systems。RAG 与 tool calling 解决的是「模型能读数据、能调函数」;Agentic 系统进一步把编排决策也交给模型——多 Agent 协作、记忆、规划、MCP 互连。对生产系统而言,关键问题是:哪些步骤必须可预测、可测试,哪些步骤值得用模型灵活性换延迟与成本。

机制/约束Anthropic 工程文 将编排分为 Workflows(预定义代码路径)与 Agents(模型动态指挥)。Workflow 可预测、易维护、通常更低延迟与 token 开销;Pure Agent 适应开放任务,但多轮推理带来更高费用,且单步错误可能级联放大。Anthropic 建议「优先用最简单方案,仅在需要时增加复杂度」。原文写「workflows offer predictability… agents are the better option when flexibility… is needed」——「企业优先 Workflow」是常见工程归纳,非官方硬性规则。幻灯片将 Agentic 能力块概括为 Orchestration / Memory / Planning / MCP,与 Anthropic 分类并不逐字对应,属演讲者归纳

Agentic AI Systems 块列出 Orchestration、Memory、Planning、MCP,标志 LLM 应用从单轮生成走向端到端自动化。

Workflows 与 Pure Agents 对照:幻灯片结论 Use workflows for predictability,与 Anthropic 叙事同向。

怎么做:Nutrition Planner 三框架实现均偏 Workflow 而非 Pure Agent——并行阶段用代码固定,校验循环用 Evaluator-Optimizer 模式,而非让模型自由规划全流程。若你的任务步骤在需求评审阶段就能枚举,应优先 Workflow;只有任务分解本身不可预知(例如开放式研究助手)才考虑 Pure Agent。

常见误区:把「用了 LLM」等同于「上了 Agent」;在合规、可审计场景默认 Pure Agent,却未建立 guardrails、观测与人工介入点;在 inflexible 的 Workflow 里硬塞 Routing,却未维护分类器准确率。


五类 Workflow Pattern 作为架构蓝图
#

为什么:单 prompt 一次生成周餐计划,难以稳定满足过敏、卡路里等结构化约束;需要把业务映射到可编码、可测试的步骤图。

机制/约束:Anthropic 列出五模式——Prompt Chaining、Parallelization、Routing、Orchestrator-Workers、Evaluator-Optimizer。Parallelization 有 Sectioning(并行子任务)与 Voting(多路投票)两种变体;Evaluator-Optimizer 定义为「一个 LLM 生成,另一个评估并反馈,循环直至达标」。

Nutrition Planner 映射为:Parallelization(fetchUserProfilefetchSeasonalIngredients 无依赖,可并行)→ Prompt Chaining 式生成计划 → Evaluator-Optimizer(NutritionGuard 评估 + Reviser 修订)。用户过敏、钠摄入上限等约束放在 Evaluator 侧,而非指望 Generator 一次记住全部规则。Spring AI 内置 StructuredOutputValidationAdvisor 做 JSON schema 重试,语义接近 Evaluator-Optimizer,但 Anthropic 文未建立一对一 API 映射

Workflow Patterns for Agentic Systems:Evaluator-Optimizer 含 Generator ↔ Evaluator 反馈环,页脚链至 Anthropic 工程文。

Mermaid diagram 1

怎么做:无论选哪一框架,先把业务画成上述模式,再选对应原语——不要反过来「框架有什么就塞什么」。

常见误区:Orchestrator-Workers 与 Evaluator-Optimizer 混用——前者子任务由中心 LLM 动态分解,后者是固定生成-评估对。


MCP 与 A2A:互操作的两条轴
#

为什么:Tool calling 普及后,每个 Agent 各自封装 GitHub、Jira、DB 连接器不可持续;Java 生态需要标准协议降低集成碎片化。

机制/约束MCP 规范 定位 AI 应用连接外部数据源与工具的开放标准;A2A 协议(The Linux Foundation 维护)描述多 Agent 发现、委托与协作——Agent 作为 Agent 暴露,而非仅包装成 tool。Nutrition Planner demo 实现了 MCP server,未实现 A2A 互操作(示例仓库无 A2A 依赖)。

Glossary:MCP 连接 AI Model 与 DB/APP;A2A 框内多 Agent 双向协作。

怎么做:MCP 解决「模型 ↔ 工具/数据」;A2A 解决「Agent ↔ Agent」。Nutrition Planner 的 Spring AI 模块用 @McpToolcreateNutritionPlan 暴露为 MCP 工具,并从 SecurityContextHolder 取当前用户——说明 MCP 与 Spring Security 可以同栈集成。选型时分开评估 client 与 server:LangChain4j 有 MCP client(Streamable HTTP、stdio)与 community stdio server,与 Spring AI spring-ai-starter-mcp-server-webmvc、Embabel embabel-agent-starter-mcpserver 的 HTTP starter 成熟度不对等,不能简化为「不支持 MCP」。

常见误区:把 MCP server 与 MCP client 混为一谈;矩阵标注「No HTTP Server」时未区分传输层与 starter 一等公民程度;在 demo 未覆盖 A2A 的前提下,假设三框架都已生产就绪地支持 Agent 间互操作。


Spring AI:Advisor 链与手写 Workflow
#

为什么:Spring 团队已深度投入 Spring AI 与 Boot 集成;若你已在 Spring 栈内,需要清楚框架给的是原语而非开箱 workflow 引擎。

机制/约束:Spring AI 提供 ChatClientCallAdvisor、MCP starter 等。截至 1.1.x,无名为 Workflow 的 GA 抽象——示例仓库中 Workflow.parallel项目自定义 Supplier 并发工具(demo 版本 1.1.4),非框架 API。

Evaluator-Optimizer 通过自定义 ValidationRetryAdvisor 实现:在 adviseCall 中先 chain.nextCall(request),用 BeanOutputConverter 将响应转为 WeeklyPlan,再跑 domain validator;失败则把校验反馈写回 user message,调用 chain.copy(this).nextCall(request) 重试。源码用 for 循环 + maxRetries=3,与幻灯片上的 while(true) 演示语义等价、实现不同。若校验仅需 JSON schema 层,可直接用框架内置 StructuredOutputValidationAdvisor,不必重复造 ValidationRetryAdvisor

Spring AI 模块:Phase 1 注释与 Workflow.parallel 并行拉取 UserProfile、SeasonalIngredients。

ValidationRetryAdvisor 实现 CallAdvisor,校验失败时 revising 并重试。

怎么做(server 侧最小片段):

WeeklyPlan createNutritionPlan(String name, WeeklyPlanRequest request) {
  var result = Workflow.parallel(
      () -> fetchUserProfileForUser(name),
      () -> fetchSeasonalIngredients(request));
  var advisor = new ValidationRetryAdvisor<>(WeeklyPlan.class,
      plan -> validateWeeklyPlan(plan, profile));
  return chatClient.prompt()
      .system(Personas.RECIPE_CURATOR)
      .user(u -> u.text(PROMPT).param("days", request.days()))
      .advisors(advisor)
      .call().entity(WeeklyPlan.class);
}

Demo 还用社区包 ToolSearchToolCallAdvisor 做按需工具暴露——非 Spring AI GA 核心,是否纳入 Spring AI 2.0(milestone due 2026-06-11)需跟踪 release note。

常见误区:假设 Workflow.parallel 来自 Spring AI;忽略 maxRetries 上限;把 Advisor 链顺序不当——validation advisor 应挂在最终 call() 路径上,且 copy(after: this) 的递归深度要可观测;误把社区 ToolSearchToolCallAdvisor 当作 Spring 官方 GA 能力。


LangChain4j:experimental 的 AgenticServices
#

为什么:若希望用 builder/注解表达 sub-agent、sequence、loop,减少手写并发与 retry,langchain4j-agentic 提供更高层 API——但模块标注 experimental,需锁定版本。

机制/约束:核心入口 AgenticServices.agentBuilder / sequenceBuilder / loopBuilder / parallelBuilder。子 Agent 用 @Agent 接口 + @V 参数声明,例如 SeasonalIngredientAgent 通过 outputKey = "seasonalIngredients" 把结果写入 AgenticScope,供后续 Agent 读取。Loop 需 maxIterationsexitCondition;官方文档说明默认在子 Agent 调用后评估退出条件——未定义 exit condition 可能导致无法提前终止(演讲者踩坑经验)。示例仓库(langchain4j 1.13.0)同时支持 builder 与 @SequenceAgent / @LoopAgent / @ExitCondition 注解风格,与幻灯片 builder 写法行为等价。

LangChain4j:AgenticServices.loopBuilder().subAgents(nutritionGuard, reviserAgent).maxIterations(3)

怎么做

var validationLoop = AgenticServices.loopBuilder()
    .subAgents(nutritionGuard, reviserAgent)
    .maxIterations(3)
    .exitCondition(scope -> {
      var r = (NutritionAuditValidationResult)
          scope.readState("validationResult", null);
      return r != null && r.allPassed();
    }).build();

var planner = AgenticServices.sequenceBuilder(Agents.NutritionPlanner.class)
    .subAgents(seasonalAgent, weeklyPlanCreator, validationLoop)
    .outputKey("weeklyPlan")
    .build();

LangChain4j 文档将 Anthropic 五模式映射到 sequential / parallel / routing / planner / loop workflow——覆盖度在文档层可核对。相对 Spring AI,LangChain4j 把并行与 loop 从应用代码抽到框架 builder,代价是 experimental 模块的 API 稳定性与 Spring 文档深度仍落后于 Spring AI starter 体系。

常见误区:把 experimental 当 production GA;testExitAtLoopEnd = true 与每次子调用后检查 exit 的行为差异未评估就上线;在 loop 内忘记给 NutritionGuard 挂载 WeeklyPlan 工具对象,导致 Evaluator 无法做营养计算。


Embabel:GOAP 规划与 Stage 状态机
#

为什么:多步流程中硬编码 call order 随 domain 类型增长而 brittle;Embabel(Rod Johnson 主导,截至 demo 尚未 GA)在 JVM 上用 @Action + domain 类型图驱动编排,LLM 只负责单步推理。

机制/约束:Embabel README 写「From the creator of Spring」,demo 依赖 com.embabel.agent 0.3.5,guide 仍带 SNAPSHOT 标签——生产前应视为预览版。默认规划为 GOAP(Goal Oriented Action Planning),源码 AStarGoapPlanner 注释写明「using the A* algorithm」——公开文档写 GOAP,演讲强调 A*;准确表述应为「GOAP 规划(A 实现)」*。Embabel 还支持 Utility / Hybrid / Supervisor 等规划器,但 demo 用默认 GOAP。

每步 @Action 完成后框架 replan(OODA 循环):例如 createWeeklyPlan 需要 WeeklyPlanRequestUserProfileSeasonalIngredients 齐备,规划器自动安排 fetch 顺序,而非开发者硬编码 call list。@Action 通过方法签名中的 domain 类型表达前置条件;Ai.withLlm(LlmOptions.withAutoLlm()) 封装单步 structured output。缺依赖时 GOAP 规划失败的具体异常与回退策略未在公开 demo 完全验证

Embabel:@Action 方法 fetchSeasonalIngredients(WeeklyPlanRequest, Ai ai),注释 Required for MCP Server support。

Evaluator-Optimizer 分支编码为 Stage 状态机NutritionAudit record 实现 Stagevalidate 返回 DoneReviseWeeklyPlan,框架调度 @Action(canRerun = true) 重跑——比 Spring AI 手写 while-loop 更声明式。

NutritionAudit 的 validate:Use available tools to calculate total calories, protein, carbs, fat, and sodium

怎么做

@Action
SeasonalIngredients fetchSeasonalIngredients(WeeklyPlanRequest req, Ai ai) {
  return ai.withLlm(LlmOptions.withAutoLlm())
      .createObject(SEASONAL_PROMPT.formatted(month, country),
          SeasonalIngredients.class);
}

record NutritionAudit(...) implements Stage {
  @Action(canRerun = true)
  Stage validate(Ai ai) {
    var result = ai.withLlm(LlmOptions.withAutoLlm())
        .withToolObject(weeklyPlan)
        .createObject(..., NutritionAuditValidationResult.class);
    return result.allPassed()
        ? new Done(weeklyPlan)
        : new ReviseWeeklyPlan(...);
  }
}

REST 入口通过 AgentInvocation 启动(0.3.5 API:AgentInvocation.builder(agentPlatform).build(WeeklyPlan.class) + invoke(inputs)),与 MCP server 共用同一 Agent 能力。

NutritionPlannerController 注入 AgentPlatform;tooltip 说明 @UnfoldingTools progressive tool disclosure。

常见误区:把 A* 当作与 GOAP 并列的独立规划器开关;在非 GA 版本上押注生产 SLA;规划失败时的异常类型与回退策略未在公开 demo 完全验证


Token 经济下的工具暴露策略
#

为什么Anthropic advanced tool use 方向指出,大量 tool schema 占用 context——「100 tools × metadata」在按 token 计费下不可持续(定量模型为行业共识,三框架无公开 benchmark 对比)。

机制/约束:缓解路径包括 progressive disclosure、tool search、category 过滤。营养校验场景里,WeeklyPlan 上可能有按日统计、按餐次计数、钠/蛋白汇总等十余个工具——若一次性注册,tool schema 会挤占本可用于食谱内容的 context。

Embabel @UnfoldingTools 初始只暴露一个高层 tool,LLM 先表达意图(例如 category 'nutrition'),框架再展开对应 @LlmTool 子集;LlmReference 将大上下文注入 system prompt 而非 callable tool。Spring AI demo 用社区 ToolSearchToolCallAdvisor + ToolSearcher 实现类似「按需暴露」,思路与 Anthropic advanced tool use 同向,实现分属不同包

@UnfoldingTools(name = "weekly_meal_plan_tools",Pass category nutrition 展开 @LlmTool

怎么做

@UnfoldingTools(name = "weekly_meal_plan_tools",
    description = "Pass category: 'nutrition' for daily/weekly totals")
record WeeklyPlan(List<DailyPlan> days) {
  @LlmTool(category = "nutrition")
  Map<DayOfWeek, NutritionInfo> dailyNutritionTotals() { ... }
}

常见误区:只计 prompt 长度、忽略 tool definition token;把所有工具都做成 @LlmTool 而不分层;Spring AI tool search GA 时间未在官方文档确认(截至 2026-06-10);在未实测 token 用量的前提下,假设 progressive disclosure 一定比全量注册更省(极端短对话下可能相反)。


三框架对照:抽象层级与生态位
#

为什么:选型本质是「愿意手写多少编排」与「能接受多少框架魔法、版本风险」的权衡。

机制/约束:下表综合 GitHub 示例仓库 与官方文档;红/黄/绿能力矩阵为演讲现场主观快照(字幕亦声明 current state),非独立 benchmark。

维度Spring AILangChain4jEmbabel
抽象层级低(ChatClient / Advisor)中(AgenticServices)高(Stage / GOAP)
Workflow 开箱手写 + 内置 validation advisoragentic 模块(experimental)内置 pattern
Spring Boot starter一等公民demo 含 starter;文档深度因时间而异基于 Spring AI 生态
MCP HTTP serverspring-ai-starter-mcp-server-webmvccommunity stdio server 为主embabel-agent-starter-mcpserver
GA 状态Broadcom 企业路线社区 + Red Hat/IBM 贡献非 GA(0.3.x)

Comparing Agentic AI Frameworks Capabilities 矩阵:LangChain4j MCP 标注 No HTTP Server,Embabel 全场 Green——需结合上文 MCP 细分理解。

Mermaid diagram 2

怎么做(决策启发,非教条):

  1. 可预测流水线 + 已有 Spring 投资:Spring AI + StructuredOutputValidationAdvisor,编排自己写清楚;团队熟悉 @ServiceChatClient.Builder 注入时迁移成本最低。
  2. 快速搭 sub-agent + loop:LangChain4j agentic,锁版本、接受 experimental 变更;适合 PoC 或内部工具,需为 API breaking change 留升级窗口。
  3. 声明式 Stage + 目标规划:Embabel 表达力强,domain 类型即文档;生产需接受非 GA 与 replan 行为不确定性,并理解 GOAP 每步 replan 可能带来额外规划开销。
  4. MCP server 要 HTTP 一等集成:逐项核对 starter 与传输类型,勿只看矩阵颜色。
  5. 观测与测试:三框架 demo 均偏 Workflow,单元测试应覆盖 validator 与并行阶段;Pure Agent 路径才强依赖 LLM-as-judge 集成测试。

若只问「哪个最好」——没有 universal 答案。Spring AI 胜在生态与可控;LangChain4j 胜在 agentic 模块开箱度;Embabel 胜在 pattern 表达与 tool disclosure,但版本与 GA 状态是硬约束。

常见误区:用一场会议的矩阵做长期架构决策;忽略 LangChain4j「~80% 用户用 Spring」等无法公开验证的经验数据;把 Spring AI 2.0 / Boot 4 演讲日期(「2026 年 5 月」)与 GitHub milestone(2.0.0 due 2026-06-11、Boot 4.1.0 due 2026-06-10)混为一谈;看到 Embabel 矩阵全绿就忽略「非 GA + 更高抽象 = 更低运行时可控性」。


参考与延伸阅读
#

相关文章