Spring AI来了

admin
2024-04-13 / 0 评论 / 23 阅读 / 正在检测是否收录...

Spring AI来了

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

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

Spring AI 的核心提供了抽象,作为开发 AI 应用程序的基础。 这些抽象有多种实现,可以通过最少的代码更改轻松进行组件交换。

一、Spring AI 提供以下功能

  • Support for all major Model providers such as OpenAI, Microsoft, Amazon, Google, and Huggingface.

    (支持所有主要模型提供商,例如 OpenAI、Microsoft、Amazon、Google 和 Huggingface)

  • Supported Model types are Chat and Text to Image with more on the way.

    (支持的模型类型包括“聊天”和“文本到图像”,还有更多模型类型正在开发中)

  • Portable API across AI providers for Chat and for Embedding models. Both synchronous and stream API options are supported. Dropping down to access model specific features is also supported.

    (跨 AI 提供商的可移植 API,用于聊天和嵌入模型。 支持同步和流 API 选项。 还支持下拉访问模型特定功能)

  • Mapping of AI Model output to POJOs.

    (AI 模型输出到 POJO 的映射)

  • Support for all major Vector Database providers such as Azure Vector Search, Chroma, Milvus, Neo4j, PostgreSQL/PGVector, PineCone, Qdrant, Redis, and Weaviate

    (支持所有主要矢量数据库提供商,例如 Azure 矢量搜索、Chroma、Milvus、Neo4j、PostgreSQL/PGVector、PineCone、Qdrant、Redis 和 Weaviate)

  • Portable API across Vector Store providers, including a novel SQL-like metadata filter API that is also portable.

    (跨 Vector Store 提供商的可移植 API,包括同样可移植的新颖的类似 SQL 的元数据过滤器 API)

  • Function calling

    (函数调用)

  • Spring Boot Auto Configuration and Starters for AI Models and Vector Stores.

    (AI 模型和向量存储的 Spring Boot 自动配置和启动器)

  • ETL framework for Data Engineering

    (数据工程的 ETL 框架)


二、俗语介绍

Models

Models模型是旨在处理和生成信息的算法,通常模仿人类的认知功能。 通过从大型数据集中学习模式和见解,这些模型可以做出预测、文本、图像或其他输出,从而增强跨行业的各种应用程序。

有许多不同类型的人工智能模型,每种模型都适合特定的用例。 虽然 ChatGPT 及其生成式人工智能功能通过文本输入和输出吸引了用户,但许多模型和公司提供了多样化的输入和输出。 在 ChatGPT 之前,很多人对 Midjourney 和 Stable Diffusion 等文本到图像生成模型着迷。

下表根据输入和输出类型对几种模型进行了分类:

InputOutputExamples
Language/Code/Images (Multi-Modal)Language/CodeGPT4 - OpenAI, Google Gemini
Language/CodeLanguage/CodeGPT 3.5 - OpenAI-Azure OpenAI, Google Bard, Meta Llama
LanguageImageDall-E - OpenAI + Azure, Deep AI
Language/ImageImageMidjourney, Stable Diffusion, RunwayML
TextNumbersMany (AKA embeddings)

Prompts

Prompts是基于语言的输入的基础,指导人工智能模型产生特定的输出。 对于熟悉 ChatGPT 的人来说,提示可能看起来只是发送到 API 的对话框中输入的文本。 然而,它包含的内容远不止于此。 在许多 AI 模型中,提示文本不仅仅是一个简单的字符串。

ChatGPT 的 API 在Prompts中具有多个文本输入,每个文本输入都被分配一个角色。 例如,系统角色告诉模型如何行为并设置交互的上下文。 还有用户角色,通常是来自用户的输入。

简单来说就是使用LLM等模型时,Prompts是输入,Prompts中输入内容被分配成不同的角色,每个角色控制不同的功能。Prompts的制定就成为重要的输入,可以共享,多人制定。

Prompt Templates

创建有效的提示涉及建立请求的上下文并用特定于用户输入的值替换部分请求。此过程使用传统的基于文本的模板引擎进行提示创建和管理。 Spring AI 为此使用 OSS 库 StringTemplate。

