ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Java AI框架选型:Spring AI、LangChain4j、AgentScope对比与实战建议

Java AI框架选型:Spring AI、LangChain4j、AgentScope对比与实战建议

1. 先搞清楚:你是要“接口封装”还是“智能体运行时”

Spring AI、LangChain4j、AgentScope、Embabel,这四个名字最近在AI应用开发群里出现的频率相当高。很多人一上来就问“哪个更好”,但在我做了几个月的框架选型和项目预研之后,我的答案很明确:先别问哪个更好,先问你的场景需要什么。

这四个框架虽然都叫“AI框架”,但底层定位差别很大。Spring AI更像是给你一套标准化的“接入层”,它不关心你脑子里天马行空的Agent流程,只管让你用最Spring的方式把大模型、向量库、工具函数串起来。LangChain4j则继承了LangChain的链式编排思维,适合快速搭RAG和工具调用,但同时又不像LangChain那么重,它在Java和Kotlin生态里做了大量本土化设计。AgentScope是走“多智能体协同”路线的,它不单是给你一个Model封装,而是给你一套能定义多个智能体、消息传递、分布式调度的运行时。至于Embabel,我必须诚实说,目前公开资料和社区规模都不太够,我更多把它当作“技术预研观察项”,而不是生产选项。

所以这篇文章不是要给你一个“谁打败谁”的结论,而是把我实际踩过的坑、做过的对比测试、生产环境里的取舍思路整理出来。适合正在选型的技术负责人、Java后端开发、以及准备从“调API”走向“做AI应用工程”的同学参考。

2. 四个框架各是什么路数,底牌在哪

2.1 Spring AI:依托Spring生态的“标准接入层”

Spring AI从2023年开始孵化,到1.0 GA之后API才基本稳定。它的核心思路是:把大模型接入这件事抽象成Spring风格的Bean和Starter。你需要ChatClient,那就注入ChatClient;你需要向量存储,那就注入VectorStore;你需要给模型加工具,那就声明一个@Tool注解的Bean。这种设计对已经用Spring Boot的团队特别友好,因为不用改变项目结构,不用引入一套全新的编程模型。

它的另一个低价优势是“适配器模式”。OpenAI、Azure OpenAI、Ollama、通义、Qwen、Claude、Gemini这些模型提供商都有对应的Spring Boot Starter。你在配置里改几个参数就能切换模型提供方,业务代码基本不用动。我实测过一个项目,原来接的是OpenAI,后来要换成通义千问,只改了application.yml里的base-url、api-key和modelName,其他代码不变。这个体验在LangChain4j里也能实现,但Spring AI和Spring Boot的配置绑定、自动装配做得更彻底。

但Spring AI也有它尴尬的地方。它不是一个“流程编排引擎”,更多是“模型与组件接入层”。虽然现在也提供了一些Agent相关的接口和Advisor机制,但真正复杂的多智能体协作、循环决策、动态图谱,它支持得并不深入。如果你想在Spring AI里实现一个类似AutoGPT的自动计划执行循环,你得自己写状态机和循环控制。

2.2 LangChain4j:Java世界里的“链式工具箱”

LangChain4j可以说是LangChain在JVM生态的一个高质量移植。它保留了LangChain的经典概念:Chain、Message、Tool、RAG组件,但去掉了很多Python生态里因版本迭代而变得冗余的包袱。

LangChain4j最亮眼的是AiServices。这个机制解决了我很长时间的痛点:以前我想让模型根据结构化输入调用Java方法,得自己解析模型输出,匹配函数签名,再处理调用结果。用AiServices之后,你可以定义一个接口,在接口方法上标注@Tool,然后把这个接口作为“代理”交给模型。模型自动决定调用哪个方法、填什么参数,你再也不用手写正则去解析JSON。

RAG方面,LangChain4j的抽象也很成熟。它把文本切分、Embedding、向量存储、检索、重排序、提示词组装拆成了独立的组件。你可以选本地库里的InMemoryEmbeddingStore做测试,也可以接Milvus、PGVector、Elasticsearch。跟Spring Boot结合也很常见,我甚至见过有人专门写一个配置类把LangChain4j的EmbeddingStore封装成Spring Bean,然后在Service层直接注入。

它的问题在于:版本迭代很激进。我经历过0.30左右的版本,后来升到0.35以上,很多API换了名字,ContentRetriever、EmbeddingStore的构造方式也改过。如果你的项目长期锁版本,问题不大,但如果你喜欢跟着最新版走,就得做好迁移的心理准备。

