在 Java 统治企业级开发的 20 年里,我们习惯了确定性的逻辑。然而,AI 浪潮让 Python 凭借灵活性抢占了先机。
Spring 创始人 Rod Johnson 在介绍 Embabel 时曾明确表示:这是他自 Spring 之后,最希望投入精力推动的一个方向性项目——目标不是简单追赶 Python,而是为 JVM 生态构建真正可落地的 Agent 能力。
Embabel 并非简单的 LLM 封装,它是类似于 Spring MVC 级别的高级 Agent 框架,旨在为 JVM 生态带来真正的 AI 生产力。
一、 核心设计:为什么它是“JVM 原生”的 Agent 革命?
1. 放弃死板的 DAG,引入“动态规划”
大多数 Agent 框架依赖预定义的有限状态机(FSM)或硬编码的顺序执行。Embabel 引入了游戏 AI 领域著名的 GOAP(目标导向行动计划)算法。
-
动态寻路:开发者只需定义 Action(行动) 和 Goal(目标),系统会自动规划执行路径,甚至能完成未被硬编码的复杂任务。
-
OODA 闭环:系统在每一步 Action 完成后都会进行 Replanning(重新规划)。它能观察上一步的效果并自适应调整。
2. 强类型约束:告别“魔术贴”字典
Python 框架中常见的 Dict 传递在大型工程中是灾难性的。Embabel 充分利用 Java/Kotlin 的强类型特性,将 Prompt 交互、代码逻辑和领域模型(Domain Model)深度融合,支持完整的重构(Refactoring)。
3. Spring 原生基因
作为 Rod Johnson 的力作,Embabel 支持熟悉的注解驱动(@Agent、@Action)、依赖注入以及完善的测试体系,让 AI 开发拥有与传统 Java 开发一致的工程化体验。
二、 实战:Spring 项目集成与自定义 AI 厂商
由于 Embabel 社区文档尚处于早期,对于如何接入国内主流模型(如通义千问)缺乏指引。本文基于 Spring + Spring AI + Embabel 这一黄金组合,手把手构建一个生产级的“退货处理智能 Agent”。
1. 自定义 AI 厂商配置
通过自定义 Llm Bean,我们可以利用 Spring AI 的 ChatModel 无缝桥接国内大模型。
/**
* 直接创建 Spring AI ChatModel,指向百炼 OpenAI 协议接口
*/
@Bean
public OpenAiChatModel bailianChatModel() {
OpenAiApi api = OpenAiApi.builder()
.apiKey("sk-xxxx")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode")
.build();
return OpenAiChatModel.builder()
.openAiApi(api)
.defaultOptions(OpenAiChatOptions.builder()
.model("qwen3-max")
.temperature(0.7)
.build())
.build();
}
/**
* Embabel Llm Bean,包装上面的 ChatModel
*/
@Bean
public Llm bailianLlm(OpenAiChatModel bailianChatModel) {
return new Llm(
"qwen3-max", // Embabel default LLM 名称
"bailian", // provider 名称,随便写
bailianChatModel);
}
在application.yml中加入:
embabel:
models:
default-llm: qwen3-max
2. 构建“退货处理 Agent”
在 Embabel 中,开发不再是写死 if-else,而是定义领域模型和动作。
@Agent(description = "处理客户退货请求的专业助手")
@Component
public class ReturnAgent {
@Action(description = "从用户输入中提取订单号和退货原因")
public OrderInfo extractOrderInfo(UserInput userInput, Ai ai) {
return ai.withDefaultLlm().createObject(
"从用户输入中提取退货信息。用户输入: %s".formatted(userInput.getContent()),
OrderInfo.class);
}
@Action(description = "查询订单信息数据库")
public DbRecord lookupOrder(OrderInfo orderInfo) {
// 模拟数据库返回,实际开发中此处为 DB 调用
return new DbRecord("ORDER123", "DELIVERED", "2024-06-15", true, 299.99);
}
@AchievesGoal(description = "为用户生成最终的退货决策和解释")
public RefundDecision finalizeDecision(OrderInfo orderInfo, DbRecord dbRecord, Ai ai) {
var prompt = "用户想退货: %s, 数据库状态: %s. 请根据7天内可退政策给出决策。".formatted(orderInfo, dbRecord);
return ai.withDefaultLlm().createObject(prompt, RefundDecision.class);
}
}
三、 深度拆解:日志里的“黑科技”
调用接口测试:GET /api/ai/refund-decision?userInput=用户想退货订单号:ORDER123
核心日志追踪:
14:18:57.398 [task-1] INFO Embabel - [epic_tu] ready to plan from:
{it:OrderInfo=FALSE, it:DbRecord=FALSE, it:UserInput=TRUE, it:RefundDecision=FALSE}
14:18:57.437 [task-1] INFO Embabel - [epic_tu] formulated plan:
extractOrderInfo -> lookupOrder -> finalizeDecision
14:18:57.486 [task-1] INFO Embabel - [epic_tu] executing action extractOrderInfo... using LLM qwen3-max
14:18:59.322 [task-1] INFO Embabel - [epic_tu] object bound it:OrderInfo
14:18:59.361 [task-1] INFO Embabel - [epic_tu] formulated plan:
lookupOrder -> finalizeDecision
14:19:03.251 [task-1] INFO Embabel - [epic_tu] completed in PT5.899S
为什么说这是“自适应规划”?
-
意图感知:初始状态只有
UserInput。系统检测到目标是RefundDecision,通过类型依赖分析,自动算出了执行路径。 -
混合执行流:
-
AI 语义提取:耗时 1.8s,将模糊的文字转化为强类型的
OrderInfo对象。 -
原生 Java 逻辑:拿到订单号后,系统自动触发
lookupOrder。注意:这一步是纯 Java 代码,无需 LLM 介入,保证了核心业务的确定性。 -
终极决策:所有拼图凑齐,LLM 结合数据库信息生成最终 JSON。
-
最终结果:
JSON
{
"approved": false,
"actionCode": "REJECT_OUTSIDE_RETURN_WINDOW",
"message": "您好,感谢您联系我们。根据我们的退货政策,商品需在签收后7天内申请退货。您的订单于2024年6月15日签收,目前已超过退货期限,因此无法为您办理退货。不过,该商品仍在保修期内,如遇质量问题,欢迎随时联系客服获取支持。",
"nextStep": "建议用户检查商品是否存在问题,如有质量问题可申请保修服务"
}
四、与LangChain的比较
在 Agent 领域,Embabel 与 LangChain 并不是“谁取代谁”的关系,而是服务于完全不同的问题空间。
| 维度 | LangChain(含 LangGraph) | Embabel |
|---|---|---|
| 核心思想 | Prompt + Chain + Tool 编排 | Goal + Action + 动态规划 |
| 流程模型 | 静态 DAG / FSM | GOAP + Replanning(自适应) |
| 数据结构 | Dict / JSON 为主 | 强类型 Domain Model |
| 执行控制 | 主要交给 LLM | JVM 算法主导,LLM 只做认知补全 |
| 工程特性 | 生态广,适合快速构建原型 | 生产友好:支持 AOP、严谨测试、易于长期维护 |
| 出错方式 | 语义漂移、隐性失败 | 显性失败、日志可追踪 |
五、推荐使用 Embabel 的场景
-
多步骤动态决策:如电商退货处理、保险理赔审批。这类场景的逻辑分支极多,用传统的 if-else 或固定图(Graph)会陷入“状态爆炸”,而 Embabel 的 GOAP 算法 能自动处理海量分支。
-
高安全性/确定性需求:如果你担心 AI “幻觉”导致调用了不该调用的接口,Embabel 的类型沙箱和行动约束能强制 AI 在预设的 Java 业务逻辑轨道内运行。
-
大型企业级项目:当你需要利用 Spring 的 DI、AOP 以及成熟的单元测试体系来管理 Agent 时,Embabel 是唯一的“二楼”框架(在 Spring 之上构建)。
六、 结语
Embabel 的出现,标志着 Java 开发者正式进入了 “意图驱动开发(Intent-Driven Development)” 的时代。
-
**从“写逻辑”到“定目标”:**开发者不再是 AI 的“保姆”,而是规则的“制定者”。
-
**让 AI 真正落地:**它通过 JVM 的严谨性驯服了 LLM 的随机性,解决了企业级应用中最核心的“信任”问题。
GitHub 传送门:https://github.com/embabel/embabel-agent