基于开源框架Spring AI Alibaba快速构建Java应用

简介: 本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。

欢迎扫描文末二维码,关注「阿里云开发者」公众号,了解更多技术干货,关于阿里的技术创新均呈现于此。

Spring AI介绍


当前Java调用大模型时,往往缺乏一个高效且统一的应用框架,Spring作为知名的Java应用框架提供商,推出了Spring AI来解决这个问题。它借鉴了langchain的一些核心理念,并结合了Java面向对象编程的优势。Spring AI的核心优势在于提供了统一的接口标准,开发者只需编写一次代码就能轻松切换不同的AI服务提供者,如OpenAI、阿里云等。此外,Spring AI还支持流式输出兼容性及自动POJO映射等功能,极大简化了开发流程。并且由于有专门团队维护,确保了长期稳定性和安全性。这种设计让基于Java的大模型应用开发变得更加便捷和高效。

Spring AI Alibaba介绍

当大模型在国内应用时,面临的主要挑战是在确保内容安全的同时,满足业务需求的智能化水平。Spring AI Alibaba作为这一背景下的一种理想选择,提供了强大的内容安全保障,并且基于Qwen-2.5模型,该模型在OpenCompass评估中被评为开源领域中的佼佼者。Spring AI Alibaba是将阿里云最佳实践与Spring AI框架本地化结合的结果,它不仅简化了开发者对接不同AI服务的过程,而且通过统一接口标准使得迁移和适配变得异常简单。其核心优势在于支持多种生成式任务(如对话、文生图等)、兼容Flux流处理机制以及提供诸如Prompt Template、OutputParser等功能,极大提升了开发效率与灵活性。此外,Spring AI Alibaba还具备调用外部数据的能力,允许用户根据实际需要定制化扩展AI功能,为构建更加智能的应用提供了坚实的基础。

Spring AI Alibaba 实战:后端构建


为了基于Spring Boot集成Spring AI Alibaba并完成一个简单的对话模型,构建一个支持prompt的流返回接口的项目,并确保GET接口支持CORS跨域,我们可以遵循以下步骤。本回答将详细指导如何配置和编写代码以达成这一目标。


1. 确认开发环境


  • 确保你的JDK版本在JDK17(含)以上。
  • 使用Spring Boot 3.3.x版本或更高版本。


2. 在阿里云申请API Key


  • 访问阿里云百炼页面并登录账号。https://www.aliyun.com/product/bailian
  • 开通“百炼大模型推理”服务,获取API Key。
  • 设置环境变量:export AI_DASHSCOPE_API_KEY=你的API_KEY 或直接在应用程序配置文件中设置。


3. 添加仓库和依赖


由于Spring AI当前版本还未提交到Maven正式仓库,因此需要添加额外的仓库来访问这些资源:


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

接着,在pom.xml中添加对spring-ai-alibaba-starter及Spring Boot parent项目的依赖:

<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.1</version>

  </dependency>

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

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

  </dependency>

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

    <artifactId>spring-boot-starter-data-jpa</artifactId>

  </dependency>

  <!-- 其他可能需要的依赖项... -->
</dependencies>

这里特别注意加入了spring-boot-starter-webflux,因为它对于处理响应式流(Flux)至关重要。


4. 配置application.properties


在项目的

src/main/resources/application.properties文件中加入如下配置:

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


5. 编写Controller


创建一个新的控制器类ChatController.java,实现带有CORS支持的聊天接口,该接口接受输入参数并通过ChatClient发送请求给AI模型,同时利用PromptTemplate提供更丰富的交互体验。此外,此控制器还将使用WebFlux框架提供的功能来返回响应式类型Flux

import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "*") // 支持所有来源的跨域请求
public class ChatController {

    private final ChatClient chatClient;
    @Value("classpath:your-prompt-template.st")
    Resource promptTemplateResource;

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

    @GetMapping("/steamChat")
    public Flux<String> steamChat(@RequestParam String input) {
        PromptTemplate promptTemplate = new PromptTemplate(promptTemplateResource);
        Prompt prompt = promptTemplate.create(Map.of("input", input));
        return chatClient.prompt(prompt).stream().content();
    }
}

请确保your-prompt-template.st是一个位于src/main/resources/下的模板文件,用于定义与AI交互时使用的具体提示文本格式,比如:

针对{input},给出回应。

通过上述步骤,你就成功地基于Spring Boot集成了Spring AI Alibaba,并实现了满足题目要求的功能。这个过程涵盖了从准备环境到最终编码的所有关键点,包括了对外部库的支持、特定功能的启用以及REST API的设计等方面。

构建匹配的聊天前端应用


基于我了解的一些信息,我们将采用React框架来创建一个简单的聊天应用。该应用会通过HTTP请求与后端交互,并支持从后端接收流式数据(flux)。


1. 初始化React项目


首先,确保你的机器上已安装了Node.js和npm或yarn。然后执行以下命令以创建一个新的React应用:

npx create-react-app frontend
cd frontend
npm install

这将创建一个名为frontend的基础React项目,并自动安装运行所需的所有依赖项。


2. 修改基本文件结构


根据需求调整基础文件内容。这里主要关注的是HTML模板、主入口文件以及核心组件。

  • public/index.html

保持默认即可,此文件定义了网页的基本结构。

  • src/index.js