2.3 AgentScope:为“多智能体协作”准备的运行时

AgentScope最早从Python生态走出来,后面提供了Java版本,正是很多Java团队需要的。它的设计目标不是“接入模型”,而是“编排多个智能体一起干活”。它给你提供了Agent的抽象、消息对象、工作流调度、分布式通信等能力。

2.0版本里提到了“RAG as a Service”这样的方向。也就是说,你不仅可以在本地做检索增强,还可以把RAG能力暴露成一个服务,供多个Agent调用。这对于企业里做知识库问答、智能客服、研究助手这类场景其实很实用。

AgentScope最大的不同是它的“控制反转”思路。你用AgentScope,不是在一段Service代码里手动调用链式逻辑,而是定义“主管Agent”和“子Agent”,让它们通过消息互相通信,共同完成一个复杂任务。这在多智能体协作、多轮反思、分组讨论这类场景里,要比Spring AI和LangChain4j省力得多。

不过,多智能体的复杂度也是它的门槛。如果你只是想做一个“单轮问答+知识库检索”,用AgentScope会觉得重;但如果你要做“多个角色协同分析一份文档,最后汇总成报告”,那它就是更合适的工具。

2.4 Embabel:新兴框架,先观察再决定

标题里的Embabel,我必须坦诚地说,它的公开资料、社区讨论和代码仓库规模,目前都还处于早期阶段。我见过有人在技术群里把它作为“轻量级模块化智能体框架”来推荐,但能查到的生产落地案例很少,中文文档也不系统。在写这篇文章时,我的结论是:所在团队如果要做长期核心业务,不建议现在押注Embabel。

但这不代表没有价值。新兴框架往往在架构设计上更激进,也更贴近“模块化”、“可插拔”的思路。如果你团队有专门的AI平台组,愿意投入人力去读源码、补文档、维护fork,那它可以作为一个技术预研方向。花半天时间跑通它的hello world,了解它的核心抽象,再决定是否值得深入,是比较稳妥的路径。我个人的原则是:框架选型看三条——社区活跃度、版本稳定性、生产案例可复制性,Embabel这三条目前都不够明确,所以暂缓。

3. 从关键维度硬碰硬:不只看Star,更看生产适合度

3.1 语言与技术栈归属

这一点最简单,但也最容易被忽视。

Spring AI只服务Java/Kotlin技术栈,和Spring Boot深度绑定。如果你的项目里有Spring Boot,那它就是“零学习门槛”的扩展。LangChain4j同样面向JVM,但它不强制依赖Spring,你可以在纯Java、Quarkus、Micronaut甚至Android项目里用。AgentScope有Python和Java两个主要版本,Java版适合已有Java微服务体系的团队。Embabel则需要按你看到的具体项目判断,通常也是JVM或Node栈,但不够统一。

我在选型时通常先做减法:团队主力语言是Java,就直接把纯Python框架排除掉,不给自己找麻烦。

3.2 RAG落地能力对比

RAG是现在AI应用落地最多的场景,所以必须单独说。

Spring AI的RAG演进速度非常快。早期要自己用EmbeddingModel生成向量,再塞进VectorStore,然后再写Advisor去查。现在1.0版本里提供了比较完整的RAG链路,包括文档加载、切分、向量化、检索、重排序,都有对应接口。而且Spring AI把RAG顾问逻辑标准化成了QuestionAnswerAdvisor,你只要配好VectorStore,ChatClient回答问题时会自动从库里检索相关信息来增强上下文。

LangChain4j的RAG能力更“强控制”。它提供了非常精细的切分策略,比如按段落、按句子、按自定义分隔符,也支持多种Embedding模型和向量库。我比较喜欢的是它的ContentRetriever接口,你可以把检索逻辑完全自定义,比如先走关键词搜索再走向量搜索做融合,返回给模型时还可以带上来源引用。这一点在合规要求高的企业场景很实用。

AgentScope在RAG上更偏向“服务化”。Java版2.0把RAG作为一个服务能力来对待,你可以把知识库检索、重排、上下文组装封装成一个可被多个Agent调用的服务,而不是在某一个Agent内部写死。这对复杂智能体场景是有利的,但也意味着你需要先理解AgentScope的服务通信方式。

Embabel目前关于RAG的资料非常有限,没有形成一套成熟的标准组件,这也是我不建议直接用于生产的原因之一。

3.3 Agent编排与工具调用

工具调用是现在AI框架的“兵家必争之地”。

