什么是 Spring AI 以及如何使用它

liugddx 2024-07-16 15:01:02 阅读 67

什么是 Spring AI 以及如何使用它SpringAI 是一个强大的工具,可以帮助 Java 应用程序开发人员以与平台无关的方式使用 LLM。

icon-default.png?t=N7T8

https://mp.weixin.qq.com/s?__biz=MzIyMzg4NzU5MQ==&mid=2247483929&idx=1&sn=d87a65ad8835c84d08ede612885d3d85&chksm=e8162b91df61a287d2b306fb5050e1cc3e1b2eb71844ccbcb3c6d38ae4ab3a37744fe7bbf928&scene=126&sessionid=1718343231#rd

 

SpringAI 是一个强大的工具,可以帮助 Java 应用程序开发人员以与平台无关的方式使用 LLM。下面我会介绍怎么使用它。

全世界的开发者都在研究人工智能如何增强其应用程序。在本文中,我将介绍一个新的 Spring 项目,该项目为 Java 开发人员提供了方便的 API 抽象,以便使用 ChatGPT 等大型语言模型 (LLM)。最后,我将演示一个简单的程序,可以根据从微博检索到的信息回答有关的问题。

Spring AI 的由来

<code>Spring AI项目旨在简化包含人工智能功能的应用程序的开发,同时避免不必要的复杂性。

该项目从著名的 Python 项目(如 LangChain 和 LlamaIndex)中汲取灵感,但 Spring AI 并不是这些项目的直接移植。该项目成立的信念是,下一波生成式人工智能应用将不仅仅面向 Python 开发人员,而是将在许多编程语言中无处不在。

Spring AI 的核心是提供抽象,作为开发 AI 应用程序的基础。这些抽象有多种实现方式,只需修改极少的代码就能轻松实现组件交换。

一些概念

在创建示例应用程序之前,先了解一些基本概念:

Models:人工智能模型是模仿人类认知功能的算法,可从大型数据集中生成预测、文本、图像或其他输出。

Prompts:Prompts是为大模型提供的一段文本,目的是让大模型根据这些提示生成想要的输出内容。Prompts在人工智能领域扮演了非常重要的角色,是实现人机交互的基础。

Prompt Templates:这些模板使用基于文本的引擎通过用用户特定的值替换部分请求来创建提示。

Embeddings:Embeddings将文本转换为数值向量,使人工智能模型能够处理和理解语言。•Tokens:Tokens是人工智能模型处理语言的基本单位,其使用量与人工智能服务的成本直接相关。

初始化 Spring AI 应用程序

安装 CLI[1] 后,启动 Spring Shell,然后运行:

spring boot new --from ai --name myai

将创建一个应用程序,可以与 ChatGPT 进行基本交互,只需按照生成的 README 文件中的说明获取您的 API 密钥,然后获取你的 ChatGPT API 密钥并将其导出,如下所示:

export SPRING_AI_OPENAI_API_KEY=your-api-key

最后,使用 mvnw 运行应用程序:

./mvnw spring-boot:run

然后你可以向它发送一个命令,如“请写一首诗”:

http :8080/ai/simple?message=”请写一首诗”

并查看 ChatGPT 的回复:

{

"completion": "静观源码,字字如兰;洞察变量,行间生意;逻辑清晰,结构优雅;优化质量,精益求精"

}

Code review

下面稍微review下代码,在 SimpleAiController 中,可以看到 AiClient 作为注入的依赖关系:

@RestController

public class SimpleAiController {

private final ChatClient chatClient;

@Autowired

public SimpleAiController(ChatClient chatClient) {

this.chatClient = chatClient;

}

//…

}

与 Spring 产品组合中的其他 XXXClient 类(如 WebClient 和 LdapClient)类似,ChatClient 代表了与任何 LLM 交互的接口。

其最简单的用法与你在使用 ChatGPT 网页界面时可能已经体验过的用法类似:给它一个字符串,它就会返回一个字符串:

@GetMapping("/ai/simple")

public Completion completion(@RequestParam(value = "message", defaultValue = "给我讲一个笑话") String message) {

return new Completion(chatClient.call(message));

}

因此,当我们发送“请给我写一首诗”时,Spring 收到了该消息,并将其发送到这个控制器,该控制器随后通过其 AIClient 实现将其传输到 OpenAI。

但是,由于模型仅定期针对最近的内容进行训练,因此它不知道最近问题的答案,如下所示:

http :8080/ai/simple?”中国男足闯进亚洲世预赛18强赛了吗?如果你知道就返回‘知道’,不知到就返回’不知道‘”

它会给出简单的答案:​​​​​​​

{

"completion": "不知道"

}

填充提示词

