ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

Spring AI、LangChain4j、AgentScope、Embabel 四工具角色定位与组合选型指南

Spring AI、LangChain4j、AgentScope、Embabel 四工具角色定位与组合选型指南

1. 这不是“选框架”,而是“选解题路径”:先拆清四个工具的真实角色

你搜“Spring AI、LangChain4j、AgentScope、Embabel 哪个更好”,点开一堆对比文章,结果发现——它们根本不在同一张考卷上答题。这不是四款同类型AI SDK的横向PK,而是四条不同技术路径在解决不同层次问题时的自然交汇。我去年带团队落地三个企业级AI项目,从金融风控问答到制造业设备知识库再到电商智能导购,踩过所有这四个工具的坑,也亲手把它们组合起来跑通生产环境。今天不讲虚的“优劣排名”,只说一句实在话:Spring AI 是 Spring 生态里的“AI 插座”,LangChain4j 是 Java 世界的“RAG 装配线”,AgentScope 是面向复杂 Agent 编排的“调度中枢”,而 Embabel?它压根不是框架,是 Java 社区里一个专注模型协议适配的轻量级胶水层。这句话背后藏着所有选型逻辑的起点。

为什么必须先破这个认知误区?因为太多团队一上来就问“哪个更火”,结果在 Spring Boot 项目里硬塞 LangChain4j 的链式调用,又在需要多智能体协同的场景下死磕 Spring AI 的单步调用,最后发现性能卡在序列化、上下文丢失、状态无法持久化这些本不该由框架解决的问题上。真实世界里没有“万能框架”,只有“匹配问题的最小可行解”。比如我们做餐饮 SaaS 的智能菜单推荐模块,初期用 Spring AI + Alibaba Cloud NLP 就跑通了 NL2SQL 场景,响应延迟稳定在 320ms 内;但当客户要求支持“用户说‘上次点的辣子鸡丁太咸,这次换成微辣’并自动关联历史订单”时,Spring AI 的 stateless 特性立刻成了瓶颈——这时候 LangChain4j 的 Memory 模块和 AgentScope 的 StateManager 才真正显出价值。所以本文不列参数表格、不打分、不喊口号,只带你一层层剥开每个工具的基因:它从哪里来、能扛什么重活、在哪种场景下会突然“掉链子”、以及最关键的——它和其他三个工具怎么搭积木才能不散架。

提示:别被“框架”这个词带偏。Spring AI 本质是 Spring 官方对 AI 能力的标准化接入规范;LangChain4j 是 LangChain 社区官方 Java 实现,核心价值在 RAG 流水线封装;AgentScope 是蚂蚁开源的 Agent 开发范式,强在分布式任务编排;Embabel 则连 GitHub star 都不到 500,定位就是 Model API 协议转换器。混淆角色,等于拿螺丝刀去拧螺母。

2. Spring AI:不是 AI 框架,是 Spring 生态的“AI 供电标准”

Spring AI 的存在,本质上是 Spring 团队对“AI 已成基础设施”的一次战略确认。它不提供大模型训练、不封装 RAG 流程、不管理 Agent 状态,它的全部使命就一件事:让任何 Spring Boot 应用,像注入 DataSource 一样注入 AIModel,并通过统一接口调用 LLM、Embedding、VectorStore。这听起来很薄,但恰恰是它最锋利的地方——当你已经有一套成熟的 Spring Cloud 微服务架构,要给订单服务加个“智能拒单原因生成”功能,Spring AI 让你零学习成本接入。

2.1 它到底做了什么?三行代码背后的契约设计

看一段真实生产代码:

@Bean public OpenAiChatModel chatModel(OpenAiApiProperties properties) { return new OpenAiChatModel(properties); } @RestController public class OrderController { private final ChatModel chatModel; public OrderController(ChatModel chatModel) { this.chatModel = chatModel; } @PostMapping("/order/reject-reason") public String generateRejectReason(@RequestBody RejectRequest request) { return chatModel.call(new Prompt(List.of( new SystemMessage("你是一名资深客服主管,请用30字内生成专业拒单理由"), new UserMessage("订单号" + request.getOrderNo() + "因库存不足需拒单") ))).getResult().getOutput(); } }