Spring AI支持Function Calling,写法也很Spring。你把一个Java方法注册成Bean,然后在ChatClient的.tools()里传入,模型在回答时会根据用户问题决定是否调用这个工具。但Spring AI对“多个工具之间如何协商”“一次任务需要多个模型协作”这类问题,并没有给出高层抽象。它更像“给模型一把瑞士军刀”,至于怎么用这把刀,由你的业务代码决定。

LangChain4j的AiServices在工具调用上做得非常顺手。你可以把一组服务方法组织成Tool类,标注@Tool,描述清楚工具用途和参数含义,模型会自动选择。它还有@ToolMemory之类的机制,可以让模型在多次对话中记住已经调用过哪些工具。这一点在复杂业务场景里很关键,比如客服机器人需要查询订单、查询库存、创建工单,模型需要知道“上一次已经查过订单号了”。

AgentScope则走的是另一条路。它的基础单元不是“一次模型调用”,而是“一个Agent”。每个Agent可以有自己的Prompt模板、模型配置和工具集合,Agent之间通过消息通信。系统级的编排能力,比如顺序执行、并行执行、条件分支,在AgentScope里都有支持。如果你要做一个“事件风暴式”的多Agent协作文本分析系统,用AgentScope比前面两个框架都舒服。

3.4 可观测性与调试体验

AI应用的可观测性和传统后端不太一样。除了看日志、监控、链路追踪,你还需要看到“模型输入了哪些Prompt”“模型返回了什么内容”“从向量库里检索到了哪几条文档”。

Spring AI在这方面做得相当体系化。它有专门的Observability API,可以和Micrometer、Zipkin、OpenTelemetry结合,把模型调用、向量检索作为Span记录下来。生产环境里出问题,你能在链路追踪系统里直接看到是哪一步丢的上下文。

LangChain4j的调试更“平易近人”。你可以在代码里监听整个调用过程,打印每个阶段的消息和工具调用记录。我在本地调试时,会专门写一个日志拦截器,把ChatMessage按时间顺序打到文件里。这个习惯帮我解决了很多“模型回答前后矛盾”的玄学问题。

AgentScope自带可视化面板,可以查看Agent的状态、消息流向和运行日志。这在调试多智能体协作时非常管用。如果不用可视化面板,单看日志会看得头大,因为多个Agent在同时说话,顺序和层级很难从纯文本里还原。这个可视化能力是AgentScope的加分项,也是其他两个框架目前没有现成方案的。

3.5 版本稳定性与企业支持

Spring AI由Spring官方团队维护,版本节奏跟Spring Boot保持同步。1.0 GA之后,API基本稳定,但升级仍需谨慎。我在项目中亲眼见过一个小版本升级导致ChatClient构建器行为变化的情况,所以建议关注changelog。

LangChain4j社区非常活跃,Roadmap清晰,但它的版本迭代速度比Spring AI更快,新功能多,破坏性变更也多。如果团队没有专职维护框架版本的人,建议锁一个大版本,别盲目追新。

AgentScope背靠阿里的工程团队,Java版也在持续改进。企业级支持比个人开源项目靠谱,但它相对“All-in-Agent”的路线意味着很多地方是按多智能体场景设计的,如果你只是做单Agent,可能体会不到它的优势,反而觉得复杂。

Embabel这里就不强行对比了,因为“没有足够信息”本身就是一种信息。

4. 实打实跑一遍:三个框架的典型链路

4.1 Spring AI:用ChatClient搭一个带RAG的问答服务

先说结论:如果你的主力技术栈是Spring Boot,用Spring AI搭RAG是最快的一条路。

假设你要做一个基于产品文档的客服问答。第一步是引入依赖:

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-openai</artifactId> <version>1.0.0</version> </dependency>

然后在application.yml里配置模型信息:

spring: ai: openai: api-key: ${OPENAI_API_KEY} chat: options: model: gpt-4o-mini

接着定义向量存储。本地测试可以用SimpleVectorStore,生产环境建议接PGVector或Milvus:

@Bean VectorStore vectorStore(EmbeddingModel embeddingModel) { return new SimpleVectorStore(embeddingModel); }

最后构建一个带RAG顾问的ChatClient:

ChatClient chatClient = ChatClient.builder(chatModel) .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore)) .build(); String answer = chatClient.prompt("根据资料回答:什么是退款保护?") .call() .content();

这段代码的核心在于QuestionAnswerAdvisor。它会在模型真正回答之前,先根据用户问题去向量库里检索相似内容,再把检索结果作为上下文拼进Prompt,最后让模型基于这些内容生成答案。你不用手动处理“把文档拼进Prompt”这种脏活。

