☰
Java开发者大模型实战:Spring AI与Agent工程化落地
2026/10/28 17:16:46 网站建设 项目流程

从传统 Java 业务开发转向大模型应用开发,很多人会卡在两个问题上:一是 API 调用方式不熟,不知道如何把提示词工程、流式输出、工具调用这些能力组合起来;二是资料太散,一会儿讲 LangChain,一会儿讲 Spring AI,一会儿又讲 Agent,看着都很厉害,但落到自己的 Spring Boot 项目里却不知道怎么下手。

我之前也反复踩过这些坑。搜索到的内容往往只讲某一个框架的单项用法,缺少一条能把 Java 后端经验迁移过来的完整链路。后来我把 Spring AI、Spring AI Alibaba、LangChain、Agent 这几条线分别跑通,再结合项目里的真实场景做了整合,才逐渐形成一套比较清晰的实战路线。

这篇文章就把这套路线完整整理出来。内容按照“概念 → 环境 → 实战 → 排错 → 工程化 → 面试考点”的顺序展开,既适合刚接触大模型的 Java 开发者,也能给已经在做 AI 应用落地的人提供一份可复用的工程参考。全文不会只贴代码,每个关键步骤我都会解释为什么要这么做,以及常见的问题在哪里。

1. 背景与核心概念:Java 开发者为什么需要关注大模型应用开发

大模型本身并不是一个新的“软件框架”,而是一种新的交互方式:你输入一段自然语言,模型根据训练数据和上下文生成回答。过去几年,Python 生态的开发者通过 LangChain 等框架快速拿到了大模型能力,但 Java 生态一直缺少一套足够工程化的方案。直到 Spring AI 出现,Java 开发者才可以用自己熟悉的依赖注入、自动配置、模块化方式去接入大模型。

Spring AI 解决的问题非常直接:它把不同厂商的大模型 API 封装成统一的接口,屏蔽了 OpenAI、通义千问、Ollama 等模型服务的差异。你在代码里只需要面向 ChatClient 编程,不需要为每家模型厂商写一套 HTTP 调用逻辑。同时,它还提供了 Prompt 模板、输出解析、向量数据库接入、工具调用、Agent 等能力,相当于把 LangChain 的一部分功能搬到了 Java/Spring Boot 生态里。

Spring AI Alibaba 则可以理解为 Spring AI 在国内模型生态上的延伸。它由阿里巴巴开源,长期目标是让 Java 开发者更顺畅地接入阿里云百炼平台上的通义千问系列模型,同时提供了 Graph 编排、Skills 等更贴近业务编排的能力。对于国内团队来说,这是一条相对低成本、低延迟的落地路径,因为不需要额外走海外接口。

LangChain 则是 Python 生态里最知名的大模型应用开发框架。虽然这篇文章的主题是 Java 和大模型,但 LangChain 值得了解,因为它奠定了很多通用概念,比如 Chain、Agent、Retrieval、Memory。听懂 LangChain 之后再回头理解 Spring AI,会发现两边只是语言和 API 不同,思想是相通的。

Agent 是这几条线里最有意思的概念。它不只是一个“聊天机器人”,而是让大模型具备调用工具、拆分任务、循环执行的能力。举例来说,你让 Agent“查询北京天气,并在气温低于 10 度时提醒我带外套”,模型会先把这个问题拆成查询天气、判断温度、生成提醒三个步骤,然后调用对应的天气查询工具完成任务。没有 Agent 之前,这些逻辑需要写死在代码里;有了 Agent 之后,模型可以自主决定调用哪个工具。

这里有一个容易混淆的点:Spring AI 和 LangChain 不是二选一的关系。如果你维护的是 Java 后端,Spring AI 是主力;如果你的团队有 Python 服务,或者需要用到 LangChain 生态里非常细分的模块,那么 LangChain 可以作为辅助或独立服务存在。关键不是选框架,而是理解模型、提示词、工具、记忆这几个核心组件是如何组织起来的。

2. 环境准备与版本说明

2.1 本地环境要求

