【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(1)——Chat Client API
Spring AI框架快速入门
- 一、前言
- 二、前期准备
- 2.1 运行环境
- 2.2 maven配置
- 2.3 api-key申请
- 三、Chat Client API
- 3.1 导入pom依赖
- 3.2 配置application.properties文件
- 3.3 创建 ChatClient
- 3.3.1 使用自动配置的 ChatClient.Builder
- 3.3.2 使用多个聊天模型
- 3.4 ChatClient请求
- 3.5 ChatClient 响应
- 3.5.1 返回 ChatResponse
- 3.5.2 返回实体
- 3.5.3 流式响应
- 3.6 提示模板
- 3.6 call() 返回值
- 3.7 stream() 返回值
- 3.8 使用默认值
- 3.8.1 默认系统文本
- 3.8.2 带参数的默认系统文本
- 3.8.3 其他默认值
- 3.9 Advisors
- 3.9.1 ChatClient 中的 Advisor 配置
- 3.9.2 日志记录
一、前言
前言:Spring AI经历了八个版本的迭代(M1~M8)之后,Spring AI 1.0.0 正式版本,终于在 2025 年 5 月 20 日正式发布,这是另一个新高度的里程碑式的版本,标志着 Spring 生态系统正式全面拥抱人工智能技术,并且意味着 Spring AI 将会给企业带来稳定 API 支持。
Spring AI 项目旨在简化包含人工智能功能的应用程序的开发,避免不必要的复杂性。
该项目的灵感来源于著名的 Python 项目,如 LangChain
和 LlamaIndex
,但 Spring AI 并非这些项目的直接移植。 该项目坚信,下一波生成式人工智能应用程序将不仅仅面向 Python 开发人员,而是将普及到多种编程语言中。
注意:Spring AI 解决了人工智能集成的基本挑战:将企业数据和 API 与人工智能模型连接起来。
Spring AI 提供了作为开发人工智能应用程序基础的抽象。 这些抽象有多种实现,从而能够以最少的代码更改轻松替换组件。
Spring AI 提供以下功能:
-
跨 AI 提供商的聊天、文本到图像和嵌入模型的便携式 API 支持。支持同步和流式 API 选项。也提供对模型特定功能的访问。
-
支持所有主要的
AI 模型提供商
,例如 Anthropic、OpenAI、Microsoft、Amazon、Google 和 Ollama。支持的模型类型包括:-
聊天补全
-
嵌入
-
文本到图像
-
音频转录
-
文本到语音
-
内容审核
-
-
结构化输出
- 将 AI 模型输出映射到 POJO。 -
支持所有主要的
向量数据库提供商
,例如 Apache Cassandra、Azure Cosmos DB、Azure Vector Search、Chroma、Elasticsearch、GemFire、MariaDB、Milvus、MongoDB Atlas、Neo4j、OpenSearch、Oracle、PostgreSQL/PGVector、PineCone、Qdrant、Redis、SAP Hana、Typesense 和 Weaviate。 -
跨向量存储提供商的便携式 API,包括新颖的类 SQL 元数据过滤 API。
-
工具/函数调用
- 允许模型请求执行客户端工具和函数,从而根据需要访问必要的实时信息并采取行动。 -
可观察性
- 提供对 AI 相关操作的洞察。 -
用于数据工程的文档提取
ETL 框架
。 -
AI 模型评估
- 帮助评估生成内容并防止幻觉响应的实用程序。 -
AI 模型和向量存储的 Spring Boot 自动配置和启动器。
-
ChatClient API
- 用于与 AI 聊天模型通信的流畅 API,在习惯用法上类似于 WebClient 和 RestClient API。 -
Advisors API
- 封装了重复出现的生成式 AI 模式,转换进出语言模型 (LLM) 的数据,并提供跨各种模型和用例的可移植性。 -
支持
聊天对话记忆
和检索增强生成 (RAG)
。
基于以上Spring AI特性,我将分多篇博客详细讲解Spring AI的用法,有帮助麻烦点赞、收藏、评论,给我点小小鼓励!!!点关注就最好了
Spring AI 1.0.0源码:GitHub
本文代码:GitHub
二、前期准备
2.1 运行环境
Spring AI基于Sping Boot 3.x
版本及以上,本文选取3.4.5
(Spring AI 1.0.0源码为3.4.5),需要JDK 17
以上,JDK 8需要升级,也可以配置双jdk环境,具体配置如下图,谁排在Path
环境中的前面谁的优先级高
2.2 maven配置
maven的setting.xml文件中需要添加快照仓库
<profile><id>spring-snapshots</id><repositories><repository><id>spring-snapshots</id><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots><releases><enabled>false</enabled></releases></repository></repositories></profile></profiles><activeProfiles><activeProfile>spring-snapshots</activeProfile></activeProfiles>
2.3 api-key申请
Spring AI提供多种类型的模型,包括聊天模型、嵌入模型、图像模型、音频模型、内容审核模型等。提供了多家 AI 提供商的便携式 Model API,例如:Claude、OpenAI、DeepSeek、ZhiPu等等
例如聊天模型,又会有许多的实现
聊天模型对比
此表格比较了 Spring AI 支持的各种聊天模型,详细说明了它们的功能:
-
多模态: 模型可以处理的输入类型(例如,文本、图像、音频、视频)。
-
工具/函数调用: 模型是否支持函数调用或工具使用。
-
流式响应: 模型是否提供流式响应。
-
重试: 是否支持重试机制。
-
可观测性: 用于监控和调试的功能。
-
内置 JSON: 原生支持 JSON 输出。
-
本地部署: 模型是否可以在本地运行。
-
OpenAI API 兼容性: 模型是否兼容 OpenAI 的 API。
提供商 | 多模态 | 工具/函数 | 流式响应 | 重试 | 可观测性 | 内置 JSON | 本地 | OpenAI API 兼容 |
---|---|---|---|---|---|---|---|---|
Anthropic Claude | 文本、PDF、图像 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Azure OpenAI | 文本、图像 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
DeepSeek (OpenAI-proxy) | 文本 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Google VertexAI Gemini | 文本、PDF、图像、音频、视频 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
Groq (OpenAI-proxy) | 文本、图像 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
HuggingFace | 文本 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
Mistral AI | 文本、图像 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
MiniMax | 文本 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | |
Moonshot AI | 文本 | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ | |
NVIDIA (OpenAI-proxy) | 文本、图像 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
OCI GenAI/Cohere | 文本 | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
Ollama | 文本、图像 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
OpenAI | 输入:文本、图像、音频 输出:文本、音频 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
Perplexity (OpenAI-proxy) | 文本 | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
QianFan | 文本 | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
ZhiPu AI | 文本 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Amazon Bedrock Converse | 文本、图像、视频、文档(PDF、HTML、MD、DOCX…) | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
本文采用DeepSeek用于聊天模型,ZhiPu用户文生图模型,其他模型同理
DeepSeek api-key获取:https://platform.deepseek.com/api_keys,DeepSeek创建完需要充值
新用户可以使用ZhiPu,能白嫖!!!
ZhiPu api-key获取:https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys
三、Chat Client API
ChatClient
提供了一个流畅的 API 用于与 AI 模型进行通信。 它同时支持同步和流式编程模型。
3.1 导入pom依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- spring-web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- deepseek依赖 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-deepseek</artifactId></dependency><!-- zhipuai依赖 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.ai</groupId>-->
<!-- <artifactId>spring-ai-starter-model-zhipuai</artifactId>-->
<!-- </dependency>-->
</dependencies><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository><repository><name>Central Portal Snapshots</name><id>central-portal-snapshots</id><url>https://central.sonatype.com/repository/maven-snapshots/</url><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository>
</repositories><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0-SNAPSHOT</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
3.2 配置application.properties文件
spring:ai:deepseek:# API 密钥api-key: <your-deepseek-api-key># 可选:DeepSeek API 基础地址,默认是 https://api.deepseek.com# base-url: https://api.deepseek.comchat:options:# DeepSeek 使用的聊天模型,可选 deepseek-chat 或 deepseek-reasoner# deepseek-chat为聊天模型,deepseek-reasoner为推理模型,推理模型会生成推理过程,比较消耗tokenmodel: deepseek-chat# 模型的温度值,控制生成文本的随机性(0.0 = 最确定,1.0 = 最随机)temperature: 0.8
3.3 创建 ChatClient
ChatClient 是使用 ChatClient.Builder
对象创建的。 可以为任何 ChatModel
Spring Boot 自动配置获取一个自动配置的 ChatClient.Builder
实例,或者以编程方式创建一个。由于依赖中导入了DeepSeek,会默认采用DeepSeek模型。
3.3.1 使用自动配置的 ChatClient.Builder
Spring AI 提供了 Spring Boot 自动配置,创建一个原型 ChatClient.Builder
bean,可以将其注入到的类中。 以下是一个简单的示例,展示如何获取对简单用户请求的 String
响应:
@RestController
public class ChatClientController {private final ChatClient chatClient;public ChatClientController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@GetMapping("/ai")String generation(@RequestParam("userInput") String userInput) {return this.chatClient.prompt().user(userInput).call().content();}
}
在这个简单的示例中,用户输入设置了用户消息的内容。 call()
方法向 AI 模型发送请求,content()
方法返回 AI 模型的响应作为 String。
3.3.2 使用多个聊天模型
在单个应用程序中使用多个聊天模型有几种场景:
-
为不同类型的任务使用不同的模型(例如,
使用强大的模型进行复杂推理,使用更快、更便宜的模型处理简单任务
) -
当一个模型服务不可用时实现回退机制
-
对不同的模型或配置进行 A/B 测试
-
根据用户偏好提供模型选择
-
组合专业模型(一个用于代码生成,另一个用于创意内容等)
默认情况下,Spring AI 自动配置单个 ChatClient.Builder
bean。但是,可能需要在应用程序中使用多个聊天模型。以下是处理这种情况的方法:
在所有情况下,都需要通过设置属性 spring.ai.chat.client.enabled=false
来禁用 ChatClient.Builder
自动配置。
这允许手动创建多个 ChatClient
实例。
引入ZhiPu
model依赖和配置
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-zhipuai</artifactId>
</dependency>
spring:ai:# 禁用默认的 Chat Clientchat:client:enabled: falsezhipuai:# ZhiPu AI 的 API 密钥api-key: 49dadd9c9d504acbb60580f6d53cf30b.vlX0Fp67MTwxdZ5i# ZhiPu AI 的接口基础地址base-url: https://open.bigmodel.cn/api/paas# ZhiPu AI 的聊天模型配置chat:options:# 可选模型如 glm-4-air、glm-4、glm-3-turbo 等model: glm-4-air# 文生图模型(如需启用,取消注释并设置模型名称,如 cogview-3)# image:# options:# model: cogview-3# 嵌入模型(如需启用,取消注释并设置模型名称,如 embedding-2)# embedding:# options:# model: embedding-2
当使用多个 AI 模型时,可以为每个模型定义单独的 ChatClient
bean:
@Configuration
public class ChatClientConfig {/*** 创建并配置一个ChatClient实例* 该方法通过注入的DeepSeekChatModel对象初始化一个ChatClient* 主要作用是将聊天模型与客户端进行绑定,以便进行后续的聊天操作** @param chatModel 聊天模型,包含了聊天所需的配置和参数* @return 返回配置好的ChatClient实例*/@Beanpublic ChatClient deepSeekChatClient(DeepSeekChatModel chatModel) {return ChatClient.create(chatModel);}/*** 创建ChatClient实例的Bean定义* 该方法将ZhiPuAiChatModel转换为ChatClient实例,供Spring框架管理** @param chatModel 聊天模型,包含了与聊天客户端相关的信息和配置* @return ChatClient实例,用于与AI聊天服务进行交互*/@Beanpublic ChatClient zhiPuAiChatClient(ZhiPuAiChatModel chatModel) {return ChatClient.create(chatModel);}
}
然后,可以使用 @Qualifier
注解将这些 bean 注入到应用程序组件中:
@Configuration
public class ChatClientExample {@BeanCommandLineRunner cli(@Qualifier("deepSeekChatClient") ChatClient deepSeekChatClient,@Qualifier("zhiPuAiChatClient") ChatClient zhiPuAiChatClient) {return args -> {var scanner = new Scanner(System.in);ChatClient chat;// 模型选择System.out.println("\n选择您的 AI 模型:");System.out.println("1. DeepSeek");System.out.println("2. ZhiPuAi");System.out.print("输入您的选择(1 或 2):");String choice = scanner.nextLine().trim();if (choice.equals("1")) {chat = deepSeekChatClient;System.out.println("使用 OpenAI 模型");} else {chat = zhiPuAiChatClient;System.out.println("使用 Anthropic 模型");}// 使用选定的聊天客户端System.out.print("\n输入您的问题:");String input = scanner.nextLine();String response = chat.prompt(input).call().content();System.out.println("助手:" + response);scanner.close();};}
}
DeepSeek
执行结果:
ZhiPu Ai
执行结果:
3.4 ChatClient请求
ChatClient
请求允许使用重载的 prompt
方法以三种不同的方式创建提示:
-
prompt()
:无参数方法。 -
prompt(Prompt prompt)
:这个方法接受一个Prompt
参数,让传入使用Prompt
创建Prompt
实例。 -
prompt(String content)
:这是一个类似于前一个重载的便捷方法。它接受用户的文本内容。
关于提示词的内容,我们下一篇博客,详细讲解
3.5 ChatClient 响应
ChatClient API
提供了几种使用 AI 模型响应的方法。
3.5.1 返回 ChatResponse
AI 模型的响应是一个由 ChatResponse
类型定义的丰富结构。 它包括有关如何生成响应的元数据,还可以包含多个响应,称为 Generations
,每个都有自己的元数据。 元数据包括用于创建响应的令牌数量(每个令牌大约是一个单词的 3/4)。 这些信息很重要,因为托管 AI 模型根据每个请求使用的令牌数量收费。
以下示例通过调用 call()
方法后的 chatResponse()
返回包含元数据的 ChatResponse
对象:
@RestController
public class ChatClientResponseController {private final ChatClient deepSeekChatClient;@Autowiredpublic ChatClientResponseController(@Qualifier("deepSeekChatClient") ChatClient deepSeekChatClient) {this.deepSeekChatClient = deepSeekChatClient;}@GetMapping("/ai/chat-client-response")ChatResponse generation() {return deepSeekChatClient.prompt().user("给我讲个笑话").call().chatResponse();}
}
执行结果:
Token统计详情:
- 输入:“讲个笑话” -> 7 tokens
- 输出:笑话内容 -> 63 tokens
- 计费依据:总tokens = 7 + 63 -> 70
关键字段说明:
finishReason
:- STOP:正常结束
- LENGTH:达到token限制
- CONTENT_FILTER:内容被过滤
- TOOL_CALLS:该模型为工具
- TOOL_CALL:仅用于与 Mistral AI API 兼容
- role:标志消息来源
- SYSTEM
- USER
- ASSISTANT
- TOOL
3.5.2 返回实体
通常希望返回一个从返回的 String
映射的实体类。 entity()
方法提供了这个功能。
首先我们定义一个ActorFilms
实体类:
public class ActorsFilms {private String actor;private List<String> movies;public ActorsFilms() {}public String getActor() {return this.actor;}public void setActor(String actor) {this.actor = actor;}public List<String> getMovies() {return this.movies;}public void setMovies(List<String> movies) {this.movies = movies;}@Overridepublic String toString() {return "ActorsFilms{" + "actor='" + this.actor + '\'' + ", movies=" + this.movies + '}';}
}
我们可以使用 entity()
方法轻松地将 AI 模型的输出String字符串映射到这个 ActorsFilms实体,如下所示:
@GetMapping("/ai/chat-client-response-entity")
ActorsFilms generation_entity() {return deepSeekChatClient.prompt().user("生成一个随机演员的电影作品。").call().entity(ActorsFilms.class);
}
运行结果:
还有一个重载的 entity
方法,参数为 entity(ParameterizedTypeReference<T> type)
,允许指定泛型列表等类型:
@GetMapping("/ai/chat-client-response-entity/list")
List<ActorsFilms> generation_entity_list() {return deepSeekChatClient.prompt().user("生成成龙和李连杰的 5 部电影作品。").call().entity(new ParameterizedTypeReference<List<ActorsFilms>>() {});
}
运行结果:
3.5.3 流式响应
stream()
方法让可以获得异步响应,如下所示:
@GetMapping("/ai/flux")
Flux<String> gen_flux() {return deepSeekChatClient.prompt().user("给我讲个笑话").stream().content();
}
运行结果:
还可以使用方法 Flux<ChatResponse> chatResponse()
流式传输 ChatResponse
。道理同上
还可以通过结构化输出转换器
显示的转换响应,其中结构化输出转换器
在后面的文章中会详细讲解
@GetMapping("/ai/struct/flux")
List<ActorsFilms> gen_struct_flux() {var converter = new BeanOutputConverter<>(new ParameterizedTypeReference<List<ActorsFilms>>() {});Flux<String> flux = deepSeekChatClient.prompt().user(u -> u.text("""生成一个随机演员的电影作品。{format}""").param("format", converter.getFormat())).stream().content();String content = flux.collectList().block().stream().collect(Collectors.joining());List<ActorsFilms> actorFilms = converter.convert(content);return actorFilms;
}
运行结果:
3.6 提示模板
ChatClient
API 允许提供带有变量的用户和系统文本作为模板,这些变量在运行时被替换。
String answer = ChatClient.create(chatModel).prompt().user(u -> u.text("告诉我 5 部由 {composer} 主演的电影").param("actor", "成龙")).call().content();
在内部,ChatClient
使用 PromptTemplate
类来处理用户和系统文本,并使用给定的 TemplateRenderer
实现替换变量。 默认情况下,Spring AI 使用 StTemplateRenderer
实现,它基于 Terence Parr 开发的开源 StringTemplate
引擎。
如果想使用不同的模板引擎,可以直接向 ChatClient
提供 TemplateRenderer
接口的自定义实现。也可以继续使用默认的 StTemplateRenderer
,但使用自定义配置。
例如,默认情况下,模板变量由 {}
语法标识。如果计划在提示中包含 JSON
,可能想使用不同的语法以避免与 JSON
语法冲突。例如,可以使用 <
和 >
分隔符。
String answer = ChatClient.create(chatModel).prompt().user(u -> u.text("告诉我 5 部由 <composer> 主演的电影").param("actor", "成龙")).templateRenderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build()).call().content();
3.6 call() 返回值
在 ChatClient
上指定 call()
方法后,响应类型有几种不同的选项。
-
String content()
:返回响应的 String 内容 -
ChatResponse chatResponse()
:返回包含多个生成以及有关响应的元数据的ChatResponse
对象,例如创建响应使用了多少令牌。 -
ChatClientResponse chatClientResponse()
:返回一个ChatClientResponse
对象,其中包含ChatResponse
对象和ChatClient
执行上下文,让可以访问在执行advisors
期间使用的其他数据(例如,在RAG
流程中检索的相关文档)。 -
entity()
返回 Java 类型-
entity(ParameterizedTypeReference<T> type)
:用于返回实体类型的Collection
。 -
entity(Class<T> type)
:用于返回特定的实体类型。 -
entity(StructuredOutputConverter<T> structuredOutputConverter)
:用于指定StructuredOutputConverter
的实例,将 String 转换为实体类型。
-
也可以调用 stream()
方法而不是 call()
。
3.7 stream() 返回值
在 ChatClient
上指定 stream()
方法后,响应类型有几种选项:
-
Flux<String> content()
:返回 AI 模型生成的字符串的Flux
。 -
Flux<ChatResponse> chatResponse()
:返回ChatResponse
对象的Flux
,其中包含有关响应的其他元数据。 -
Flux<ChatClientResponse> chatClientResponse()
:返回ChatClientResponse
对象的Flux
,其中包含ChatResponse
对象和ChatClient
执行上下文,让可以访问在执行advisors
期间使用的其他数据(例如,在RAG
流程中检索的相关文档)。
3.8 使用默认值
在 @Configuration
类中创建带有默认系统文本的 ChatClient
可以简化运行时代码。 通过设置默认值,只需要在调用 ChatClient
时指定用户文本,无需在运行时代码路径中为每个请求设置系统文本。
3.8.1 默认系统文本
在以下示例中,我们将配置系统文本始终以海盗的声音回答。 为了避免在运行时代码中重复系统文本,创建一个 defaultTextChatClient
实例。
@Configuration
public class Config {@BeanChatClient defaultTextChatClient(@Qualifier("deepSeekChatModel") ChatModel chatModel) {return ChatClient.builder(chatModel).defaultSystem("你是一个友好的聊天机器人,用海盗的声音回答问题").build();}
}
以及一个调用它的 @RestController
:
@Resource
@Qualifier("defaultTextChatClient")
private ChatClient chatClient;@GetMapping("/ai/simple")
public Map<String, String> completion(@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message) {return Map.of("completion", this.chatClient.prompt().user(message).call().content());
}
运行结果:
3.8.2 带参数的默认系统文本
在以下例子中,将在系统文本中使用占位符,以便在运行时而不是设计时指定完成的声音。
@Bean
ChatClient withParamTextChatClient(@Qualifier("deepSeekChatModel") ChatModel chatModel) {return ChatClient.builder(chatModel).defaultSystem("你是一个友好的聊天机器人,用 {voice} 的声音回答问题").build();
}
@Resource
@Qualifier("withParamTextChatClient")
private ChatClient withParamTextChatClient;@GetMapping("/ai/withParamTextChatClient")
Map<String, String> withParamTextChatClientCompletion(@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message, @RequestParam(value = "voice", defaultValue = "语文老师") String voice) {return Map.of("completion",this.withParamTextChatClient.prompt().system(sp -> sp.param("voice", voice)).user(message).call().content());
}
运行结果:
3.8.3 其他默认值
在 ChatClient.Builder
中,可以指定默认的提示配置。
-
defaultOptions(ChatOptions chatOptions)
:传入ChatOptions
类中定义的便携选项或特定于模型的选项,如OpenAiChatOptions
中的选项。有关特定于模型的ChatOptions
实现的更多信息。 -
defaultFunction(String name, String description, java.util.function.Function<I, O> function)
:name
用于在用户文本中引用函数。description
解释函数的用途,帮助 AI 模型选择正确的函数以获得准确的响应。function
参数是模型在需要时将执行的 Java 函数实例。 -
defaultFunctions(String… functionNames)
:在应用程序上下文中定义的java.util.Function
的 bean 名称。 -
defaultUser(String text), defaultUser(Resource text), defaultUser(Consumer<UserSpec> userSpecConsumer)
:这些方法定义用户文本。Consumer<UserSpec>
允许使用 lambda 来指定用户文本和任何默认参数。 -
defaultAdvisors(Advisor… advisor)
:Advisors
允许修改用于创建 Prompt 的数据。QuestionAnswerAdvisor
实现通过将提示附加与用户文本相关的上下文信息来启用Retrieval Augmented Generation
模式。 -
defaultAdvisors(Consumer<AdvisorSpec> advisorSpecConsumer)
:此方法允许定义一个Consumer
来使用AdvisorSpec
配置多个advisors
。Advisors
可以修改用于创建最终Prompt
的数据。Consumer<AdvisorSpec>
指定一个 lambda 来添加 advisors,如QuestionAnswerAdvisor
,它通过将提示附加基于用户文本的相关上下文信息来支持Retrieval Augmented Generation
。
可以在运行时使用不带 default
前缀的相应方法覆盖这些默认值。
-
options(ChatOptions chatOptions)
-
function(String name, String description, java.util.function.Function<I, O> function)
-
functions(String… functionNames)
-
user(String text), user(Resource text), user(Consumer<UserSpec> userSpecConsumer)
-
advisors(Advisor… advisor)
-
advisors(Consumer<AdvisorSpec> advisorSpecConsumer)
3.9 Advisors
Advisors API
提供了一种灵活而强大的方式来拦截、修改和增强 Spring 应用程序中的 AI 驱动交互。
在调用带有用户文本的 AI 模型时,一个常见的模式是将提示附加或增强上下文数据。
这种上下文数据可以是不同类型的。常见类型包括:
-
自己的数据
:这是 AI 模型没有训练过的数据。即使模型见过类似的数据,附加的上下文数据在生成响应时也会优先考虑。 -
对话历史
:聊天模型的 API 是无状态的。如果告诉 AI 模型一个标志,它不会在后续交互中记住。必须随每个请求发送对话历史,以确保在生成响应时考虑之前的交互。
3.9.1 ChatClient 中的 Advisor 配置
ChatClient API 提供了一个 AdvisorSpec
接口用于配置 advisors。这个接口提供了添加参数、一次性设置多个参数以及向链中添加一个或多个 advisors 的方法。
重要:将 advisors 添加到链中的顺序至关重要,因为它决定了它们的执行顺序。每个 advisor 都以某种方式修改提示或上下文,一个 advisor 所做的更改会传递给链中的下一个。
ChatClient.builder(chatModel).build().prompt().advisors(MessageChatMemoryAdvisor.builder(chatMemory).build(),QuestionAnswerAdvisor.builder(vectorStore).build()).user(userText).call().content();
在此配置中,MessageChatMemoryAdvisor
将首先执行,将对话历史添加到提示中。然后,QuestionAnswerAdvisor
将基于用户的问题和添加的对话历史执行其搜索,可能提供更相关的结果。其中的聊天记忆等在后面文章做详细讲解,这里知道advisors
特性即可
3.9.2 日志记录
SimpleLoggerAdvisor
是一个记录 ChatClient
的 request
和 response
数据的 advisor。 这对于调试和监控的 AI 交互很有用。
提示:Spring AI 支持 LLM 和向量存储交互的可观察性
。具体讲解见后续文章
要启用日志记录,在创建 ChatClient 时将 SimpleLoggerAdvisor
添加到 advisor 链中。 建议将其添加到链的末尾:
@GetMapping("/ai/log")
ChatResponse gen_log() {return deepSeekChatClient.prompt().advisors(new SimpleLoggerAdvisor()).user("给我讲个笑话?").call().chatResponse();
}
要查看日志,将 advisor 包的日志级别设置为 DEBUG
:
logging.level.org.springframework.ai.chat.client.advisor=DEBUG
将此添加到 application.properties
或 application.yaml
文件中。
可以通过使用以下构造函数自定义从 AdvisedRequest
和 ChatResponse
记录的哪些数据:
使用示例:
SimpleLoggerAdvisor customLogger = new SimpleLoggerAdvisor(request -> "自定义请求:" + request.userText,response -> "自定义响应:" + response.getResult()
);
运行结果:
到此,Spring AI中的Chat Client部分讲解完成,下一篇讲解Prompt
!
创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️
相关文章:

【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(1)——Chat Client API
Spring AI框架快速入门 一、前言二、前期准备2.1 运行环境2.2 maven配置2.3 api-key申请 三、Chat Client API3.1 导入pom依赖3.2 配置application.properties文件3.3 创建 ChatClient3.3.1 使用自动配置的 ChatClient.Builder3.3.2 使用多个聊天模型 3.4 ChatClient请求3.5 Ch…...

【笔记】在 MSYS2(MINGW64)中正确安装 Rust
#工作记录 1. 环境信息 Windows系统: MSYS2 MINGW64当前时间: 2025年6月1日Rust 版本: rustc 1.87.0 (17067e9ac 2025-05-09) (Rev2, Built by MSYS2 project) 2. 安装步骤 步骤 1: 更新系统包数据库并升级已安装的包 首先,确保我们的 MSYS2 系统是最新状态。打…...

从汇编的角度揭秘C++引用,豁然开朗
C中的引用是指已有对象的别名,可以通过该别名访问并修改被引用的对象。那么其背后的原理是什么呢?引用是否会带来额外的开销呢?我们从一段代码入手,来分析一下引用的本质。 #include <stdio.h> int main() {int a 10;int …...
设计模式系列(07):建造者模式(Builder)
本文为设计模式系列第7篇,聚焦创建型模式中的建造者模式,涵盖定义、原理、实际业务场景、优缺点、最佳实践及详细代码示例,适合系统学习与实战应用。 目录 1. 模式概述2. 使用场景3. 优缺点分析4. 实际应用案例5. 结构与UML类图6. 代码示例7…...
Maven 项目中集成数据库文档生成工具
在 Maven 项目中,可以通过集成 数据库文档生成工具(如 screw-maven-plugin、mybatis-generator 或 liquibase)来自动生成数据库文档。以下是使用 screw-maven-plugin(推荐)的完整配置步骤: 1. 添加插件配置…...

聊聊Tomato Architecture
序 本文主要研究一下Tomato Architecture Clean/Onion/Hexagonal/Ports&Adapters Architectures Clean Architecture clean architecture定义了四层结构,最内层是entities(enterprise business rules),再往外是use cases(application business ru…...

小白的进阶之路系列之十二----人工智能从初步到精通pytorch综合运用的讲解第五部分
在本笔记本中,我们将针对Fashion-MNIST数据集训练LeNet-5的变体。Fashion-MNIST是一组描绘各种服装的图像瓦片,有十个类别标签表明所描绘的服装类型。 # PyTorch model and training necessities import torch import torch.nn as nn import torch.nn.functional as F impor…...
Java并发编程实战 Day 6:Future与异步编程模型
【Java并发编程实战 Day 6】Future与异步编程模型 在今天的课程中,我们将深入学习Java中的Future与异步编程模型。这是为期30天的"Java并发编程实战"系列的第6天。 理论基础 Future接口 Future接口是Java提供的用于表示异步计算的结果。它提供了以下方…...
.NET Core 中预防跨网站请求伪造 (XSRFCSRF) 攻击
.NET Core 中预防跨网站请求伪造 (XSRF/CSRF) 攻击 在如今的网络环境中,安全问题一直是开发者们不可忽视的重要方面。跨网站请求伪造(Cross-Site Request Forgery,简称 CSRF)就是一种常见且具有威胁性的网络攻击方式。攻击者通过…...
MFC Resource.h 文件详解与修改指南
MFC Resource.h 文件详解与修改指南 Resource.h 是 Visual C 和 MFC 项目中用于集中管理资源标识符(Resource ID)的头文件。它由 Visual Studio 的资源编辑器自动生成并维护,也可以手动编辑。理解并合理使用该文件对于管理对话框、控件、菜单…...

2025年06月03日Github流行趋势
项目名称:onlook 项目地址url:https://github.com/onlook-dev/onlook项目语言:TypeScript历史star数:12871今日star数:624项目维护者:Kitenite, drfarrell, spartan-vutrannguyen, apps/devin-ai-integrati…...
AI视频编码器(0.4.3) 调试训练bug——使用timm SoftTargetCrossEntropy时出现loss inf
检查过程 进入loss内部实现: > /root/miniconda3/envs/UMT2/lib/python3.9/site-packages/timm/loss/cross_entropy.py(35...

【数据分析】基于Cox模型的R语言实现生存分析与生物标志物风险评估
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理生存分析画图输出图片其他标记物的分析总结系统信息介绍 分析生存数据与多种生物标志物之间的关系。它通过Cox比例风险模型来评估不同生物标志物…...

使用nginx配置反向代理,负载均衡
首先啥叫反向代理 咋配置呢,那当然是在nginx目录下改conf文件了 具体咋改呢,那就新增一个新的server配置,然后在location里新增你想代理的服务器 实际上负载均衡也就是根据反向代理的思路来的,如下所示 配置的话实际上也与上…...

从 iPhone 备份照片: 保存iPhone图片的5种方法
随着智能手机越来越融入我们的生活,我们的照片已成为我们设备上最有价值的数据形式之一。然而,iPhone内部存储空间仍然有限,因此我们需要将iPhone中的照片备份到另一个地方,以释放空间并确保珍贵的图像记忆的安全。阅读本指南&…...

Spring Ai 从Demo到搭建套壳项目(一)初识与实现与deepseek对话模式
前言 为什么说Java长青,主要是因为其生态圈完善,Spring又做了一款脚手架,把对接各个LLM厂商的sdk做了一遍,形成一系列的spring-ai-starter-** 的依赖。 目前为止版本去到1.0.0.M6,golang跟不上了吧, Make …...

快速上手pytest
1. pytest的基础 1.1 什么是pytest pytest 是 python 中的一个测试框架,用于编写简洁、可扩展的测试代码,帮助开发者验证结果是否与预期相符。 python 中有很多的测试框架,那我们为什么要学习 pytest 呢? pytest 的优势&…...

设备驱动与文件系统:02 键盘
操作系统中键盘驱动的讲解 在这一讲中,我将为大家讲解键盘相关内容。从上一讲开始,我们进入了操作系统第四个部分的学习,也就是操作系统对设备的驱动与管理。 上一讲我们探讨的是显示器,并且提到,一个终端设备是由显示…...
matlab分布式电源接入对配电网的影响
MATLAB仿真的分布式电源接入对于配电网的影响,潮流计算加了固定的pq 分布式电源接入对配电网的影响/bustypes.m , 1004 分布式电源接入对配电网的影响/case34.m , 5385 分布式电源接入对配电网的影响/case9.m , 1366 分布式电源接入对配电网的影响/dSbus_dV.m , 14…...
前端ul-image的src接收base64快捷写法
前端ul-image的src接收base64快捷写法 data:image/png;base64,你的base64数据 注意如果是jpg就改成jpg,中间的逗号格式要注意,/注意不要反了 假设后端返回的detail中的url已经是base64格式,下面是示例 <u-image height"120rpx"…...

交通违法拍照数据集,可识别接打电话,不系安全带的行为,支持YOLO,COCO JSON,VOC XML格式的标注数据集 最高正确识别率可达88.6%
交通违法拍照数据集 数据集概述 数据来源:交通监控摄像头、执法记录仪、公开数据集数据类型:图像、视频、元数据(时间、地点、车辆信息)违法类型标注:接打电话、未系安全带 数据采集与标注方法 采集设备࿱…...

Qt OpenGL 3D 编程入门
Qt 提供了强大的 OpenGL 集成功能,使得在 Qt 应用中实现 3D 图形变得更加简单。以下是使用 Qt 进行 OpenGL 3D 编程的基础知识。 1. 环境配置 创建 Qt 项目 新建 Qt Widgets Application 项目 在 .pro 文件中添加 OpenGL 模块: qmake QT co…...

性能优化 - 工具篇:基准测试 JMH
文章目录 Pre引言1. JMH 简介2. JMH 执行流程详解3. 关键注解详解3.1 Warmup3.2 Measurement3.3 BenchmarkMode3.4 OutputTimeUnit3.5 Fork3.6 Threads3.7 Group 与 GroupThreads3.8 State3.9 Setup 与 TearDown3.10 Param3.11 CompilerControl 4. 示例代码与分析4.1 关键点解读…...
Ubuntu 中安装 PostgreSQL 及常规操作指南
目录 一、安装 PostgreSQL 最新版本安装(推荐) 安装特定版本(如 14) 二、基本服务管理 三、连接数据库 四、常规数据库操作 1. 用户与权限管理 2. 数据库管理 3. 表操作 4. 数据操作 五、常用 psql 元命令 六、备份与恢…...

Nginx网站服务:从入门到LNMP架构实战
🏡作者主页:点击! Nginx-从零开始的服务器之旅专栏:点击! 🐧Linux高级管理防护和群集专栏:点击! ⏰️创作时间:2025年5月30日14点22分 前言 说起Web服务器,…...

Java面试八股--08-数据结构和算法篇
1、怎么理解时间复杂度和空间复杂度 时间复杂度和空间复杂度一般是针对算法而言,是衡量一个算法是否高效的重要标准。先纠正一个误区,时间复杂度并不是算法执行的时间,在纠正一个误区,算法不单单指冒泡排序之类的,一个…...

Java面试八股--06-Linux篇
目录 一、Git 1、工作中git开发使用流程(命令版本描述) 2.Reset与Rebase,Pull与Fetch的区别 3、git merge和git rebase的区别 4、git如何解决代码冲突 5、项目开发时git分支情况 二、Linux 1、Linux常用的命令 2、如何查看测试项目的…...
Ajax技术分析方法全解:从基础到企业级实践(2025最新版)
引言 Ajax技术自2005年正式命名以来,已支撑全球83%的Web应用实现异步交互。2025年最新数据显示,单页面应用(SPA)的Ajax请求密度已达日均120亿次/应用。本文将系统化解析Ajax分析方法论,涵盖从基础原理到企业级工程实践的完整技术栈。 一、Ajax技术架构解构 1.1 核心组件…...
Unity 性能优化终极指南 — GameObject 篇
🎯 Unity 性能优化终极指南 — GameObject 方法篇 🧩 GameObject 是什么?—— Unity世界的核心实体 GameObject 是 Unity 引擎中最核心、最基础的构建单元。它代表了场景中的一个实体对象,可以是一个角色、一个UI元素、一盏灯光、…...

dvwa7——SQL Injection
LOW: f12打开hackbar 一:判断注入类型 输入id1报错 闭合单引号 ,页面恢复正常 所以为单引号字符型 二:开始攻击 1.判断列数 ?id1 order by 2-- 到3的时候开始报错,所以一共两列 2.爆回显位置 ?id-1 union s…...