无需修改,默认配置足够用于当前示例。

  • src/App.js

此文件负责渲染根组件。我们将导入并显示自定义的ChatComponent

import React from 'react';
import ChatComponent from './components/ChatComponent';

function App() {
  return (
    <div className="App">
      <ChatComponent />
    </div>

  );
}

export default App;
  • src/components/ChatComponent.js

这是实现用户界面逻辑的主要部分,包括输入框、发送按钮及展示消息区域。我们还将在此处处理向服务器发送请求并监听响应流的过程。

import React, { useState } from 'react';

const ChatComponent = () => {
  const [input, setInput] = useState('');
  const [messages, setMessages] = useState('');

  const handleInputChange = (event) => {
    setInput(event.target.value);
  };

  const handleSendMessage = async () => {
    if (!input.trim()) return; // 避免空消息
    try {
      const response = await fetch(`http://localhost:8080/ai/steamChat?input=${encodeURIComponent(input)}`, { method: 'GET' });
      if (!response.ok) throw new Error('Network response was not ok');
      
      const reader = response.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let done = false;

      while (!done) {
        const { value, done: readerDone } = await reader.read();
        done = readerDone;
        const chunk = decoder.decode(value, { stream: true });
        setMessages((prevMessages) => prevMessages + chunk);
      }

      // 添加分隔符区分不同轮次的消息
      setMessages((prevMessages) => prevMessages + '\n\n=============================\n\n');
    } catch (error) {
      console.error('Error fetching data:', error);
    } finally {
      setInput('');  // 清空输入框
    }
  };

  const handleClearMessages = () => {
    setMessages('');
  };

  return (
    <div>
      <input type="text" value={input} onChange={handleInputChange} placeholder="Enter your message" />
      <button onClick={handleSendMessage}>Send</button>

      <button onClick={handleClearMessages}>Clear</button>

      <div>
        <h3>Messages:</h3>

        <pre>{messages}</pre>

      </div>

    </div>

  );
};

export default ChatComponent;

上述代码中,我们利用fetchAPI向指定URL发起GET请求,并使用ReadableStream读取服务器返回的数据流。每次接收到新的数据块时,都会更新页面上的消息列表。此外,还包括了一个清空消息记录的功能。


3. 运行项目


完成以上步骤后,就可以启动前端服务查看效果了:

npm start

这会在本地启动开发服务器,默认访问地址为http://localhost:3000。打开浏览器进入该地址,你就能看到一个可以发送消息并实时接收回复的简单聊天界面了。

注意:

  • 确保后端服务在http://localhost:8080上运行并且能够正确响应/ai/steamChat路径下的请求。
  • 如果遇到跨域资源共享(CORS)问题,请检查后端是否已经允许来自前端域名的请求。




来源  |  阿里云开发者公众号
作者  |  
沈询



lQDPJxtDT2qZCe3NAQLNAQKwi5rXw9OESjkHEvZYkMDCAA_258_258.jpg




相关文章
|
14天前
|
存储 人工智能 Java
Spring AI Alibaba 配置管理,用 Nacos 就够了
本文通过一些实操案例展示了 Spring AI Alibaba + Nacos 在解决 AI 应用中一系列复杂配置管理挑战的方案,从动态 Prompt 模板的灵活调整、模型参数的即时优化,到敏感信息的安全加密存储。Spring AI Alibaba 简化了对接阿里云通义大模型的流程,内置 Nacos 集成也为开发者提供了无缝衔接云端配置托管的捷径,整体上极大提升了 AI 应用开发的灵活性和响应速度。
120 11
|
26天前
|
人工智能 运维 NoSQL
云栖大会|多模+一体化,构建更高效的AI应用
在2024年云栖大会「NoSQL数据库」专场,多位知名企业和阿里云瑶池数据库团队的技术专家,共同分享了阿里云Lindorm、Tair、MongoDB和MyBase的最新进展与实践。Tair推出Serverless KV服务,解决性能瓶颈和运维难题;Lindorm助力AI和具身智能时代的多模数据处理;MongoDB云原生化提升开发效率;MyBase One打破云边界,提供云边端一体化服务。这些技术进展和最佳实践,展示了阿里云在NoSQL数据库领域的创新能力和广泛应用前景。
|
24天前
|
机器学习/深度学习 人工智能 自然语言处理
探索AI驱动的个性化学习平台构建###
【10月更文挑战第29天】 本文将深入探讨如何利用人工智能技术,特别是机器学习与大数据分析,构建一个能够提供高度个性化学习体验的在线平台。我们将分析当前在线教育的挑战,提出通过智能算法实现内容定制、学习路径优化及实时反馈机制的技术方案,以期为不同背景和需求的学习者创造更加高效、互动的学习环境。 ###
50 3
|
27天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
51 2
|
28天前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
48 2
|
SQL 存储 Java
Java 应用与数据库的关系| 学习笔记
快速学习 Java 应用与数据库的关系。
207 0
Java 应用与数据库的关系| 学习笔记
|
SQL 存储 Java
Java 应用与数据库的关系| 学习笔记
快速学习 Java 应用与数据库的关系。
192 0
Java 应用与数据库的关系| 学习笔记
|
SQL 存储 关系型数据库
Java应用与数据库的关系|学习笔记
快速学习Java应用与数据库的关系
Java应用与数据库的关系|学习笔记
|
12天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
3天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####