本文示例基于 Java 17 + Spring Boot 3.x + Maven 构建,这是 Spring AI 目前比较主流的组合。请先确认你的环境:

环境项建议版本说明
JDK17 或更高Spring Boot 3 要求 JDK 17+
Maven3.8+也可以使用 Gradle
Spring Boot3.3.x / 3.4.x需要匹配 Spring AI 版本矩阵
模型 APIOpenAI / 通义千问 / Ollama 任一本文会分别演示

如果你的项目还在使用 JDK 8,建议先升级。Spring Boot 3 和 Spring AI 对 Java 17 的支持已经非常成熟,继续停留在旧版本会限制很多新特性。

2.2 申请模型 API Key

调用大模型需要拿到 API Key。不同平台的申请位置不同,但大体流程一致:

  • 登录模型服务平台。
  • 创建一个 API Key,复制保存。
  • 查看开通哪些模型,比如 qwen-plus、gpt-4o-mini 等。
  • 把 API Key 配置到环境变量中,不要硬编码在代码或配置文件里。

本地开发时可以在 IDE 的环境变量里配置,也可以使用.env文件,但要注意不要把.env提交到 Git。生产环境建议使用配置中心或密钥管理服务。

2.3 本地模型方案:Ollama

如果不想申请外部 API Key,可以使用 Ollama 在本地部署开源模型。Ollama 是一个极简的大模型本地部署工具,支持一键运行多个开源模型。安装完成之后,执行:

ollama pull qwen2.5 ollama run qwen2.5

这样本地就有了一个可以通过 HTTP 访问的模型服务,默认地址是http://localhost:11434。后续 Spring AI 可以把这个地址配置为模型服务地址。本地部署的好处是数据不出内网、调用成本为零,适合开发和测试环境,生产环境则要根据并发和显存情况评估。

2.4 创建 Maven 工程

我习惯用 Spring Initializr 创建工程,地址是https://start.spring.io/。选择 Java 17、Spring Boot 3.x,然后添加 Spring Web 依赖。创建完之后的目录结构大致如下:

demo-ai/ ├── pom.xml ├── src/ │ └── main/ │ ├── java/ │ │ └── com/example/demo/ │ │ ├── DemoAiApplication.java │ │ ├── controller/ │ │ │ └── ChatController.java │ │ ├── service/ │ │ │ └── WeatherService.java │ │ └── config/ │ │ └── ChatClientConfig.java │ └── resources/ │ ├── application.yml │ └── prompts/ │ └── system-prompt.st

这里提前把 package 结构理清楚,代码不会堆在一起。后续新增的 Controller、Service、Config 都放在对应的包里。

3. Spring AI 实战:搭建第一个大模型接口

3.1 添加依赖

Spring AI 的官方 starter 会帮我们完成大部分自动配置。以 OpenAI 接入为例,在pom.xml中加入:

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

如果你的环境是 Spring AI Alibaba,则需要使用:

<dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-starter</artifactId> <version>对应版本号</version> </dependency>

需要注意,Spring AI 的版本更新很快,具体版本号要以官方 Release 页面和版本矩阵为准。不同版本的 starter 名称、配置项可能略有差异,本文以 Spring AI 1.0 GA 之后的稳定 API 为例进行讲解。

3.2 编写配置

在application.yml中配置模型服务地址和 API Key。以下以 OpenAI 为例:

spring: application: name: demo-ai ai: openai: api-key: ${OPENAI_API_KEY} base-url: https://api.openai.com model: chat: openai

这里的${OPENAI_API_KEY}会读取环境变量,这样不会把密钥泄露到代码仓库。spring.model.chat=openai表示默认使用 OpenAI 模型作为 Chat 模型。

如果使用 Ollama 本地模型,配置则改为:

spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: qwen2.5

这种设计的好处是:代码不需要关心模型来自哪个平台,统一通过 Spring AI 抽象出来的接口调用。想要切换模型时,只需要修改配置文件。

3.3 使用 ChatClient 完成对话

