【Spring AI】
- [1. Spring AI简介](#1. Spring AI简介)
-
- [1.1 Spring AI是什么](#1.1 Spring AI是什么)
-
- [1.1.1 概述](#1.1.1 概述)
- [1.2 发布版本](#1.2 发布版本)
- [1.3 Spring AI的主要功能](#1.3 Spring AI的主要功能)
- [2. 结合DeepSeek上手使用](#2. 结合DeepSeek上手使用)
-
- [2.1 准备工作](#2.1 准备工作)
- [2.2 DeepSeek开放平台创建API KEY](#2.2 DeepSeek开放平台创建API KEY)
- [2.3 实现简单对话](#2.3 实现简单对话)
- [3. Spring AI的聊天模型](#3. Spring AI的聊天模型)
-
- [3.1 概述](#3.1 概述)
- [3.2 ChatClient接口](#3.2 ChatClient接口)
-
- [3.2.1 ChatClient接口定位与作用](#3.2.1 ChatClient接口定位与作用)
- [3.2.2 ChatClient接口核心特点](#3.2.2 ChatClient接口核心特点)
- [3.2.3 核心接口与用法](#3.2.3 核心接口与用法)
- [3.3 最佳实践](#3.3 最佳实践)
- [3.4 流式输出](#3.4 流式输出)
- [4. 一个接口使用不同的大模型](#4. 一个接口使用不同的大模型)
-
- [4.1 多厂商模型的调用方式](#4.1 多厂商模型的调用方式)
- [5. 提示词](#5. 提示词)
- [6. Spring AI的函数调用](#6. Spring AI的函数调用)
-
- [6.1 函数调用实现](#6.1 函数调用实现)
-
- [6.1.1 创建自定义的Function](#6.1.1 创建自定义的Function)
- [6.1.2 编写Controller](#6.1.2 编写Controller)
- [6.1.3 测试](#6.1.3 测试)
- [7. SpringAI调用Ollama](#7. SpringAI调用Ollama)
-
- [7.1 什么是Ollama](#7.1 什么是Ollama)
- [7.2 使用Docker安装](#7.2 使用Docker安装)
- [7.3 SpringAI结合Ollama](#7.3 SpringAI结合Ollama)
- [8. 图像模型](#8. 图像模型)
-
- [8.1 Image Model API概述](#8.1 Image Model API概述)
- [8.2 Image Model API接口及相关类](#8.2 Image Model API接口及相关类)
-
- [8.2.1 ImageModel(图像模型)](#8.2.1 ImageModel(图像模型))
- [8.2.2 ImagePrompt(图像提示)](#8.2.2 ImagePrompt(图像提示))
- [8.2.3 ImageMessage(图像消息)](#8.2.3 ImageMessage(图像消息))
- [8.2.4 ImageOptions(图像选项)](#8.2.4 ImageOptions(图像选项))
- [8.2.5 ImageResponse(图像响应)](#8.2.5 ImageResponse(图像响应))
- [8.2.6 ImageGeneration(图像生成)](#8.2.6 ImageGeneration(图像生成))
- 附录
1. Spring AI简介
在当今这样一个快速发展的技术时代,人工智能(AI)已经成为各行各业的一种标配。而作为一款主流的Java应用开发框架Spring,肯定会紧跟时代的潮流,所以,推出了Spring AI框架。
1.1 Spring AI是什么
官网 https://spring.io/projects/spring-ai
1.1.1 概述

Spring AI 是一个面向 AI 工程的应用框架。它的目标是把 Spring 生态系统中的设计原则(例如可移植性、模块化设计等)应用到 AI 领域,并推动在 AI 应用中使用 POJO(普通 Java 对象)作为应用的构建模块。
其核心在于解决 AI 集成的基础性挑战:将你的企业数据(Data)和 API 与 AI 模型连接起来。
特性(Features)
Spring AI 提供以下功能:
-
支持所有主要的 AI 模型供应商(Model providers),包括 Anthropic、OpenAI、Microsoft、Amazon、Google,以及 Ollama。支持的模型类型有:
- 聊天补全(Chat Completion)
- 嵌入(Embedding)
- 文本生成图像(Text to Image)
- 音频转录(Audio Transcription)
- 文本转语音(Text to Speech)
- 内容审核 / Moderation(Moderation)
-
对不同 AI 提供商的 API,支持同步(synchronous)和流式(streaming)调用方式,同时也可以访问特定模型(model-specific)的特性。
-
结构化输出(Structured Outputs) ------ 将 AI 模型的输出映射为 POJOs(方便在 Java 环境中处理)
-
支持主要的向量数据库(Vector Database)提供商(Providers),例如 Apache Cassandra、Azure Vector Search、 Chroma、Milvus、MongoDB Atlas、Neo4j、Oracle、PostgreSQL/PGVector、PineCone、Qdrant、Redis、Weaviate 等等。
-
在向量存储提供商之间提供可移植 API(Portable API),包括一个类 SQL 的元数据过滤 API(metadata filter API)。
-
支持工具 / 函数调用(Tools / Function Calling)------即模型可以请求执行客户端的工具或函数,以便在必要时访问实时的信息。
-
可观测性(Observability) --- 提供 AI 相关操作的可监控、可视化洞见。
-
文档注入(Document injection)以及用于数据工程的 ETL 框架。
-
AI 模型评估(AI Model Evaluation) --- 包括用于评估生成内容的工具,并帮助防止"幻觉"(hallucinated responses)的问题。
-
ChatClient API --- 用于与 AI 聊天模型通信的 Fluent API,其风格类似于 Spring 的 WebClient 和 RestClient。
-
Advisors API --- 封装了常用的生成式 AI 模式,负责变换语言模型(LLM)之间或发送/接收的内容,并为不同模型和用例提供可移植性。
-
支持聊天对话记忆(Chat Conversation Memory)和检索增强生成(Retrieval Augmented Generation, RAG)等功能。
-
Spring Boot 的自动配置(Auto Configuration)和 Starter(启动器)支持所有 AI 模型和向量存储 ------ 你可以用 Spring Initializr 来选择你想用的模型或向量存储。
这些功能组合起来,使你可以实现诸如 "在你的文档上做问答 (Q&A over your documentation)" 或 "与你的文档进行聊天 (Chat with your documentation)" 这样的常见用例。
1.2 发布版本
写这篇文章的时间是2025年09月20日,可以看到已经有了
- 1.0.1 Current (当前稳定版)
- 1.1.0-SNAPSHOT(开发中的快照版本)
- 1.1.0-M1(预发布版本 Milestone 1)

1.3 Spring AI的主要功能
- 第一、 对主流 AI 大模型供应商提供了支持,比如:OpenAI、DeepSeek、Microsoft、Ollama、Amazon、Google HuggingFace等。
- 第二、 支持AI大模型类型包括:聊天、文本到图像、文本到声音等。
- 第三、 支持主流的Embedding Models(嵌入模型)和向量数据库,比如:Azure Vector Search、Chroma、Milvus、Neo4j、Redis、PineCone、PostgreSQL/PGVector 等。
- 第四、 把 AI 大模型输出映射到简单的 Java 对象(POJOs)上。
- 第五、 支持了函数调用(Function calling)功能。
- 第六、 为数据工程提供 ETL(数据抽取、转换和加载)框架。
- 第七、 支持 Spring Boot 自动配置和快速启动,便于运行 AI 模型和管理向量库。
2. 结合DeepSeek上手使用
2.1 准备工作
DeepSeek 是一款由深度求索所开发的 AI 人工智能大模型,其基于深度学习和多模态数据融合技术,采用先进的 Transformer 架构和跨模态协同算法,可实现对复杂文档和图像的自动化解析与结构化信息提取。
依托于最新推出的"深度思考"模式(R1),这款AI大模型在极低成本下实现了与国际顶尖模型ChatGPT-o1相媲美的性能表现,其中文理解与输出能力更是远超ChatGPT、Claude等顶尖模型。再加上极具竞争力的API定价和全面开源的策略,让这款AI大模型成功在国际上火爆出圈
如果说AI是一个广泛的概念,那么DeepSeek就是是AI领域中的一个具体产品。
DeepSeek的特点:
- 成本:DeepSeek致力于降低AI应用的成本。通过采用先进的技术和独特的模型架构,DeepSeek在保持高性能的同时,显著降低了推理和训练的成本。
- 性能:DeepSeek在性能上表现出色。它使用强化学习技术训练,推理过程中包含大量反思与验证,能够处理更加复杂的数据和任务。在一些benchmark测试中,其性能与OpenAI的模型相当,但推理成本远低于同类产品。
- 功能:DeepSeek擅长处理数学、编程和复杂逻辑推理等任务。它的推理能力源于深度思考特性,推理长度与准确率呈正相关。此外,DeepSeek还支持多模态信息处理,能够应对更加多样化的应用场景。
- 应用领域:DeepSeek在多个领域展现出巨大的应用潜力。无论是在医疗、教育、交通等传统领域,还是在智能制造、智慧城市等新兴领域,DeepSeek都有望发挥重要作用。
综上所述,AI是一个广泛的概念,涵盖了人工智能领域的所有技术和应用。而DeepSeek则是AI领域中的一个具体产品,它在成本、性能、功能和应用领域等方面都有着独特的特点和优势。两者之间的关系可以理解为:DeepSeek是AI领域中的一个具体实现和优秀代表。
如何使用Java集成DeepSeek:
DeepSeek 作为一款卓越的国产 AI 模型,越来越多的公司考虑在自己的应用中集成。对于 Java 应用来说,我们可以借助 Spring AI 集成 DeepSeek,非常简单方便!
2.2 DeepSeek开放平台创建API KEY
DeepSeek官网 https://www.deepseek.com/
接口文档 https://api-docs.deepseek.com/zh-cn/
在官网上创建api key 注意是需要充值的!
使用curl调用
bash
(base) ➜ ~ curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-8c780d3293d94b799d7b8000972xxxxx" \
-d '{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"stream": false
}'
bash
{
"id": "3ec31844-c3da-466b-b286-xxx0b90bcf83",
"object": "chat.completion",
"created": 1758340902,
"model": "deepseek-chat",
"choices": [
{
"index": 0,
"message": {},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 11,
"total_tokens": 23,
"prompt_tokens_details": {},
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 12
},
"system_fingerprint": "fp_08f168e49b_xxxxxx_fp8_kvcache"
}
2.3 实现简单对话
新建一个Maven项目
其中父类的pom依赖
bash
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.beijing</groupId>
<artifactId>SpringAi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 子模块 -->
<modules>
<module>springai_hello</module>
</modules>
<properties>
<spring-boot.version>3.3.8</spring-boot.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-ai.version>1.0.1</spring-ai.version>
</properties>
<!-- 版本管理 -->
<dependencyManagement>
<dependencies>
<!-- Spring Boot 依赖版本管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring AI 依赖版本管理 -->
<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>
<!-- Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
子类springai_hello
application.yml
bash
server:
port: 18888
spring:
application:
name: springai_hello
ai:
openai:
api-key: sk-8cxxxd3293d94b799d7b8000972xxxx
base-url: https://api.deepseek.com
chat:
options:
model: deepseek-chat
temperature: 0.7
temperature参数用于控制生成文本的多样性。具体来说:
值越高,生成的文本越多样化,但也可能包含更多的随机性和不可预测的内容。 值越低,生成的文本越接近于确定性的结果,即生成的文本会更加一致和可预测。
子类的pom
bash
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.beijing</groupId>
<artifactId>SpringAi</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>springai_hello</artifactId>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>
</project>

配置文件
ChatModelConfig
java
package com.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ChatModelConfig {
/**
* 配置 ChatClient(用于对话调用)
*/
@Bean
public ChatClient chatClient(OpenAiChatModel openAiChatModel) {
return ChatClient.builder(openAiChatModel).build();
}
}
Controller
java
package com.controller;
package com.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatController {
@Resource
private ChatClient chatClient;
@GetMapping("/hello")
public String generate(@RequestParam(value = "message") String message) {
String call = chatClient
.prompt()
.system("你是一个无所不能的机器人")
.user(message)
.call()
.content();
return call;
}
}
方法 | 作用 |
---|---|
prompt() |
提示词 |
user(message) |
设置用户消息 |
call() |
发送请求给模型,获取响应 |
content() |
获取模型生成的文本内容 |
3. Spring AI的聊天模型
3.1 概述
Spring AI的聊天模型API为开发者提供了一条便捷通道,能够将强大的AI驱动的聊天完成功能无缝集成到各类应用中。借助预先训练的语言模型,如广为人知的GPT,它能够依据用户输入生成自然流畅、类人化的回复。这一API不仅工作机制高效,而且设计理念极为先进,旨在实现简单易用与高度可移植性,让开发者能以极少的代码改动在不同AI模型间自由切换,充分契合Spring框架一贯秉持的模块化与可互换性原则。
3.2 ChatClient接口
Spring AI 的 ChatClient 是一个面向开发者的无状态 AI 对话客户端,提供了基于流式/非流式调用的统一 API,用于和不同的 大语言模型(LLM)(如 OpenAI、Ollama、Azure OpenAI、Anthropic 等)交互。
3.2.1 ChatClient接口定位与作用
-
ChatClient 是 Spring AI 提供的统一客户端接口,用来调用各种大语言模型(LLM)。
-
目标类似:
- RestTemplate(同步 HTTP 调用)
- WebClient(响应式 HTTP 调用)
-
作用是:对接底层模型(OpenAI、Azure、Ollama、Anthropic...)时,开发者不需要关心底层 SDK,直接用统一 API 就能发请求、收响应。
换句话说:ChatClient 是 AI 领域的统一编程入口。
3.2.2 ChatClient接口核心特点
-
统一 API:不管调用哪个模型,写法都一致。
-
Prompt 构建:支持 system / user / 多消息角色。
-
调用模式:
- 同步调用(一次性返回完整答案)
- 流式调用(逐 Token 实时输出,基于 Reactor Flux)
-
扩展能力:
- Advisor:对话增强器(类似拦截器/AOP)
- Tool / Function Calling:让 AI 调用外部函数或服务
- Structured Output:LLM 输出直接转为 Java 对象
-
监控集成:支持 Micrometer / Tracing
3.2.3 核心接口与用法
① 创建 ChatClient
java
// 快速工厂方法
ChatClient client = ChatClient.create(chatModel);
// Builder 模式(带默认配置)
ChatClient client = ChatClient.builder(chatModel)
.defaultSystem("你是一个专业的Java导师")
.defaultUser("你好")
.build();
② 构建 Prompt
java
String reply = client.prompt("你是一个乐于助人的助手")
.system()
.user("帮我解释一下 FutureTask 是什么") // User role
.call()
.content();
支持从文件、模板、参数化:
java
chatClient.prompt()
.user(u -> u.text("请写一首关于 {topic} 的诗").param("topic", "AI"))
.call()
.content();
③ 调用方式
- 同步调用
java
String answer = client.prompt().user("讲个笑话").call().content();
- 流式调用
java
client.prompt("写一首诗")
.stream()
.content()
.subscribe(System.out::print);
④ Advisor(对话增强器)
Advisor = 对话拦截器,可以在请求前/响应后增强。
例如:追加上下文、敏感词过滤、打日志。
java
chatClient.prompt("帮我写一份简历")
.advisors(new LoggingAdvisor(), new RedactSensitiveDataAdvisor())
.call();
⑤ 工具调用(Function Calling)
AI 可以自动触发你的函数:
java
class WeatherTool {
public String getWeather(String city) {
return city + " 今天天气晴朗 25℃";
}
}
chatClient.prompt("北京天气怎么样?")
.tools(new WeatherTool())
.call()
.content();
⑥ 结构化输出
让模型返回 JSON → 自动转为对象:
java
record Person(String name, int age) {}
Person person = chatClient.prompt("输出一个人: {\"name\":\"小明\",\"age\":16}")
.call()
.entity(Person.class);
System.out.println(person.name()); // 小明
⑦ 完整响应对象
java
ChatResponse response = chatClient.prompt("讲个冷笑话").call().chatResponse();
System.out.println(response.getResult().getOutputText());
System.out.println(response.getMetadata().getUsage()); // token 使用情况
System.out.println(response.getMetadata().getFinishReason());
3.3 最佳实践
- 在配置类统一定义 ChatClient Bean,避免重复创建。
- 同步调用适合短回答,流式调用适合长文本。
- Advisor 可以做安全过滤/上下文增强。
- 工具调用要加参数验证/Schema,减少错误调用。
- 结合 Micrometer 做监控,分析 token 消耗与调用时延。
3.4 流式输出
java
package com.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
public class ChatController {
@Resource
private ChatClient chatClient;
@GetMapping(value = "/hello",produces = "text/html; charset = UTF-8")
public Flux<String> generate(@RequestParam(value = "message") String message) {
Flux<String> stream = chatClient
.prompt()
.system("你是一个阿里巴巴的Java专家")
.user(message)
.stream()
.content();
return stream;
}
}
4. 一个接口使用不同的大模型
4.1 多厂商模型的调用方式
Spring AI 的关键类是 ChatClient,其调用流程大概如下:
java
String response = chatClient
.prompt()
.user("你好,请解释量子力学")
.call()
.content();
这里 chatClient 可以通过配置绑定不同厂商:
- OpenAI
- Azure OpenAI
- Anthropic
- 自定义大模型(DeepSeek、千问等)
Spring AI 的 核心扩展点是 ChatModel 和 ChatClient 的实现:
java
@Bean
public ChatClient chatClient(List<ChatModel> chatModels) {
return new DefaultChatClient(chatModels);
}
- chatModels 是你可以注入的所有模型。
- Spring AI 内部会根据模型 id 或 type 决定使用哪个厂商。
配置不同厂商的模型
Spring AI 允许你在配置文件或代码中声明多个模型:
java
spring:
ai:
chat:
models:
openai:
type: openai
api-key: YOUR_OPENAI_KEY
deepSeek:
type: custom
endpoint: https://api.deepseek.com/v1/chat
api-key: YOUR_DEEPSEEK_KEY
qianwen:
type: custom
endpoint: https://api.qianwen.ai/v1/chat
api-key: YOUR_QIANWEN_KEY
然后在代码里通过 ChatClient 调用时选择模型:
java
String answer = chatClient
.model("deepSeek") // 指定调用 DeepSeek
.prompt()
.user("帮我写一篇 AI 概念介绍")
.call()
.content();
⚡ 关键点:model("模型名") 就是多厂商支持的入口。
如果 Spring AI 还没有内置 DeepSeek 或千问模型,你可以自定义实现 ChatModel:
然后 Spring AI 就能像调用内置模型一样调用你的自定义模型。
java
@Component("deepSeek")
public class DeepSeekChatModel implements ChatModel {
@Override
public ChatResponse sendMessage(ChatMessage message) {
// 调用 DeepSeek 的 REST API
String result = callDeepSeekApi(message.getContent());
return ChatResponse.of(result);
}
}
5. 提示词
-
提示词是引导大模型生成特定输出的输入,提示词的设计和措辞会极大地影响模型的响应结果。
-
Prompt 提示词是与模型交互的一种输入数据组织方式,本质上是一种复合结构的输入,在 prompt 我们是可以包含多组不同角色(System、User、Aissistant等)的信息。如何管理好 Prompt 是简化 AI 应用开发的关键环节。
-
Spring AI 提供了 Prompt Template 提示词模板管理抽象,开发者可以预先定义好模板,并在运行时替换模板中的关键词。在 Spring AI 与大模型交互的过程中,处理提示词首先要创建包含动态内容占位符 {占位符} 的模板,然后,这些占位符会根据用户请求或应用程序中的其他代码进行替换。在提示词模板中,{占位符} 可以用 Map 中的变量动态替换。
java
@GetMapping("/prompt")
public String prompt(@RequestParam("name") String name, @RequestParam("voice") String voice){
String userText= """
给我推荐北京的至少三种美食
""";
// 用户信息
UserMessage userMessage = new UserMessage(userText);
// 系统信息
String systemText= """
你是一个美食咨询助手,可以帮助人们查询美食信息。
你的名字是{name},
你应该用你的名字和{voice}的饮食习惯回复用户的请求。
""";
// PromptTemplate
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);
// 替换占位符
Message systemMessage = systemPromptTemplate
.createMessage(Map.of("name", name, "voice", voice));
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
List<Generation> results = chatModel.call(prompt).getResults();
return results.stream()
.map(x->x.getOutput().getContent())
.collect(Collectors.joining(""));
}
6. Spring AI的函数调用
-
Spring AI 的函数调用(Function Calling)功能允许大语言模型在生成回答时触发预定义的外部函数,从而实现动态数据获取或业务逻辑操作(如查询数据库、调用 API 等)。
-
SpringAI 帮我们规范了函数定义、注册等过程,并在发起模型请求之前自动将函数注入到 Prompt 中,而当模型决策在合适的时候去调用某个函数时,Spring AI 完成函数调用动作,最终将函数执行结果与原始问题再一并发送给模型,模型根据新的输入决策下一步动作。这其中涉及与大模型的多次交互过程,一次函数调用就是一次完成的交互过程。
-
函数调用的核心流程
-
第一步,定义函数:声明可供模型调用的函数(名称、描述、参数结构)。
-
第二步,模型交互:将函数信息与用户输入一起发送给模型,模型决定是否需要调用函数。
-
第三步,执行函数:解析模型的函数调用请求,执行对应的业务逻辑。
-
第四步,返回结果:将函数执行结果返回给模型,生成最终回答。
6.1 函数调用实现
6.1.1 创建自定义的Function
- 下面CalculatorService类自定义了加法和乘法运算的函数
java
@Configuration
public class CalculatorService {
public record AddOperation(int a, int b) {
}
public record MulOperation(int m, int n) {
}
@Bean
@Description("加法运算")
public Function<AddOperation, Integer> addOperation() {
return request -> {
return request.a + request.b;
};
}
@Bean
@Description("乘法运算")
public Function<MulOperation, Integer> mulOperation() {
return request -> {
return request.m * request.n;
};
}
}
总结:
Spring AI 使自定义函数这个过程变得简单,只需定义一个返回 java.util.Function 的 @Bean 定义,并在调用 ChatModel 时将 bean 名称作为选项进行注册即可。在底层,Spring 会用适当的适配器代码包装你的函数,以便与 AI 模型进行交互,免去了编写繁琐的代码。
6.1.2 编写Controller
java
@GetMapping(value = "/chat", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public String ragJsonText(@RequestParam(value = "userMessage") String userMessage){
return ChatClient.builder(chatModel)
.build()
.prompt()
.system("""
您是算术计算器的代理。
您能够支持加法运算、乘法运算等操作,其余功能将在后续版本中添加,如果用户问的问题不支持请告知详情。
在提供加法运算、乘法运算等操作之前,您必须从用户处获取如下信息:两个数字,运算类型。
请调用自定义函数执行加法运算、乘法运算。
请讲中文。
""")
.user(userMessage)
.functions("addOperation", "mulOperation")
.call()
.content();
}
- 为了让模型知道并调用你的自定义函数,您需要在 Prompt 请求中启用它,如上述代码,在
functions("addOperation", "mulOperation")
中告知ChatClient要使用这两个自定义函数。 - 另外指定了System Prompt:要求AI 模型被设定为一个算术计算器代理,能够执行加法和乘法运算,并且要求用户提供两个数字和运算类型。这个提示词内容很关键,如何让AI按照自己的意图去执行,要不断测试提示词内容。
6.1.3 测试

7. SpringAI调用Ollama
7.1 什么是Ollama
Ollama官方地址 https://ollama.com/
Ollama 是一个 在本地运行大模型(LLM) 的工具和平台。
它的核心目标是:
👉 让你在 自己的电脑上(Mac、Linux、Windows)非常方便地下载、运行和管理大语言模型(类似 OpenAI 的 GPT、Meta 的 LLaMA、Mistral 等)。
换句话说:
- 如果 Hugging Face 更像是"模型超市",
- 那么 Ollama 就是"本地模型的运行时 + 包管理器"。
🚀 Ollama 的主要特点
- 开箱即用
安装 Ollama 后,只需要一条命令就能启动一个大模型:
ollama run llama2
它会自动下载模型文件并运行,无需自己折腾复杂的依赖。
- 支持多种模型
-
内置支持:LLaMA 2、Mistral、Phi-3、CodeLLaMA、Gemma 等
-
也可以加载自定义模型(通过 Modelfile 配置)。
- 轻量化 & 本地推理
- 针对消费级电脑优化,能在 MacBook 或普通 PC 上跑小规模 LLM。
- 底层用的是 GGUF 格式的量化模型文件,显存/内存占用更低。
- 简单的 API 调用
提供一个类似 OpenAI API 的接口:
bash
curl http://localhost:11434/api/generate -d '{
"model": "llama2",
"prompt": "Hello, Ollama!"
}'
这让它可以无缝接入到各种应用里(比如 LangChain、Spring AI)。
- 跨平台
最初只支持 macOS,现在已经支持 Linux 和 Windows。
- 隐私和安全
所有数据和模型都在本地运行,不会上传到云端 → 适合对数据安全要求高的场景。
7.2 使用Docker安装
bash
docker pull ollama/ollama


bash
(base) ➜ ~ docker run -d \
--name ollama \
-v ollama:/root/.ollama \
-p 11434:11434 \
ollama/ollama
-v ollama:/root/.ollama
数据卷映射,把宿主机的 ollama 数据卷挂载到容器内的 /root/.ollama
目录。
/root/.ollama
是 Ollama 存储模型文件、配置文件 的地方。
好处:即使容器删除,模型文件也会保留,不需要每次重新下载。
bash
(base) ➜ ~ curl http://localhost:11434/api/tags
{"models":[]}
进入容器跑大模型
bash
# 进入docker
docker exec -it ollama /bin/bash
# 运行1.5b模型
ollama run deepseek-r1:1.5b

启动大模型
7.3 SpringAI结合Ollama
java
package com.beijing.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OllamaController {
@Resource
private OllamaChatModel ollamaChatModel;
@GetMapping("/ollama")
public String ollama(@RequestParam(value = "message") String message){
return ollamaChatModel.call(message);
}
}
java
package com.beijing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MoreLlmApplication {
public static void main(String[] args) {
SpringApplication.run(MoreLlmApplication.class, args);
}
}
xml
server:
port: 16888
spring:
application:
name: moreLLM
ai:
ollama:
base-url: http://localhost:11434
chat:
options:
model: deepseek-r1:1.5b
temperature: 0.7
java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.beijing</groupId>
<artifactId>SpringAi</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>moreLLM</artifactId>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
</dependencies>
</project>
8. 图像模型
8.1 Image Model API概述
-
在Spring AI框架中,Image Model API旨在为与专注于图像生成的各种AI模型进行交互提供一个简单且可移植的接口,使开发者能够以最小的代码改动切换不同的图像相关模型。这一设计符合Spring模块化和互换性的理念,确保开发者可以快速调整其应用程序以适应不同的图像处理相关的AI能力。
-
此外,通过支持像ImagePrompt这样的辅助类来进行输入封装以及使用ImageResponse来处理输出,图像模型API统一了与致力于图像生成的AI模型之间的通信。它管理请求准备和响应解析的复杂性,为图像生成功能提供直接而简化的API交互。
-
Image Model API建立在Spring AI通用模型API之上,提供了特定于图像的抽象和实现。
8.2 Image Model API接口及相关类
8.2.1 ImageModel(图像模型)
这里展示的是ImageModel接口定义:
java
@FunctionalInterface
public interface ImageModel extends Model<ImagePrompt, ImageResponse> {
ImageResponse call(ImagePrompt request);
}
8.2.2 ImagePrompt(图像提示)
ImagePrompt是一个封装了ImageMessage对象列表及可选模型请求选项的ModelRequest。下面显示的是ImagePrompt类的一个简化版本,省略了构造函数和其他工具方法:
java
public class ImagePrompt implements ModelRequest<List<ImageMessage>> {
private final List<ImageMessage> messages;
private ImageOptions imageModelOptions;
@Override
public List<ImageMessage> getInstructions() {...}
@Override
public ImageOptions getOptions() {...}
}
8.2.3 ImageMessage(图像消息)
ImageMessage类封装了用于影响生成图像的文本及其权重。对于支持权重的模型,它们可以是正数或负数。
java
public class ImageMessage {
private String text;
private Float weight;
public String getText() {...}
public Float getWeight() {...}
}
8.2.4 ImageOptions(图像选项)
表示可以传递给图像生成模型的选项。ImageOptions接口扩展了ModelOptions接口,并用于定义可以传递给AI模型的一些可移植选项。
java
public interface ImageOptions extends ModelOptions {
Integer getN();
String getModel();
Integer getWidth();
Integer getHeight();
String getResponseFormat(); // openai - url or base64 : stability ai byte[] or base64
}
8.2.5 ImageResponse(图像响应)
持有AI模型的输出,每个ImageGeneration实例包含来自单一提示的可能多个输出结果之一。
java
public class ImageResponse implements ModelResponse<ImageGeneration> {
private final ImageResponseMetadata imageResponseMetadata;
private final List<ImageGeneration> imageGenerations;
@Override
public ImageGeneration getResult() {
// get the first result
}
@Override
public List<ImageGeneration> getResults() {...}
@Override
public ImageResponseMetadata getMetadata() {...}
}
8.2.6 ImageGeneration(图像生成)
最终,ImageGeneration类扩展自ModelResult,代表输出响应及有关此结果的元数据。
java
public class ImageGeneration implements ModelResult<Image> {
private ImageGenerationMetadata imageGenerationMetadata;
private Image image;
@Override
public Image getOutput() {...}
@Override
public ImageGenerationMetadata getMetadata() {...}
}
P13 TODO
附录
1.炸裂!Spring AI 1.0 正式发布 https://zhuanlan.zhihu.com/p/1909928795659567609
2.【尚硅谷SpringAI实战教程,springai轻松上手大模型应用开发】 https://www.bilibili.com/video/BV1Cxj7zjEng/?p=9&share_source=copy_web&vd_source=6888e998072955ff0cd273996df291f5
3.【2025吃透Spring AI 1.0全套教程(入门+实战+原理&源码;大模型+tools+mcp+Agent全流程落地),7天学完,让你少走99%弯路!!】https://www.bilibili.com/video/BV1z7h3zbEd2/?share_source=copy_web&vd_source=6888e998072955ff0cd273996df291f5