【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(1)——Chat Client API

article/2025/6/6 1:17:45

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 项目,如 LangChainLlamaIndex,但 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 配置多个 advisorsAdvisors 可以修改用于创建最终 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 是一个记录 ChatClientrequestresponse 数据的 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.propertiesapplication.yaml 文件中。

可以通过使用以下构造函数自定义从 AdvisedRequestChatResponse 记录的哪些数据:

在这里插入图片描述
使用示例:

SimpleLoggerAdvisor customLogger = new SimpleLoggerAdvisor(request -> "自定义请求:" + request.userText,response -> "自定义响应:" + response.getResult()
);

运行结果:

在这里插入图片描述

到此,Spring AI中的Chat Client部分讲解完成,下一篇讲解Prompt

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

在这里插入图片描述


http://www.hkcw.cn/article/OfMmGCMTbo.shtml

相关文章

FreeRTOS的简单介绍

一、FreeRTOS介绍 FreeRTOS并不是实时操作系统&#xff0c;因为它是分时复用的 利用CubeMX快速移植 二、快速移植流程 1. 在 SYS 选项里&#xff0c;将 Debug 设为 Serial Wire &#xff0c;并且将 Timebase Source 设为 TIM2 &#xff08;其它定时器也行&#xff09;。为何…

Deepseek/cherry studio中的Latex公式复制到word中

需要将Deepseek/cherry studio中公式复制到word中&#xff0c;但是deepseek输出Latex公式&#xff0c;比如以下Latex代码段&#xff0c;需要通过Mathtype翻译才能在word中编辑。 $$\begin{aligned}H_1(k1) & H_1(k) \frac{1}{A_1} \left( Q_1 u_1(k) Q_{i1} - Q_2 u_2(k…

如何爬取google应用商店的应用分类呢?

以下是爬取Google Play商店应用包名(package name)和对应分类的完整解决方案&#xff0c;采用ScrapyPlaywright组合应对动态渲染页面&#xff0c;并处理反爬机制&#xff1a; 完整爬虫实现 1. 安装必要库 # 卸载现有安装pip uninstall playwright scrapy-playwright -y# 重新…

英福康INFICON VGC501, VGC502, VGC503 单通道、双通道和三通道测量装置

英福康INFICON VGC501, VGC502, VGC503 单通道、双通道和三通道测量装置

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…

JsonCpp 库如何集成到Visual studio

这是用于 在 C 中解析和生成 JSON 数据 的工具包&#xff0c;适合在需要与前端、网络、配置等 JSON 格式交互的 C 项目中使用。 Json&#xff08;基于JsonCpp&#xff09; 格式全称&#xff1a;JavaScript Object Notation 格式特点&#xff1a; 与开发语言无关轻量级的数据…

sourceinsight4.0不识别.cc解决办法

options—>preferences 选择 c language, 点击右边的 file types, 添加 ;*.cc即可 重新创建工程, 不仅有.cc, 还有.cc的目录结构

RNN结构扩展与改进:从简单循环网络到时间间隔网络的技术演进

本文系统介绍 RNN 结构的常见扩展与改进方案。涵盖 简单循环神经网络&#xff08;SRN&#xff09;、双向循环神经网络&#xff08;BRNN&#xff09;、深度循环神经网络&#xff08;Deep RNN&#xff09; 等多种变体&#xff0c;解析其核心架构、技术特点及应用场景&#xff0c;…

IBM DB2分布式数据库架构

一、什么是分布式数据库架构 分布式数据库架构是现代数据库系统的重要发展方向&#xff0c;特别适合处理大规模数据、高并发访问和高可用性需求的应用场景。下面我们从原理、架构模式、关键技术、实现方式和常见产品几个方面来系统讲 1、分布式数据库的基本概念与原理 1. 什…

第十三章 Java基础-特殊处理

文章目录 1.包和final2.权限修饰符和代码块3.抽象类1.包和final 2.权限修饰符和代码块 3.抽象类

Could not get unknown property ‘mUser‘ for Credentials [username: null]