Spring AI 1.0 之后,推荐使用ChatClient来完成对话。ChatClient采用了 Builder 模式,我们可以先从容器中拿到ChatClient.Builder,然后构建一个实例。下面创建一个最简的 Controller:

// 文件路径:src/main/java/com/example/demo/controller/ChatController.java package com.example.demo.controller; import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient = builder.build(); } @GetMapping("/chat") public String chat(@RequestParam(defaultValue = "请用一句话介绍 Spring AI") String prompt) { return chatClient.prompt(prompt) .call() .content(); } }

这段代码的核心是chatClient.prompt(prompt).call().content()。prompt()表示构造一个 Prompt 请求,call()是同步调用,content()取出模型返回的文本内容。启动项目后,访问http://localhost:8080/chat?prompt=你好,就能看到模型返回结果。

3.4 流式输出与 System Prompt

在很多真实场景中,我们希望实现像 ChatGPT 打字机一样的效果。Spring AI 提供了stream()方法:

@GetMapping("/chat/stream") public String chatStream(@RequestParam String prompt) { return chatClient.prompt(prompt) .stream() .content() .collectList() .block() .stream() .collect(Collectors.joining()); }

这里为了方便演示,把流式内容合并成字符串返回了。实际项目中应该使用Flux<String>配合 WebFlux 实现 SSE 推送。

还可以通过.system()设置系统提示词,让模型扮演特定角色:

String result = chatClient.prompt() .system("你是一个专业的 Java 技术面试官,回答要简洁、准确。") .user("请解释一下 Spring Boot 自动配置的原理") .call() .content();

System Prompt 的作用是给模型设定身份和行为边界,建议写成独立文件或配置项,不要散落在代码中。

3.5 运行验证

启动 Spring Boot 应用,在浏览器或者 curl 中验证:

curl "http://localhost:8080/chat?prompt=Java%E7%9A%84%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%89%B9%E6%80%A7%E6%9C%89%E5%93%AA%E4%BA%9B"

如果返回一段可读的中文文本,说明 Spring AI 的基本链路已经跑通了。接下来可以继续测试流式接口、System Prompt 等。

4. Spring AI Alibaba 实战:对接国内大模型与 Graph

4.1 为什么单独讲 Spring AI Alibaba

把 Spring AI Alibaba 单独拿出来讲,是因为它在国内生产环境的落地价值非常明显。国内访问海外模型的延迟和稳定性问题,会让很多企业转向国内云厂商的模型服务。Spring AI Alibaba 对阿里云百炼平台的通义千问系列模型做了高度适配,配置和用法与标准 Spring AI 几乎一致,学习成本很低。

同时,Spring AI Alibaba 提供了 Graph 编排能力。Graph 的思想类似于 LangGraph:把复杂的业务流程拆成多个节点,每个节点负责一个步骤,节点之间通过状态传递数据。对于 Java 后端团队来说,Graph 是比“写死 if-else 调用链”更好的规模化方案。

4.2 引入依赖并配置 DashScope

先引入 Spring AI Alibaba 的 starter:

<dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-starter</artifactId> </dependency>

然后在application.yml中配置:

spring: ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus

这里的DASHSCOPE_API_KEY是阿里云百炼平台的密钥,qwen-plus是通义千问的模型名称。如果你的项目已经使用了标准 Spring AI 的 OpenAI starter,也可以同时配置多个模型服务,然后通过spring.ai.model.chat指定默认使用哪个。

4.3 一个简单的 qwen 对话接口

与标准 Spring AI 一样,代码层面依然使用ChatClient:

// 文件路径:src/main/java/com/example/demo/controller/QwenChatController.java package com.example.demo.controller; import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class QwenChatController { private final ChatClient chatClient; public QwenChatController(ChatClient.Builder builder) { this.chatClient = builder.build(); } @GetMapping("/qwen/chat") public String qwenChat(@RequestParam String prompt) { return chatClient.prompt(prompt) .call() .content(); } }

从这个示例可以看出,Spring AI 的抽象能力让不同模型服务之间的切换成本极低。你甚至可以在配置中心动态切换模型,而不用修改 Java 代码。

