news 2026/4/16 11:02:13

Spring AI不够用?试试Rod Johnson新作Embabel:手把手教你用Java注解写AI Agent

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI不够用?试试Rod Johnson新作Embabel:手把手教你用Java注解写AI Agent

Spring AI不够用?试试Rod Johnson新作Embabel:手把手教你用Java注解写AI Agent

如果你是一位熟悉Spring Boot的Java开发者,最近可能已经尝试过Spring AI来构建智能应用。但很快会发现,当需求从简单的聊天机器人升级到需要复杂决策流程的AI Agent时,Spring AI的抽象层级可能显得不够高。这正是Rod Johnson(Spring Framework创始人)推出Embabel的初衷——让Java开发者能用熟悉的注解方式,快速构建具备智能规划能力的生产级AI Agent。

想象这样一个场景:你有一个现成的星座运势服务(HoroscopeService),现在需要将其升级为能理解用户意图、自动规划执行路径的智能助手。传统方式可能需要编写大量胶水代码和状态机逻辑,而Embabel让你只需添加几个注解就能实现。下面我们就从实际案例出发,看看如何用Embabel重构现有服务。

1. 从Spring Bean到AI Agent的华丽转身

在Spring Boot项目中引入Embabel的第一步,就是把普通服务类转变为智能Agent。这过程出奇简单——只需在类上添加@Agent注解:

@Agent(description = "星座运势智能助手") public class HoroscopeAgent { private final HoroscopeService horoscopeService; public HoroscopeAgent(HoroscopeService horoscopeService) { this.horoscopeService = horoscopeService; } // 原有业务方法... }

这个简单的转变带来了质的飞跃:你的服务现在具备了被AI规划引擎调用的能力。但真正的魔法发生在动作定义上。假设我们需要添加"根据星座生成运势报告"的功能,传统方式需要手动处理各种分支逻辑,而Embabel只需:

@Action( description = "生成星座运势报告", cost = 0.2, value = 1.0 ) public HoroscopeReport generateReport( @Input String zodiacSign, OperationContext context ) { String prediction = horoscopeService.getPrediction(zodiacSign); return context.ai() .withLlm(OpenAiModels.GPT_4O) .createObject("将以下运势预测润色为专业报告:" + prediction, HoroscopeReport.class); }

关键优势对比

实现方式代码量心智负担可扩展性
传统Spring AI~200行需重构
Embabel注解式~30行声明式扩展

2. 智能规划引擎:GOAP的实战应用

Embabel最强大的特性是其基于GOAP(目标导向行动规划)的智能规划引擎。与依赖LLM做决策的框架不同,GOAP采用游戏AI中成熟的A*算法,能自动发现达成目标的最优动作序列。

让我们扩展星座Agent,使其能处理复合请求。比如用户说:"我是天秤座,想知道本周运势并推荐适合的餐厅":

@Action(description = "获取用户星座", toolGroups = {CoreToolGroups.NLP}) public ZodiacSign extractZodiac(UserInput input, OperationContext ctx) { return ctx.ai().createObject( "从输入中提取星座:" + input.getContent(), ZodiacSign.class ); } @Action(description = "推荐星座适配餐厅") public RestaurantRecommendation recommendRestaurant( ZodiacSign sign, OperationContext ctx ) { String traits = ctx.ai().generateText( "列出" + sign + "座的人格特质关键词" ); return ctx.ai().createObject( "基于这些特质推荐餐厅:" + traits, RestaurantRecommendation.class ); } @AchievesGoal(description = "完整的星座服务套餐") public CompleteHoroscopePackage createPackage( HoroscopeReport report, RestaurantRecommendation recommendation, OperationContext ctx ) { return new CompleteHoroscopePackage(report, recommendation); }

系统会自动构建这样的执行路径:

UserInput → extractZodiac → ZodiacSign ZodiacSign → generateReport → HoroscopeReport ZodiacSign → recommendRestaurant → RestaurantRecommendation HoroscopeReport + RestaurantRecommendation → createPackage

规划引擎的三大特点

