news 2026/3/4 13:39:46

Spring AI 入门到上手:用 Java 把大模型接进业务(DeepSeek / Ollama / RAG / Function Calling 一篇搞懂)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI 入门到上手:用 Java 把大模型接进业务(DeepSeek / Ollama / RAG / Function Calling 一篇搞懂)

Spring AI 入门到上手:用 Java 把大模型接进业务(DeepSeek / Ollama / RAG / Function Calling 一篇搞懂)

适用人群:做 Java / SpringBoot 的同学,想把大模型接到系统里:智能客服、知识库问答、内容生成、自动审核/助手等。
技术栈:Spring Boot 3.x + JDK 17 + Spring AI(OpenAI 协议)+ Redis/Milvus(可选)+ ES(可选)


1. Spring AI 到底解决什么问题?

很多人第一次接大模型,会直接HttpClient/RestTemplate去调某个平台的 API。短期能跑,但很快会遇到几个问题:

  1. 供应商绑定严重:今天用 DeepSeek,明天要切通义/Claude/Ollama,代码改一大片。
  2. Prompt、上下文、流式输出、工具调用都得自己拼装,容易越写越乱。
  3. RAG(知识库问答)这条链路(读取→切分→向量化→入库→检索→拼 Prompt→回答)自己搭很耗时。
  4. 工程化能力缺失:监控、重试、日志、超时、降级、统一配置,不好统一治理。

Spring AI 的价值就是:把“调用大模型”这件事抽象成 Spring 风格的组件。你写业务时关心的是:

  • 我是聊天(Chat)还是 Embedding?
  • 要不要流式?
  • 要不要函数调用(Tools)?
  • 要不要接向量库做 RAG?

而不是天天和不同供应商的请求结构搏斗。


2. 快速跑通:用 DeepSeek(OpenAI 协议)做一次对话

2.1 版本建议(很重要)

  • Spring Boot:3.x
  • JDK:17
  • Spring AI:建议选同一条版本线(用 BOM 管)

Spring AI 版本迭代快,建议把版本锁在 BOM 上,避免依赖互相“打架”。

2.2 Maven 依赖(OpenAI 协议 Starter)

<properties><java.version>17</java.version><spring-ai.version>1.0.0-M5</spring-ai.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency></dependencies>

2.3 application.yml 配置(以 DeepSeek 为例)

server:port:8899spring:application:name:spring-ai-deepseek-demoai:openai:api-key:sk-xxxxxbase-url:https://api.deepseek.comchat:options:model:deepseek-chattemperature:0.7

关键点:DeepSeek 提供 OpenAI 风格接口,所以用spring-ai-openai-*就能接。

2.4 最小 Controller

importjakarta.annotation.Resource;importorg.springframework.ai.openai.OpenAiChatModel;importorg.springframework.web.bind.annotation.*;@RestControllerpublicclassChatController{@ResourceprivateOpenAiChatModelchatModel;@GetMapping("/ai/generate")publicStringgenerate(@RequestParam(defaultValue="hello")Stringmessage){returnchatModel.call(message);}}

访问:
GET http://localhost:8899/ai/generate?message=用一句话解释Spring%20AI


3. ChatClient vs ChatModel:项目里我更推荐用 ChatClient

3.1 为什么?

  • ChatModel更偏底层(Prompt、Options 你都得自己组织)
  • ChatClient更像“业务层 API”,链式写法清晰,更适合 Controller/Service

3.2 ChatClient 最常用的 3 种能力

A) 普通对话(最常用)
importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.web.bind.annotation.*;@RestControllerpublicclassChatClientController{privatefinalChatClientchatClient;publicChatClientController(ChatClient.Builderbuilder){this.chatClient=builder.build();}@GetMapping("/chat")publicStringchat(@RequestParam(defaultValue="你是谁")Stringmessage){returnchatClient.prompt().user(message).call().content();}}
B) 角色设定(System Prompt)