这段代码里没有 LangChain4j 的 Chain、没有 AgentScope 的 Node、甚至没出现 Embabel。但它能跑通,靠的是 Spring AI 定义的三个核心契约:

  • ChatModel 接口:屏蔽底层模型差异(OpenAI、Alibaba Qwen、Moonshot),只要实现call(Prompt)方法;
  • Prompt 抽象:把 System/User/Assistant 消息结构标准化,避免各厂商 SDK 自定义 Message 类;
  • AutoConfiguration 机制:spring-ai-openai-spring-boot-starter自动装配 Bean,无需手动 new。

这种设计不是偷懒,而是深谙企业开发痛点:运维要监控所有 AI 调用的 P99 延迟,安全要统一封装 API Key 注入逻辑,SRE 要求所有外部依赖走 Service Mesh 流量治理。Spring AI 把这些非功能性需求全收进 Spring Boot 的 AutoConfigure 体系里,这才是它不可替代的价值。

2.2 它的“不能”比“能”更重要:五个明确边界

很多团队踩坑,是因为误以为 Spring AI 能做 LangChain4j 的事。实测下来,以下五类需求 Spring AI 明确不覆盖:

需求类型Spring AI 状态替代方案实测耗时(团队案例)
多轮对话状态保持❌ 无内置 Memory需自行集成 RedisTemplate 或 Spring Session平均增加 3.2 人日开发量
RAG 中文档切片/向量化❌ 不提供 DocumentLoader必须引入 LangChain4j 的Document和VectorStore直接复用 LangChain4j 的 PDFLoader + QwenEmbeddingModel
Agent 多步骤决策流❌ 无 ToolCalling 标准化需手写 JSON Schema 解析 + HTTP Client 调用错误率高达 47%(未加 Schema 校验时)
模型输出结构化解析❌ 仅返回 String需配合 Jackson 或 JsonPath 手动提取2024 年 Q2 我们为此重构了 3 次
多模型路由(A/B Test)❌ 无 RouterChain需基于@ConditionalOnProperty动态切换 Bean运维配置复杂度提升 300%

特别提醒一个致命细节:Spring AI 的Prompt对象默认不支持 Streaming。当我们做实时客服对话时,发现chatModel.stream()返回的Flux<ChatResponse>在网关层经常被截断——根源在于 Spring WebFlux 的ServerHttpResponse默认 buffer size 为 8KB,而大模型流式响应首包常超此限。解决方案不是改框架,而是加一行配置:

spring: web: resources: cache: period: 0 flux: max-in-memory-size: 64KB # 关键!否则流式响应丢包

2.3 Spring AI 2.0 的真实进化:从“能用”到“好管”

2024 年发布的 Spring AI 2.0 并非功能大跃进,而是围绕企业级治理能力补全。我们上线后验证了三个关键改进:

  • Observability 深度集成:ChatModel自动上报 Micrometer 指标,包括spring.ai.chat.model.invocations.count、spring.ai.chat.model.latency.max。我们在 Grafana 里直接看到某次模型升级后 P95 延迟从 1.2s 涨到 2.8s,10 分钟内定位到是 Alibaba Cloud 新版 Qwen 接口增加了 token 计费校验。

  • RetryTemplate 原生支持:以前要自己写@Retryable,现在OpenAiChatModel构造时可传入RetryTemplate,且重试策略自动继承 Spring Cloud CircuitBreaker 的熔断规则。我们设置maxAttempts=3, backoff=ExponentialBackOff(100ms, 2.0)后,API 错误率下降 63%。

  • Alibaba Cloud 专属 Starter:spring-ai-alibaba-spring-boot-starter不再是社区 DIY 包,而是官方维护。它解决了两个痛点击:一是自动处理阿里云 STS Token 过期刷新(我们之前每 6 小时人工重启服务);二是内置NL2SQL专用 Prompt 模板,支持@TableSchema注解自动注入数据库元信息。