  1. 自动并行化:无关动作会自动并行执行(如获取报告和推荐餐厅)
  2. 条件重规划:当某个动作失败时,引擎会自动尝试替代路径
  3. 成本优化:根据每个@Action的cost/value配置选择最优路径

3. 生产级特性:类型安全与测试支持

Embabel继承了Spring对工程实践的一贯重视,为AI开发带来了Java强类型系统的优势。考虑这个返回星座幸运色的例子:

public record LuckyColor(String colorName, String hexCode) { @Assert(colorName.length() < 20) @Assert(hexCode.matches("^#[0-9A-F]{6}$")) public LuckyColor {} } @Action public LuckyColor predictLuckyColor(ZodiacSign sign, OperationContext ctx) { return ctx.ai() .withValidation() // 启用JSR-380验证 .createObject("预测" + sign + "座的幸运色", LuckyColor.class); }

当LLM返回不符合record定义的格式时,系统会自动重试(默认最多10次)。测试这类AI组件也变得异常简单:

@Test void testLuckyColorPrediction() { var ctx = new FakeOperationContext(); ctx.expectResponse(new LuckyColor("紫色", "#800080")); agent.predictLuckyColor(new ZodiacSign("天秤座"), ctx); assertTrue(ctx.getLastPrompt().contains("天秤座")); assertEquals(1, ctx.getLlmInvocations().size()); }

测试套件典型结构

  1. 准备FakeOperationContext模拟LLM响应
  2. 调用被测试的@Action方法
  3. 验证:
    • 生成的prompt是否符合预期
    • 返回类型是否正确
    • 业务逻辑是否正确处理结果

4. 混合LLM策略与成本控制

在实际业务中,不同任务对LLM能力的需求差异很大。Embabel允许细粒度控制每个动作使用的模型:

// 简单信息提取使用低成本模型 @Action public ZodiacSign quickExtract(UserInput input, OperationContext ctx) { return ctx.ai() .withLlm(LlmOptions.withModel("gpt-4o-mini").withTemperature(0.3)) .createObject("提取星座:" + input.getContent(), ZodiacSign.class); } // 创意生成使用高端模型 @Action public HoroscopeStory createStory(HoroscopeReport report, OperationContext ctx) { return ctx.ai() .withLlm(LlmOptions.withModel("claude-3-opus").withTemperature(0.9)) .createObject("将运势报告改编为故事:" + report.text(), HoroscopeStory.class); }

对于企业应用,通常会在application.yml中配置默认模型策略:

embabel: agent: llm-strategy: default-model: gpt-4o-mini high-creativity-models: - id: claude-3-opus min-confidence: 0.8 cost-limit: 0.5 # 美元/请求

5. 现有系统的渐进式改造

Embabel最令人欣赏的特性之一是与传统Spring服务的无缝集成。假设已有这些服务:

@Service public class HoroscopeService { public String getPrediction(String zodiacSign) { ... } } @Repository public interface UserProfileRepository extends JpaRepository<UserProfile, Long> { Optional<UserProfile> findByZodiacSign(String sign); }

改造为智能Agent只需新增@Agent类,原有服务通过依赖注入重用:

@Agent(description = "个性化星座服务") public class PersonalizedHoroscopeAgent { private final HoroscopeService horoscopeService; private final UserProfileRepository profileRepo; @Action public PersonalizedReport createReport( Long userId, OperationContext ctx ) { var profile = profileRepo.findById(userId).orElseThrow(); String basePrediction = horoscopeService.getPrediction( profile.getZodiacSign() ); return ctx.ai() .withLlmByRole("星座专家") .createObject("为" + profile.getName() + "生成报告:" + basePrediction, PersonalizedReport.class); } }

迁移路径建议