4.4 Graph:用有状态编排替代复杂调用链

Graph 是 Spring AI Alibaba 提供的流程编排方案。一个典型的 Graph 由节点(Node)和边(Edge)组成。每个节点是一个任务单元,比如“意图识别”“查询数据库”“生成回答”,边定义了节点之间的流转关系。节点会读取共享状态,处理完再写回状态,下一个节点从状态中拿数据继续处理。

这里不展开 Graph 的完整代码,因为不同版本的 API 变动较大。但从工程角度看,你可以把 Graph 理解成一个可控的 Agent 编排框架:没有 Graph 时,Agent 调用工具是模型自由发挥;有了 Graph 之后,调用顺序和分支条件可以由开发者约束,这在金融、政务等对流程有严格要求的业务里非常重要。

考虑以下场景:用户提交一个“帮我查一下上个月订单量”的问题,没有 Graph 时,模型可能直接生成 SQL 并执行,风险不可控;有 Graph 时,可以把流程固定为“意图识别 → 生成 SQL → 人工确认 → 执行 → 结果总结”五个节点,每一步都在可控范围内。

4.5 Skills:给模型装配技能

Spring AI Alibaba 还支持 Skills 能力,可以理解为一组可复用的工具包。比如你有一个“数据分析”技能,内部封装了查库、画图、生成结论三个步骤,模型只要识别到用户意图是数据分析,就会自动加载这个技能。Skills 和 @Tool 的区别是:@Tool 更偏向单点工具,Skills 更像面向业务场景的工具组合。实际开发中建议先用 @Tool 跑通单点能力,再在复杂业务里引入 Skills。

5. Agent 实战:让模型学会使用工具

5.1 Agent 的工作原理

Agent 的核心不是模型本身,而是“模型 + 工具 + 循环”。当用户提出一个需要操作外部系统的需求时,Agent 会经历以下过程:

  1. 模型理解用户意图,判断是否需要调用工具。
  2. 如果需要,模型生成一个包含工具名和参数的调用请求。
  3. 应用程序执行工具,把工具返回结果交给模型。
  4. 模型根据工具结果生成最终回答。

这个循环会持续,直到模型认为任务完成。在 Spring AI 中,我们可以通过 @Tool 注解把一个 Java 方法暴露给模型。

5.2 用 @Tool 定义工具

假设我们有一个天气查询服务:

// 文件路径:src/main/java/com/example/demo/service/WeatherService.java package com.example.demo.service; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; @Service public class WeatherService { @Tool(description = "根据城市名查询当前天气") public String getWeather(String city) { // 这里演示使用模拟数据,真实项目中可以调用第三方天气 API if (city.contains("北京")) { return "北京:晴,气温 8 度,北风 3 级"; } return city + ":多云,气温 15 度,微风"; } }

@Tool注解会让 Spring AI 自动生成该方法的 JSON Schema 描述,然后把描述发给模型。模型看到工具描述后,就会知道“查询天气”这个能力存在,并且知道需要传入 city 参数。

5.3 把工具交给 ChatClient

接下来创建一个配置类,把 WeatherService 注册到 ChatClient 中:

// 文件路径:src/main/java/com/example/demo/config/ChatClientConfig.java package com.example.demo.config; import com.example.demo.service.WeatherService; import org.springframework.ai.chat.client.ChatClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ChatClientConfig { @Bean public ChatClient chatClient(ChatClient.Builder builder, WeatherService weatherService) { return builder .defaultTools(weatherService) .build(); } }

这里的defaultTools(weatherService)会扫描 WeatherService 中带 @Tool 注解的方法,并把它们注册为模型可调用的工具。模型在生成回答时,如果认为需要查询天气,就会返回一个工具调用请求,Spring AI 自动执行该方法,并把返回值再交给模型。

5.4 验证 Agent 的完整链路

创建一个测试接口:

// 文件路径:src/main/java/com/example/demo/controller/AgentController.java package com.example.demo.controller; import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class AgentController { private final ChatClient chatClient; public AgentController(ChatClient chatClient) { this.chatClient = chatClient; } @GetMapping("/agent/weather") public String agentWeather(@RequestParam String city) { return chatClient.prompt("请查询" + city + "的天气") .call() .content(); } }