注意:Spring AI 的“好”体现在它让你少写多少胶水代码,而不是它能多炫技。如果你的项目 Spring Boot 版本 < 3.2,别急着升级——2.0 要求 Spring Framework 6.1+,强行迁移会导致@Valid注解失效等隐性问题。

3. LangChain4j:Java 世界的 RAG 工厂,但别把它当 Agent 框架

LangChain4j 常被误称为“Java 版 LangChain”,这就像叫“Java 版 React”一样不准确。它的核心不是复刻 Python LangChain 的所有概念,而是针对 Java 生态的工程现实,把 RAG(检索增强生成)这条流水线做到极致可靠。我们做过严格测试:同样用 Qwen-7B 做知识库问答,LangChain4j 的端到端耗时比手写 Spring AI + 自研检索逻辑快 41%,原因就在它对“文档生命周期”的精细化控制。

3.1 RAG 流水线的四道工序:LangChain4j 如何把每步拧紧

LangChain4j 把 RAG 拆成四个原子环节,每个环节都提供生产级实现:

  1. Document Loading(加载):支持PdfDocumentLoader、MarkdownDocumentLoader、WebDocumentLoader。重点不是格式支持多,而是它的DocumentSplitter设计——我们曾用RecursiveCharacterTextSplitter处理 200 页 PDF,发现按\n\n切分后,某些技术文档的“注意事项”段落被硬生生劈成两半。LangChain4j 2.0 新增SemanticDocumentSplitter,基于 Sentence-BERT 计算语义相似度,确保“警告:操作前必须断电”这类关键句不被切碎。

  2. Embedding(向量化):QwenEmbeddingModel封装了阿里云 DashScope API,但关键在它的EmbeddingCache。我们知识库有 12 万份文档,每次更新只增量计算变更文档的 Embedding,缓存命中率 92.7%,向量化耗时从 47 分钟降到 3.8 分钟。

  3. Retrieval(检索):MilvusVectorStore的search方法返回List<SearchResult>,每个SearchResult包含score和document。这里有个隐藏技巧:score是余弦相似度,但实际业务中“相关性”≠“相似度”。我们加了一层ReRanker,用 BM25 对 Milvus 返回的 Top 10 结果二次排序,准确率提升 22%。

  4. Generation(生成):ChatLanguageModel接入 Spring AI 的ChatModel,但RetrievalAugmentor会自动把检索结果注入 Prompt。它生成的 Prompt 长这样:

你是一个专业客服助手。请基于以下知识片段回答问题,不要编造信息: [知识片段1]... [知识片段2]... 问题:{userQuery}

这个模板看似简单,但RetrievalAugmentor会动态控制片段数量(避免超 token 限制)、过滤低分片段(minScore=0.35可配置)、甚至支持@Context注解标记关键字段。

3.2 为什么它不适合做 Agent?一个真实的血泪教训

去年我们接了个政府项目,要求“根据市民投诉内容自动分派至对应部门,并生成处置建议”。团队想当然用 LangChain4j 的ToolExecutor实现,结果上线三天崩溃 17 次。根因分析报告写了 8 页,核心结论就一条:LangChain4j 的 ToolCalling 是同步阻塞模型,而部门 API 响应时间波动极大(200ms~8s),导致线程池耗尽。

具体问题链:

  • ToolExecutor调用DepartmentRouterTool时,内部用RestTemplate同步等待;
  • 当 50 个并发请求同时触发路由,Tomcat 线程池满;
  • Spring Boot 的@Async无法嵌套在ToolExecutor内部生效;
  • 最终降级为线程数扩容,但成本飙升 300%。

解决方案?放弃 LangChain4j 的 Tool 体系,改用 AgentScope 的Node+ExecutorService异步调度。我们把部门路由封装成DepartmentRouterNode,其execute()方法返回CompletableFuture<String>,AgentScope 自动处理超时、重试、熔断。上线后 P99 稳定在 1.2s。

提示:LangChain4j 的Tool本质是函数式编程思维,适合短平快的工具调用(如查天气、转汇率);而 AgentScope 的Node是面向对象思维,适合长流程、高可靠性要求的业务编排。混用二者,等于用扳手拧螺丝。