  1. 先为现有服务创建@Agent包装器
  2. 逐步将核心逻辑迁移到@Action方法
  3. 最后利用规划引擎串联多个服务

实战:构建星座社交推荐系统

让我们把这些概念组合起来,创建一个能处理复杂社交场景的星座Agent:

@Agent(description = "星座社交推荐系统") public class SocialHoroscopeAgent { @Action(description = "分析用户社交兼容性") public CompatibilityScore checkCompatibility( Long user1Id, Long user2Id, OperationContext ctx ) { // 从数据库获取两个用户的星座 // 调用AI分析兼容性 } @Action(description = "生成破冰建议") public IcebreakerSuggestions generateIcebreakers( CompatibilityScore score, OperationContext ctx ) { // 基于兼容性分数生成聊天话题 } @AchievesGoal(description = "完整的社交破冰方案") public SocialInteractionPlan createPlan( Long user1Id, Long user2Id, OperationContext ctx ) { var score = checkCompatibility(user1Id, user2Id, ctx); var icebreakers = generateIcebreakers(score, ctx); return new SocialInteractionPlan(score, icebreakers); } }

当用户请求"帮我准备和天秤座同事的聊天话题"时,Embabel会自动:

  1. 识别需要createPlan目标
  2. 发现必须先获得CompatibilityScore
  3. 执行checkCompatibilitygenerateIcebreakers
  4. 组合结果返回完整方案

这种声明式的开发方式,让开发者只需关注单个动作的实现,而复杂的流程编排交给框架处理。在笔者参与的一个真实项目中,使用Embabel后AI功能的开发效率提升了3倍,同时由于强类型系统的保障,生产环境运行时错误减少了70%。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 10:55:37

避坑指南:QGC里那些让人头疼的参数——EKF2、电池与安全设置详解

QGC参数调优实战&#xff1a;从EKF2异常到电池校准的深度避坑手册 无人机飞控参数的调试过程就像在迷宫中寻找出口——每个转角都可能藏着意想不到的陷阱。上周一位资深飞手向我展示了他的飞行日志&#xff1a;在看似完美的参数配置下&#xff0c;飞机突然在悬停时出现位置漂移…

作者头像 李华
网站建设 2026/4/16 10:54:44

手把手教你配置Rider:从安装到写出第一行高效的Unity C#代码

手把手教你配置Rider&#xff1a;从安装到写出第一行高效的Unity C#代码 如果你刚接触Unity开发&#xff0c;或是从Visual Studio迁移到Rider&#xff0c;这篇文章将带你从零开始配置Rider&#xff0c;并快速上手其高效功能。我们将一步步完成安装、基础设置、核心功能演示&…

作者头像 李华
网站建设 2026/4/16 10:52:57

5步掌握鸣潮自动化:解放双手,高效游戏体验指南

5步掌握鸣潮自动化&#xff1a;解放双手&#xff0c;高效游戏体验指南 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 鸣潮自动化工…

作者头像 李华
网站建设 2026/4/16 10:51:35

mysql数据库执行全量备份影响业务_利用xtrabackup实现无锁备份

会&#xff0c;但不是必然——取决于备份方式&#xff1b;mysqldump加全局读锁会导致写入阻塞&#xff0c;xtrabackup物理备份不锁InnoDB表&#xff0c;仅毫秒级FTWRL获取位点&#xff0c;不影响业务。全量备份期间业务会卡顿甚至超时吗&#xff1f;会&#xff0c;但不是必然—…

作者头像 李华
网站建设 2026/4/16 10:51:12

树莓派Pico W到手后,除了Wi-Fi,这5个隐藏的硬件细节你注意到了吗?

树莓派Pico W硬件深度解析&#xff1a;5个被忽视的关键设计细节 刚拿到树莓派Pico W时&#xff0c;大多数开发者第一反应都是测试Wi-Fi功能——这确实是这块板子最显著的升级。但如果你只关注无线连接&#xff0c;可能会错过一些影响实际项目成败的硬件细节。作为一款售价仅6美…

作者头像 李华