把“人设”固定住,避免每次都写一大段提示词:

importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassAiConfig{@BeanpublicChatClientchatClient(ChatClient.Builderbuilder){returnbuilder.defaultSystem("你是一个资深Java开发助手,回答要简洁、可落地,必要时给代码。").build();}}
C) 流式输出(体验会好很多)

适用于:前端打字机效果、长回答、模型推理慢的场景。

importreactor.core.publisher.Flux;importorg.springframework.web.bind.annotation.*;@RestController@RequestMapping("/ai")publicclassStreamController{privatefinalChatClientchatClient;publicStreamController(ChatClientchatClient){this.chatClient=chatClient;}@GetMapping(value="/stream",produces="text/plain; charset=UTF-8")publicFlux<String>stream(@RequestParamStringmessage){returnchatClient.prompt().user(message).stream().content();}}

注意:很多 API 测试工具不容易观察流式效果,浏览器/前端更直观。


4. Function Calling(工具/函数调用):让模型“会办事”,不是只会聊天

大模型擅长“生成”,但它不知道你的业务数据。
Function Calling 的作用:模型发现需要数据 → 调用你提供的函数 → 你返回真实结果 → 模型基于真实数据再组织回答

典型场景:

  • 查用户余额、查订单、查基金净值、查审批状态
  • 触发“创建工单 / 发通知 / 写入数据库”(是否允许要自己控制)

4.1 定义一个函数(Spring Bean + Function)

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Description;importjava.util.function.Function;@ConfigurationpublicclassToolsConfig{publicrecordAddReq(inta,intb){}publicrecordAddResp(intresult){}@Bean@Description("计算两个整数的加法")publicFunction<AddReq,AddResp>add(){returnreq->newAddResp(req.a()+req.b());}}

4.2 在 ChatClient 里启用函数

importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.web.bind.annotation.*;@RestControllerpublicclassToolController{privatefinalChatClientchatClient;publicToolController(ChatClient.Builderbuilder){this.chatClient=builder.build();}@GetMapping("/tool")publicStringtool(@RequestParamStringmessage){returnchatClient.prompt().system("你是计算助手,遇到加法问题必须调用 add 函数。").user(message).functions("add").call().content();}}

你问:2+3 等于多少
模型会决定调用add,再把结果组织成自然语言输出。

实战建议:

  • 工具调用要白名单控制,不要让模型随便调用敏感操作。
  • 工具返回结果要结构化(record/POJO),便于模型理解。

5. 接入 Ollama:本地跑模型(离线/内网/数据敏感场景)

如果你需要:

  • 研发内网、不能出网
  • 数据敏感,不想把内容发到公网
  • 成本控制,想本地推理

Ollama 就很合适。

5.1 依赖

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId></dependency>

5.2 配置

spring:ai:ollama:base-url:http://localhost:11434chat:options:model:deepseek-r1:1.5btemperature:0.7

5.3 使用方式和 ChatClient 一样

你换了底层模型供应商,但业务代码几乎不动,这就是 Spring AI 的工程价值。


6. RAG(知识库问答):让回答“有依据”,减少胡编

很多业务不是“开放聊天”,而是:

  • 产品手册问答
  • 内部制度问答
  • 工单历史/FAQ 问答
  • 研发文档/接口文档问答

这类场景最怕“编造”。RAG 的思路是:先检索到真实资料,再让模型基于资料回答

6.1 最小 RAG 组成

  • Embedding 模型:把文本转向量
  • VectorStore:存向量并支持相似度检索
  • Advisor:把检索结果自动拼进 Prompt

6.2 代码示例(思路版)

importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;importorg.springframework.ai.vectorstore.VectorStore;importorg.springframework.web.bind.annotation.*;@RestController@RequestMapping("/rag")publicclassRagController{privatefinalChatClientchatClient;privatefinalVectorStorevectorStore;publicRagController(ChatClientchatClient,VectorStorevectorStore){this.chatClient=chatClient;this.vectorStore=vectorStore;}@GetMapping(value="/chat",produces="text/plain; charset=UTF-8")publicStringchat(@RequestParamStringq){returnchatClient.prompt().user(q).advisors(newQuestionAnswerAdvisor(vectorStore)).call().content();}}

生产实践要点:

  • 文档入库前要做“切分”(chunk),并保存 metadata(来源、标题、更新时间)
  • 检索要加阈值,避免捞到不相关内容
  • System Prompt 要明确:“资料没有就说不知道,不要编”

7. 常见坑与实战建议(非常关键)

  1. 超时要配:模型响应时间不稳定,网关/客户端都要适当放宽,避免接口总 504。
  2. 流式返回要注意:前端最好用 SSE/Fetch Stream,别用传统一次性 JSON。
  3. Prompt 不要堆太长:长不是问题,乱才是问题。把角色、约束、输出格式写清楚,比堆背景更重要。
  4. 函数调用要控权限:模型“能调用什么”必须严格控制。
  5. 日志与审计:至少把请求参数、模型响应、工具调用记录下来(脱敏)。
  6. 成本与限流:生产必须做配额、限流、缓存(同问同答可以缓存)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 4:37:29

中专读大数据技术,考什么证才不被HR秒拒?2026最全避坑清单

中专学历大数据技术方向考证指南 中专学历在求职大数据技术相关岗位时&#xff0c;证书是弥补学历短板的重要方式。以下是2026年最全避坑清单&#xff0c;涵盖高含金量证书及备考建议&#xff0c;避免因证书选择不当被HR秒拒。 高含金量证书推荐 证书名称颁发机构适合岗位优势…

作者头像 李华
网站建设 2026/3/4 2:17:50

Qwen3-VL-2B周边工具推荐:提升开发效率的3大辅助组件

Qwen3-VL-2B周边工具推荐&#xff1a;提升开发效率的3大辅助组件 如果你已经体验过Qwen3-VL-2B-Instruct这个视觉理解机器人&#xff0c;可能会发现它确实很强大——能看懂图片、识别文字、回答图文问题。但作为开发者&#xff0c;我们总希望效率能更高一点&#xff0c;工作流…

作者头像 李华
网站建设 2026/3/4 3:13:10

造相Z-Image文生图模型v2:Typora文档自动化生成方案

造相Z-Image文生图模型v2&#xff1a;Typora文档自动化生成方案 1. 为什么需要文档插图自动化 写技术文档时&#xff0c;最让人头疼的往往不是文字内容&#xff0c;而是配图。你可能经历过这样的场景&#xff1a;花半小时写完一段清晰的技术说明&#xff0c;却卡在配图环节—…

作者头像 李华
网站建设 2026/3/4 2:28:18

Qwen3-ASR-1.7B部署教程:HTTP入口访问+实例IP直连WebUI完整步骤

Qwen3-ASR-1.7B部署教程&#xff1a;HTTP入口访问实例IP直连WebUI完整步骤 1. 快速了解Qwen3-ASR-1.7B Qwen3-ASR-1.7B是阿里通义千问推出的端到端语音识别模型&#xff0c;拥有17亿参数&#xff0c;支持中、英、日、韩、粤等多语种及自动语言检测功能。这个模型基于qwen-asr…

作者头像 李华
网站建设 2026/3/4 5:09:11

AI智能文档扫描仪详细步骤:如何获得最佳扫描对比度

AI智能文档扫描仪详细步骤&#xff1a;如何获得最佳扫描对比度 1. 为什么对比度是扫描质量的关键 你有没有遇到过这样的情况&#xff1a;拍完一张合同照片&#xff0c;上传到扫描工具里&#xff0c;结果边缘识别失败&#xff0c;系统根本找不到文档轮廓&#xff1f;或者好不容…

作者头像 李华