
最近后台收到不少同学问“SpringAI 项目到底怎么上手”“系统提示词怎么配”“能不能直接接 DeepSeek”今天就把我这段时间折腾 SpringAI 的入门经验整理出来。这篇内容不是照着官方文档念一遍而是把新手最容易卡住的点、最该提前知道的知识串起来从环境搭建到第一个对话接口再到提示词配置、智能审核这类实战场景一次性把 SpringAI 大模型应用开发的基础脉络理清楚。适合刚接触 SpringAI 的 Java 后端、想在企业项目里快速接入大模型能力的开发同学。哪怕你没写过 AI 应用也没关系只要会 Spring Boot 的基础用法照着下面的步骤走基本当天就能跑通一个能对话、能调用工具的小项目。1. SpringAI 到底是个啥先解决“为什么”的问题1.1 一图流理解 SpringAI 的定位很多新手第一次听到 SpringAI下意识会以为它是一个大模型其实不是。SpringAI 是 Spring 官方推出的 AI 应用开发框架定位很明确把大模型接入 Spring Boot 项目的“最后一公里”问题解决了。打个比方大模型本身像一台发电机能产生电力但你需要把电接到家里、装上开关、接入各种电器才能用。SpringAI 就是那套电路系统让你不用自己造发电机也不用自己拉电线只需要插上插头就能用电。你不需要管 OpenAI、DeepSeek、通义千问这些模型的 HTTP 接口差异SpringAI 帮你把底层调用封装成了统一的 ChatClient、ChatModel 这些接口。业务代码里只需要面向 Spring 的抽象编程换模型服务商的时候改一行配置就行。1.2 SpringAI 与其他 AI 框架的对比市面上的 AI 开发框架不少新手容易挑花眼。我用实际体验给大家捋一捋主流方案的差别。方案使用门槛和 Spring 生态的关系典型场景SpringAI低熟悉 Spring Boot 即可上手原生融合Bean 管理、配置体系一致Java 应用内嵌 AI 能力LangChain4j中需要理解自己的抽象概念支持 Spring Boot 集成但相对独立Java 项目里的 AI Agent 开发LangChain中高Python 生态与 Java 技术栈关系弱需要通过 HTTP 调用Python 数据分析、AI 应用原型直接调云厂商 SDK低但重复工作量大与 Spring 无关需要自己封装简单的接口透传这里强调一点如果你是纯 Java 后端团队没有专门做 AI 算法的人SpringAI 是最省心的选择。它的依赖注入、自动配置、配置项管理和 Spring Boot 完全是同一套思路学习成本基本集中在大模型概念本身而不是框架用法上。1.3 为什么要用 SpringAI核心优势解读我对比完发现SpringAI 的核心价值在于三件事。第一统一抽象。不管今天是接 OpenAI 兼容接口还是接国产大模型代码层面都是 ChatModel。业务里写一次后面换模型只是改 yml 里的 model 名称和 base-url。第二和 Spring 生态无缝衔接。你用 SpringAI 写的工具函数可以像普通 Bean 一样管理配上 Description 注解就能被模型自动识别调用。做 Web 项目时Controller、Service、持久层那套开发习惯完全不用变。第三内置了提示词模板、输出解析、向量数据库集成、工具调用这些 AI 应用的高频能力。这些能力如果自己从头写至少要额外写大几百行代码还要处理各种异常边界。2. 环境准备与项目初始化把地基打牢2.1 工具链选型JDK、Maven、IDE 怎么配SpringAI 对 Java 版本有要求我用的是 JDK 17这是目前 Spring Boot 3.x 的基准版本建议直接用它别用 JDK 8 然后到处踩依赖冲突的坑。Maven 用 3.6.3 以上IDE 这块我用 IDEA社区版就够。另外要注意SpringAI 目前版本更新速度比较快1.0 之前的版本 API 变化很大。如果你现在新建项目直接上手 1.0.x 或者查看官方文档推荐的稳定版本。2.2 创建一个带 SpringAI 依赖的最小工程最简单的方式是在 Spring Initializr 上生成项目骨架Group、Artifact 按自己的习惯填依赖先只勾选一个 Spring Web然后手动在 pom.xml 里加 SpringAI 依赖。我平时习惯用 Maven核心依赖有两种加法取决于你要接什么模型。以接 DeepSeek 这类 OpenAI 兼容模型为例dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId version1.0.0/version /dependency如果你接的是通义、智谱、Kimi 等国内厂商SpringAI 同样提供了对应的 starter。先看到这里记住一件最要紧的事版本必须和你的 Spring Boot 版本匹配否则启动时会出现各种各样的 NoSuchMethodError、ClassNotFound。2.3 配置文件的写法api-key 和模型名放哪在 application.yml 里最核心的配置是 api-key、base-url 和模型名称。以 DeepSeek 为例spring: application: name: springai-demo ai: openai: api-key: ${DEEPSEEK_API_KEY} base-url: https://api.deepseek.com chat: options: model: deepseek-chat这一段看起来简单但有新手容易踩一个大坑SpringAI 里关于模型供应商的配置前缀并不统一。接 OpenAI 官方的 key 时前缀是 spring.ai.openai接 DeepSeek 时因为兼容 OpenAI 协议很多人直接套用 openai 前缀但其实客户端会自动把 base-url 拼到请求路径上如果 base-url 末尾多了一个斜杠或者漏了带 v1 的路径就会一直报 404。我的建议是环境变量只存敏感信息比如 api-key 用 ${DEEPSEEK_API_KEY} 引用模型名、base-url 这些可以写在 yml 里方便调试。另外不要把 key 硬编码到代码里这既是安全习惯也方便不同环境切换。2.4 验证环境是否联通先写一个失败得快速的测试配置完成后不要急着写业务先做一个连通性验证。我的习惯是写一个 ApplicationRunner在启动时自动发一条最简单的话给模型Component public class StartupProbe implements ApplicationRunner { private final ChatModel chatModel; public StartupProbe(ChatModel chatModel) { this.chatModel chatModel; } Override public void run(ApplicationArguments args) { String response chatModel.call(你好); System.out.println(AI 回复: response); } }如果启动后控制台打印出正常的 AI 回复说明网络、key、模型名都没问题。这一步能把环境问题和业务代码问题隔离开排错范围缩小很多。3. 第一个对话 Demo把最基础的链路跑通3.1 ChatClient你实际打交道最多的对象在 SpringAI 里ChatModel 是底层能力的入口但日常开发我更推荐直接用 ChatClient。它提供了更流畅的链式调用 API代码可读性高也更容易维护。配置一个 ChatClient Bean在配置类里写Configuration public class ChatConfig { Bean public ChatClient chatClient(ChatModel chatModel) { return ChatClient.builder(chatModel).build(); } }如果你需要支持不同的模型比如一个走 DeepSeek 做对话一个走多模态模型做图片识别那就生成两个 ChatClient Bean搭配 Qualifier 使用。新手阶段先别搞那么复杂一个 ChatClient 足够。3.2 写一个最简单的对话接口有了 Bean接下来就是创建一个 Controller用来暴露 HTTP 接口RestController RequestMapping(/ai) public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient chatClient) { this.chatClient chatClient; } GetMapping(/chat) public String chat(RequestParam String message) { return chatClient.prompt() .user(message) .call() .content(); } }启动项目后浏览器访问 http://localhost:8080/ai/chat?message你好就能看到模型返回的文本。这一条链路虽然不长但里面有几个概念你无论如何都要搞明白Prompt、Message、ChatResponse。这三个对象是你后面写复杂逻辑的地基。3.3 从同步接口到流式输出别忽略体验细节同样的接口如果改成流式输出响应体验会好很多尤其当模型吐字比较长的时候。加上 spring-boot-starter-webflux 之后接口可以返回 FluxGetMapping(value /chat/stream, produces text/event-stream) public FluxString chatStream(RequestParam String message) { return chatClient.prompt() .user(message) .stream() .content(); }前端用 EventSource 或者 fetch 流式读取就能实现打字机效果。注意Spring MVC 默认是阻塞模型如果你的项目里本来没有 WebFlux建议单开一个 Controller 或者单独配置返回值类型别改全局配置否则可能影响现有接口。4. 核心概念拆解Prompt、Message、ChatResponse4.1 Prompt 不是简单字符串而是一组指令的集合很多新手把 prompt 当成“用户输入的文本”写代码时直接一个 String 传进去。这够用但理解不全面。SpringAI 里Prompt 是一个封装对象它可以包含多个 Message还可以附带模型生成参数比如 temperature、maxTokens、topP 这些。这意味着你每次调模型不只是在“问问题”而是在构造一次完整的模型调用上下文。把 prompt 当作一个上下文包来理解后续做复杂业务会轻松很多你要注意用户说了什么也要注意系统设定了什么规则还要注意这次调用允许多少创意度。4.2 理解 Message 的角色System、User、AssistantMessage 在 SpringAI 里主要有三种类型对应大模型 API 中常见的消息角色。系统消息SystemMessage是最容易被新手忽略的。它负责定义模型的角色和回复规矩比如“你是一个专业的电商审核员”“回答必须使用中文”“不要输出多余解释”。这一步对应的是大家经常搜的“SpringAI 系统提示词怎么配置”本质上就是把一段固定的规则文本放到 SystemMessage 里每次调用之前自动带上。用户消息UserMessage就是你要让模型处理的具体内容可以是一段文本也可以是图片等多模态内容。助手消息AssistantMessage一般用于多轮对话时把之前的回复作为上下文传给模型构造对话记忆时会用到。用 ChatClient 配置系统提示词非常直观String response chatClient.prompt() .system(你是一个严谨的电商评论审核员只输出 PASS 或 REJECT不要多余解释。) .user(商品质量很好但快递太慢了) .call() .content();4.3 ChatResponse 里到底有什么ChatResponse 是模型调用结果的封装。新手经常只调 .content() 拿文本忽略了它内部的丰富信息。通过 ChatResponse 可以拿到生成结果、Token 用量、结束原因等元数据。这在做成本统计、日志审计时非常重要。一个实际用的多的场景是统计消耗尤其是在接付费模型的时候不同模型的 token 单价不一样把每次调用的 token 数记录到数据库月底对账就有依据了。ChatResponse response chatClient.prompt() .user(讲个冷笑话) .call(); String content response.getResult().getOutput().getContent(); Generation generation response.getResult();4.4 参数调优temperature 是最直观的旋钮模型调用参数里新手最先需要认识的就是 temperature。它控制输出的随机性值越低输出越确定、越保守值越高输出越发散、有创造性。我自己的经验是做审核、分类、结构化抽取这类任务temperature 设置成 0 或者 0.1 比较稳做文案创作、头脑风暴可以调到 0.7 以上。SpringAI 中通过 options 设置String response chatClient.prompt() .user(写一句夏季饮品宣传语) .options(ChatOptions.builder() .temperature(0.8) .maxTokens(200) .build()) .call() .content();这里有一个新手容易掉进去的误区以为 temperature 越高模型回答质量越高。其实不是temperature 只影响随机性不影响模型的知识水平和逻辑上限。输出质量的关键还是提示词写得好不好、模型选得对不对。5. 实战一用 SpringAI 做智能审核/内容分析5.1 场景设定从评论区审核开始网络热词里“springai 智能审核”出现频率不低这正好是 SpringAI 非常适合的落地场景。我这里用一个评论审核的例子来演示毕竟内容审核是很多业务系统的刚需。需求背景一个社区产品每天有大量用户评论需要判断评论是正常、广告、辱骂还是其他违规内容。传统方式维护敏感词表太死板语义绕过容易被漏掉用大模型做语义理解会灵活很多。5.2 用提示词模板来管理审核规则直接通过 .system() 写死规则也能用但规则多了之后代码会变得很难维护。更好的方案是使用 SpringAI 的提示词模板机制把规则外部化。在 resources 下建一个 prompts 目录放一个审核模板你是一个内容安全审核员。 审核规则 1. 判断内容属于 normal、advertisement、abuse、other_violation 中的一类 2. 只输出分类名称不要额外解释 用户评论 {userComment}代码里读取模板并填充变量public String audit(String comment) { String prompt 你是一个内容安全审核员。 审核规则 1. 判断内容属于 normal、advertisement、abuse、other_violation 中的一类 2. 只输出分类名称不要额外解释 用户评论 %s .formatted(comment); return chatClient.prompt() .system(请严格遵守上面的审核规则) .user(prompt) .call() .content(); }这样看起来已经能用但生产环境绝对不能直接把模型输出当字符串去匹配因为模型偶尔会多输出一个标点、换行或者把“normal”写成“Normal”后面接一个 JSON 解析会稳定很多。5.3 结构化输出让模型返回 JSON 而不是大白话只要涉及后续的逻辑处理结构化的输出几乎必配。把这个需求改成返回 JSONpublic AuditResult audit(String comment) { String prompt 你是一个内容安全审核员。 请对以下用户评论进行分类和简要说明以 JSON 格式返回字段如下 { category: normal 或 advertisement 或 abuse 或 other_violation, reason: 判断理由 } 用户评论 %s .formatted(comment); return chatClient.prompt() .user(prompt) .call() .entity(AuditResult.class); }对应的实体public record AuditResult(String category, String reason) { }用 .entity() 是 SpringAI 提供的高效方式框架会帮你把模型返回的 JSON 映射到 Java 对象。这一步很关键因为它让 AI 能力真正融入了 Java 的业务代码后续存库、告警、统计都能直接用对象字段。我做这类审核接口时还有两个小经验。一是别把审核结果直接当终审结论更稳的做法是高风险内容再走一轮人工抽检二是大模型审核接口要设计超时和降级模型服务抖动不能影响主链路可以设置调用失败后走敏感词兜底。6. 实战二进阶知识——工具调用与 RAG 入门6.1 工具调用让模型能查数据库、调接口大模型的训练数据是固定的所以它天生不知道你系统里的订单状态、库存数量。工具调用Function Calling是解决这个问题的主流方案模型在需要额外信息时会生成一个结构化的函数调用请求你的代码执行后再把结果回传给模型。SpringAI 的 Description 注解在这里非常关键。模型靠它理解这个工具是干什么的、参数是什么含义。写一个查询订单的示例Component public class OrderQueryTools { Description(根据订单号查询订单状态) public OrderStatus queryOrder(String orderId) { // 实际这里会注入 OrderService 查数据库 return new OrderStatus(orderId, SHIPPED); } }然后在 ChatClient 上挂载这个工具String response chatClient.prompt() .user(订单 20251212 现在什么状态) .tools(new OrderQueryTools()) .call() .content();这里需要特别提醒新手工具调用不是模型直接执行方法而是模型“决定要不要调用、传入什么参数”真正的方法执行还是发生在你的应用里。所以工具方法里务必做好参数校验不能盲目相信模型生成的参数。6.2 RAG给模型外挂一本“内部知识库”RAG检索增强生成是当前落地大模型最实用的技术之一。它的核心思路是先把知识文档拆分成片段做向量化存入向量数据库用户提问时先从库里检索最相关的片段再把这些片段和问题一起丢给模型生成答案。这样模型就能基于你的私有知识库回答问题而且不需要微调模型本身。SpringAI 提供了非常友好的向量数据库抽象以 PostgreSQL 的 pgvector 为例加入依赖dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-pgvector/artifactId /dependency然后把文档加载、拆分成 Embedding存入 VectorStore查询时再走向量检索。完整的代码展开会很长但需要记住的关键链路只有三条文档加载、向量化入库、语义检索。如果你刚入门建议先用官方示例把 RAG 跑通再考虑结合自己的业务文档。这个领域踩坑点通常不在 SpringAI 本身而在数据质量管理你自己造的文档如果都是重复信息检索效果就非常差。7. 常见问题与避坑实录7.1 启动失败依赖冲突和配置前缀这里把容易遇到的问题整理成一个速查表方便大家对照排查。现象原因解决办法启动报 NoClassDefFoundErrorSpringAI 版本与 Spring Boot 版本不匹配查看官方文档的版本兼容矩阵接口调用报 401api-key 没配置或配置错检查环境变量 DI和 yml 引用是否一致接口调用报 404base-url 路径不对末尾缺少 v1 或多了斜杠去掉末尾斜杠确认供应商的 API 路径返回内容出现中文乱码响应编码问题检查应用编码和接口 produces 设置7.2 提示词反复试都不生效问题可能不在提示词有段时间我调一个分类功能系统提示词怎么强调都没用模型总是输出多余内容。后来排查下来是参数问题temperature 设置成了 0.9导致即使规则明确输出也偏发散。把 temperature 调低后效果立刻就稳定了。所以出现这种问题时先按顺序排查三件事模型参数有没有调高、系统提示词有没有真的传进去、模型本身是不是能力不够。很多时候不是提示词不行而是模型服务的版本默认参数和你预期不一致。7.3 成本控制一次调用烧了多少 token大模型应用上线后最容易被忽视的是 token 成本。我自己写过一个小工具在 Service 层包装了一次 ChatModel 调用打印出每次调用的 prompt tokens 和 completion tokens并记录到日志。public ChatResponse chatWithLog(String message) { ChatResponse response chatClient.prompt() .user(message) .call(); // 在实际项目里在这里记录 token 用量并存储起来 return response; }这个习惯能帮你尽早建立成本意识。我见过不少团队上线 AI 功能后才问“这个月怎么烧了几万”基本都是因为没提前做 token 管控。建议从开发第一天就把 token 统计埋进去。7.4 模型回复不稳定加一层后处理校验大模型再强也难免偶尔“嘴瓢”。如果你的业务对准确性要求高建议在模型输出后增加一层代码校验。比如审核场景模型返回 JSON 后先校验 category 字段是否是合法枚举值不合法就直接走默认策略而不是让脏数据往下游流动。这一层校验看起来简单但真的能挡住不少线上问题。7.5 调试工具建议聊聊 SpringAI 的调试方式排查问题的时候建议打开 SpringAI 的请求日志。调试阶段可以把日志级别调低logging: level: org.springframework.ai: DEBUG这样能在控制台里看到发给模型的请求体、返回体比在代码里到处打断点高效很多。等排查完再调回 INFO否则生产环境的日志量会把你淹没。8. SpringAI 后续还可以扩展的方向这里再聊一些我个人的体会。SpringAI 只是 AI 应用开发的起点不是终点。入门之后比较值得投入的方向有三个一个是针对业务场景的提示词工程优化把规则沉淀成可复用的模板另一个是工具调用与现有业务系统的深度整合让模型真正能完成业务动作而不是只停留在对话再一个是评估体系的建设因为大模型应用的难点从“能不能跑通”变成“效果稳不稳定”之后你要有办法量化输出质量。在团队已经有了基础能力之后越早建立模板管理和评估机制后面做复杂应用越省力气。很多项目的失败不是模型选错而是没有一套可持续优化的流程。我自己的做法是每次业务方反馈效果不佳都会把输入、输出、当时用的模型参数一起存下来形成一份真实的回归测试集。这样一来调整提示词或者切换模型时拿这套集子一跑效果有没有变好一目了然。这比凭感觉迭代要靠谱得多。最后再分享一个小经验学习 SpringAI 时不要一开始就追新版本特性。把 ChatClient、Prompt、Message、工具调用这几个核心概念弄扎实后面看任何复杂的 AI 应用架构都能快速理解。毕竟框架会迭代但大模型应用的核心链路万变不离其宗。