Spring AI 2.0
文章目录Spring AI 2.0简介阿里云百炼大模型平台接入新建 HelloWorld 项目Ollama简介以及安装和使用Spring AI项目调用本地Ollama模型进阶玩法5个让DeepSeek更好用的技巧1. 绑定到局域网2. 搭配 Continue 插件写代码3. 用 AnythingLLM 做知识库问答4. 模型量化节省显存5. 换个好看的界面stream()方法Flux流式响应输出Advisors —— 拦截器模式增强AI能力对话与提示词工程Prompt一、核心概念总览二、核心知识点详解1. 消息类型Message Type2. 提示词工程基础原则3. 提示词模板PromptTemplate4. ChatClient 流畅 API三具体应用实例1PromptTemplate提示词模版2使用 ChatClient 的流式 API 可以最快速地组装提示词3系统提示词工程 —— defaultSystem结构化输出一、结构化输出核心概念1.1 为什么需要结构化输出1.2 Spring AI 2.0 结构化输出核心特性二、核心实现方式2.1 两种主要方案2.2 原生结构化输出2.3 实例 1基础 POJO 结构化输出2.4 实例 2集合类型结构化输出三底层实现原理会话记忆(Chat Memory)工具调用(Function Calling / Tools)一、什么是工具调用二、核心工作原理三、快速入门实例让 AI 学会“看时间”四、进阶实践让 AI 执行操作五工具调用底层实现原理嵌入模型(Embedding Model)与向量数据库(Vector Databases)RAG(检索增强生成)MCP(模型上下文协议)多模态支持Spring AI 1.0Spring AI 2.0简介Spring AI 2.0 开发Java Agent智能体 - Spring AI 2.0简介Spring AI 的核心设计思想是什么它解决了 Java 开发者接入大模型时的哪些痛点阿里云百炼大模型平台接入Spring AI 2.0 开发Java Agent智能体 - 阿里云百炼大模型平台接入新建 HelloWorld 项目Spring AI 2.0 开发Java Agent智能体 - 新建 HelloWorld 项目Ollama简介以及安装和使用Spring AI 2.0 开发Java Agent智能体 - Ollama简介以及安装和使用Spring AI项目调用本地Ollama模型Spring AI 2.0 开发Java Agent智能体 - Spring AI项目调用本地Ollama模型Ollama 安装部署进阶玩法5个让DeepSeek更好用的技巧1. 绑定到局域网把Ollama的 OLLAMA_HOST 环境变量设为 0.0.0.0局域网内其他设备都能调用。我家里台式机跑模型笔记本和手机都能用。2. 搭配 Continue 插件写代码VS Code / JetBrains 安装 Continue 插件配置指向本地Ollama。写代码时选中一段CtrlL 直接让DeepSeek帮你解释或重构。详细的Continue DeepSeek配置教程我之前写了一篇完整指南DeepSeek本地部署全攻略3. 用 AnythingLLM 做知识库问答把PDF文档、技术手册丢进 AnythingLLM底层用DeepSeek做推理相当于给DeepSeek装了个外挂知识库。Windows安装ollama和AnythingLLM及部署DeepSeek模型14. 模型量化节省显存用ollama create Modelfile自定义量化参数能让7B模型在6GB显存上跑起来。DeepSeek-R1-Distill-Llama-8B实操手册Ollama自定义Modelfile构建与量化部署技巧5. 换个好看的界面终端对话太硬核了。推荐装 Open WebUI界面和ChatGPT一样好用dockerrun-d-p3000:8080\-vopen-webui:/app/backend/data\--nameopen-webui--restartalways\ghcr.io/open-webui/open-webui:main然后打开浏览器访问 http://localhost:3000一个完整的类ChatGPT界面就有了——对话历史、Markdown渲染、代码高亮全都有。stream()方法Flux流式响应输出Spring AI 2.0 开发Java Agent智能体 - stream()方法Flux流式响应输出非流式输出 call等待大模型把回答结果全部生成后输出给用户流式输出stream逐个字符输出一方面符合大模型生成方式的本质另一方面当模型推理效率不是很高时流式输出比起全部生成后再输出大大提高用户体验。GetMapping(value/chat/stream,producestext/html;charsetUTF-8)publicFluxStringchatStream(RequestParam(valuemsg)Stringmessage){returnchatClient.prompt().user(message).stream().content();}Advisors —— 拦截器模式增强AI能力Spring AI 2.0 开发Java Agent智能体 - Advisors —— 拦截器模式增强AI能力对话与提示词工程Prompt一、核心概念总览Spring AI 2.0 提供了统一、易用的对话与提示词工程 API核心组件包括组件作用关键特性Message封装对话内容支持SYSTEM、USER、ASSISTANT、TOOL四种类型SpringPrompt模型输入容器包含消息列表和模型配置选项PromptTemplate提示词模板引擎支持变量替换、外部文件加载、自定义分隔符SpringChatClient对话 API 入口流畅链式调用简化提示词构建与响应处理SpringChatModel底层模型接口统一抽象不同大模型OpenAI、Anthropic、Ollama等Spring二、核心知识点详解1. 消息类型Message TypeSpring AI 定义了四种标准消息类型用于构建结构化对话SYSTEM设定 AI 角色、行为准则和能力边界如 “你是一位 Java 开发专家只回答编程相关问题”USER用户输入的问题或指令ASSISTANTAI 的历史回复用于多轮对话上下文TOOL工具调用的结果如函数执行返回值2. 提示词工程基础原则有效提示词应包含三要素角色设定明确 AI 身份和能力范围上下文信息提供必要背景知识清晰指令明确任务目标和输出格式提示词优化技巧使用分隔符如 、—区分不同内容块设定输出格式如 JSON、Markdown控制模型参数temperature0~1越低越确定maxTokens最大输出长度3. 提示词模板PromptTemplate解决硬编码提示词的复用性和维护性问题支持变量替换使用 {} 占位符外部文件加载从 resources 读取模板自定义渲染器如修改分隔符为 系统提示词模板SystemPromptTemplate专门用于角色设定4. ChatClient 流畅 APISpring AI 2.0 推荐使用 ChatClient 进行对话开发特点链式调用代码简洁内置提示词构建器支持流式响应Flux统一处理不同模型的响应格式Spring三具体应用实例1PromptTemplate提示词模版我们如果不用提示词模版很多时候写代码是这样的// 不用模板手写相同的逻辑重复且难以维护GetMapping(/chat/java)publicStringjava(){returnchatClient.prompt().user(介绍下Java).call().content();}GetMapping(/chat/python)publicStringpython(){returnchatClient.prompt().user(介绍下Python).call().content();}我们现在用提示词模版简化系统设计/** * 使用模板一套代码应对所有场景 * param topic * return */RequestMapping(value/ask,producestext/html;charsetutf-8)publicFluxStringask(Stringtopic){PromptTemplatetemplatenewPromptTemplate(介绍下{topic});Promptprompttemplate.create(Map.of(topic,topic));returnchatClient.prompt(prompt).stream().content();}测试浏览器输入 http://localhost:8080/ask?topicjava2使用 ChatClient 的流式 API 可以最快速地组装提示词我们看下代码/** * 使用 ChatClient 的流式 API 可以最快速地组装提示词 * param topic * return */RequestMapping(value/ask2,producestext/html;charsetutf-8)publicFluxStringask2(Stringtopic){returnchatClient.prompt().system(你是一个专业的书评助手)// 设置系统提示.user(u-u.text(请给我三本关于{topic}的书籍).param(topic,topic)).stream().content();}测试浏览器输入 http://localhost:8080/ask2?topicpython3系统提示词工程 —— defaultSystem通过defaultSystem构建专家角色将其作为 AI 的行动纲领确保所有对话都有统一的行为准则。我们先在AiConfiguration配置类里加一个ChatClient实例/** * 创建一个 ChatClient 对象用于处理聊天请求。 * * param model OpenAiChatModel 对象用于处理聊天请求。 * return ChatClient 对象用于处理聊天请求。 */BeanpublicChatClientchatClient3(OpenAiChatModelmodel){// System Prompt 工程清晰定义 AI 的角色、任务、约束和输出格式StringsystemPrompt 你是一个资深的 Java 技术顾问。 禁止回答任何非技术类问题例如天气或娱乐八卦。 代码示例必须符合 Java 17 规范。 回答需要符合以下格式首先一句话概括问题的核心然后提供代码示例最后补充注意事项。 如果自己不确定可以说关于这个问题我目前没有确切的信息禁止编造内容。 ;returnChatClient.builder(model)// 创建 ChatClient 对象并设置模型为 model.defaultSystem(systemPrompt).defaultAdvisors(newSimpleLoggerAdvisor())// 添加一个 SimpleLoggerAdvisor记录请求日志.build();// 构建 ChatClient 对象}接下来MyAiChatController里加下chatClient3实例以及定义一个新接口方法AutowiredprivateChatClientchatClient3;/** * param question * return */RequestMapping(value/ask3,producestext/html;charsetutf-8)publicFluxStringask3(Stringquestion){returnchatClient3.prompt()// 创建一个 Prompt 对象用于构建聊天请求。.user(question)// 设置用户输入的文本。.stream()// 调用 ChatClient 对象的 call() 方法发送聊天请求给大模型 并获取响应。.content();// 获取响应的文本内容。}我们来测试下浏览器输入 http://localhost:8080/ask3?question写一个java起泡法排序算法结构化输出一、结构化输出核心概念Spring AI 2.0 的结构化输出是将大语言模型 (LLM) 的自然语言响应转换为可预测、类型安全的 Java 对象如 POJO、Record、Map、List 等的机制避免手动解析文本的复杂性和不稳定性。1.1 为什么需要结构化输出自然文本输出结构化输出格式不固定解析困难格式严格直接映射为 Java 对象无类型安全易出错强类型校验编译期检查下游系统集成复杂可直接传递给其他应用程序函数维护成本高减少解析逻辑提升系统稳定性1.2 Spring AI 2.0 结构化输出核心特性自动 JSON Schema 生成基于 Java 类自动生成 JSON Schema确保模型输出符合预期格式多种转换器支持BeanOutputConverter、MapOutputConverter、ListOutputConverter 等原生结构化输出支持模型内置的 JSON 模式如 OpenAI 的 JSON mode提高输出可靠性链式调用简化通过 .entity() 方法直接将响应转换为目标类型代码更简洁集合类型支持轻松处理 List、Set 等集合类型的结构化输出二、核心实现方式2.1 两种主要方案方案说明适用场景自动转换使用.entity()方法Spring AI 自动处理转换大多数通用场景代码简洁高效显式转换器手动创建BeanOutputConverter等精细控制转换过程复杂场景需要自定义 JSON Schema或验证规则2.2 原生结构化输出Spring AI 2.0 支持模型原生的结构化输出能力通过AdvisorParams.ENABLE_NATIVE_STRUCTURED_OUTPUT启用自动处理以下流程Spring生成 JSON Schema. 配置模型使用 JSON 模式验证输出格式反序列化为 Java 对象2.3 实例 1基础 POJO 结构化输出定义目标 Java 类Record// 使用 Java 16 的 Record 特性编译器会自动生成构造器、equals/hashCode等方法publicrecordTopicBooks(Stringtopic,// 主题ListStringbooks// 书籍列表){}创建服务类实现结构化输出/** * param topic * return */RequestMapping(value/ask4,producestext/html;charsetutf-8)publicStringask4(Stringtopic){TopicBookstopicBookschatClient.prompt().system(你是一个专业的书评助手)// 设置系统提示.user(u-u.text(请给我三本关于{topic}的书籍).param(topic,topic)).call().entity(TopicBooks.class);System.out.println(topicBooks);returnOK;}浏览器请求 http://localhost:8080/ask4?topicjava后台输出TopicBooks[topicJava,books[Head First Java, Effective Java, Java ConcurrencyinPractice]]2.4 实例 2集合类型结构化输出定义定义书评类// 使用 Java 16 的 Record 特性编译器会自动生成构造器、equals/hashCode等方法publicrecordBookReview(StringreviewerName,// 书评人intrating,// 评分1-5Stringcomment// 评论内容){}生成多条书评/** * return */RequestMapping(value/ask5)publicStringask5(){ListBookReviewbookReviewschatClient.prompt().user(u-u.text(请给{bookName}书籍三条评价信息).param(bookName,Head First Java)).call().entity(newParameterizedTypeReferenceListBookReview(){});System.out.println(bookReviews);returnOK;}浏览器请求 http://localhost:8080/ask5后台输出[BookReview[reviewerNameAliceChen,rating5,comment以生动有趣的漫画和互动练习讲解Java基础非常适合初学者建立编程思维但部分代码示例需结合新版JDK调整。],BookReview[reviewerNameDavidSmith,rating4,comment项目驱动的学习方式让人印象深 刻通过构建实际应用巩固了面向对象概念建议补充多线程和Lambda表达式的现代实践。],BookReview[reviewerNameMariaGarcia,rating4,comment幽默的叙事风格降低了学习门 槛但章节进度跳跃较大需要配合官方文档查漏补缺整体仍是入门首选。]]三底层实现原理大型语言模型生成结构化输出的能力对于依赖于可靠解析输出值的下游应用至关重要。开发人员希望快速地将人工智能模型的输出转换为数据类型例如JSON、XML或Java类以便传递给其他应用程序的函数和方法。Spring AIStructured Output Converters有助于将大语言模型的输出转换为结构化格式。如下图所示这种方法围绕大语言模型文本补全端点运行使用通用补全API从大型语言模型LLM生成结构化输出需要对输入和输出进行细致处理。在调用LLM前后结构化输出转换器发挥着至关重要的作用以确保实现所需的输出结构。在大语言模型调用之前转换器会将格式说明附加到提示中为模型生成所需输出结构提供明确指导。这些说明充当蓝图引导模型的响应符合指定的格式。下图展示了使用结构化输出 API 时的数据流。会话记忆(Chat Memory)Spring AI 2.0 开发Java Agent智能体 - 会话记忆(Chat Memory)Spring AI 2.0 对聊天记忆Chat Memory进行了多项改进请说明其消息驱逐策略发生了怎样的变化以及如何避免了工具调用过程中的重复记忆问题工具调用(Function Calling / Tools)Spring AI 2.0 中 ChatClient API 有哪些重要变化ToolCallingAdvisor 的自动注册机制是如何工作的一、什么是工具调用工具调用Tool Calling又称 Function Calling是 Spring AI 2.0 的核心能力之一它让 LLM 能够调用你在 Java 后端中定义的函数从而打通了 AI 与外部系统的连接。简单来说就是让大模型不仅能“聊天”还能真正“做事”——比如查询数据库、调用 API、执行业务逻辑等。在 Spring AI 2.0 中工具调用已与 Java 方法签名全面打通只需用Tool注解标记一个 Java 方法AI 就能像调用本地函数一样调用它。在没有工具调用的情况下AI 模型只能基于其训练数据回答问题无法获取实时信息或执行操作。例如当你问“现在几点了”时模型会回答“我无法获取实时信息请告诉我当前日期。”而有了工具调用模型可以自动调用你提供的getCurrentDateTime()方法精准地返回当前时间。我们可以先测试下浏览器输入 http://localhost:8080/ai?question现在是几点了二、核心工作原理工具调用的核心流程可以概括为四个步骤定义工具在 Java 代码中定义一个方法并用Tool(description xxx)注解标明其功能描述。注册工具将工具类实例注册到ChatClient中Spring AI 会自动将其转换为 AI 模型可识别的JSON Schema。模型决策当 LLM 判断需要调用工具时会在响应中生成 JSON 格式的调用指令包含函数名和参数而非直接输出最终答案。执行与应答Spring AI 将 JSON 指令转换为实际的方法调用并将结果返回给模型模型再基于这些“实时数据”生成最终的自然语言回答。重要提醒请务必注意模型本身从不直接执行任何代码。它只是根据用户问题和定义的工具以 JSON 格式“请求”你执行这个工具。真正的执行权 100% 掌握在你的 Java 应用中这是一个关键的安全设计。三、快速入门实例让 AI 学会“看时间”下面通过一个完整的代码示例展示如何让 AI 获取当前日期和时间。本实例基于 Spring AI 2.0 推荐的Tool注解方式。importorg.springframework.ai.tool.annotation.Tool;importorg.springframework.context.i18n.LocaleContextHolder;importorg.springframework.stereotype.Component;importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;ComponentpublicclassDateTimeTools{Tool(description获取用户在指定时区的当前日期和时间用于回答需要实时时间的问题)publicStringgetCurrentTime(){// 获取用户的时区偏好设置varzoneIdLocaleContextHolder.getTimeZone().toZoneId();varnowLocalDateTime.now().atZone(zoneId);// 格式化为 yyyy-MM-dd HH:mm:ssreturnDateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss).format(now);}}对比说明两种常见的工具定义方式Tool 注解推荐代码最简洁只需在方法上添加Tool注解即可。这是 Spring AI 2.0 主推的新 API也是本实例采用的方式。FunctionCallback 方式旧版在 Spring AI 1.x 中需要实现复杂的Function接口代码量较大。此 API 已被标记为过时deprecated建议在新项目中使用Tool注解的方式。MyAiChatController控制器里在调用 ChatClient 时通过 .tools() 方法将定义好的工具注册进去。AutowiredprivateDateTimeToolsdateTimeTools;RequestMapping(/aitool)publicStringaitool(Stringquestion){returnchatClient.prompt()// 创建一个 Prompt 对象用于构建聊天请求。.user(question)// 设置用户输入的文本。.tools(dateTimeTools)// 注册工具.call()// 调用 ChatClient 对象的 call() 方法发送聊天请求给大模型并获 取响应。.content();// 获取响应的文本内容。}我们再测试下浏览器输入 http://localhost:8080/aitool?question现在是几点了通过对比可以清晰地看出注册工具后AI 自动识别需求并调用了 getCurrentDateTime 方法从而提供了精准的实时信息。四、进阶实践让 AI 执行操作工具调用不仅能获取信息还能让 AI 执行具体操作。以下示例展示了如何实现闹钟设置功能。在工具类DateTimeTools中添加操作型工具Tool(description设置闹钟调用此工具可在指定时间触发提醒。时间参数必须是 ISO-8601 格 式例如2026-05-03 15:30:00)publicvoidsetAlarm(ToolParam(description闹钟的触发时间标准格式yyyyMM-dd HH:mm:ss)StringalarmTime){System.out.println(⏰ 闹钟已设置将在 alarmTime 提醒用户。);// 此处可扩展实际逻辑如存入数据库、发送推送通知等}现在向 AI 提问“帮我设置一个 1分钟后的闹钟。”带工具注册的调用会自动触发如下流程AI 模型首先调用getCurrentDateTime获取当前时间。模型计算出 10 分钟后对应的时间点。模型调用setAlarm工具传入计算出的具体时间控制台输出闹钟设置成功的提示。这正是 Agent 模式的雏形模型负责理解意图、拆解任务、规划步骤你只需提供对应的工具方法AI就能自动编排执行。五工具调用底层实现原理Spring AI 通过一组灵活的抽象支持工具调用使您能够以一致的方式定义、解析和执行工具。本节概述了 Spring AI 中工具调用的主要概念和组件。当我们希望将某个工具提供给模型使用时会将其定义包含在聊天请求中。每个工具定义包括名称、描述以及输入参数的模式。当模型决定调用工具时它会发送一条包含工具名称和按照定义的模式建模的输入参数的响应。应用程序负责使用工具名称来识别并执行带有所提供输入参数的工具。应用程序会处理工具调用的结果。应用程序将工具调用结果发送回模型。模型使用工具调用结果作为额外上下文生成最终响应工具是工具调用的构建模块它们由ToolCallback接口进行建模。Spring AI 提供了内置支持可从方法和函数中指定ToolCallback s但您也可以随时定义自己的ToolCallback实现以支持更多用例。ChatModel实现会透明地将工具调用请求分发到相应的ToolCallback实现并将工具调用结果返回给模型最终由模型生成最终响应。它们通过ToolCallingManager接口来完成这一过程该接口负责管理工具执行的生命周期。嵌入模型(Embedding Model)与向量数据库(Vector Databases)Spring AI 2.0 开发Java Agent智能体 - 嵌入模型(Embedding Model)与向量数据库(Vector Databases)Windows 下 Docker Desktop 安装教程及常用命令2026 最新Spring AI 2.0 对向量存储Vector Store进行了哪些升级新增了哪些向量存储后端RAG(检索增强生成)Spring AI 2.0 开发Java Agent智能体 - RAG(检索增强生成)分享一套锋哥原创的基于Spring AI 2.0的RAG企业内部知识库问答系统(AI大模型 SpringBoot4Vue3Ollama)分享一套锋哥原创的基于Spring AI 2.0的RAG医疗健康知识智能问答系统(AI大模型 SpringBoot4Vue3Ollama)分享一套锋哥原创的基于Spring AI 2.0的带AI智能客服的商城系统(支付宝沙箱模拟支付SprnigBoot4Vue3)利用Cursor AI编程 两小时实现 基于Spring AI 2.0的带智能客服的商城系统(带在线支付功能)MCP(模型上下文协议)Spring AI 2.0 开发Java Agent智能体 - MCP(模型上下文协议)多模态支持Spring AI 2.0 开发Java Agent智能体 - 多模态支持