Prompt Templates输入Prompts的模板,在Spring AI中,Prompt Templates可以比作Spring MVC架构中的“视图”。 提供模型对象(通常是 java.util.Map)来填充模板内的占位符。 “‘rendered’”字符串成为提供给 AI 模型的提示内容。

Embeddings

Embeddings将文本转换为数值数组或向量,使人工智能模型能够处理和解释语言数据。 这种从文本到数字的转换是人工智能如何与人类语言交互并理解人类语言的关键要素。 作为探索人工智能的 Java 开发人员,没有必要理解复杂的数学理论或这些向量表示背后的具体实现。 对它们在人工智能系统中的角色和功能有基本的了解就足够了,特别是当您将人工智能功能集成到应用程序中时。

嵌入在实际应用中尤其重要,例如检索增强生成(RAG)模式。 它们能够将数据表示为语义空间中的点,该语义空间类似于欧几里得几何的二维空间,但维度更高。 这意味着就像欧几里得几何中平面上的点根据其坐标可以接近或远离一样,在语义空间中,点的接近反映了含义的相似性。 关于相似主题的句子在这个多维空间中位置更近,就像图表上彼此靠近的点一样。 这种接近性有助于文本分类、语义搜索甚至产品推荐等任务,因为它允许人工智能根据相关概念在扩展语义环境中的“位置”来辨别和分组。

您可以将这个语义空间视为一个向量。

Output Parsing

AI 模型的输出传统上以 java.lang.String 形式到达,即使您要求回复采用 JSON 格式。 它可能是正确的 JSON,但它不是 JSON 数据结构。 它只是一个字符串。 此外,在提示中询问“for JSON”并不是 100% 准确。

这种复杂性导致了一个专门领域的出现,涉及创建提示以产生预期的输出,然后将生成的简单字符串解析为可用的数据结构以进行应用程序集成。

输出解析采用精心设计的提示,通常需要与模型进行多次交互才能实现所需的格式。

这一挑战促使 OpenAI 引入“OpenAI 函数”作为精确指定模型所需输出格式的方法。


三、Bringing Your Data to the AI model

(将您的数据引入人工智能模型)

存在三种技术可用于自定义 AI 模型以合并您的数据:

微调:这种传统的机器学习技术涉及定制模型并更改其内部权重。 然而,对于机器学习专家来说,这是一个具有挑战性的过程,而且对于 GPT 等模型来说,由于其规模,资源极其密集。 此外,某些型号可能不提供此选项。

提示填充:更实用的替代方案是将数据嵌入到提供给模型的提示中。 考虑到模型的令牌限制,需要技术来在模型的上下文窗口中呈现相关数据。 这种方法通俗地称为“填充提示”。 Spring AI 库可帮助您实现基于“填充提示”技术(也称为检索增强生成 (RAG))的解决方案。

函数调用:此技术允许注册自定义用户函数,将大型语言模型连接到外部系统的 API。 Spring AI 极大地简化了支持函数调用所需编写的代码。


四、其它说明

Retrieval Augmented Generation

一种名为检索增强生成 (RAG) 的技术已经出现,旨在解决将相关数据纳入提示中以实现准确的 AI 模型响应的挑战。

该方法涉及批处理风格的编程模型,其中作业从文档中读取非结构化数据,对其进行转换,然后将其写入矢量数据库。 从较高层面来看,这是一个 ETL(提取、转换和加载)管道。 RAG技术的检索部分使用向量数据库。

作为将非结构化数据加载到矢量数据库的一部分,最重要的转换之一是将原始文档分割成更小的部分。 将原始文档分割成更小的部分的过程有两个重要步骤:

将文档拆分为多个部分,同时保留内容的语义边界。 例如,对于包含段落和表格的文档,应避免在段落或表格的中间拆分文档。 对于代码,避免在方法实现的中间拆分代码。

将文档的各个部分进一步拆分为大小仅为 AI 模型令牌限制的一小部分的部分。

RAG 的下一阶段是处理用户输入。 当人工智能模型要回答用户的问题时,该问题和所有“相似”文档片段都会被放入发送给人工智能模型的提示中。 这就是使用矢量数据库的原因。 它非常擅长查找相似内容。

