ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Spring AI 2.0实战:从多模型到Agent的一周学习路线

Spring AI 2.0实战:从多模型到Agent的一周学习路线 Spring AI 2.0 对 Java 开发者来说最值得优先搞清楚的是整条学习线多模型接入、Tools 函数调用、MCP 协议、Skills 复用、Agent 编排这五个东西怎么串起来而不是只学会某一个 API。这篇文章按一套一周能走完的实战路线写先跑通单模型对话再补结构化输出然后依次接 Tools、接 MCP再把 Skills 和 Agent 的关系理清最后给常见报错和排查顺序。适合两类人一是 Spring 很熟但没碰过 AI 的 Java 工程师二是已经用 HTTP 或 Python 调过模型、想把能力沉淀到 Java 工程里的人。一周这个时间点比较诚实指的是七天搭出一个带对话、工具调用、外部服务接入的完整项目而不是把底层原理全部啃完。1. Spring AI 2.0 先把 Java 集成的哪些脏活收了1.1 没有 Spring AI 时Java 接模型要重复做什么很多 Java 项目最早接入大模型路径非常原始用 RestTemplate 或 WebClient 发 HTTP 请求手动拼 JSON手动解析返回再手动处理流式输出。单个模型还能忍一旦要换模型厂商或者要支持好几个模型代码就开始失控。更麻烦的是函数调用。不同厂商对 tool calling 的请求体、参数格式、返回结构都不一样。模型说要查天气你得先把工具声明转成 JSON Schema再在返回结果里解析工具调用标记自己维护这一轮对话的上下文。这套东西写一次可以写两次就开始想抽公共层抽完发现还是和具体厂商耦合。Spring AI 解决的正是这一层重复劳动。它把模型接入、工具调用、结构化输出、上下文记忆、MCP 连接这些能力抽象成统一的 Spring 风格接口。对 Java 开发者来说最大的收益不是少写几个类而是整个团队可以用同一套写法去接不同模型不用每来一个新模型就重新培训一遍集成方式。1.2 2.0 这一层抽象到底抽象了什么核心抽象可以拆成几块看ChatModel 统一了对话模型接口。OpenAI、Ollama、DashScope 这类国内可访问的模型服务在 Java 代码里都收敛成一个 ChatModel 或 ChatClient。ChatClient 提供流式 API支持同步、流式、返回实体对象日常开发基本都从它入口进。Tool 注解把普通 Java 方法暴露给模型调用不需要手动维护 JSON Schema。结构化输出可以把模型返回的文本直接映射成 Java 实体类省去自己写解析器的过程。Advisors 充当拦截器可以在每次请求前后插入公共逻辑比如注入系统提示词、记录日志、拼装记忆。MCP 相关 starter 负责连接外部 MCP Server把远程工具注册进模型可见的 tool 列表。这些能力单独看都不稀奇关键是它们能组合。ChatClient 可以边用工具边接 MCP边做结构化输出最后再由 Agent 逻辑决定调用顺序。这种组合能力才是 Spring AI 2.0 值得学的真正原因。1.3 先别急着背 API先建立三个预期第一个预期网上教程标题经常写“一周学完”但真实目标是“一周跑通主链路”也就是能做出一个可演示、可扩展的原型。原理部分后面再补不影响你先跑起来。第二个预期Spring AI 迭代速度不慢部分 API 在小版本之间会有调整。写代码时优先跟着官方文档或你本地拉到的 jar 包走不要盲信一篇几个月前的文章里的包名。第三个预期多模型、MCP、Agent 这些词听起来很唬人但落到工程里都只是“配置 接口 状态管理”。理解这一点后面遇到报错就不会慌。2. 一周实战路线从 ChatClient 到 Agent 的顺序2.1 前三天先解决“能对话、能结构化、能调用工具”第一天只做一件事把 ChatModel 跑通。选一个本地模型服务或者用云端模型的 API能通过 ChatClient 问一句话并且拿到完整回复就算过关。这一步的核心是确认依赖、配置、网络三个环节没问题。第二天加结构化输出。让模型返回一个学生信息、订单信息之类的对象直接用 Java 实体类接收。不要只输出字符串然后手动 substring那样后面一定会出问题。第三天加 Tools。写一个最简单的工具方法比如根据城市名返回天气让模型在对话中自动决定调用它。这里你会第一次理解“模型不会主动干活它只会告诉你它想调用什么工具”。2.2 后三天解决“能接外部系统、能复用技能、能编排任务”第四天开始接触 MCP。先连接一个现成的 MCP Server比如文件系统、数据库、设计稿这类工具观察模型如何通过 MCP 拿到外部数据。重点不是自己写 Server而是理解客户端连接、工具发现、调用流转。第五天理清 Skills。你需要知道 Skills 和 RAG 的区别也要知道 Skills 和 MCP 的区别。简单说Skills 偏“模型该怎么做这件事”MCP 偏“模型能连上哪些外部设备”。可以把 Skills 理解为一套可复用的提示词和验证规则包。第六天做 Agent。不要第一次就写复杂的状态机先实现一个最简单的循环模型判断是否需要工具需要就调用调用完把结果塞回上下文再让模型继续直到给出最终答案。这个循环就是 Agent 的地基。2.3 第七天整合项目时按什么标准验收第七天不要开新功能把前六天的东西整合成一个完整项目。比如做一个“智能客服 订单查询 知识库问答”的小应用后端用 Spring AI前端用 Vue 简单接一下。验收标准建议按这个顺序看能连续对话且对话历史不会越来越乱。模型能在需要时调工具工具返回异常时不会直接崩。结构化输出字段稳定不会偶尔多一个字段或少一个字段。接 MCP 的调用延迟可接受超时有兜底。内存和 CPU 占用在可接受范围内连续跑几十轮不卡死。这一套走完你对 Spring AI 2.0 的掌握度就已经超过“只会调接口”的阶段了。3. 多模型接入先本地后云端配置优先于代码3.1 入门用本地模型最大的好处是能离线调试想快速试错我建议先跑本地模型比如通过 Ollama 拉一个 7B 或 8B 参数级别的模型。原因很直接不依赖外部网络不消耗 API 费用出问题时可以直接看模型日志不会出现“不知道是网络问题还是代码问题”的尴尬局面。本地模型对机器有要求。显存越大越好至少 8GB 起步比较舒服没有独立显卡也能跑但速度会慢很多只能用来验证流程。启动前先用ollama run在命令行里测一下确保模型本身能回复再把它接进 Spring AI。这一阶段不要追求效果追求链路通。链路通了后面换云端大模型只是改配置的事。3.2 云端模型统一走 ChatModel 配置接入云端模型时Spring AI 的写法大致是这样引入对应 starter配置 base-url、api-key、模型名然后代码里还是用同一个 ChatClient。环境上能用哪个模型服务就配哪个配置示例大概长这样spring: ai: model: chat: dashscope dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus注意这段配置只是示例具体属性名要和你引入的依赖版本对齐。不同小版本之间配置前缀可能有变化。我一般会先看一眼官方文档或 jar 包里的配置元数据再写 application.yml。还有一条必须养成习惯api-key 不要写死在配置文件里用环境变量或配置中心管理。项目一旦提交到仓库密钥泄出去就不是小事。3.3 切换模型后必须重新验证的四个点换模型不是改个模型名就结束。至少要从四个维度重新验证响应速度不同模型的首字延迟差别很大交互类场景对延迟敏感。输出稳定性同一个 Prompt模型 A 可能规规矩矩返回 JSON模型 B 可能带一堆解释文本。工具调用质量有的模型对 tool calling 支持得好有的模型经常“假装调用”或调用参数错误。失败模式限流、超时、上下文超长不同服务方返回的错误格式不一样兜底逻辑要按实际返回调整。也就是说多模型接入的价值在于“可切换”但切换之后必须把每个模型当作独立服务对待。不能因为接口统一就认为行为一致。4. Tools 函数调用把模型从“会聊天”变成“能干活”4.1 为什么模型必须依赖工具才能完成真实任务模型的知识是静态的训练完之后不会自动知道今天的天气、最新的库存、用户的实际订单。它也没有权限去执行下单、发通知、改数据库这类操作。Tools 的出现就是给模型开一个口子遇到需要外部信息或执行动作的场景模型返回一个工具调用请求由你的 Java 代码真正执行再把执行结果返回给模型继续推理。这里有一个常见误解模型“会写代码”不等于模型“会执行代码”。它只是从语义上理解这个工具能做什么然后按照约定格式发出调用请求。真正执行的是你的方法。4.2 用 Tool 声明一个工具最小步骤用一个实例说明。假设我要写一个查询天气的工具最小实现大概是Component public class WeatherTools { private final WeatherService weatherService; public WeatherTools(WeatherService weatherService) { this.weatherService weatherService; } Tool(description 根据城市名查询实时天气) public String getWeather(String city) { return weatherService.query(city); } }把这个类注册进 Spring 容器ChatClient 配置好工具扫描模型就能在对话中调用它。相比手写 JSON Schema这套方式明显省事但要注意Tool 的注解、包路径、工具注册方式在不同版本里有差异示例代码是帮你理解思路落地时以实际版本为准。顺手提一句这里说的 Tools 是 AI 函数调用里的工具不是 Android SDK Tools、VMware Tools 那类系统工具。搜索时候很容易被这些词干扰别绕进去。4.3 工具描述、入参校验和返回值设计工具方法名不重要description 才是关键。模型选择工具时主要靠 description 判断“这个方法适不适合当前任务”。写得模糊模型就不会调用写得准确调用率会明显提升。入参上能做的校验一定要做。模型生成的参数有时候就是不对比如城市名带了空格、日期格式不对、枚举值写错。方法内部先校验失败时返回结构化错误信息而不是直接抛异常把整个请求打崩。返回值设计遵循一个原则让模型直接能读懂。能返回字符串就返回字符串能返回简单对象就返回简单对象。不要返回一个巨大的实体对象模型在处理大量字段时更容易出错。必要时在返回前做裁剪只保留模型需要的字段。4.4 工具调用最容易翻车的三个场景第一个场景是模型不调用工具。先看 description 是否足够清晰再看工具是否真的被注册进了 ChatClient最后看模型本身是否支持 function calling。第二个场景是调用陷入死循环。模型调用工具、拿到结果、继续调用反复不停。解决办法是设置最大迭代次数超过就强制结束并返回当前信息。真实项目里这个限制必须有。第三个场景是工具执行时间太长。模型在等工具结果时如果接口超时整个对话就卡住了。建议给外部调用设置独立的超时时间并且让工具快速返回“查询中”这样的中间状态不要死等。5. MCP 协议AI 应用连接外部系统的新标准5.1 MCP 到底解决的是连接问题还是协议问题MCP 全称 Model Context Protocol解决的是 AI 应用和外部工具、数据源之间的连接规范问题。以前每接一个外部系统就要写一套适配接文件系统写一套文件读写接数据库写一套查询接设计协作工具再写一套 API。MCP 把这些统一成一套协议Server 端暴露能力Client 端发现并调用能力。你可以把 MCP 理解成一个“插头标准”。有了这个标准AI 应用不用针对每个外部工具单独定制接口工具方也只需要实现一次 MCP Server就能被所有支持 MCP 的客户端使用。5.2 在 Spring AI 里接入 MCP Server 的落地路径Spring AI 提供了 MCP Client 相关依赖接入一个现成 Server 通常分三步第一步引入 MCP Client starter确认你的 Spring Boot 版本和 Spring AI 版本兼容。第二步配置要连接的 MCP Server。常见传输方式有两种一种是通过本地进程启动的 stdio 方式一种是走网络请求的 SSE 或 HTTP 方式。本地调试用 stdio 方便部署到服务器上通常用网络方式。第三步启动应用确认模型能“看到” MCP Server 暴露的工具然后通过对话触发调用。配置示例大致长这样但属性名一定要以当前版本为准spring: ai: mcp: client: connections: - name: filesystem type: stdio command: npx args: [-y, modelcontextprotocol/server-filesystem, /tmp]这段配置的意思是启动一个文件系统 MCP Server把 /tmp 目录暴露给 AI 应用。真正接入时注意 Server 要根据实际环境换成可用的命令和参数。5.3 MCP 和 Tools 不是替代关系是两层东西MCP 和 Tools 经常被放在一起讲但它们是两个层级的概念。Tools 是模型看到的“能力单元”MCP 是能力单元从外部“运输”进来的协议。一个本地用 Tool 写的方法和远端通过 MCP 暴露的工具最终都会变成模型可见的 tool 列表。所以正确的理解是Spring AI 负责把各种来源的工具统一成模型能理解的形式MCP 负责解决“远端工具如何接入”的问题。两者是配合关系不是二选一。5.4 哪些工具适合用 MCP 暴露适合用 MCP 暴露的是那些具有通用性的外部能力。比如文件读写、数据库查询、设计稿信息读取、文档内容提取、办公软件操作、科学计算工具等。现在很多设计协作工具、文档工具、数据分析软件都提供了 MCP Server接一个就能让模型读取相关数据。不太适合用 MCP 暴露的是那些内部强耦合的业务逻辑。这种功能直接用本地工具方法更合适没必要多一层网络开销。6. Skills 与 Agent从单次问答到多步任务6.1 Skill 和 MCP 经常被混在一起区别其实很清晰Agent Skill 和 MCP 是 Agent 生态里最容易混淆的两个概念。简单区分Skill 是一套可复用的能力包里面包含提示词、操作步骤、示例和校验规则作用是告诉模型“面对这类任务时应该怎么思考、怎么执行”。它改变的是模型的行为方式。MCP 是一条连接通道作用是让模型能访问外部工具和数据。它改变的是模型的能力边界。打个比方Skill 是工作手册MCP 是插座。模型拿着工作手册知道该怎么做通过插座才能接上外部设备。两者不冲突反而经常一起用。RAG 也顺带说清楚RAG 是给模型提供知识文档解决“不知道”的问题Skill 是给模型提供做事方法解决“不会做”的问题。一个管知识一个管流程。6.2 Agent 不是框架功能是一种任务循环很多人以为引入某个 Agent 框架就自动获得 Agent实际不是。Agent 的本质是一个循环模型根据当前目标判断下一步如果需要外部信息就调用工具拿到结果后更新上下文再继续判断直到完成目标或达到限制。用伪代码表示就是while (step maxSteps) { result model.run(context) if (result.needTool) { toolResult execute(result.toolCall) context.add(toolResult) continue } if (validate(result)) { return result } return handleFailure(result) }Spring AI 里实现这个循环可以从最简单的方式开始手动写一个 while 循环结合 ChatClient 和工具调用返回结果。跑通之后再考虑引入更复杂的编排框架。比如有些基于 Spring AI Alibaba 的 Graph 项目把多步任务做成流程图适合任务链路复杂的场景但那是提升阶段的事不要第一步就上。6.3 结构化输出先定义实体类后面省很多事Agent 跑完最终结果要给业务系统用就不能是自由文本。Spring AI 支持把模型输出映射到 Java 实体类但前提是实体类字段描述要写清楚。以订单结果为例public record OrderResult( JsonPropertyDescription(订单号) String orderId, JsonPropertyDescription(订单金额) BigDecimal amount, JsonPropertyDescription(订单状态枚举CREATED, PAID, SHIPPED, DONE) String status ) {}让模型返回这个对象时它会根据字段描述生成对应 JSON再由框架转换回 Java 对象。字段描述越明确返回越稳定。尤其是枚举值一定要在描述里把可选项写全不能指望模型猜。如果偶尔解析失败优先检查模型版本对 JSON 输出的支持以及实体类字段和 Prompt 要求是否一致。不要一上来就怀疑框架大多时候是描述没写清楚。7. 常见报错与排查顺序7.1 启动失败版本矩阵是第一嫌疑Spring AI 项目启动失败最常见的原因不是代码写错而是依赖版本不兼容。Spring Boot 版本、Spring AI 版本、Spring AI Alibaba 版本、MCP 相关版本它们之间有对应关系混用经常导致 Bean 创建失败或自动配置不生效。排查顺序固定下来先看完整堆栈找到第一个异常再看 pom.xml 或 build.gradle 里的版本约束然后去官方文档确认当前 Spring Boot 对应的 Spring AI 版本。不要在启动失败时反复改业务代码那是浪费时间。7.2 内存不足先分清是 JVM 还是模型服务很多人跑 Spring AI 时遇到 OutOfMemoryError 之类的问题第一反应是给 JVM 加内存。但在本地开发环境里内存压力往往来自三个地方Spring Boot 应用本身的 JVM 堆。Ollama 这类本地模型服务占用的内存或显存。IDE、容器、数据库等外部进程。本地模型 开发环境 集成工具全挤在一台机器上很容易内存紧张。解决办法是先看任务管理器确认谁在吃内存。如果是模型服务换小参数模型或降低并发如果是 JVM再调 -Xmx如果容器内存上限不够就要调容器配置。还有一个容易忽略的点日志文件、模型下载缓存、临时文件会慢慢占满磁盘。磁盘满的时候表现也很像内存不足。7.3 模型输出不对从输入和工具描述查起模型返回的结果不符合预期不要先怀疑模型能力。按这个顺序查先看 Prompt 有没有把约束说清楚尤其是“只能返回 JSON”“不要输出解释文字”这类要求。再看结构化输出实体类字段描述是否准确。接着看工具 description 是否足够明确。最后看上下文里是否残留了之前轮次的错误信息。有时候模型调用了工具但传进来的参数不对。最常见的翻车点是日期格式、城市名、ID 类型。处理办法是在工具方法入口加校验和归一化模型传参不规范时先修正再执行业务逻辑。7.4 一套固定的排查流程把整个项目的问题排查收敛成一张对照表会省很多时间现象优先排查常见原因应用启动失败依赖版本、Bean 定义Spring Boot 与 Spring AI 版本不匹配模型不回复网络、API Key、模型名服务地址不通或配置项名过期模型不调用工具工具注册、description工具没扫描进 ChatClient工具调用后死循环迭代次数限制Agent 循环缺少最大步数返回 JSON 解析失败实体类描述、模型输出字段描述不完整或模型加了额外文本运行一段时间内存上涨JVM 堆、本地模型、日志并发过高或模型服务占资源MCP 工具看不到Server 地址、传输方式stdio 命令不存在或网络 Server 没启动真出问题时先定位现象属于哪一类再按对应行排查。不要一上来就改并发、换模型那样只会引入更多变量。一周走完这条线你的收获应该是能独立搭一个 Spring AI 项目能用多模型配置应对不同环境能把业务能力以 Tool 或 MCP 方式暴露给模型能写一个带限制条件的简易 Agent也能在出问题时按顺序定位是配置、输入还是依赖的问题。下一步再往深走无非是记忆管理、任务编排、可观测性这些生产化话题。把这一周的基本功打牢后面学什么都不慌。
返回列表