我实际使用中最满意的点是:它可以和现有事务、安全框架完全共存。你可以在Controller层做用户权限校验,在Service层调用ChatClient,整体代码风格跟普通Spring应用一致,团队新人上手很快。

但要注意,QuestionAnswerAdvisor默认上下文窗口有限,如果你们文档很多,需要自己配置Top-K、相似度阈值等参数,否则你会发现模型总是引用不相关内容。

4.2 LangChain4j:用AiServices快速让模型调用你的业务方法

LangChain4j最有吸引力的用法是“让模型直接调用你的业务代码”。

第一步引入依赖:

<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>1.0.0-alpha1</version> </dependency>

创建模型:

OpenAiChatModel model = OpenAiChatModel.builder() .apiKey(System.getenv("OPENAI_API_KEY")) .modelName("gpt-4o-mini") .build();

定义工具接口。注意,这里不是普通的Java接口,而是会被模型识别成“可调用工具”的接口:

public interface OrderAssistant { String queryOrderStatus(String orderId); }

再写一个实现类,并标注@Tool:

public class OrderTools { private final OrderService orderService; @Tool("查询订单状态,参数为订单号") public String queryOrderStatus(String orderId) { return orderService.getStatus(orderId); } }

然后用AiServices把它织成一个“智能服务”:

OrderAssistant assistant = AiServices.builder(OrderAssistant.class) .chatModel(model) .tools(new OrderTools()) .build(); String answer = assistant.queryOrderStatus("PO-20240601");

这里用户直接发起一条“查一下PO-20240601到哪一步了”的消息,模型会识别意图,调用queryOrderStatus方法,把真实数据带回模型生成回答。

这个模式比传统的“意图识别+规则路由”优雅得多。你不需要把每个接口调用意图都写死在代码里,模型会基于工具描述和用户表达自动匹配。

但坑也有:工具描述必须写清楚参数含义,否则模型会拿错参数。我曾经把一个日期格式的工具描述写得不够明确,模型连续三天都把参数传成“yyyy-MM-dd”格式,而代码里需要的却是时间戳,排查了很久才发现是描述没有交代清楚格式。

4.3 AgentScope:搭一个“写周报”的多智能体小组

AgentScope适合的场景,我用一个写周报的案例来说明。

假设你希望多个“角色”协作完成一份周报。一个“收集Agent”负责汇总系统里的需求、缺陷、上线事件,一个“分析Agent”负责看数据趋势,一个“撰写Agent”负责把结论组织成完整周报。

在AgentScope里,你可以把这些角色定义成不同的Agent,它们共享一套消息协议。主流程编辑好之后,Agent之间自动交换消息。比如收集Agent把原始信息发给分析Agent,分析Agent把结果发回,最后由撰写Agent输出完整内容。

相比在Spring AI或LangChain4j里手动写循环调用,AgentScope把“谁先执行、谁后执行、结果怎么传递”这件事变成了流程配置。这个抽象层级更高,也更适合多人协作的大型智能体项目。

我建议你初次尝试AgentScope时,先不急于接自己的业务,而是跑一遍官方示例,把它的消息、上下文、Agent生命周期这几个概念摸清楚。如果一上来就强行把旧代码迁进去,会很痛苦。

5. 这些坑,文档一般不会写

5.1 模型参数与供应商差异:同样的Prompt,不同模型结果差异巨大

框架能帮你统一接口,但统一不了模型。同一个Prompt在GPT-4o、Qwen、Claude上的表现可能完全不同。有些模型擅长JSON输出,有些模型擅长长文归纳,有些模型会在工具调用时产生多余文本。

我建议把模型名、温度、Top-P、超时时间这些参数全部放到配置中心或环境变量里,不要写死在代码中。否则做模型切换时,你会被迫重新发一版。

另外,供应商的API兼容性并没有你想象得那么统一。看似都是OpenAI协议,实际响应用的字段可能不同,尤其是工具调用和流式输出。框架虽做了一层适配,但不可能抹掉所有差异。切换模型之后,一定要拿线上样本做回归测试。

5.2 Token与上下文长度:RAG比你想的更容易超限

RAG链路最容易踩的坑,不是向量库没配好,而是文档切分和上下文组装。

文档切得太碎,检索效果差,模型拿不到完整信息。文档切得太粗,每次检索都会把一大段塞进Prompt,很容易超过模型上下文限制。我见过一个知识库项目,原本每段切500个Token,但一份技术文档里有很多连续表格,切出来之后每次都把整张表带进上下文,导致超限报错。