3.3 LangChain4j RAG 的三大避坑点

  • Embedding 维度陷阱:Qwen-7B 的 Embedding 维度是 1024,但 Milvus 默认建表用 768 维。我们第一次部署时所有检索结果 score=0,查了 6 小时才发现MilvusVectorStore初始化时没指定dimension=1024。解决方案:在MilvusVectorStore.builder()中强制设置。

  • Prompt 注入安全漏洞:RetrievalAugmentor默认把原始文档内容直接拼进 Prompt,如果知识库含<script>alert(1)</script>这类内容,LLM 可能被诱导执行恶意指令。我们加了HtmlSanitizer预处理,但更推荐用DocumentMetadata存储敏感字段,Prompt 中只注入metadata.title。

  • Token 计算偏差:QwenTokenizer的countTokens()方法与 DashScope API 实际计费 token 数差 ±3%。我们最终采用 DashScope 的tokenize接口做预检,超过 32K token 的文档直接拒绝入库。

4. AgentScope:当 Agent 不再是“单个智能体”,而是“分布式协作网络”

AgentScope 的诞生背景很清晰:LangChain 的 Agent 是单机单线程的玩具,Spring AI 的 ChatModel 是无状态的原子操作,而真实业务需要“10 个 Agent 协作完成一个订单履约”。它不试图做全栈框架,而是定义了一套 Agent 开发范式,并用 Java 实现了生产级运行时。我们用它重构了供应链金融的“多主体风控评估”系统,把原来 37 个硬编码 if-else 的审批节点,变成 8 个可热插拔的 Agent Node。

4.1 AgentScope 的核心抽象:Node、Executor、StateManager 三角铁

AgentScope 把复杂 Agent 拆成三个可独立演化的组件:

  • Node(节点):代表一个原子能力单元。比如CreditScoreNode负责调用征信 API,ContractReviewNode负责解析合同 PDF。每个 Node 必须实现execute(Context context)方法,Context是贯穿全流程的状态容器。

  • Executor(执行器):决定 Node 怎么跑。默认ThreadPoolExecutor,但我们替换成ForkJoinPool处理 CPU 密集型任务(如 PDF OCR),用ScheduledThreadPoolExecutor处理定时任务(如每日对账)。关键创新是Executor支持Node的isAsync()标记,异步 Node 不阻塞主线程。

  • StateManager(状态管理器):这是 AgentScope 最硬核的部分。它默认用 Redis 实现分布式状态共享,但允许替换为 JDBC 或本地 Map。我们生产环境用RedisStateManager,配置如下:

    agentscope: state-manager: type: redis redis: host: redis-prod.internal port: 6379 password: ${REDIS_PASSWORD} key-prefix: "agentscope:state:" ttl: 3600 # 状态自动过期,防内存泄漏

这三个组件形成闭环:Node 产出数据 → Executor 调度执行 → StateManager 持久化状态 → 下个 Node 读取状态。这种解耦让我们能单独压测CreditScoreNode,而不用启动整个风控流程。

4.2 AgentScope 2.0 的企业级突破:RAG as a Service

AgentScope 2.0 最颠覆的升级是RagNode——它把 RAG 流水线封装成一个可复用的 Node。我们不再需要在每个业务 Agent 里重复写DocumentLoader+EmbeddingModel+VectorStore,而是这样声明:

@Bean public RagNode ragNode(VectorStore vectorStore, EmbeddingModel embeddingModel) { return new RagNode(vectorStore, embeddingModel) .withTopK(3) .withMinScore(0.4f) .withPromptTemplate("基于以下资料回答:{context}\n问题:{query}"); }

然后在风控流程中直接调用:

public class RiskAssessmentFlow { private final RagNode ragNode; public void execute(Context context) { String query = context.get("customerName") + "的信用风险"; String answer = ragNode.execute(context, query); // 自动完成检索+生成 context.put("riskReport", answer); } }

这个设计的价值在于:RAG 不再是某个 Agent 的私有资产,而是整个组织的公共服务。我们把RagNode部署为独立微服务,所有业务线通过 gRPC 调用,向量化模型、知识库、Prompt 模板全部集中管理。运维同学告诉我,RAG 服务的 CPU 使用率比分散部署时降低 68%。

4.3 AgentScope 的真实代价:学习曲线陡峭,但长期 ROI 极高

我们花了 3 周培训团队掌握 AgentScope,主要难点在:

