news 2026/6/22 5:25:47

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/6/20 6:32:42

MoveWindow在OnSize中的调用时机与优劣对比详解

在开发Windows桌面应用程序时&#xff0c;窗口大小变化是一个必须妥善处理的基本事件。WM_SIZE消息的响应&#xff0c;特别是MoveWindow函数在其间的调用&#xff0c;直接关系到用户界面布局的动态调整和视觉稳定性。对此缺乏深入理解&#xff0c;往往会导致界面错乱或性能问题…

作者头像 李华
网站建设 2026/6/13 20:24:15

gRPC开发者快速入门

gRPC 开发者快速入门 精简版快速入门&#xff0c;只保留核心概念与上手步骤。 目录 一句话了解 gRPC核心概念&#xff08;4 步&#xff09;四种 RPC 类型5 分钟上手&#xff08;以 Python 为例&#xff09;错误处理与超时元数据&#xff08;Metadata&#xff09;同步 vs 异步安…

作者头像 李华
网站建设 2026/6/17 13:51:55

Chandra AI聊天助手行业应用:医疗问答系统实践

Chandra AI聊天助手行业应用&#xff1a;医疗问答系统实践 1. 当医疗咨询遇上本地化AI助手 最近在社区医院做志愿者时&#xff0c;遇到一位阿姨反复询问高血压用药注意事项。她拿着药盒&#xff0c;对照着说明书上的专业术语&#xff0c;眉头越皱越紧。旁边几位老人也围过来&…

作者头像 李华
网站建设 2026/6/17 22:21:39

Pi0机器人控制中心详细步骤:上传三视角图像+输入关节状态+获取6-DOF预测

Pi0机器人控制中心详细步骤&#xff1a;上传三视角图像输入关节状态获取6-DOF预测 1. 什么是Pi0机器人控制中心 Pi0机器人控制中心是一个专为具身智能研究者和机器人开发者设计的交互式操作界面。它不是那种需要写几十行代码才能跑起来的实验项目&#xff0c;而是一个开箱即用…

作者头像 李华
网站建设 2026/6/17 20:14:30

Qwen3-VL:30B多模态能力展示:看图聊天智能助手在飞书的惊艳效果

Qwen3-VL:30B多模态能力展示&#xff1a;看图聊天智能助手在飞书的惊艳效果 最近在飞书里用上了Qwen3-VL:30B&#xff0c;感觉像是给团队配了个“全能助理”。以前开会讨论设计稿&#xff0c;得把图片发到群里&#xff0c;然后大家七嘴八舌地讨论&#xff0c;现在直接把图扔给…

作者头像 李华
网站建设 2026/6/17 23:05:42

translategemma-4b-it环境部署:零基础搭建本地化多模态翻译服务

translategemma-4b-it环境部署&#xff1a;零基础搭建本地化多模态翻译服务 1. 为什么你需要一个本地多模态翻译工具 你有没有遇到过这样的场景&#xff1a; 看到一张英文说明书图片&#xff0c;想立刻知道上面写了什么&#xff0c;但拍照翻译App总把表格识别错、漏掉关键参…

作者头像 李华