最近遇到jekins打包报错&#xff1a; Could not get unknown property mUser for Credentials [username: null] of type org.gradle.internal.credentials.DefaultPasswordCredentials_Decorated。 项目使用的是gradle&#xff0c;通过pipeline打docker包&#xff1b;因为ma…

核显战3A,锐龙9000G系列CPU曝光

在刚过去不久的台北国际电脑展上&#xff0c;AMD 为大家带来了 RX 9060 XT、Radeon AI PRO R 9700 显卡以及线程撕裂者系列新品。 尽管狠活儿不少&#xff0c;但这场电脑展仍然让不少同学失望而归。 因为&#xff0c;原本预期亮相锐龙 9000G 系列桌面 APU 竟没有公布半点消息。…

[yolov11改进系列]基于yolov11引入空间通道系统注意力机制SCSA的python源码+训练源码

【SCSA介绍】 1、Spatial and Channel Synergistic Attention ​ 通道和空间注意力分别为各种下游视觉任务的特征依赖性和空间结构关系提取带来了显著的改进。虽然两者的组合更有利于发挥各自的优势&#xff0c;但通道和空间注意力之间的协同作用尚未得到充分探索&#xff0c…

穿越文件之海:Linux链接与库的奇幻旅程,软硬连接与动静态库

文章目录 引言1、软硬链接1.1、基本认知1.2、实现原理1.3、应用场景1.4、取消链接1.5、ACM时间 2、动静态库2.1、认识库2.2、库的作用 3、制作静态库3.2、静态库的使用 4、制作动态库4.1、动态库的打包4.3、动态库的链接原理 5、动态库知识补充 引言 在计算机的无形世界中&…

2024年认证杯SPSSPRO杯数学建模D题(第二阶段)AI绘画带来的挑战解题全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现&#xff1a; 2023 年开年&#xff0c;ChatGPT 作为一款聊天型AI工具&#xff0c;成为了超越疫情的热门词条&#xff1b;而在AI的另一个分支——绘图领域&#xff0c;一款名为Midjourney&#xff08;MJ&#xff…

6.3 计算机网络面试题

网络OSI模型和TCP/IP模型分别介绍一下 OSI 应用层&#xff1a;http htps DNS 为应用程序提供统一的接口表示层&#xff1a;将数据转换为兼容另一个系统能识别的格式会话层&#xff1a; 建立管理终止表示层实体之间的通信会话传输层: tcp udp 负责端到端的数据传输网络层: ip …

LeetCode 高频 SQL 50 题(基础版) 之 【高级查询和连接】· 下

上部分链接&#xff1a;LeetCode 高频 SQL 50 题&#xff08;基础版&#xff09; 之 【高级查询和连接】 上 题目&#xff1a;1164. 指定日期的产品价格 题解&#xff1a; select product_id,10 price from Products group by product_id having min(change_date) > 201…

ssm学习笔记day04

RequestMapping 首先添加依赖 Maven的配置 测试 在controller创建HelloController&#xff0c;如果只加RequestMapping&#xff0c;默认跳转到新页面 如果要是加上ResponseBody就把数据封装在包(JSON)&#xff0c;标签RestController是前后分离的注解&#xff08;因为默认用…

Spine工具入门教程4之网格与权重

1、概念 网格的定义&#xff1a; 启用网格&#xff0c;可以在图片内设置多边形&#xff0c;操纵多边形的顶点可以让图片变形。 权重的定义&#xff1a; 图解网格和权重的操作方法&#xff1a; 2、调整网格/权重 &#xff08;1&#xff09;设置网格 目前调整小臂骨骼对图片不…

吉他入门个人学习笔记

目录 一.一二期 1. 十二平均律 2.调音 3.弦数-音名-唱名 三.第三期 1.43231323训练 2.c大调二十四品常用音阶图 四.第四期 1.小星星 2.爬格子训练 五.第五期 六.第六期——大三和弦 和弦总览 1.C和弦 2.D和弦 3.E和弦 4.G和弦 5.A和弦 第七期.小三和弦 五百…