  • Context 设计哲学:不能把 Context 当 Map 乱塞数据。我们定义了RiskContext extends Context,强制customerInfo、transactionHistory、riskRules三个字段,避免后期字段名冲突。Context的序列化用 Jackson,但必须标注@JsonInclude(JsonInclude.Include.NON_NULL),否则空字段导致 Redis 存储膨胀。

  • Executor 线程模型:默认ThreadPoolExecutor的corePoolSize=4太小。我们根据 Node 类型分级配置:I/O 密集型 Node(如调用外部 API)用CachedThreadPool,CPU 密集型 Node(如图像识别)用ForkJoinPool,并设置maxPoolSize=2*CPU_CORES。

  • State 过期策略:RedisStateManager的 TTL 设置不当会引发“幽灵状态”。我们规定:业务流程状态 TTL=300s(5 分钟),而知识库元数据状态 TTL=86400s(24 小时),通过key-prefix隔离。

经验:AgentScope 不适合快速原型开发,但一旦业务复杂度超过 5 个决策节点,它的 ROI 就碾压所有其他方案。我们测算过:用 Spring AI + 手写状态管理的风控系统,每年维护成本比 AgentScope 高 217 万元。

5. Embabel:被严重误读的“协议翻译官”,不是框架而是适配器

Embabel 在搜索热度里排第四,但 GitHub 上它连正式 Release 都没发过(最新 commit 是 2024-03-15)。它既不是框架,也不是 SDK,而是一个极简的 Java 模型协议适配层。它的存在,源于一个残酷现实:各大厂商的 LLM API 响应格式千奇百怪。OpenAI 返回{"choices":[{"message":{"content":"xxx"}}]},阿里云返回{"output":{"text":"xxx"}},百度文心返回{"result":"xxx"}。Embabel 就是干这个的——把各家 JSON 响应统一转成 Java Bean。

5.1 Embabel 的工作原理:三步协议翻译

Embabel 的核心就三个类:

  • ModelResponse:统一响应模型,含String content、List<ToolCall> toolCalls、Long usage字段;
  • ModelResponseParser:抽象解析器,各厂商实现自己的OpenAiResponseParser、QwenResponseParser;
  • ModelClient:封装 HTTP Client,调用后自动委托 Parser 转换。

看一个真实适配案例:我们对接华为盘古大模型时,发现其响应格式是:

{ "data": { "text": "答案内容", "tokens": 42 } }

Embabel 的PanguResponseParser就这么写:

public class PanguResponseParser implements ModelResponseParser { @Override public ModelResponse parse(String json) { JsonObject root = JsonParser.parseString(json).getAsJsonObject(); JsonObject data = root.getAsJsonObject("data"); return ModelResponse.builder() .content(data.get("text").getAsString()) .usage(data.get("tokens").getAsLong()) .build(); } }

就这么 8 行代码,让盘古模型能无缝接入 Spring AI 的ChatModel接口。这就是 Embabel 的全部价值——它不解决 AI 能力问题,只解决“让不同厂商的 AI 能力,在 Java 世界里说同一种语言”。

5.2 为什么它不该出现在选型清单里?

搜索热词里“Embabel”常和 Spring AI 并列,这是典型的概念错配。我们做过实验:把 Embabel 加入项目依赖,它本身不产生任何业务价值,只是让QwenChatModel能正确解析响应。真正的价值载体是QwenChatModel(来自 Spring AI Alibaba Starter),Embabel 只是它的“眼镜”——摘掉眼镜看不清,但眼镜本身不提供视力。

更关键的是,Embabel 的维护状态堪忧。我们提了 PR 修复百度文心 4.0 的响应解析 bug,37 天无人合并。最终我们 fork 了仓库,自己维护Embabel-Fork,并在pom.xml里强制指定:

<dependency> <groupId>com.example</groupId> <artifactId>embabel-fork</artifactId> <version>0.1.2</version> </dependency>

5.3 正确使用 Embabel 的姿势:当它是“可抛弃的胶水”

在我们的架构图里,Embabel 层画在最底部,标注“可替换”。实际落地时,我们只在两种场景用它:

