首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

8. Spring Ai之入门到精通(超级详细)

  • 25-03-04 10:31
  • 4412
  • 11643
blog.csdn.net

简介

        2024年5月30号Spring AI 的 1.0.0 里程碑 1 版本发布。表明版本已正在巩固,并且大部分主要错误和问题已经解决,API基本已确定,不会发生很大的变化。

       在与大模型集成方面,继LangChain4j之后,又一重大的框架诞生。标志着在人工智能的浪潮中,Java不会因此被边缘化,让生成式人工智能应用程序不仅适用于Python,也适用于Java。

Spring Ai官网:Spring AI

前置准备

        Spring Ai除了支持国外的大模型外,也支持国内很多大模型,比如清华的智普Ai,百度的千帆和月之暗面的 kimi。集成Spring Ai需要用到 api-key,大家按照自己的需要,去Ai开放平台申请。

        下面我主要用到OpenAi和智普Ai来讲解案例代码,OpenAi是国外的,需要我们要有个国外手机号(亚洲很多被封了,用不了),登录OpenAi官网创建apikey(需要用到魔法软件科学上网)。下面给出各个注册渠道.

Open-AI:

  • OpenAi-HK  GPT4.0 API KEY By OPENAI HK 中转ChatGPT  (本文用这种,不用翻)

  • AiCore API  New API

  • OpenAi购买平台 首页 | OpenAI_GPT4_购买平台_OpenAI API - eylink官网

ZhiPu-AI:

  • 官网 智谱AI开放平台

概念和案例实践

 新建SpringBoot工程,然后添加以下依赖:

  1. "1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <groupId>org.springframework.bootgroupId>
  7. <artifactId>spring-boot-starter-parentartifactId>
  8. <version>3.2.4version>
  9. parent>
  10. <modelVersion>4.0.0modelVersion>
  11. <groupId>org.gorgorgroupId>
  12. <artifactId>spring-ai-demoartifactId>
  13. <version>1.0-SNAPSHOTversion>
  14. <properties>
  15. <maven.compiler.source>17maven.compiler.source>
  16. <maven.compiler.target>17maven.compiler.target>
  17. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
  18. properties>
  19. <dependencyManagement>
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.aigroupId>
  23. <artifactId>spring-ai-bomartifactId>
  24. <version>1.0.0-M1version>
  25. <type>pomtype>
  26. <scope>importscope>
  27. dependency>
  28. dependencies>
  29. dependencyManagement>
  30. <dependencies>
  31. <dependency>
  32. <groupId>org.springframework.bootgroupId>
  33. <artifactId>spring-boot-starter-webartifactId>
  34. dependency>
  35. <dependency>
  36. <groupId>org.springframework.aigroupId>
  37. <artifactId>spring-ai-openai-spring-boot-starterartifactId>
  38. dependency>
  39. <dependency>
  40. <groupId>org.springframework.aigroupId>
  41. <artifactId>spring-ai-zhipuai-spring-boot-starterartifactId>
  42. dependency>
  43. dependencies>
  44. <repositories>
  45. <repository>
  46. <id>spring-milestonesid>
  47. <name>Spring Milestonesname>
  48. <url>https://repo.spring.io/milestoneurl>
  49. <snapshots>
  50. <enabled>falseenabled>
  51. snapshots>
  52. repository>
  53. <repository>
  54. <id>spring-snapshotsid>
  55. <name>Spring Snapshotsname>
  56. <url>https://repo.spring.io/snapshoturl>
  57. <releases>
  58. <enabled>falseenabled>
  59. releases>
  60. repository>
  61. repositories>
  62. project>

    添加application.yml配置文件

        需要配置智普api-key和openai api-key.

  1. server:
  2. port: 10096
  3. spring:
  4. application:
  5. name: ai-demo
  6. ai:
  7. zhipuai:
  8. api-key: ${ZHIPUAI_API_KEY}
  9. chat:
  10. options:
  11. model: glm-3-turbo
  12. embedding:
  13. enabled: false
  14. openai:
  15. api-key: ${OPENAI_API_KEY}
  16. base-url: https://api.openai-hk.com
  17. chat:
  18. options:
  19. model: gpt-4o-mini
  20. embedding:
  21. enabled: true
 1. ChatClient 和 ChatModel

        ChatClient是SpringAI 0.8.0版本的概念,到1.0.0版本变成了ChatModel,但同时保留了ChatClient,ChatClient底层还是调用ChatModel,ChatClient支持Fluent Api,ChatModel不支持。两者都是表示某个模型,具体是什么模型,需要看配置。

    基于ChatClient 和 ChatModel 实现聊天效果:

  1. @Configuration
  2. public class ChatConfig {
  3. @Autowired
  4. private OpenAiChatModel openAiChatModel;
  5. @Bean
  6. public ChatClient chatClient() {
  7. return ChatClient
  8. .builder(openAiChatModel)
  9. .build();
  10. }
  11. }