后来改为“按标题结构切分”:先识别Markdown标题,把同一标题下的段落合并成块,超过阈值再二次切割。这样检索到的内容相对完整,超限问题也减少很多。另外,Prompt里要明确告诉模型“只基于检索内容回答,不要使用外部知识”,否则模型会自由发挥,产生幻觉。

5.3 异步与事务边界:别让AI调用和数据库事务粘在一起

这是很多后端团队容易忽略的一点。AI调用通常是几十秒甚至分钟级别,绝不能放在数据库事务里。我有一个很惨痛的教训:在一个服务里调用模型生成文案,然后把这个过程放在@Transactional方法里,结果模型接口慢响应3秒,数据库连接池直接被占满,整个服务雪崩。

正确做法是:AI调用放在事务外层,先查数据,再调用模型,最后开启事务存结果。更稳妥一点,把AI调用做成异步任务,通过消息队列或任务表驱动,前端轮询进度。这样即使模型接口挂了,也不会拖垮主业务流程。

5.4 版本更新带来的迁移痛苦:Spring AI 1.0前后的变化

框架快速发展期,最烦人的就是API变来变去。

Spring AI从0.8到1.0,很多类的包名和构建器方式都调整过。网上很多教程还是老版本写法,比如OpenAiChatClient,在1.0里已经变成了ChatClient.builder(chatModel)。如果你按旧教程写,编译直接报错。

LangChain4j类似,ChatLanguageModel和StreamingChatLanguageModel的接口在多个版本里都有微调。我建议每升级一个小版本,先跑一遍所有的测试用例,不要光看编译通过就完事。模型的返回格式变化不会在编译期暴露,只能在测试里发现。

6. 到底怎么选?一张表和三条判断逻辑

6.1 决策建议速查表

场景首选框架理由
已有Spring Boot项目,想快速接大模型Spring AI与Spring生态无缝集成,配置和开发体验最顺
需要快速实现RAG、复杂工具调用LangChain4jAiServices和检索抽象非常灵活
核心场景是多智能体协作AgentScope内置消息通信、流程调度和可视化面板
想尝试极新的模块化设计Embabel适合预研,不适合核心生产
大型分布式多节点Agent系统AgentScope分布式通信是它的强项
高度定制化的知识库问答LangChain4j检索、重排、融合可以完全自己控制
团队全是Java新人,没有AI框架经验Spring AI学习曲线低,符合Spring习惯

6.2 用三条判断逻辑对号入座

第一条逻辑:看你们团队技术栈和现有系统。如果现在就是Spring Boot体系,选Spring AI的迁移成本最低,团队用起来最顺手。如果你们是纯Java服务,但不想被Spring绑定,LangChain4j更合适。如果你们是做前端多模态Agent平台,或者研究性项目,AgentScope更适合。

第二条逻辑:看核心场景到底对不对。单Agent + RAG,首选Spring AI或LangChain4j。多Agent + 自动决策 + 协作式任务,AgentScope更合适。只做一个“模型适配层”,Embabel这种新兴框架也许能满足,但风险高。

第三条逻辑:看你们能接受多少维护成本。Spring AI有官方维护,但1.0后仍在加速演进。LangChain4j社区强,但破坏性变更频繁。AgentScope功能多,但学习曲线陡。选框架不是选“最好的”,而是选“你团队能长期驾驭的”。

我也想说说混合方案。生产环境里,我见过不少团队把Spring AI和LangChain4j混着用:底层模型接入和配置交给Spring AI,上层复杂工具编排和RAG检索用LangChain4j。这两个框架可以共存,只是你要多花一点心思理清边界。AgentScope也可以作为上层协调器,调用Spring AI或LangChain4j构建的子Agent。这种组合的好处是各自发挥长处,坏处是系统里出现两个框架,概念重叠可能让人混乱。没有一定的工程能力,还是别混用太多。

最后分享一点个人体会:我在做技术预研时,最怕的不是框架功能不够,而是框架版本不成熟导致团队反复返工。与其追求“最好”的框架,不如先选一个团队上手最快、社区能兜底的方案,把业务跑起来,再逐步引入更复杂的编排能力。AI框架的更新速度快到让人怀疑人生,但业务价值稳定得多了。框架是助推器,不是引擎本身。希望这篇对比能帮你少走点弯路,也欢迎你在评论区聊聊你团队实际选型时踩过的坑。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进