LangChain4j vs Spring AI入门到精通,Java AI选型收藏这篇就够了!
摘要:当 Java 团队建设 AI 应用时,真正困难的通常不是“能否调通模型”,而是“如何把 Prompt、RAG、工具调用、可观测性、限流熔断、灰度发布、权限隔离与业务系统稳定地耦合起来”。本文不再停留在 API 罗列层面,而是从架构原理、工程治理、高并发设计、生产级代码与典型场景出发,对 LangChain4j 与 Spring AI 做一次面向实战的深度比较。
一、先说结论:这不是二选一,而是架构风格的选择
如果只看“调用大模型”这一件事,两者都能完成任务;真正决定选型的,是你的系统边界、团队能力模型与中长期演进方向。
- • LangChain4j 更适合:快速验证 AI 场景、构建 Agent/RAG 原型、对 Spring 生态绑定要求不高、希望用较少抽象快速打通链路。
- • Spring AI 更适合:已有 Spring Boot / Spring Cloud / Spring Security / Micrometer 技术栈,强调统一配置、治理、可观测性、企业集成与长期维护。
- • 从架构视角看:
- • LangChain4j 偏向“AI 能力编排框架”。
- • Spring AI 偏向“AI 能力接入 Spring 体系的企业集成框架”。
- • 从组织效率看:
- • 小团队、探索期、业务未定型时,LangChain4j 往往更快。
- • 大团队、平台化、合规要求高时,Spring AI 更容易纳入统一治理。
一句话概括:LangChain4j 赢在 AI 编排体验,Spring AI 赢在企业工程化整合。
二、为什么 Java AI 选型不能只看 API 易用性
一个进入生产环境的 LLM 系统,至少包含以下五层:
入口层 API / Web / MQ
AI 应用层 Prompt / RAG / Tool / Memory
模型接入层 OpenAI / Azure / Anthropic / 本地模型
知识检索层 Embedding / Vector DB / Hybrid Search
治理层 Cache / Rate Limit / Retry / Circuit Breaker / Trace
基础设施层 Config / Secret / Metrics / Audit / IAM
很多 PoC 死在这里:Demo 可以回答问题,但一旦进入正式环境,就会暴露出几个典型问题。
- • 模型调用延迟不稳定,导致线程池被拖垮。
- • Token 成本无法审计,业务越跑越贵。
- • RAG 召回质量不稳定,线上回答忽高忽低。
- • Prompt 与检索模板没有版本治理,回归问题难定位。
- • 并发升高后,上游模型接口限流,引发级联故障。
- • 多租户和权限过滤缺失,知识库越权访问风险极高。
因此,技术选型的核心不是“谁能接 OpenAI”,而是:
- 谁更适合你的系统分层。
- 谁更容易承接高并发和治理要求。
- 谁更能与现有工程体系低成本融合。
三、两大框架的设计哲学差异
3.1 LangChain4j:围绕 AI 任务编排组织 API
LangChain4j 的核心思路是把 AI 应用拆成几个天然概念:
- • Model:模型调用
- • Prompt / Message:提示词与消息
- • Memory:对话上下文
- • Retriever / RAG:检索增强
- • Tools:外部工具调用
- • AI Services:面向接口的 AI 能力封装
它的优势在于“贴近 AI 开发者思维”。你在设计智能客服、SQL Agent、知识助手时,通常先想的是“模型 + 检索 + 工具 + 记忆”,而不是“Bean 生命周期 + 自动配置 + Spring 约束”。
这意味着:
- • 上手快,原型构建效率高。
- • 对 AI 编排抽象更直接。
- • 在非 Spring 环境中也容易使用。
代价是:
- • 企业治理能力需要自己补齐更多内容。
- • 当系统复杂度上升时,配置、观测、线程模型、容错、权限隔离,往往需要你自己搭架子。
3.2 Spring AI:把 AI 能力纳入 Spring 的统一治理域
Spring AI 的设计目标并不是“重新发明一个 LangChain”,而是把大模型能力以 Spring 的方式接入企业系统。
它的典型价值不在于某个单点 API,而在于这类能力的组合:
- •
AutoConfiguration统一装配 - •
Properties统一配置 - • 与 Spring Boot Actuator、Micrometer、Observability 对齐
- • 与 WebFlux、Security、Validation、事务边界、消息队列协同
- • 更容易纳入组织既有的研发规范
这意味着:
- • 平台化、标准化、可维护性更强。
- • 新成员理解成本更低,因为它遵循 Spring 的一贯范式。
- • 对接企业中间件与治理组件时,整体摩擦更小。
代价是:
- • 早期原型速度未必比 LangChain4j 更快。
- • 某些 AI 编排能力的表达方式,会更偏 Spring 风格而不是 Agent 框架风格。
四、核心能力对比:不要只看“有没有”,要看“怎么落地”
| 对比维度 | LangChain4j | Spring AI | 架构判断 |
|---|---|---|---|
| 学习成本 | 低 | 中 | PoC 阶段 LangChain4j 更快 |
| 与 Spring 生态融合 | 中 | 高 | 企业应用 Spring AI 更顺手 |
| RAG 编排能力 | 强 | 强 | 两者都能做,LangChain4j 更贴近 AI 思维 |
| Tool / Agent 表达 | 强 | 中到强 | LangChain4j 更自然 |
| 配置治理 | 中 | 高 | Spring AI 明显占优 |
| 可观测性接入 | 需补齐 | 更自然 | Spring AI 更利于统一监控 |
| 线程模型与响应式整合 | 依赖自行设计 | 与 WebFlux 更契合 | 高并发下 Spring AI 更稳妥 |
| 多模块扩展 | 可做 | 更成熟 | 平台化更适合 Spring AI |
| 独立轻量部署 | 强 | 中 | 非 Spring 项目 LangChain4j 更友好 |
| 长期维护与团队协作 | 中到高 | 高 | 大团队偏 Spring AI |
结论不是“哪个更先进”,而是:
- • AI 场景驱动开发:LangChain4j 更自然。
- • 企业平台驱动开发:Spring AI 更完整。
五、从系统架构看,二者最关键的差别在哪里
5.1 LangChain4j 更像 AI 领域能力层
推荐的架构分层如下:
Controller / Consumer -> Application Service -> AI Orchestrator (LangChain4j) -> Prompt Builder -> Retriever -> Tool Executor -> Memory Adapter -> Domain Service -> Repository / External Gateway
这种设计下,LangChain4j 最适合放在“AI Orchestrator”层,做以下事情:
- • 对话与 Prompt 组装
- • 检索结果融合
- • 工具选择与调用
- • 结果重写与格式化
同时,把以下能力放在框架外部治理:
- • 限流与熔断
- • 缓存
- • Trace / Metrics
- • 鉴权与租户隔离
- • 配置中心与密钥管理
5.2 Spring AI 更像企业 AI 接入层
推荐的架构分层如下:
API Gateway -> Spring Boot AI Service -> ChatClient / ChatModel / VectorStore -> Observability / Retry / RateLimiter -> Security / Tenant Filter / Audit -> Domain Service -> PostgreSQL / Redis / MQ / Vector DB
这种设计下,Spring AI 既能承担 AI 编排职责,也适合直接接入统一治理体系:
- • 用配置管理不同模型供应商
- • 用 Micrometer 统一采集延迟、错误率、Token
- • 用 Spring Security 做租户与权限控制
- • 用 WebFlux 支撑长连接和流式输出
- • 用 Resilience4j 做限流、隔离、熔断、重试
所以在复杂企业系统里,Spring AI 的真正优势不是“回答更准”,而是更容易被纳入系统工程。
六、依赖与工程骨架建议
6.1 LangChain4j 工程骨架
<dependencies> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j</artifactId> <version>1.11.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>1.11.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-pgvector</artifactId> <version>1.11.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-boot3</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency></dependencies>
说明:
- • LangChain4j 完全可以运行在 Spring Boot 中。
- • 生产环境建议把它作为 AI 编排库,而不是孤立运行。
- • 高并发项目不要只停留在“main 方法演示代码”。
6.2 Spring AI 工程骨架
<dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-openai</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-vector-store-pgvector</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-boot3</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency></dependencies>
说明:
- • Spring AI 更适合与 Actuator、Micrometer、Config、Security 一起出现。
- • 如果项目本身就是 Spring Boot 微服务,整体接入成本通常更低。
七、生产级场景一:智能客服 RAG 系统
一个真正上线的智能客服,不是“向量检索 + LLM”这么简单,而是至少要处理:
- • 多租户知识隔离
- • 热门问题缓存
- • 敏感词与合规审计
- • 模型限流与降级
- • 流式输出
- • 失败回退
- • 会话上下文截断
- • 引用来源返回
7.1 参考架构
Client / Web / App
API Gateway
Customer AI Service
Query Rewrite
Hybrid Retrieval
BM25
Vector Search
Policy Filter
Prompt Assembly
LLM
Redis Cache
Metrics / Trace / Audit
PgVector / Milvus / ES
7.2 LangChain4j 生产级实现
以下示例强调几点:
- • 不把模型直连暴露给 Controller
- • 使用服务层封装 Prompt、检索、缓存、降级
- • 支持多租户元数据过滤
- • 支持并发保护与流式输出
package com.example.ai.customer;import dev.langchain4j.data.segment.TextSegment;import dev.langchain4j.model.chat.ChatLanguageModel;import dev.langchain4j.rag.content.Content;import dev.langchain4j.rag.content.aggregator.ReciprocalRankFuser;import dev.langchain4j.rag.content.retriever.ContentRetriever;import dev.langchain4j.rag.query.Query;import io.github.resilience4j.bulkhead.annotation.Bulkhead;import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;import io.github.resilience4j.ratelimiter.annotation.RateLimiter;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Service;import java.time.Duration;import java.util.List;import java.util.Map;import java.util.concurrent.CompletableFuture;@Servicepublic class CustomerSupportService { private final ChatLanguageModel chatModel; private final ContentRetriever vectorRetriever; private final ContentRetriever keywordRetriever; private final ReciprocalRankFuser rankFuser; private final StringRedisTemplate redisTemplate; public CustomerSupportService(ChatLanguageModel chatModel, ContentRetriever vectorRetriever, ContentRetriever keywordRetriever, StringRedisTemplate redisTemplate) { this.chatModel = chatModel; this.vectorRetriever = vectorRetriever; this.keywordRetriever = keywordRetriever; this.redisTemplate = redisTemplate; this.rankFuser = new ReciprocalRankFuser(Map.of( "vector", 1.0, "keyword", 0.8 )); } @Bulkhead(name = "llmBulkhead") @RateLimiter(name = "llmRateLimiter") @CircuitBreaker(name = "llmCircuitBreaker", fallbackMethod = "fallbackAnswer") public AnswerResponse answer(String tenantId, String sessionId, String question) { String cacheKey = "ai:answer:%s:%s".formatted(tenantId, question); String cached = redisTemplate.opsForValue().get(cacheKey); if (cached != null) { return AnswerResponse.cached(cached); } Query query = Query.from(question); CompletableFuture<List<Content>> vectorFuture = CompletableFuture.supplyAsync(() -> vectorRetriever.retrieve(query)); CompletableFuture<List<Content>> keywordFuture = CompletableFuture.supplyAsync(() -> keywordRetriever.retrieve(query)); List<Content> fusedContents = rankFuser.aggregate(query, Map.of( "vector", vectorFuture.join(), "keyword", keywordFuture.join() )); List<String> references = fusedContents.stream() .limit(5) .map(content -> content.textSegment().text()) .toList(); String context = String.join("\n---\n", references); String prompt = """ 你是企业客服助手,请严格依据知识库回答。 规则: 1. 不允许编造退款、开票、合同条款。 2. 如果知识不足,直接回答“知识库暂无明确信息”。 3. 优先给出步骤化答复。 租户:%s 会话:%s 知识库片段: %s 用户问题: %s """.formatted(tenantId, sessionId, context, question); String answer = chatModel.generate(prompt); redisTemplate.opsForValue().set(cacheKey, answer, Duration.ofMinutes(10)); return new AnswerResponse(answer, references, false, false); } public AnswerResponse fallbackAnswer(String tenantId, String sessionId, String question, Throwable ex) { return new AnswerResponse( "当前智能客服负载较高,请稍后重试,或转人工处理。", List.of(), false, true ); } public record AnswerResponse( String answer, List<String> references, boolean fromCache, boolean degraded ) { public static AnswerResponse cached(String answer) { return new AnswerResponse(answer, List.of(), true, false); } }}
这段代码体现的不是“调用成功”,而是生产环境真正关心的点:
- • 缓存前置:减少热点问答重复耗时与成本。
- • 并行检索:向量检索与关键词检索并发执行。
- • 融合召回:避免单一路径召回偏差。
- • 限流隔离:防止模型接口抖动拖垮业务线程。
- • 降级返回:避免错误直接透传给用户。
7.3 Spring AI 生产级实现
如果你的客服系统本身就是 Spring 微服务,Spring AI 版本通常更便于统一治理。
package com.example.ai.customer;import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;import io.github.resilience4j.ratelimiter.annotation.RateLimiter;import org.springframework.ai.chat.client.ChatClient;import org.springframework.ai.document.Document;import org.springframework.ai.vectorstore.SearchRequest;import org.springframework.ai.vectorstore.VectorStore;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import reactor.core.publisher.Flux;import reactor.core.scheduler.Schedulers;import java.util.List;import java.util.Map;@Servicepublic class CustomerSupportChatService { private final ChatClient chatClient; private final VectorStore vectorStore; public CustomerSupportChatService(ChatClient.Builder builder, VectorStore vectorStore) { this.chatClient = builder .defaultSystem(""" 你是企业级客服助手。 输出要求: 1. 只基于知识库回答; 2. 优先输出步骤; 3. 不确定时明确说明; 4. 结尾附上引用编号。 """) .build(); this.vectorStore = vectorStore; } @Cacheable(cacheNames = "customer-ai-answer", key = "#tenantId + ':' + #question") @RateLimiter(name = "chatRateLimiter") @CircuitBreaker(name = "chatCircuitBreaker", fallbackMethod = "fallback") public String answer(String tenantId, String question) { List<Document> documents = vectorStore.similaritySearch( SearchRequest.builder() .query(question) .topK(5) .similarityThreshold(0.75) .filterExpression("tenantId == '%s'".formatted(tenantId)) .build() ); String context = buildContext(documents); return chatClient.prompt() .user(user -> user .text(""" 以下是检索到的知识库内容: {context} 用户问题: {question} """) .param("context", context) .param("question", question)) .call() .content(); } @RateLimiter(name = "chatStreamRateLimiter") public Flux<String> answerStream(String tenantId, String question) { return Flux.fromCallable(() -> loadContext(tenantId, question)) .subscribeOn(Schedulers.boundedElastic()) .flatMapMany(context -> chatClient.prompt() .user(user -> user .text(""" 参考知识库: {context} 用户问题: {question} """) .param("context", context) .param("question", question)) .stream() .content()); } public String fallback(String tenantId, String question, Throwable ex) { return "当前服务繁忙,请稍后重试,或转人工处理。"; } private String loadContext(String tenantId, String question) { List<Document> docs = vectorStore.similaritySearch( SearchRequest.builder() .query(question) .topK(5) .similarityThreshold(0.75) .filterExpression("tenantId == '%s'".formatted(tenantId)) .build() ); return buildContext(docs); } private String buildContext(List<Document> documents) { StringBuilder sb = new StringBuilder(); int i = 1; for (Document document : documents) { sb.append("[").append(i++).append("] ") .append(document.getText()) .append("\n"); } return sb.toString(); }}
这段 Spring AI 代码的关键价值在于:
- • 与缓存、限流、熔断、响应式流天然协同。
- • 更适合直接进入标准 Spring Boot 微服务。
- • 对团队成员来说,阅读与维护门槛更低。
7.4 这个场景该怎么选
- • 如果你要快速试错客服机器人、多轮对话、工具调用,LangChain4j 更顺手。
- • 如果你要把客服能力接到已有客服中台、SSO、审计、监控、网关体系里,Spring AI 更省工程成本。
八、生产级场景二:文档解析与多模态抽取
在企业中,多模态场景通常不是“识图聊天”,而是:
- • 发票识别与字段抽取
- • 合同版式解析
- • 物流面单审核
- • 工单截图质检
- • 生产巡检图像判定
这类场景的关键不是把图片发给模型,而是建立稳定链路:
- 上传文件
- 异步落盘或对象存储
- OCR / 版面分析 / 模型抽取
- 结构化结果校验
- 人工复核回写
- 审计与追踪
8.1 生产环境设计要点
- • 不建议在 Web 线程中直接做大文件解析。
- • 建议采用“上传同步返回任务 ID + 后台异步处理”的模式。
- • 抽取结果必须经过结构化校验,不能直接信任模型文本。
- • 高价值场景必须设置人工复核闭环。
8.2 结构化抽取结果定义
package com.example.ai.document;import jakarta.validation.constraints.NotBlank;import jakarta.validation.constraints.NotNull;import java.math.BigDecimal;import java.time.LocalDate;public record InvoiceExtractionResult( @NotBlank String invoiceNo, @NotNull LocalDate invoiceDate, @NotBlank String buyerName, @NotNull BigDecimal totalAmount, @NotBlank String currency, double confidence) {}
8.3 Spring AI 异步任务式实现
package com.example.ai.document;import com.fasterxml.jackson.databind.ObjectMapper;import jakarta.validation.ConstraintViolation;import jakarta.validation.Validator;import org.springframework.ai.chat.client.ChatClient;import org.springframework.core.io.ByteArrayResource;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import java.util.Set;import java.util.UUID;@Servicepublic class InvoiceExtractionService { private final ChatClient chatClient; private final ObjectMapper objectMapper; private final Validator validator; private final ExtractionTaskRepository taskRepository; public InvoiceExtractionService(ChatClient.Builder builder, ObjectMapper objectMapper, Validator validator, ExtractionTaskRepository taskRepository) { this.chatClient = builder.build(); this.objectMapper = objectMapper; this.validator = validator; this.taskRepository = taskRepository; } public String submit(byte[] imageBytes) { String taskId = UUID.randomUUID().toString(); taskRepository.markRunning(taskId); extractAsync(taskId, imageBytes); return taskId; } @Async("aiTaskExecutor") public void extractAsync(String taskId, byte[] imageBytes) { try { String content = chatClient.prompt() .user(user -> user .text(""" 请识别发票图片并仅返回 JSON: { "invoiceNo": "", "invoiceDate": "yyyy-MM-dd", "buyerName": "", "totalAmount": 0, "currency": "CNY", "confidence": 0.0 } """) .media("image/jpeg", new ByteArrayResource(imageBytes))) .call() .content(); InvoiceExtractionResult result = objectMapper.readValue(content, InvoiceExtractionResult.class); Set<ConstraintViolation<InvoiceExtractionResult>> violations = validator.validate(result); if (!violations.isEmpty()) { taskRepository.markManualReview(taskId, content, violations.toString()); return; } taskRepository.markSuccess(taskId, result); } catch (Exception ex) { taskRepository.markFailed(taskId, ex.getMessage()); } }}
这个实现比简单 Demo 更接近真实生产:
- • 有任务状态机,而不是阻塞等待。
- • 返回 JSON 而不是自由文本,便于后续入库。
- • 用
Validator做结构化校验。 - • 不满足规则自动转人工复核。
8.4 LangChain4j 适合什么位置
在多模态场景里,LangChain4j 更适合承担:
- • 多步骤抽取链编排
- • OCR 结果 + 图片 + 业务规则联合推理
- • 工具调用与字段修正
- • 复杂工作流原型验证
如果你的重点是“复杂 Agent 工作流”,LangChain4j 表达会更自然;如果重点是“企业任务系统接入、状态机、审计、监控”,Spring AI 与 Spring 全家桶更顺。
九、生产级场景三:企业知识库与高并发检索
RAG 在生产环境里最容易被误解。很多团队以为向量库接上就完了,实际上线上系统决定效果的往往是这几个环节:
- • 分块策略是否合理
- • 元数据是否完备
- • 召回策略是否稳定
- • 是否做了混合检索
- • 是否做重排与去重
- • 是否处理了租户过滤和权限过滤
9.1 一个更合理的 RAG Pipeline
原始文档
清洗与切分
Embedding
BM25 索引
向量库
关键词索引
用户问题
Query Rewrite
Hybrid Retrieve
Rerank / Dedup
Prompt Assembly
LLM Answer
9.2 为什么生产环境必须做混合检索
纯向量检索适合语义相近问题,但对以下查询并不稳定:
- • 产品型号
- • 订单号
- • 合同编号
- • 专有名词
- • 缩写词
- • 新近上线且训练样本少的领域概念
因此,高质量 RAG 往往采用:
- • 语义检索:解决“意思相近”
- • 关键词检索:解决“字面命中”
- • 元数据过滤:解决“范围正确”
- • 重排:解决“最终排序”
9.3 LangChain4j 的优势点
LangChain4j 在 RAG 编排、检索器组合、结果融合上思路清晰,适合做以下事情:
- • 多路检索器并联
- • 路由式查询策略
- • 自定义融合算法
- • 复杂 Prompt 装配
9.4 Spring AI 的优势点
Spring AI 在知识库场景更适合承接这些需求:
- • 统一接入企业数据源
- • 与作业系统协同做离线入库
- • 接入监控、配置中心、权限系统
- • 作为平台能力对多个业务线提供统一 API
十、高并发与可扩展设计:真正拉开差距的地方
很多文章讨论 AI 框架时,几乎不谈并发模型,这是不够专业的。LLM 应用天然具备几个高风险点:
- • 上游模型调用延迟高且波动大
- • 流式输出连接持续时间长
- • 向量检索与模型调用都消耗昂贵资源
- • 请求失败率受外部平台影响大
因此,生产环境至少要设计以下机制。
10.1 线程模型
- • 同步 Servlet 模式适合低并发后台任务,不适合大规模长连接流式输出。
- • 对于聊天、SSE、WebSocket 类场景,优先考虑 WebFlux 或事件驱动模型。
- • 检索、OCR、Embedding、文件解析等阻塞操作应隔离线程池,避免占满业务线程。
10.2 限流与舱壁隔离
必须至少分三类资源池:
- • 模型调用池
- • 检索池
- • 异步文档处理池
这样做的原因是:当模型接口抖动时,不应把检索和普通业务接口一起拖死。
10.3 缓存分层
建议采用三层缓存:
- Prompt 结果缓存:针对热点标准问答。
- 检索结果缓存:针对重复查询减少向量库压力。
- Embedding 缓存:针对重复文本避免重复向量化。
10.4 降级策略
至少准备四类降级:
- • 主模型失败,切到低成本小模型。
- • RAG 失败,仅返回通用回答模板。
- • 检索超时,仅返回人工服务引导。
- • 多模态失败,转异步人工审核。
10.5 多租户与权限过滤
这是企业系统里最容易踩坑的一点。向量库检索不能只按相似度,要带上:
- •
tenantId - •
appId - •
departmentId - •
documentScope - •
sensitivityLevel
否则相似度足够高时,极易发生跨租户知识泄漏。
十一、生产级配置建议
11.1 Spring Boot 配置示例
spring: threads: virtual: enabled: true ai: openai: api-key: ${OPENAI_API_KEY} base-url: ${OPENAI_BASE_URL:https://api.openai.com} chat: options: model: gpt-4o-mini temperature: 0.2 max-tokens: 1200 data: redis: host: ${REDIS_HOST:localhost} port: ${REDIS_PORT:6379}management: endpoints: web: exposure: include: health,metrics,prometheusresilience4j: ratelimiter: instances: chatRateLimiter: limitForPeriod: 100 limitRefreshPeriod: 1s timeoutDuration: 100ms circuitbreaker: instances: chatCircuitBreaker: slidingWindowSize: 50 failureRateThreshold: 50 waitDurationInOpenState: 10s bulkhead: instances: llmBulkhead: maxConcurrentCalls: 30 maxWaitDuration: 50ms
11.2 这些配置背后的架构意义
- •
temperature在企业问答里应偏低,保证稳定性。 - •
max-tokens不宜过大,否则延迟、成本、失败率都会上升。 - •
limitForPeriod不是越大越好,要与供应商配额联动。 - •
maxConcurrentCalls应由模型吞吐、网络、向量检索耗时综合决定。
十二、可观测性:没有监控,AI 系统无法运维
生产 AI 系统至少要采集以下指标:
| 指标 | 用途 |
|---|---|
| 请求量 QPS | 判断压力规模 |
| 平均延迟 / P95 / P99 | 判断用户体验和稳定性 |
| 模型调用失败率 | 判断外部依赖健康度 |
| Token 输入输出量 | 做成本审计 |
| 检索召回数量 | 观察 RAG 是否有效 |
| 缓存命中率 | 判断是否存在重复浪费 |
| 降级率 | 判断系统是否长期处于风险边缘 |
| 人工复核率 | 判断抽取质量是否可用 |
建议落地方式:
- • Micrometer + Prometheus + Grafana
- • TraceId 贯穿网关、检索、模型、缓存、数据库
- • 审计日志记录 Prompt 模板版本、知识库版本、模型版本
如果没有这些数据,线上出现“答案变差了”时,你几乎无法定位是:
- • 模型变了
- • Prompt 变了
- • 检索变了
- • 文档切分变了
- • 向量库过滤条件丢了
十三、基准测试怎么做才专业
很多文章给出“某框架 45ms,某框架 52ms”,但不说明口径,这种结论参考意义很低。AI 应用压测至少要拆三类:
- 纯框架开销:不调用远端模型,只测本地编排。
- 检索链路开销:固定向量库与数据集,比较检索处理耗时。
- 端到端开销:真实调用模型,统计完整用户请求延迟。
13.1 JMH 只适合测本地逻辑
package com.example.benchmark;import org.openjdk.jmh.annotations.Benchmark;import org.openjdk.jmh.annotations.BenchmarkMode;import org.openjdk.jmh.annotations.Fork;import org.openjdk.jmh.annotations.Measurement;import org.openjdk.jmh.annotations.Mode;import org.openjdk.jmh.annotations.OutputTimeUnit;import org.openjdk.jmh.annotations.Scope;import org.openjdk.jmh.annotations.State;import org.openjdk.jmh.annotations.Warmup;import java.util.concurrent.TimeUnit;@State(Scope.Benchmark)@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MILLISECONDS)@Warmup(iterations = 3)@Measurement(iterations = 5)@Fork(1)public class LocalPipelineBenchmark { private final PromptAssembler assembler = new PromptAssembler(); private final RetrievalFusionService fusionService = new RetrievalFusionService(); @Benchmark public String promptAssemble() { return assembler.assemble("如何申请退款?", "知识片段A\n知识片段B"); } @Benchmark public int retrievalFusion() { return fusionService.fuseAndScore(); }}
13.2 端到端压测更推荐 Gatling / k6 / JMeter
真正有价值的指标是:
- • 50 并发、100 并发、300 并发下的 P95 / P99
- • 流式首包时间
- • 单位请求 Token 成本
- • 错误率与降级率
- • 向量库 CPU / 内存 / IOPS
13.3 一个更可信的性能判断方式
通常情况下:
- • LangChain4j 在单体编排逻辑上可能更轻。
- • Spring AI 在纳入完整企业治理后,整体链路未必更快,但系统稳定性通常更好。
所以不要问“谁更快”,而要问:
- • 在相同治理能力下谁更快?
- • 在相同可观测性、缓存、限流、熔断条件下谁更稳?
十四、真实项目中的选型建议
14.1 优先选择 LangChain4j 的情况
- • 项目处于 0 到 1 探索期。
- • 团队更关注 Agent、RAG、Tool Calling 的快速实验。
- • 不是 Spring 技术栈主导。
- • 希望较低抽象成本构建 AI 能力原型。
- • 业务迭代快,要求先证明场景成立。
14.2 优先选择 Spring AI 的情况
- • 已有成熟 Spring Boot / Spring Cloud 体系。
- • 系统要进入生产且面向多团队复用。
- • 强调可观测性、合规、审计、权限、配置治理。
- • 需要统一接入缓存、消息、任务调度、网关、安全体系。
- • 要做“AI 平台能力”而不是单点智能功能。
14.3 推荐的混合策略
很多企业最终会采用混合方案:
- • 业务生产主链路:Spring AI
- • 复杂 Agent 原型或实验编排:LangChain4j
- • 公共治理能力:统一放在 Spring Boot 基础设施层
这不是重复建设,而是让两个框架各做自己最擅长的事。
十五、架构师视角下的最终决策模型
如果你是架构负责人,建议按下面四个问题判断:
问题一:我们是在做一个 AI 功能,还是在建设 AI 平台?
- • AI 功能优先:可偏 LangChain4j
- • AI 平台优先:可偏 Spring AI
问题二:团队的主技术栈是什么?
- • Spring Boot 深度使用团队:Spring AI 通常更低摩擦
- • 多技术栈混合团队:LangChain4j 灵活性更高
问题三:系统是否强调治理和审计?
- • 如果答案是“强依赖”,Spring AI 更匹配企业工程现实。
问题四:我们是否需要频繁试验复杂 Agent 工作流?
- • 如果答案是“是”,LangChain4j 会让 AI 编排体验更好。
十六、最终总结
LangChain4j 与 Spring AI 的差异,本质上不是“哪个能不能做 RAG”,而是两种不同的系统设计哲学:
- • LangChain4j 让你更快地表达 AI 编排逻辑。
- • Spring AI 让你更稳地把 AI 能力纳入企业系统。
如果你的目标是快速把 AI 场景跑起来,LangChain4j 往往更高效;如果你的目标是把 AI 作为长期、可治理、可观测、可审计的企业能力沉淀下来,Spring AI 通常更合适。
真正成熟的技术选型,不是迷信框架,而是看它是否与以下三件事一致:
- 你的组织能力模型
- 你的系统治理要求
- 你的业务演进节奏
从这个角度看,没有银弹,只有更匹配的架构选择。
十七、落地建议清单
如果你准备把文章中的结论应用到真实项目,建议先完成这份最小落地清单:
- 明确系统是 PoC、业务功能还是平台能力。
- 为模型调用增加限流、熔断、超时与降级。
- 为 RAG 增加租户过滤、混合检索、引用返回。
- 为多模态任务增加异步处理和结构化校验。
- 为 Prompt、模型版本、知识库版本建立审计能力。
- 为系统接入 Metrics、Trace、日志与成本统计。
- 在 50 / 100 / 300 并发下做端到端压测,而不是只看单机 Demo。
做到这些之后,你的 AI 系统才算真正进入“可上线、可维护、可扩展”的阶段。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

更多推荐

所有评论(0)