Controller层代码:

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private ChatClient chatClient;
  5. @Autowired
  6. private ZhiPuAiChatModel chatModel;
  7. @Autowired
  8. private OpenAiChatModel openAiChatModel;
  9. /**
  10. * openAi 聊天
  11. *
  12. * @param message
  13. * @return
  14. */
  15. @GetMapping("/ai/openAiChat")
  16. public Map openAiChat(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
  17. return Map.of("generation", openAiChatModel.call(message));
  18. }
  19. /**
  20. * zhipuAi 聊天
  21. *
  22. * @param message
  23. * @return
  24. */
  25. @GetMapping("/ai/generate")
  26. public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
  27. return Map.of("generation", chatModel.call(message));
  28. }
  29. /**
  30. * ChatClient使用(流式调用)
  31. * @param message
  32. * @param voice
  33. * @return
  34. */
  35. @GetMapping("/ai/chatClient")
  36. Map completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message, String voice) {
  37. return Map.of(
  38. "completion",
  39. chatClient.prompt()
  40. .system(sp -> sp.param("voice", voice))
  41. .user(message)
  42. .call()
  43. .content());
  44. }
  45. }
2. 文生图
  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private OpenAiImageModel imageModel;
  5. /**
  6. * 图片生成(文生图)
  7. *
  8. * @param message
  9. * @return
  10. */
  11. @GetMapping("/ai/imageGeneration")
  12. public Map imageGeneration(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
  13. OpenAiImageOptions imageOptions = OpenAiImageOptions.builder()
  14. .withQuality("hd")
  15. .withN(1)
  16. .withHeight(1024)
  17. .withWidth(1024).build();
  18. ImagePrompt imagePrompt = new ImagePrompt(message, imageOptions);
  19. ImageResponse response = imageModel.call(imagePrompt);
  20. return Map.of("generation", response.getResult().getOutput().getUrl());
  21. }
  22. }
3. 多模态

多模态(Multimodal)指的是数据或信息的多种表现形式。在人工智能领域,我们经常会听到这个词,尤其是在近期大型模型(如GPT-4)开始支持多模态之后。

  •  模态:模态是指数据的一种形式,例如文本、图像、音频等。每一种形式都是一种模态。
  • 多模态:多模态就是将不同模态的数据结合起来,以更全面、更丰富的方式来处理信息。比如,我们可以同时处理文本、图像、语音等多种类型的数据。

举个例子,如果我想告诉你“我有一个苹果”,我可以用文字写出来,也可以用语言说出来,还可以用图片画出来。这就是相同信息的多种模态表现形式。