启动项目后,访问:

curl "http://localhost:8080/agent/weather?city=%E5%8C%97%E4%BA%AC"

预期结果是模型调用了 WeatherService 的 getWeather 方法,然后再生成一句话回答,内容类似于“北京今天晴,气温 8 度,北风 3 级”。如果你在日志里看到工具调用链路,说明 Agent 循环已经生效。

这里需要提醒的是,大模型的工具调用并不总是完美的。有时模型会传错参数,有时会绕开工具直接编造答案。因此生产环境的工具参数校验非常重要,工具方法内部必须做防御式编程。

5.5 LangChain Agent 的对照实现

同样的 Agent 能力在 LangChain 里通常写作:

from langchain_openai import ChatOpenAI from langchain.agents import create_openai_functions_agent, AgentExecutor from langchain.tools import tool @tool def get_weather(city: str) -> str: """根据城市名查询当前天气""" return f"{city}:晴,气温 15 度" llm = ChatOpenAI(model="gpt-4o-mini", api_key="sk-xxx") agent = create_openai_functions_agent(llm, tools=[get_weather], prompt="你是天气助手") executor = AgentExecutor(agent=agent, tools=[get_weather]) print(executor.invoke({"input": "北京天气怎么样"}))

可以看到,LangChain 和 Spring AI 的思路是一样的,只是 API 风格不同。理解了 Agent 的核心机制后,切换语言和框架并不难。

6. LangChain 与 LangGraph:Python 侧必知生态

6.1 LangChain 的核心模块

LangChain 是目前 Python 生态中使用最广泛的大模型应用框架之一。它的设计核心是把大模型应用拆成几个可组合的模块:

  • Model I/O:封装不同模型,提供 Prompt 模板和输出解析。
  • Retrieval:文档加载、切分、向量化、检索,是 RAG 的基础。
  • Memory:在会话中保存历史消息。
  • Chains:把多个步骤组合成一条流水线。
  • Agents:让模型自主选择和使用工具。

在 LangChain 的老版本中,很多组件都集中在langchain主包里。新版本做了一个比较大的拆分,比如模型调用被拆到了langchain-openai、langchain-anthropic等独立包中。学习的时候要注意区分版本。

6.2 最简 LangChain 示例

下面是一个最基础的 LangChain 示例,使用 LangChain 表达式语言(LCEL)构建一个“prompt → llm”的调用链:

# 文件路径:langchain_demo/main.py from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate # 初始化模型 llm = ChatOpenAI( model="gpt-4o-mini", api_key="sk-xxx" ) # 创建 Prompt 模板 prompt = ChatPromptTemplate.from_template("请用一句话解释 {concept}") # 使用 LCEL 组合成链 chain = prompt | llm # 调用链 result = chain.invoke({"concept": "RAG"}) print(result.content)

LCEL 使用了管道符|来组合组件,非常直观。prompt | llm表示先把用户输入填充到模板中,再把格式化后的 prompt 传给模型。如果后续要加输出解析,只需要继续用管道符拼接。

6.3 LangGraph 是什么

LangGraph 是 LangChain 团队推出的专注于构建有状态 Agent 应用的框架。传统 Chain 是无状态的线性管道,而 Agent 需要根据用户输入动态决定下一步,这就需要一个可以维护状态、支持分支和循环的编排框架。LangGraph 正是为此设计的。

LangGraph 的核心概念包括节点(Node)、边(Edge)和状态(State)。你可以在状态里维护对话历史、中间变量;在节点里编写具体逻辑;在边里定义条件跳转。比如一个客服 Agent,可以定义“意图识别”节点,如果判断是退货,跳转到“退货流程”节点;如果判断是投诉,跳转到“转人工”节点。

6.4 LangGraph 与 LangChain 的区别

这是很多人面试时容易混淆的点。

