2026-01-21
Embabel
0

目录

一、 核心设计:为什么它是“JVM 原生”的 Agent 革命?
1. 放弃死板的 DAG,引入“动态规划”
2. 强类型约束:告别“魔术贴”字典
3. Spring 原生基因
二、 实战:Spring 项目集成与自定义 AI 厂商
1. 自定义 AI 厂商配置
2. 构建“退货处理 Agent”
三、 深度拆解:日志里的“黑科技”
核心日志追踪:
为什么说这是“自适应规划”?
最终结果:
四、与LangChain的比较
五、推荐使用 Embabel 的场景
六、 结语

在 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 无缝桥接国内大模型。

java
/** * 直接创建 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中加入:

yml
embabel: models: default-llm: qwen3-max

2. 构建“退货处理 Agent”

在 Embabel 中,开发不再是写死 if-else,而是定义领域模型和动作。

java
@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

核心日志追踪:

Plaintext

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

为什么说这是“自适应规划”?

  1. 意图感知:初始状态只有 UserInput。系统检测到目标是 RefundDecision,通过类型依赖分析,自动算出了执行路径

  2. 混合执行流

    • 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 / FSMGOAP + Replanning(自适应)
数据结构Dict / JSON 为主强类型 Domain Model
执行控制主要交给 LLMJVM 算法主导,LLM 只做认知补全
工程特性生态广,适合快速构建原型生产友好:支持 AOP、严谨测试、易于长期维护
出错方式语义漂移、隐性失败显性失败、日志可追踪

五、推荐使用 Embabel 的场景

  1. 多步骤动态决策:如电商退货处理、保险理赔审批。这类场景的逻辑分支极多,用传统的 if-else 或固定图(Graph)会陷入“状态爆炸”,而 Embabel 的 GOAP 算法 能自动处理海量分支。

  2. 高安全性/确定性需求:如果你担心 AI “幻觉”导致调用了不该调用的接口,Embabel 的类型沙箱和行动约束能强制 AI 在预设的 Java 业务逻辑轨道内运行。

  3. 大型企业级项目:当你需要利用 Spring 的 DI、AOP 以及成熟的单元测试体系来管理 Agent 时,Embabel 是唯一的“二楼”框架(在 Spring 之上构建)。

六、 结语

Embabel 的出现,标志着 Java 开发者正式进入了 “意图驱动开发(Intent-Driven Development)” 的时代。

  1. **从“写逻辑”到“定目标”:**开发者不再是 AI 的“保姆”,而是规则的“制定者”。

  2. **让 AI 真正落地:**它通过 JVM 的严谨性驯服了 LLM 的随机性,解决了企业级应用中最核心的“信任”问题。

GitHub 传送门https://github.com/embabel/embabel-agent

本文作者:鑫 · Dev

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!