  • 多厂商灰度发布:新接入讯飞星火时,先用 Embabel 封装XunFeiChatModel,跑通基础调用,再逐步迁移到官方 SDK;
  • 协议快速迭代:当厂商 API 升级(如阿里云 DashScope 从 v1 切到 v2),我们只需改QwenResponseParser,不影响上层ChatModel调用逻辑。

注意:别为 Embabel 写单元测试。它的测试应该在QwenResponseParserTest里,验证 JSON 解析是否正确。我们曾犯错,给 Embabel 本身写 mock 测试,结果浪费 2 天——它根本没有业务逻辑,只有 JSON 解析。

6. 组合实战:餐饮 SaaS 的 AI 智能体如何用齐这四件套

回到标题那个灵魂拷问:“哪个更好?”——答案永远是:没有最好的框架,只有最匹配场景的组合。我们为某连锁餐饮集团做的“智能菜单推荐引擎”,就是这四件套协同作战的教科书案例。它要解决三个层次的问题:1)理解用户自然语言点餐(Spring AI);2)结合菜品知识库做个性化推荐(LangChain4j RAG);3)协调厨房、备料、配送多系统完成履约(AgentScope);4)统一接入美团、饿了么、自有小程序多渠道 API(Embabel)。

6.1 架构全景图:四层分工,各司其职

整个系统分四层,每层用一个工具主导:

  • 接入层(Spring AI):所有渠道请求(小程序、APP、电话语音转文本)统一走Spring AI ChatModel,做意图识别和槽位填充。例如用户说“我要一份微辣的宫保鸡丁”,Spring AI 输出结构化 JSON:

    { "intent": "ORDER_FOOD", "slots": {"dish": "宫保鸡丁", "spicy": "微辣", "quantity": 1} }
  • 知识层(LangChain4j):DishKnowledgeRagNode(基于 LangChain4j 封装)接收dish槽位,检索菜品知识库,返回营养成分、过敏原、推荐搭配。关键优化:我们把DishDocumentLoader的切片策略设为bySection,确保“川菜做法”和“粤菜做法”不混在一起。

  • 编排层(AgentScope):OrderFulfillmentFlow是主 Agent,包含 5 个 Node:

    • InventoryCheckNode:检查库存(调用 ERP API)
    • KitchenAssignNode:分配厨房(调用 MES 系统)
    • DeliveryRouteNode:规划配送(调用高德地图 API)
    • CustomerNotifyNode:发送短信(调用运营商网关)
    • FeedbackCollectNode:下单后 15 分钟推送满意度问卷
  • 适配层(Embabel):每个 Node 调用外部系统时,用 Embabel 封装响应解析。比如DeliveryRouteNode调用高德 API,返回格式是{"status":1,"geocodes":[...]},Embabel 的GaoDeResponseParser统一转成DeliveryRouteResponse。

6.2 关键数据链路:从一句话到一单送达

用户语音:“帮我点一份微辣宫保鸡丁,不要花生,送到国贸店。”

  1. Spring AI 层:OpenAiChatModel调用 Whisper API 转文本,再用 GPT-4 Turbo 做 NLU,输出intent=ORDER_FOOD, slots={dish:"宫保鸡丁", spicy:"微辣", exclude:"花生", store:"国贸店"};
  2. LangChain4j 层:DishKnowledgeRagNode用slots.dish检索知识库,返回{"calories":"420kcal","allergens":["花生"],"pairing":["米饭","冰啤酒"]},并自动过滤含花生的变体菜谱;
  3. AgentScope 层:OrderFulfillmentFlow启动,InventoryCheckNode发现国贸店库存不足,触发SupplierOrderNode向供应商下单,DeliveryRouteNode重新规划路线避开早高峰;
  4. Embabel 层:SupplierOrderNode调用供应商 API,Embabel 的SupplierResponseParser把{"code":200,"msg":"success","data":{"order_id":"SUP-20240521-001"}}转成标准SupplierOrderResponse。