有效提示的一种技术是除了用户发送的问题或消息之外还填充信息。比如下面这个例子:

?message=”根据这篇文章:“{title}”,请回答我这个问题:“{question}”

spring ai也可用于RAG应用。下面我会用从微博提取相关信息的例子说明。

从微博提取相关信息

我们将微博关于国足晋级18强赛[2]新闻下载并将其放在项目的 src/main/resources 目录中。我使用的是ilovepdf[3]将html转pdf。

存储在向量数据库中

接下来,将该 pdf 的内容加载到 VectorStore 中。可以使用 Redis 等本地存储,由于本篇文章只是入门,我就直接使用 SimpleVectorStore,它是一个内存存储。

注意:此演示默认使用“OpenAIEmbeddingClient”,并使用你的 OpenAI token。请参阅本地运行的其他嵌入客户端的文档。此外,由于我使用的是“SimpleVectorStore”,因此每次启动时都会再次调用openai的接口生成嵌入。对于生产应用程序,需要使用持久化向量存储。

由于我们使用的是 PDF,因此请将以下依赖项添加到你的项目中:​​​​​​​

<dependency>

<groupId>org.springframework.ai</groupId>

<artifactId>spring-ai-pdf-document-reader</artifactId>

<version>1.0.0</version>

</dependency>

这会添加解析 PDF 文件所需的 API。然后在应用程序中,加入向量存储,包括 PDF 作为其内容:

@Bean

VectorStore vectors(EmbeddingClient embedding, @Value("国足.pdf") Resource pdf) {

SimpleVectorStore vectors = new SimpleVectorStore(embedding);

var reader = new PagePdfDocumentReader(pdf);

var splitter = new TokenTextSplitter();

var documents = splitter.apply(reader.get());

vectors.accept(documents);

return vectors;

}

其作用是将文档分割成更小的块,然后将它们作为一组向量存储在本地。在下一步中,我们将让 Spring AI 进行一些数学计算,以确定将哪些文档块发送给 OpenAI 作为我们问题的一部分。

然后,让我们更新 SimpleAiController 使其也依赖于 VectorStore,如下所示:

private final VectorStore vectors;

@Autowired

public SimpleAiController(ChatClient chat, VectorStore vectors) {

this.chat = chat;

this.vectors = vectors;

}

查找要包含的相关信息

现在我们准备向 SimpleAiController 添加一个新接口。这次,它将有两个参数,一个用于填充提示,一个用于消息:​​​​​​​

@GetMapping("/ai/stuffed")

public Completion completion(

@RequestParam(value = "prompt", defaultValue = "基于这些文档: {documents}") String prompt,

@RequestParam(value = "message", defaultValue = "国足晋级18强了吗?") String message) {

// … content to follow

}

但我们不会像第一次那样简单地调用 chatClient.call,而是:

1.在向量存储中搜索相关块2.构造一个包含这些块的提示

可以通过用户的消息搜索向量存储,如下所示:​​​​​​​

var documents = this.vectors.similaritySearch(message);

var inlined = documents.stream().map(Document::getContent).collect(Collectors.joining(System.lineSeparator()));

然后,可以发送这些文档和用户的消息,以便 OpenAI 拥有更多可以使用的上下文:

var system = new SystemPromptTemplate(prompt).createMessage(Map.of("documents", inlined));

var user = new UserMessage(message);

return new Completion(this.chat.call(new Prompt(List.of(system, user))).getResult().getOutput().getContent());

尝试一下

以上代码写完,启动应用程序并尝试一下!

http :8080/ai/stuffed?”中国男足闯进亚洲世预赛18强赛了吗?如果你知道就返回‘知道’,不知到就返回’不知道‘”

{

“completion”: "根据这篇新闻报道,中国国足已经成功晋级2026年世界杯亚洲区预选赛的18强赛。"

}

结论

Spring AI 是一个强大的工具,可以以与平台无关的方式与LLM集成。今天,这篇文章讲解了 ChatClient 和 VectorStore API 的功能,只需几十行代码即可创建引用提供的一组数据的聊天机器人集成。

选择 Spring AI 可以让你在 Spring 框架中无缝集成聊天大模型,向量数据库,多模态大模型,嵌入模型等等,可以参考介绍文档[4]。选择像 Spring AI 这样与平台无关的框架可以让你切换平台或使用多个平台,而无需改变与它们交互的方式实现和大模型解耦合。

References

[1] 安装 CLI: https://docs.spring.io/spring-cli/reference/installation.html

[2] 国足晋级18强赛: https://weibo.com/6221932120/OiO6Tmr5V

[3] ilovepdf: https://www.ilovepdf.com/html-to-pdf

[4] 介绍文档: https://docs.spring.io/spring-ai/reference/index.html



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。