自学内容网 自学内容网

Spring AI 介绍与入门使用 -- 一个Java版Langchain

Langchain 是什么?

Langchain 是一个Python 的AI开发框架,它集成了模型输入输出、检索、链式调用、内存记忆(Memory)、Agents以及回调函数等功能模块。通过这些模块的协同工作,它能够支持复杂的对话场景和任务执行流程,同时利用模板(Templates)机制简化开发过程,让开发者可以更加灵活高效地构建基于AI的应用服务。

Langchain虽好,奈何Java不能用

Langchain的核心问题在于它主要是用Python实现的,过去Java社区中缺乏一个由专门团队维护的、功能完善的类Langchain框架。不过这个问题随着Spring 团队的介入得到了解决。使得Java距离AI又进了一步。

Spring AI 介绍

Spring AI 是由Pivotal的Spring团队专门维护的AI调用框架,它通过标准化不同AI服务提供商的接口实现,使开发者能够以统一的方式编写代码,并仅通过修改配置即可轻松切换不同的AI实现。该框架兼容多种基于流的机器人模型,并提供了一系列实用工具如Prompt Template和OutputParser等,极大地简化了AI应用开发流程。

Spring AI Alibaba介绍

Spring AI Alibaba 是 Spring AI 的实现,支持阿里云百炼系列模型。其特征包括:统一的模型输入输出接口、向量检索功能(兼容Elasticsearch、PG等存储)、Prompt Template 用于灵活生成提示词,以及 Function Calling 支用来调用自定义函数以扩展模型能力。这些特性使得开发者能够便捷地集成和使用多种AI模型,提升开发效率。

Spring Ai Alibaba 的例子之一:简单的对话,基于Prompt

基于Spring Boot集成Spring AI Alibaba,完成一个简单的对话模型,并使用Prompt能力和ChatClient能力以及Flux流返回,可以遵循以下步骤:

1. 环境准备

  • JDK版本:确保你的项目使用的JDK版本至少为JDK 17。
  • Spring Boot版本:确保你的Spring Boot版本在3.3.x或以上。

2. 配置阿里云通义千问API Key

首先需要访问阿里云百炼页面并登录您的账号。接着选择开通“百炼大模型推理”服务,按照提示操作直到成功申请到API Key。将获取到的API Key记录下来,后续配置中会用到。

通义现在有免费额度,不花钱的,羊毛薅起来

3. 设置环境变量

为了安全地管理敏感信息,推荐通过环境变量设置API Key:

export AI_DASHSCOPE_API_KEY=${YOUR_VALID_API_KEY}

同时,在application.properties文件里引用这个环境变量以确保应用能够读取到API Key:

spring.ai.dashscope.api-key: ${AI_DASHSCOPE_API_KEY}

4. 添加仓库与依赖

由于Spring AI Alibaba尚处于Milestone阶段,需添加特定仓库来获取相关依赖。编辑pom.xml文件,加入如下内容:

<repositories>
    <repository>
        <id>sonatype-snapshots</id>

        <url>https://oss.sonatype.org/content/repositories/snapshots</url>

        <snapshots>
            <enabled>true</enabled>

        </snapshots>

    </repository>

    <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>

然后,在同一文件内增加对spring-ai-alibaba-starter及其父级Spring Boot项目的依赖:

<parent>
    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-parent</artifactId>

    <version>3.3.4</version>

    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>

        <artifactId>spring-ai-alibaba-starter</artifactId>

        <version>1.0.0-M2</version>

    </dependency>

    <!-- 其他所需依赖... -->
</dependencies>

5. 编写控制器代码

创建一个REST控制器类,注入ChatClient实例,并实现基本的聊天功能。这里我们将利用Flux流返回方式提供实时响应。

@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "*")
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    @GetMapping("/chat")
    public Flux<String> chat(@RequestParam String input) {
        return this.chatClient.prompt()
                .user(input)
                .stream()
                .content();
    }
}

6. 使用Prompt模板增强交互

为了使对话更加丰富和可控,我们可以引入Prompt模板机制。这要求我们先定义一个模板文件(例如joke-prompt.st),其内容可能类似于:

Tell me a {adjective} joke about {topic}.

接着修改之前的控制器,使其能够从指定的模板文件加载并填充参数:

@Autowired
private Resource jokeResource;

@GetMapping("/promptedChat")
public Flux<String> promptedChat(@RequestParam(value = "adjective", defaultValue = "funny") String adjective,
                                 @RequestParam(value = "topic", defaultValue = "cows") String topic) {
    PromptTemplate promptTemplate = new PromptTemplate(jokeResource);
    Prompt prompt = promptTemplate.create(Map.of("adjective", adjective, "topic", topic));
    
    return this.chatClient.prompt(prompt)
            .stream()
            .content();
}

Spring Ai Alibaba 例子2 ,function calling 函数回调

详细步骤

结合上述分析及我了解的信息中给出的建议,下面提供了一个具体的实例,展示了如何基于Spring Boot集成Spring AI Alibaba完成一个function calling,并利用Prompt能力与Flux流返回数据。

前提条件
  • JDK版本:17及以上。
  • Spring Boot版本:3.3.x及以上。
  • 已经从阿里云获取API Key,并按要求配置环境变量AI_DASHSCOPE_API_KEY
项目配置

确保你的pom.xml文件里包含如下依赖:

<parent>
    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-parent</artifactId>

    <version>3.3.4</version>

    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>

        <artifactId>spring-ai-alibaba-starter</artifactId>

        <version>1.0.0-M2</version>

    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-webflux</artifactId>

    </dependency>

    ...other dependencies...
</dependencies>

同时添加所需的仓库:

<repositories>
    <repository>
      <id>sonatype-snapshots</id>

      <url>https://oss.sonatype.org/content/repositories/snapshots</url>

      <snapshots>
        <enabled>true</enabled>

      </snapshots>

    </repository>

    <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>
定义并注册函数

创建一个简单的服务类,比如MessageStatusService.java,用来模拟消息状态查询的功能:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;

public class MessageStatusService implements Function<MessageStatusRequest, String> {

    @Override
    public String apply(MessageStatusRequest request) {
        return "消息ID: " + request.getMessageId() + " 的状态是:正常";
    }

    public static class MessageStatusRequest {
        @JsonProperty(required = true, value = "消息id")
        @JsonPropertyDescription("消息id, 比如123123***")
        private String messageId;

        // 构造器、getter和setter省略
    }
}

然后,在Spring配置类中注册此服务:

@Configuration
public class AppConfig {

    @Bean
    @Description("查询指定消息ID的状态")
    public Function<MessageStatusRequest, String> messageStatusFunction() {
        return new MessageStatusService();
    }
}
控制器代码

最后,编写一个控制器类来处理HTTP请求,并使用PromptTemplate构建提示词,同时通过DashScopeChatOptions启用函数调用功能。

@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "*")
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    @GetMapping("/status")
    public Flux<String> checkMessageStatus(@RequestParam String id) {
        PromptTemplate promptTemplate = new PromptTemplate("我想知道消息id: {id} 的状态");

        DashScopeChatOptionsBuilder opsBuilder = DashScopeChatOptions.builder()
                .withFunction("messageStatusFunction");
        DashScopeChatOptions ops = opsBuilder.build();

        Map<String, Object> map = Map.of("id", id);
        Prompt prompt = promptTemplate.create(map, ops);

        return chatClient.prompt(prompt).stream().content();
    }
}

小结

上面两个,作为一个例子,基本上展示了spring ai的一些核心能力,欢迎大家也自己尝试一下。


原文地址:https://blog.csdn.net/whisperzzza/article/details/142864338

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!