实现 RAG 时使用了几个概念。 这些概念映射到 Spring AI 中的类:

DocumentReader:一个 Java 函数接口,负责从数据源加载 List。 常见的数据源有 PDF、Markdown 和 JSON。

Document:数据源的基于文本的表示形式,还包含用于描述内容的元数据。

DocumentTransformer:负责以各种方式处理数据(例如,将文档分割成更小的部分或向文档添加额外的元数据)。

DocumentWriter:允许您将文档保存到数据库中(最常见的是在 AI 堆栈中,矢量数据库)。

Embedding:将数据表示为 List,向量数据库使用它来计算用户查询与相关文档的“相似度”。

Function Calling

大型语言模型(LLM)在训练后被冻结,导致知识过时,并且无法访问或修改外部数据。函数调用机制解决了这些缺点。 它允许您注册自定义用户函数,将大型语言模型连接到外部系统的 API。 这些系统可以为法学硕士提供实时数据并代表他们执行数据处理操作。

Spring AI 极大地简化了支持函数调用所需编写的代码。 它为您代理函数调用对话。 您可以将函数作为 @Bean 提供,然后在提示选项中提供该函数的 bean 名称以激活该函数。 您还可以在单个提示中定义和引用多个函数。

Evaluating AI responses

有效评估人工智能系统响应用户请求的输出对于确保最终应用的准确性和有用性非常重要。 一些新兴技术可以使用预训练模型本身来实现此目的。

此评估过程涉及分析生成的响应是否符合用户的意图和查询的上下文。 相关性、连贯性和事实正确性等指标用于衡量人工智能生成的响应的质量。

一种方法涉及呈现用户的请求和人工智能模型对模型的响应,查询响应是否与提供的数据一致。

此外,利用矢量数据库中存储的信息作为补充数据可以增强评估过程,有助于确定响应相关性。

Spring AI 项目当前提供了一些非常基本的示例,说明如何以提示的形式评估响应以包含在 JUnit 测试中。

五、功能说明

Embeddings Models

Chat Models

Image Generation Models

Vector Databases

六、springboot ai接入Ollama Chat

这里以Chat Models为例,创建一个springboot ai项目。

说明:由于Openai api key收费,这里以Ollama Chat为LLM演示。

本地搭建Ollama Chat

  1. 下载Ollama https://ollama.com/download/OllamaSetup.exe
  2. 拉取运行

    ollama run llama2
  3. 如果想支持中文拉取这个

    ollama pull llama2-chinese
  4. 执行

    ollama run llama2-chinese
  5. ollama默认服务地址端口

    http://localhost:11434/

image-20240412215708882

搭建springboot ai项目

说明:对JDK有版本要求,最低JDK17.

maven:3.8.3

JDK:17

2、引入依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example.ai</groupId>
    <artifactId>ollama-chat</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ollama-chat</name>
    <description>Ollama Chat project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>

    <dependencyManagement>
        <dependencies>
            <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>
</project>

编写Controller

package com.example.ai.ollamachat.controller;

import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.beans.factory.annotation.Autowired;
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;

import java.util.Map;

@RestController
public class ChatController {

    private final OllamaChatClient chatClient;

    @Autowired
    public ChatController(OllamaChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/ai/generate")
    public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", chatClient.call(message));
    }

    @GetMapping("/ai/generateStream")
    public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        Prompt prompt = new Prompt(new UserMessage(message));
        return chatClient.stream(prompt);
    }

}

application.properties配置

spring.application.name=ollama-chat
spring.ai.ollama.base-url=http://localhost:11434/
spring.ai.ollama.chat.enabled=true
spring.ai.ollama.chat.options.model=llama2
spring.ai.ollama.chat.options.temperature=0.7

更多参数配置见文档 https://docs.spring.io/spring-ai/reference/api/clients/ollama-chat.html

测试

访问http://localhost:8080/ai/generate

返回结果

{"generation":"\nWhy don't scientists trust atoms? Because they make up everything! \uD83D\uDE02"}

说明

OllamaApi 聊天接口和构建块图:

ollama-chat-completion-api

更多其它LLM接入,后续更新。

1

评论 (0)

取消