维度LangChainLangGraph
定位大模型应用开发框架Agent 流程编排框架
执行模型Chain,线性为主Graph,有状态、多分支
状态管理弱强,显式状态对象
适用场景简单问答、RAG 链路复杂 Agent、多步骤任务
与 LangChain 关系基础框架深度依赖 LangChain

简单来说,LangChain 提供零件,LangGraph 提供工厂流水线。单纯做知识库问答,用 LangChain 就够;一旦涉及 Agent 自主决策、循环调用工具,LangGraph 更合适。

6.5 什么时候选择 LangGraph

如果你的业务满足以下任一条件,值得考虑 LangGraph:

  • 流程有多个分支,需要根据中间结果动态决定下一步。
  • 需要人工审批、重试、回退等控制逻辑。
  • 单个 Agent 无法完成任务,需要多个 Agent 协作。
  • 需要可视化追踪每一步的执行状态。

但如果只是一个简单的“模型 + 固定提示词”的接口,不建议上来就引入 LangGraph,那样反而会增加复杂度。工程上有一个原则:能用简单链解决,就不要先上编排框架。

7. 常见问题与排查思路

7.1 高频报错排查表

下面是 Spring AI、LangChain、Agent 开发中常见的几类问题。

问题现象常见原因解决思路
401 UnauthorizedAPI Key 无效或未正确配置检查环境变量,确认 Key 是否有权限
连接超时网络不通、模型服务地址错误校验 base-url,排查防火墙
模型返回空内容上下文太长、模型拒绝回答检查输入长度,尝试精简 Prompt
工具没有被调用@Tool 方法未扫描到确认类被 Spring 管理,检查 defaultTools 注册
工具参数解析失败模型生成的 JSON 参数不符合方法签名在工具方法内做参数校验,提供兜底返回
依赖冲突Spring Boot 版本与 Spring AI 不匹配参考官方版本矩阵统一版本
流式输出乱码没有设置正确的字符集检查响应头 Content-Type 是否 UTF-8
Ollama 连接失败Ollama 服务未启动或端口不对先执行 ollama list 验证本地服务

7.2 典型排查案例

案例一:模型返回了工具应该返回的文本,而不是执行工具后的结果。这个现象通常是因为模型没有真正触发工具调用,只是根据描述“猜”了一个结果。解决办法是检查工具描述是否清晰,给出足够的示例,并且让模型不要自行假设工具结果。

案例二:API Key 配置没问题,但一直报 429 限流。大部分模型平台都有 RPM(每分钟请求数)和 TPM(每分钟 Token 数)限制。解决办法是增加本地重试机制、控制并发数,或者升级服务配额。

案例三:同一个 Prompt,有时回答好,有时回答差。这是大模型本身的随机性造成的。生产环境建议把温度参数调低,例如设置为 0.2 或 0,并固定使用同一模型版本。

7.3 关于成本问题的思考

很多同学会担心大模型调用成本高。这里需要区分两种情况:API 调用方式和本地部署方式。API 调用按 Token 计费,适合快速验证和中低并发场景;本地部署则需要 GPU 资源,适合数据敏感、常态化高并发的场景。两者没有绝对的好坏,关键是根据需求选择匹配的模型规格。

成本控制方面有几点可以落地:

  • 优先选择小模型或轻量模型处理简单任务。
  • 对重复问题做缓存,减少相同请求。
  • 控制上下文中历史消息的数量,避免 Token 膨胀。
  • 复杂任务拆成多个小模型调用,而不是一个超长上下文。

8. 大模型应用工程化最佳实践

8.1 API Key 与配置安全

API Key 是账号级别的敏感信息,一旦泄露,可能造成资产损失。开发环境建议使用环境变量;生产环境建议放入密钥管理服务,并通过配置中心下发。不要在前端代码、日志、Git 提交历史中出现 Key。

8.2 Prompt 治理

Prompt 不应该散落在业务代码里。建议把高频 Prompt 收敛到配置中心或独立的资源目录中,并进行版本管理。每次修改 Prompt 都要记录变更,方便回归测试。对于重要业务,可以建立一套 Prompt 评测用例集,自动化验证 Prompt 修改后的效果。