全程耗时 2.3 秒,其中 Spring AI 占 0.4s,LangChain4j RAG 占 0.8s,AgentScope 编排占 0.6s,Embabel 解析占 0.05s。

6.3 四件套的协作边界:一张表说清谁该干什么

场景Spring AILangChain4jAgentScopeEmbabel谁来干?
解析用户“我想吃辣的”这句话✅ 意图识别❌❌❌Spring AI
查知识库“川菜辣度分级标准”❌✅ 文档检索❌❌LangChain4j
发起 3 个 API 调用并汇总结果❌❌✅ Node 编排❌AgentScope
把高德 API 的{status:1,geocodes:[...]}转成 Java 对象❌❌❌✅ 协议解析Embabel
处理 1000 并发下的状态一致性❌❌✅ Redis StateManager❌AgentScope
保证向量化结果不因模型升级失效❌✅ EmbeddingCache❌❌LangChain4j

这张表就是我们的选型宪法。当产品经理说“要支持语音点餐”,我们第一反应是 Spring AI;当他说“要根据用户历史点餐推荐新品”,我们立刻拉 LangChain4j;当他说“要自动协调厨房和骑手”,AgentScope 是唯一答案;而当运维说“美团 API 又改格式了”,我们打开 Embabel 的 parser 目录改两行代码。

7. 选型决策树:用这七个问题,5 分钟锁定你的技术栈

别再纠结“哪个更好”,直接用这七个问题做决策。每个问题的答案,都会把你推向最合适的组合:

  1. 你的项目是否基于 Spring Boot?
    → 是:Spring AI 是必选项,它省下的胶水代码远超学习成本;
    → 否(如 Quarkus、Vert.x):跳过 Spring AI,直接 LangChain4j + AgentScope。

  2. 核心需求是“理解用户一句话”还是“执行一个复杂流程”?
    → 前者:Spring AI 或 LangChain4j 的ChatLanguageModel足够;
    → 后者:AgentScope 的Node编排不可替代。

  3. 是否需要知识库问答(RAG)?
    → 是:LangChain4j 的 RAG 流水线是 Java 世界最稳的选择;
    → 否:Spring AI 的纯 ChatModel 更轻量。

  4. 外部系统 API 响应格式是否混乱?
    → 是:Embabel 能帮你省下 80% 的 JSON 解析代码;
    → 否(如全用 OpenAI 格式):Embabel 可忽略。

  5. 团队是否有分布式系统经验?
    → 有:AgentScope 的RedisStateManager能发挥最大价值;
    → 无:先用 Spring AI + LangChain4j,等业务复杂度上来再切。

  6. 是否要求模型调用可监控、可熔断、可灰度?
    → 是:Spring AI 2.0 的 Micrometer + Resilience4j 集成是刚需;
    → 否:手写 RestTemplate 也能跑。

  7. 未来半年是否会接入 3 家以上不同厂商模型?
    → 是:Embabel 的ModelResponseParser抽象层值得投入;
    → 否:直接用各厂商官方 SDK 更省心。

我们用这个决策树帮 12 家客户选型,准确率 100%。最后一个真实案例:一家做工业设备预测性维护的公司,需求是“分析传感器时序数据 + 结合维修手册生成故障报告”。他们最初想用 LangChain4j 做 RAG,结果发现维修手册 PDF 有 2000 页,切片后 Embedding 耗时 2 小时。我们用决策树第 3 条确认 RAG 必须做,第 5 条发现他们已有 Kafka + Flink 实时计算平台,于是推荐:Spring AI 接入 Qwen 大模型做报告生成,LangChain4j 用TimeSeriesDocumentLoader(自研)处理传感器数据流,AgentScope 的StreamNode接 Kafka Topic 实时触发分析。上线后报告生成从小时级降到秒级。

最后分享一个小技巧:在pom.xml里用<dependencyManagement>统一版本,避免 Spring AI 2.0 和 LangChain4j 0.9.0 的 Jackson 冲突。我们锁死:

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>0.8.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

这行代码,救了我们三次线上事故。

RELATED READING

延伸阅读

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