同样地,给大模型一副图片,可以上大模型对这张图片进行详细地描述。给大模型一段文本,可以让大模型进行概要提取,内容总结等。

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private OpenAiChatModel openAiChatModel;
  5. /**
  6. * 多模态
  7. *
  8. * @param message
  9. * @return
  10. * @throws MalformedURLException
  11. */
  12. @GetMapping("/ai/multimodal")
  13. public String Multimodal(@RequestParam(value = "message", defaultValue = "解释一下你在这张图片上看到了什么?") String message) throws MalformedURLException {
  14. var userMessage = new UserMessage(message,
  15. List.of(new Media(MimeTypeUtils.IMAGE_PNG,
  16. new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png"))));
  17. ChatResponse response = openAiChatModel.call(new Prompt(List.of(userMessage),
  18. OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
  19. return response.getResult().getOutput().getContent();
  20. }
  21. }
4. 语音转文字

        语音文件需要在spring-ai中下载spring-ai/models/spring-ai-openai/src/test/resources/speech at main · spring-projects/spring-ai · GitHubAn Application Framework for AI Engineering. Contribute to spring-projects/spring-ai development by creating an account on GitHub.icon-default.png?t=N7T8https://github.com/spring-projects/spring-ai/tree/main/models/spring-ai-openai/src/test/resources/speech

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel;
  5. @Value("classpath:/speech/jfk.flac")
  6. private Resource audioFile;
  7. /**
  8. * 语音转文字
  9. */
  10. @GetMapping("/ai/audioTranscription")
  11. private String audioTranscription(){
  12. OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
  13. .withResponseFormat(OpenAiAudioApi.TranscriptResponseFormat.TEXT)
  14. .withTemperature(0f)
  15. .build();
  16. AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
  17. AudioTranscriptionResponse response = openAiAudioTranscriptionModel.call(transcriptionRequest);
  18. return response.getResult().getOutput();
  19. }
  20. }
5. Function Calling 工具调用

        大模型是基于历史数据进行训练的,回答我们的问题也是基于历史数据进行回复, 如果你想要大模型具备获取最新消息的能力, 此时,就需要用到工具机制,它能帮助大模型获取最新的数据消息.

Function Calling 工作原理图:

  执行流程,如下图:

  首先,当我们发送问题给大模型的时候,比如“今天是几号?”,大模型会响应一个结果给我们,这个结果不是问题的答案,而是大模型告诉我们需要执行哪个工具。我们执行工具后,才能得到问题的答案,但这个答案可能不太像人回复的,不太符合自然语言的样子,比如工具结果是“2024-07-13 11:23:00”,此时我们需要把问题,执行工具请求和工具执行结果一起发给大模型,得到最好的答案。

工具定义:

  • 实现 java.util.function.Function 接口
  • @Description注解: 注释是可选的,它提供了一个函数描述,帮助模型理解何时调用函数。它是一个重要的属性,可以帮助AI模型确定要调用的客户端函数。

  • @JsonClassDescription注解: 对方法进行描述.

  • @JsonPropertyDescription注解: 对参数进行描述.

 代码实现:

  1. @Component
  2. @Description("先获取指定地点,再获取当前时间")
  3. public class DateService implements Function {
  4. @JsonClassDescription("地点请求")
  5. public record Request(@JsonPropertyDescription("地点")String address) { }
  6. public record Response(String date) { }
  7. @Override
  8. public Response apply(Request request) {
  9. System.out.println(request.address);
  10. return new Response(String.format("%s的当前时间是%s", request.address, LocalDateTime.now()));
  11. }
  12. }

工具调用:

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private OpenAiChatModel openAiChatModel;
  5. /**
  6. * 工具调用
  7. */
  8. @GetMapping("/ai/function")
  9. public String function(@RequestParam String message) {
  10. Prompt prompt = new Prompt(message, OpenAiChatOptions.builder().withFunction("dateService").build());
  11. // Prompt prompt = new Prompt(message, OpenAiChatOptions.builder().withFunctionCallbacks(
  12. // List.of(FunctionCallbackWrapper.builder(new DateService())
  13. // .withName("dateService")
  14. // .withDescription("获取指定地点的当前时间").build())
  15. // ).build());
  16. Generation generation = openAiChatModel.call(prompt).getResult();
  17. return (generation != null) ? generation.getOutput().getContent() : "";
  18. }
  19. }
6.  Embeddings文本向量化

        什么叫向量?  向量可以理解为平面坐标中的一个坐标点(x,y),在编程领域,一个二维向量就是一个大小为float类型的数组。也可以用三维坐标系中的向量表示一个空间中的点.  而文本向量化是指,利用大模型可以把一个字,一个词或一段话映射为一个多维向量.

        为什么要向量化? 当我们把所有的文本生成向量后, 就可以利用向量的特点,进行相似度搜索.这种搜索算法比elasticsearch的分词算法更好.

Spring AI 支持的向量数据库:

  • Azure Vector Search - The Azure vector store.

  • Apache Cassandra - The Apache Cassandra vector store.

  • Chroma Vector Store - The Chroma vector store.

  • Elasticsearch Vector Store - The Elasticsearch vector store.

  • GemFire Vector Store - The GemFire vector store.

  • Milvus Vector Store - The Milvus vector store.

  • MongoDB Atlas Vector Store - The MongoDB Atlas vector store.

  • Neo4j Vector Store - The Neo4j vector store.

  • PgVectorStore - The PostgreSQL/PGVector vector store.

  • Pinecone Vector Store - PineCone vector store.

  • Qdrant Vector Store - Qdrant vector store.

  • Redis Vector Store - The Redis vector store.

  • SAP Hana Vector Store - The SAP HANA vector store.

  • Weaviate Vector Store - The Weaviate vector store.

  • SimpleVectorStore - A simple implementation of persistent vector storage, good for educational purposes.

以下我们使用Redis作为向量数据库

然后需要注意的是,普通的Redis是不支持向量存储和查询的,需要额外的redisearch模块,我这边是直接使用docker来运行一个带有redisearch模块的redis容器的,命令为:

docker run -p 6379:6379 redis/redis-stack-server:latest

注意端口6379不要和你现有的Redis冲突了。

引入redis依赖

  1. <dependency>
  2. <groupId>org.springframework.aigroupId>
  3. <artifactId>spring-ai-redis-storeartifactId>
  4. dependency>
  5. <dependency>
  6. <groupId>redis.clientsgroupId>
  7. <artifactId>jedisartifactId>
  8. <version>5.1.0version>
  9. dependency>

 定义向量模型和Redis向量数据库 Bean

  1. @Configuration
  2. public class RedisConfig {
  3. @Autowired
  4. private EmbeddingModel openAiEmbeddingModel;
  5. @Bean
  6. public RedisVectorStore vectorStore() {
  7. RedisVectorStore.RedisVectorStoreConfig config = RedisVectorStore.RedisVectorStoreConfig.builder()
  8. .withURI("redis://127.0.0.1:6379")
  9. // .withIndexName("rag_index")
  10. // .withPrefix("rag:")
  11. .withMetadataFields(
  12. RedisVectorStore.MetadataField.text("filename"),
  13. RedisVectorStore.MetadataField.text("question"))
  14. .build();
  15. return new RedisVectorStore(config, openAiEmbeddingModel,true);
  16. }
  17. @Bean
  18. public EmbeddingModel openAiEmbeddingModel() {
  19. // Can be any other EmbeddingModel implementation.
  20. return new OpenAiEmbeddingModel(new OpenAiApi(System.getenv("OPENAI_API_KEY")));
  21. }
  22. }

 定义向量存储和搜索核心逻辑代码

文本读取,解析和存储,SpringAi提供了以下核心概念:

Document

  1. DocumentReader:用来读取TXT、PDF等文件内容                                          
    • JsonReader:读取JSON格式的文件
    •  TextReader:读取txt文件
    • PagePdfDocumentReader:使用Apache PdfBox读取PDF文件
    • TikaDocumentReader:使用Apache Tika来读取PDF, DOC/DOCX, PPT/PPTX, and HTML等文件
  2. DocumentTransformer:用来解析文件内容
    • tokenTextSplitter:按照token进行解析。

  3. DocumentWriter:用来写入文件内容到向量数据库
    • VectorStore:DocumentWriter的子类。

流程如下:

  1. /**
  2. *
  3. *文本解析
  4. */
  5. public class CustomerTextSplitter extends TextSplitter {
  6. @Override
  7. protected List splitText(String text) {
  8. return List.of(split(text));
  9. }
  10. public String[] split(String text) {
  11. return text.split("\\s*\\R\\s*\\R\\s*");
  12. }
  13. }
  1. @Component
  2. public class DocumentService {
  3. @Value("classpath:meituan-qa.txt")
  4. private Resource resource;
  5. @Autowired
  6. private RedisVectorStore vectorStore;
  7. /**
  8. * 向量存储
  9. * @return
  10. */
  11. public List loadText() {
  12. //文本读取
  13. TextReader textReader = new TextReader(resource);
  14. textReader.getCustomMetadata().put("filename", "meituan-qa.txt");
  15. List documents = textReader.get();
  16. CustomerTextSplitter customerTextSplitter= new CustomerTextSplitter();
  17. List list = customerTextSplitter.apply(documents);
  18. // 把问题存到元数据中
  19. list.forEach(document -> document.getMetadata().put("question", document.getContent().split("\\n")[0]));
  20. // 向量存储(文本存储)
  21. vectorStore.add(list);
  22. return list;
  23. }
  24. /**
  25. * 向量搜索
  26. * @param message
  27. * @return
  28. */
  29. public List search(String message) {
  30. List documents = vectorStore.similaritySearch(message);
  31. return documents;
  32. }
  33. /**
  34. * 元数据搜索
  35. * @param message
  36. * @param question
  37. * @return
  38. */
  39. public List metadataSearch(String message, String question) {
  40. return vectorStore.similaritySearch(
  41. SearchRequest
  42. .query(message)
  43. // .withTopK(5)
  44. .withSimilarityThreshold(0.1)
  45. .withFilterExpression(String.format("question in ['%s']", question)));
  46. }
  47. }

   需要向量的文本 meituan-qa.txt

  1. Q:在线支付取消订单后钱怎么返还?
  2. 订单取消后,款项会在一个工作日内,直接返还到您的美团账户余额。
  3. Q:怎么查看退款是否成功?
  4. 退款会在一个工作日之内到美团账户余额,可在“账号管理——我的账号”中查看是否到账。
  5. Q:美团账户里的余额怎么提现?
  6. 余额可到美团网(meituan.com)——“我的美团→美团余额”里提取到您的银行卡或者支付宝账号,另外,余额也可直接用于支付外卖订单(限支持在线支付的商家)。
  7. Q:余额提现到账时间是多久?
  8. 1-7个工作日内可退回您的支付账户。由于银行处理可能有延迟,具体以账户的到账时间为准。
  9. Q:申请退款后,商家拒绝了怎么办?
  10. 申请退款后,如果商家拒绝,此时回到订单页面点击“退款申诉”,美团客服介入处理。
  11. Q:怎么取消退款呢?
  12. 请在订单页点击“不退款了”,商家还会正常送餐的。
  13. Q:前面下了一个在线支付的单子,由于未付款,订单自动取消了,这单会计算我的参与活动次数吗?
  14. 不会。如果是未支付的在线支付订单,可以先将订单取消(如果不取消需要15分钟后系统自动取消),订单无效后,此时您再下单仍会享受活动的优惠。
  15. Q:为什么我用微信订餐,却无法使用在线支付?
  16. 目前只有网页版和美团外卖手机App(非美团手机客户端)订餐,才能使用在线支付,请更换到网页版和美团外卖手机App下单。
  17. Q:如何进行付款?
  18. 美团外卖现在支持货到付款与在线支付,其中微信版与手机触屏版暂不支持在线支付。

    Controller层代码实现

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private DocumentService documentService;
  5. /**
  6. * 向量存储
  7. */
  8. @GetMapping("/ai/vectorStore")
  9. public Map vectorStore() {
  10. List documents = documentService.loadText();
  11. return Map.of("generation", documents);
  12. }
  13. /**
  14. * 向量搜索
  15. * @param message
  16. * @return
  17. */
  18. @GetMapping("/ai/documentSearch")
  19. public List documentSearch(@RequestParam String message) {
  20. return documentService.search(message);
  21. }
  22. /**
  23. * 元数据搜索
  24. * @param message
  25. * @param question
  26. * @return
  27. */
  28. @GetMapping("/ai/metadataSearch")
  29. public List documentMetadataSearch(@RequestParam String message, @RequestParam String question) {
  30. return documentService.metadataSearch(message, question);
  31. }
  32. }
7. RAG 检索增强生成

        RAG是什么?检索增强生成又是什么意思?大模型的知识仅限于它所训练的数据,如果你问大模型,你们公司的xxx产品有什么作用,大模型肯定会回答不出来。如果你想让大模型拥有你们公司知识库的数据, 此时就可以用到RAG。

        简单的讲,RAG的原理是,根据用户输入的问题,先从你们公司的知识库查询出答案,再把用户输的问题和搜索出来的答案,让大模型根据我们的答案回复用户的问题。

         而根据用户问题,从知识库搜索问题,需要用到上面所说的文本向量化。根据文本的相识度,从知识库中搜索出符合用户问题的答案出来。

RAG的工作原理

RAG的工作原理可以分为以下几个步骤:

1.接收请求:首先,系统接收到用户的请求(例如提出一个问题)。

2.信息检索(R):系统从一个大型文档库中检索出与查询最相关的文档片段。这一步的目标是找到那些可能包含答案或相关信息的文档。

3.生成增强(A):将检索到的文档片段与原始查询一起输入到大模型(如chatGPT)中,注意使用合适的提示词,比如原始的问题是XXX,检索到的信息是YYY,给大模型的输入应该类似于:请基于YYY回答XXXX。

4.输出生成(G):大模型基于输入的查询和检索到的文档片段生成最终的文本答案,并返回给用户。

RAG代码实现

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private OpenAiChatModel openAiChatModel;
  5. @Autowired
  6. private DocumentService documentService;
  7. /**
  8. * RAG
  9. * @param message
  10. * @return
  11. */
  12. @GetMapping("/ai/customerService")
  13. public String customerService(@RequestParam String message) {
  14. // 向量搜索
  15. List documentList = documentService.search(message);
  16. // 提示词模板
  17. PromptTemplate promptTemplate = new PromptTemplate("{userMessage}\n\n 用以下信息回答问题:\n {contents}");
  18. // 组装提示词
  19. Prompt prompt = promptTemplate.create(Map.of("userMessage", message, "contents", documentList));
  20. // 调用大模型
  21. return openAiChatModel.call(prompt).getResult().getOutput().getContent();
  22. }
  23. }