8.3 限流、重试与降级

大模型接口的响应时间通常比普通 HTTP 接口慢,而且高峰期可能出现超时。工程上需要做三层防护:

  • 使用 Spring Retry 或 Resilience4j 做超时重试,但要注意避免重复扣费。
  • 对调用方做限流,防止突发流量打爆模型配额。
  • 设置降级策略,模型服务不可用时返回兜底文案或本地缓存结果。

8.4 输出校验与可观测性

模型输出是不可控的,必须做校验。比如让模型输出 JSON 时,不能假设它一定返回合法 JSON,需要在代码中解析并捕获异常。同时,每次调用都应该记录模型名、输入输出摘要、Token 消耗、耗时等指标,便于排查问题和成本归因。

8.5 生产环境注意事项

  • 灰度发布:先在测试环境验证模型效果,再逐步放量。
  • 数据合规:用户输入可能包含隐私,注意脱敏和日志过滤。
  • 模型版本固定:不要依赖“最新模型”这种隐式版本,防止模型行为大变。
  • 访问控制:AI 接口同样是业务接口,需要鉴权、防刷、限流。

9. 大模型面试核心考点与学习路线

9.1 面试题速查

最近很多 Java 岗位面试开始加入大模型相关内容,尤其是涉及 AI 应用开发的岗位。以下 6 个问题出现频率很高:

问题核心考点
Spring AI 和 LangChain 有什么区别框架定位、语言生态、抽象方式
Agent 和 Chain 的区别动态决策与固定管线
什么是 ReActAgent 的思考-行动-观察循环
Function Calling 是什么模型如何调用外部工具
LangGraph 和 LangChain 的区别有状态编排与线性链
RAG 和微调怎么选知识更新、成本、可控性

9.2 面试答题思路

Spring AI 与 LangChain 的区别,可以从语言生态和定位来答:Spring AI 是 Java/Spring 生态的统一抽象,主要服务后端和微服务场景;LangChain 是 Python 生态的组合框架,Prompt、Chain、Agent 组件更丰富。二者在概念上是同类,实现语言和环境不同。

Agent 与 Chain 的区别,关键是“决策权”。Chain 在代码里写死了下一步做什么,Agent 由模型根据上下文选择下一步。可以用天气助手举例:Chain 只能固定调用天气接口,Agent 可以自主决定是否调用、调用哪个、结果如何拼装。

RAG 与微调的选择,可以从三个维度分析:知识更新频率高选 RAG,回答风格和能力层面选微调;RAG 成本低、响应快,微调效果稳但成本高。很多生产场景其实是 RAG + 微调组合使用。

9.3 学习路线建议

如果你是从零开始,我推荐按下面路线走:

第一阶段(1 周):掌握 Spring AI 基本用法。跑通 ChatClient、流式输出、Prompt 模板,理解配置项含义。

第二阶段(1 周):掌握工具调用和 Agent。写一个调用第三方接口的 @Tool 方法,理解模型工具调用的循环。

第三阶段(1 周):掌握 RAG。学习向量化、向量数据库、文档切分,搭建一个简单的知识库问答系统。

第四阶段(1 周):了解 LangChain 和 LangGraph。重点不是写大量 Python 代码,而是理解概念,知道什么时候用哪个框架。

第五阶段(按需):深入微调和模型部署。用 Ollama 跑本地模型,了解 vLLM 等推理框架的基本思路。

9.4 最后的建议

大模型应用开发最忌讳的是“拿着锤子找钉子”。不要为了用 Agent 而用 Agent,不要为了上 LangGraph 而把简单的接口复杂化。先把 Spring AI 的基本能力跑通,再逐步往 Prompt 优化、工具调用、知识库方向扩展,每一步都解决一个真实业务问题。

如果条件允许,建议在本地用 Ollama 部署一个模型,这样无论怎么调试都不会产生费用,踩坑成本很低。之后再切换线上模型时,你会发现 Spring AI 的代码不用改,只改配置就能完成迁移。动手写一个简单的 Demo,比看十篇概念文章都有效。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询