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> {@Overridepublic 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.rhkb.cn/news/444722.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 | Leetcode C语言题解之第460题LFU缓存

题目&#xff1a; 题解&#xff1a; /* 数值链表的节点定义。 */ typedef struct ValueListNode_s {int key;int value;int counter;struct ValueListNode_s *prev;struct ValueListNode_s *next; } ValueListNode;/* 计数链表的节点定义。 其中&#xff0c;head是数值链表的头…

多点低压差分(M-LVDS)线路驱动器和接收器——MS2111

MS2111 是多点低压差分 (M-LVDS) 线路驱动器和接收器。经过 优化&#xff0c;可运行在高达 200Mbps 的信号速率下。所有部件均符合 M LVDS 标准 TIA / EIA-899 。该驱动器的输出支持负载低至 30Ω 的多 点总线。 MS2111 的接收器属于 Type-2 &#xff0c; 可在 -1…

【GESP】C++一级练习BCQM3037,简单计算,国庆七天乐收官

又回到了简单计算的题目&#xff0c;继续巩固练习。 题解详见&#xff1a;https://www.coderli.com/gesp-1-bcqm3037/ 【GESP】C一级练习BCQM3037&#xff0c;简单计算&#xff0c;国庆七天乐收官 | OneCoder又回到了简单计算的题目&#xff0c;继续巩固练习。https://www.cod…

性能测试工具locust —— Python脚本参数化!

1.1.登录用户参数化 在测试过程中&#xff0c;经常会涉及到需要用不同的用户登录操作&#xff0c;可以采用队列的方式&#xff0c;对登录的用户进行参数化。如果数据要保证不重复&#xff0c;则取完不再放回&#xff1b;如可以重复&#xff0c;则取出后再返回队列。 def lo…

std::future::then的概念和使用方法

std::future::then是 C 中用于异步操作的一种机制&#xff0c;它允许在一个异步任务完成后&#xff0c;接着执行另一个操作&#xff08;即延续操作&#xff09;。以下是关于 std::future::then 的概念和使用方法&#xff1a; 1. 概念&#xff1a; std::future::then 的主要目…

Chrome清除nslookup解析记录 - 强制http访问 - 如何禁止chrome 强制跳转https

步骤&#xff1a; 地址栏输入 chrome://net-internals/#hsts在Delete domain 栏的输入框中输入要http访问的域名&#xff0c;然后点击“delete”按钮最后在Query domain 栏中搜索刚才输入的域名&#xff0c;点击“query”按钮后如果提示“Not found”即可&#xff01; 办法来自…

Java | Leetcode Java题解之第459题重复的子字符串

题目&#xff1a; 题解&#xff1a; class Solution {public boolean repeatedSubstringPattern(String s) {return kmp(s s, s);}public boolean kmp(String query, String pattern) {int n query.length();int m pattern.length();int[] fail new int[m];Arrays.fill(fa…

Hunuan-DiT代码阅读

一 整体架构 该模型是以SD为基础的文生图模型&#xff0c;具体扩散模型原理参考https://zhouyifan.net/2023/07/07/20230330-diffusion-model/&#xff0c;代码地址https://github.com/Tencent/HunyuanDiT&#xff0c;这里介绍 Full-parameter Training 二 输入数据处理 这里…

E系列I/O模块在锂电装备制造系统的应用

为了满足电池生产线对稳定性和生产效率的严苛要求&#xff0c;ZLG致远电子推出高速I/O应用方案&#xff0c;它不仅稳定可靠&#xff0c;而且速度快&#xff0c;能够迅速响应生产需求。 锂电池的生产工艺较为复杂&#xff0c;大致分为三个主要阶段&#xff1a;极片制作、电芯制作…

单点登录Apereo CAS 7.1客户端集成教程

从上一篇部署并成功运行CAS服务端后,我们已经能通过默认的账号密码进行登录。 上篇地址:单点登录Apereo CAS 7.1安装配置教程-CSDN博客 本篇我们将开始对客户端进行集成。 CAS中的客户端,就是指我们实际开发的各个需要登录认证的应用。现在,跟着笔者的步伐,一起探索如何…

springmvc直接访问 上下文路径 302 后路径更改并跳转源码解析

【问题现状】 application.yml 配置如下属性&#xff1a; server:servlet:context-path: /learning直接访问&#xff1a;http://localhost:8888/learning 路径时&#xff0c;会返回302的响应状态&#xff1b;并跳转路径&#xff1a;http://localhost:8888/learning/ (原路径后…

Docker Overlay2 空间优化

目录 分析优化数据路径规划日志大小限制overlay2 大小限制清理冗余数据 总结 分析 overlay2 目录占用磁盘空间较大的原因通常与 Docker 容器和镜像的存储机制以及它们的长期累积相关&#xff0c;其实我之前在 Docker 原理那里已经提到过了。 通常时以下几种原因导致&#xff…

☕️从小工到专家的 Java 进阶之旅:全新的HttpClient,现代高效的网络通信利器

你好&#xff0c;我是看山。 本文收录在 《从小工到专家的 Java 进阶之旅》 系列专栏。日拱一卒&#xff0c;功不唐捐。 在 Java 开发领域&#xff0c;网络通信一直是至关重要的部分。从早期的网络编程方式到如今&#xff0c;Java 在 HTTP 客户端方面经历了不断的演进。 其中&…

【C语言】函数栈帧的创建和销毁

文章目录 前言函数栈帧相关寄存器相关汇编指令内存函数栈帧的创建销毁过程 前言 为了更好的了解函数里面变量是如何创建&#xff0c;为什么创建的变量是随机值和函数怎么传参和顺序是怎样的、以及实参和形参的关系&#xff0c;还要函数之间的调用、返回和销毁的过程。我们今天…

Comfyui 学习笔记5

1.图像处理小工具&#xff0c;沿某个轴反转Image Flip 2. reactor换脸 3. 通过某人的多张照片进行训练 训练的模型会保存在 models/reactor/face/下面&#xff0c;使用时直接load就好 4. 为一个mask 更加模糊 羽化 5. 指定位置替换&#xff0c;个人感觉这种方式进行换脸的融…

Pura 70系列和Pocket 2已支持升级尝鲜鸿蒙NEXT,报名教程在这里

相信不少关注鸿蒙 NEXT 的人都知道&#xff0c;10月8日起&#xff0c;华为开启了鸿蒙 NEXT 系统的公测&#xff0c;但有不少人不知道的是&#xff0c;除了公测的 Mate 60 和 Mate X5 两个系列的机型&#xff0c;还有两个系列的手机其实也可以提前升级体验鸿蒙 NEXT 系统。 Pur…

从数据管理到功能优化:Vue+TS 项目实用技巧分享

引言 在项目开发过程中&#xff0c;优化用户界面和完善数据处理逻辑是提升用户体验的重要环节。本篇文章将带你一步步实现从修改项目图标、添加数据、优化日期显示&#xff0c;到新增自定义字段、调整按钮样式以及自定义按钮跳转等功能。这些操作不仅提升了项目的可视化效果&am…

统一流程引擎如何具体实现对多系统业务流程的整合?

在信息化时代&#xff0c;企业和组织通常会使用多个业务系统来满足不同的业务需求。然而&#xff0c;这些分散的业务系统往往会导致业务流程的碎片化&#xff0c;降低工作效率。统一流程引擎的出现为解决这一问题提供了有效的途径。它能够整合多系统的业务流程&#xff0c;实现…

LeetCode 3310. 移除可疑的方法

LeetCode 3310. 移除可疑的方法 你正在维护一个项目&#xff0c;该项目有 n 个方法&#xff0c;编号从 0 到 n - 1。 给你两个整数 n 和 k&#xff0c;以及一个二维整数数组 invocations&#xff0c;其中 invocations[i] [ai, bi] 表示方法 ai 调用了方法 bi。 已知如果方法 k…

云栖实录 | MaxCompute 迈向下一代的智能云数仓

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 张治国 | 阿里云智能集团研究员、阿里云 MaxCompute 负责人 谢德军&#xff5c;阿里云智能集团资深技术专家 于得水&#xff5c;阿里云智能集团资深技术专家 谌鹏飞&#xff5c…