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

news2024/11/28 12:51:00

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的一些核心能力,欢迎大家也自己尝试一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2206535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大数据】数据采集工具sqoop介绍

文章目录 什么是sqoop?一、Sqoop的起源与发展二、Sqoop的主要功能三、Sqoop的工作原理四、Sqoop的使用场景五、Sqoop的优势六、Sqoop的安装与配置 sqoop命令行一、Sqoop简介与架构二、Sqoop特点三、Sqoop常用命令及参数四、使用示例五、注意事项 什么是sqoop? Sqoop是一款开…

BlackMarket_ 1靶机渗透

项目地址 plain https://download.vulnhub.com/blackmarket/BlackMarket.zip 实验过程 开启靶机虚拟机 ![](https://img-blog.csdnimg.cn/img_convert/169d964d61ea9660c1104e723f71449e.png) 使用nmap进行主机发现&#xff0c;获取靶机IP地址 plain nmap 192.168.47.1-254…

D34【python 接口自动化学习】- python基础之输入输出与文件操作

day34 文件关闭 学习日期&#xff1a;20241011 学习目标&#xff1a;输入输出与文件操作&#xfe63;-46 常见常新&#xff1a;文件的关闭 学习笔记&#xff1a; 文件关闭的内部工作过程 close&#xff08;&#xff09;函数 with语句 常用的打开关闭文件 # 文件关闭 # 方式…

第十八篇——有什么比无穷大更大,比无穷小更小?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 看到这篇文章之后&#xff0c;我才发现&#xff0c;我还可以多么有知&…

IP-Guard与Ping32两大加密软件对比:安全性、功能与性能全面评测

随着网络安全威胁的不断升级&#xff0c;越来越多的企业开始重视文件加密&#xff0c;尤其是那些涉及敏感数据、技术文档和业务机密的文件。市场上涌现出众多加密软件&#xff0c;而IPGuard与Ping32作为其中的佼佼者&#xff0c;分别在不同的企业中获得了广泛应用。本文将对这两…

胤娲科技:破茧成蝶——具身智能工业机器人引领工业新纪元

想象一下&#xff0c;走进一家未来的工厂&#xff0c;不再是冰冷的机械臂在单调地重复着同样的动作&#xff0c;而是灵活多变的智能机器人&#xff0c; 它们能够“看一遍、学一遍、做一遍”&#xff0c;然后高效地投入到生产中。这样的场景&#xff0c;是否已经让你对未来充满了…

MySQL基本语法、高级语法知识总结以及常用语法案例

MySQL基本语法总结 MySQL是一种广泛使用的关系型数据库管理系统&#xff0c;其基本语法涵盖了数据库和数据表的创建、查询、修改和删除等操作。 一、数据库操作 创建数据库&#xff08;CREATE DATABASE&#xff09; 语法&#xff1a;CREATE DATABASE [IF NOT EXISTS] databa…

工业4G路由R10提升物流仓储效率

在当今全球化的商业环境中&#xff0c;物流仓储行业面临着越来越大的压力&#xff0c;需要不断提高效率、降低成本并确保货物的安全与准时交付。面对这些挑战&#xff0c;技术革新成为了推动行业发展的关键力量。工业4G路由R10作为一款集成了边缘计算、数据采集、协议转换、远程…

【FL0012】基于SpringBoot和微信小程序的大学生校园兼职系统

&#x1f9d1;‍&#x1f4bb;博主介绍&#x1f9d1;‍&#x1f4bb; 全网粉丝10W,CSDN全栈领域优质创作者&#xff0c;博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发…

基于JAVA+SpringBoot+Vue的医疗报销系统

基于JAVASpringBootVue的医疗报销系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈喽兄…

【MATLAB源码-第272期】基于matlab的OMP算法的毫米波MIMO通信系统的混合波束成形仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在现代无线通信系统中&#xff0c;随着频谱资源的日益紧张&#xff0c;毫米波&#xff08;mmWave&#xff09;技术成为5G及未来通信系统的重要组成部分。毫米波频段的宽频带提供了远超传统微波频段的频谱资源&#xff0c;能够…

使用LlamaFactory进行模型微调

使用LlamaFactory进行模型微调 简介 论文地址&#xff1a;https://arxiv.org/pdf/2403.13372 仓库地址&#xff1a;https://github.com/hiyouga/LLaMA-Factory/tree/main 名词解释 1. 预训练 (Pre-training, PT) 预训练是指模型在大规模无监督数据集上进行初步训练的过程…

Kafka-初识

一、Kafka是什么&#xff1f; Kafka是一个高度可扩展、弹性、容错和安全的分布式流处理平台&#xff0c;由服务器和客户端组成&#xff0c;通过高性能TCP网络协议进行通信。它可以像消息队列一样生产和消费数据。可以部署在裸机硬件、虚拟机和容器上&#xff0c;也可以部署在本…

使用3080ti运行blip2的

使用3080ti运行blip2的案例 注意&#xff01;blip2很吃显存&#xff0c;需要大于80GB显存的卡。我最后安装的所有包的版本信息&#xff08;python 3.9 &#xff09;以供参考&#xff1a; 首先&#xff0c;我在运行blip2的demo的时候显存用了80G以上&#xff0c;所以大家卡的显存…

VS Code最新版本Retome远程ssh不兼容旧服务器问题

✨✨欢迎来到T_X_Parallel的博客&#xff01;&#xff01;       &#x1f6f0;️博客主页&#xff1a;T_X_Parallel       &#x1f6f0;️欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 目录 问题&#xff1a;无法正常使用vscode-remote插件远…

深度优先搜索 - 岛屿最大面积

题目描述 给定一个由 0 和 1 组成的非空二维数组 grid &#xff0c;用来表示海洋岛屿地图。 一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的四个边缘都被 0&#xff08;代表水&…

从零开始搭建UVM平台(十二)-加入sequence机制

书接上回&#xff1a; 从零开始搭建UVM平台&#xff08;一&#xff09;-只有uvm_driver的验证平台 从零开始搭建UVM平台&#xff08;二&#xff09;-加入factory机制 从零开始搭建UVM平台&#xff08;三&#xff09;-加入objection机制 从零开始搭建UVM平台&#xff08;四&…

邮件系统国产化改造: 保障信息安全、提升效率的最佳选择

在当前数字化转型的大背景下&#xff0c;我国政府提出了构建网络强国和数字强国的宏伟蓝图。这一战略的实施&#xff0c;不仅为数字政府的建设提供了坚实的基础&#xff0c;也为政府和企业的数字化升级指明了方向。在这一进程中&#xff0c;邮件系统的国产化改造就显得尤为重要…

功能安全测试安全渗透测试,一文讲清楚

本文我们将以围绕系统安全质量提升为目标&#xff0c;讲述在功能安全测试&安全渗透测试上实践过程。 希望通过此篇文章&#xff0c;帮助大家更深入、透彻地了解安全测试。 安全渗透测试实践 安全前置扫描主要是识别白盒漏洞、黑盒漏洞问题&#xff0c;针对JSRC类问题&am…

pycharm里debug时如何看到数据的维度

使用表达式计算&#xff08;Evaluate Expression&#xff09; 调试时&#xff0c;使用 PyCharm 的 “Evaluate Expression” 功能可以动态查看或修改数据。具体步骤如下&#xff1a; 在调试模式中按 Alt F8&#xff08;Windows&#xff09;或 Option F8&#xff08;Mac&…