8. Advisor机制

        Advisor是Spring AOP中的概念, 一个Advisor表示一个切面, 由Advice和PointCut组成,Advice表示切面的逻辑, PointCut表示切点, 也就是切那些方法.而Spring AI也用了Advisor的设计思想, 也具备前置切面和后置切面.

8.1 QuestionAnswerAdvisor

QuestionAnswerAdvisor的作用是对问题请求进行增强,增强逻辑为:

  1. 根据原始问题进行相似度搜索,得到匹配知识点
  2. 拼接RAG提示词模板

评估模型代码如下:

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private ChatClient chatClient;
  5. @Autowired
  6. private RedisVectorStore vectorStore;
  7. @Autowired
  8. private OpenAiChatModel chatModel;
  9. /**
  10. * 模型评估
  11. */
  12. @GetMapping("/ai/evaluation")
  13. public EvaluationResponse evaluation(String message) {
  14. //RAG
  15. ChatResponse response = chatClient.prompt()
  16. .advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()))
  17. .user(message)
  18. .call()
  19. .chatResponse();
  20. // 评估器
  21. var relevancyEvaluator = new RelevancyEvaluator(ChatClient.builder(chatModel));
  22. // 评估请求
  23. EvaluationRequest evaluationRequest = new EvaluationRequest(message,
  24. (List) response.getMetadata().get(QuestionAnswerAdvisor.RETRIEVED_DOCUMENTS), response);
  25. // 评估结果
  26. EvaluationResponse evaluationResponse = relevancyEvaluator.evaluate(evaluationRequest);
  27. return evaluationResponse;
  28. }
  29. }

        后续Spring AI会根据增强后的请求进行提示词模版的变量填充,得到请求最终的提示词,并将请求发送给大模型,得到大模型的返回结果,QuestionAnswerAdvisor也会对返回结果进行增强,会把匹配的知识点放入ChatResponse的metadata中。 

8.2 MessageChatMemoryAdvisor

        是一种Advisor,也是用来增强问答请求和响应的,而其中另外一个概念就是ChatMemory,默认实现为InMemoryChatMemory,它可以用来按conversationId进行历史对话记录的存储。

  1. @RestController
  2. public class ChatDemoController {
  3. @Autowired
  4. private ChatClient chatClient;
  5. private InMemoryChatMemory chatMemory= new InMemoryChatMemory();
  6. /**
  7. * ChatMemory
  8. */
  9. @GetMapping("/ai/chatMemory")
  10. private String chatMemory(String message,String userId){
  11. ChatResponse response = chatClient.prompt()
  12. .advisors(new MessageChatMemoryAdvisor(chatMemory,userId,100))
  13. .system(sp -> sp.param("voice", "律师"))
  14. .user(message)
  15. .call()
  16. .chatResponse();
  17. return response.getResult().getOutput().getContent();
  18. }
  19. }

因此MessageChatMemoryAdvisor的作用就是将原始请求和向量添加到ChatMemory中。

8.3 PromptChatMemoryAdvisor

        也是用来记录历史对话记录的,和MessageChatMemoryAdvisor的不同点在于,MessageChatMemoryAdvisor是把每个历史请求和响应封装为Message增强到请求中,而PromptChatMemoryAdvisor是把所有请求和响应也会存到ChatMemory中,但是会把所有内容合并一条Message增强到请求中。

8.4 VectorStoreChatMemoryAdvisor

        这个就更加强大了,它既会进行RAG,也会把存储历史对话,只不过会把对话记录封装为Document存到向量数据库中。

文章知识点与官方知识档案匹配,可进一步学习相关知识
Java技能树首页概览151208 人正在系统学习中
注:本文转载自blog.csdn.net的gorgor在码农的文章"https://blog.csdn.net/weixin_46203834/article/details/140807594"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

103
后端
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top