Java调用LLM大模型 - 基于 Spring AI 实现_API

Spring AI:为Java开发者提供高效集成大模型能力的框架

当前Java调用大模型时,面临缺乏优质AI应用框架的挑战。Spring作为资深的Java应用框架提供者,通过推出Spring AI来解决这一问题。它借鉴了langchain的核心理念,并结合了Java面向对象编程的特点,为开发者提供了统一且可灵活替换的接口。Spring AI的核心优势包括标准化不同AI供应商(如阿里云、OpenAI等)的接口实现,使得代码只需编写一次即可轻松切换不同的AI服务;同时,该框架由专门团队维护,保证了稳定性和安全性,让Java开发者能够更高效地集成和利用大模型能力。

Spring AI Alibaba:整合Qwen模型,确保内容安全与智能性的国内优秀选择

当大模型进入国内市场时,如何在确保内容安全可控的同时,还能保持模型的智能性以满足业务需求,成为了一个关键挑战。Spring AI Alibaba作为这一领域的优秀选择,不仅整合了Qwen(通义千问)系列模型及其阿里云的最佳实践,还提供了强大的内容安全保障。Qwen-2.5已在OpenCompass评选中被评为开源模型中的第一名,证明了其卓越性能。Spring AI Alibaba是一套基于Spring生态系统的AI框架本地化实现,它通过提供统一且标准化的接口来简化不同AI服务提供商之间的切换过程,极大降低了开发与迁移成本。开发者只需调整配置即可轻松更换底层AI实现,同时支持包括文本生成、图像创建在内的多种应用场景。此外,该框架兼容Flux流输出,并为开发者提供了Prompt模板等功能,使得构建高效且灵活的AI应用变得更加便捷。总之,Spring AI Alibaba凭借其全面的功能支持和良好的抽象设计,在促进国内AI项目快速落地方面展现出了显著优势。

使用SpringBoot集成Spring AI Alibaba构建对话模型及流返回接口

基于SpringBoot集成Spring AI Alibaba来完成一个简单的对话模型,并构建一个支持prompt的流返回接口,具体步骤如下:

前提条件

  1. 确保您的开发环境满足以下要求:
  • JDK版本:JDK 17(含)以上。
  • Spring Boot版本:3.3.x或更高。
  1. 在阿里云申请通义千问API-key。参考我了解的信息中的第1篇参考内容第3步进行操作。
  2. 配置百炼 API KEY:
export AI_DASHSCOPE_API_KEY=${REPLACE-WITH-VALID-API-KEY}

添加仓库和依赖

  1. 添加Spring仓库到您的pom.xml文件中,因为Spring AI的M1版本尚未提交到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>
  1. pom.xml中添加spring-ai-alibaba-starter依赖以及设置Spring Boot父项目依赖。确保使用与您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>

创建Controller类并注入ChatClient

  1. 创建一个新的Controller类ChatController,在其中注入ChatClient实例。这里还实现了跨域支持(CORS),并通过@GetMapping注解定义了一个名为/ai/steamChat的GET接口,该接口接受input参数作为用户输入,并返回Flux<String>类型的响应数据流。以下是完整的代码实现:
@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "*") // 开启跨域访问
public class ChatController {

  private final ChatClient chatClient;
  @Value("classpath:correct-and-expand.st")
  Resource resource;

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

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

应用属性配置

  1. application.propertiesapplication.yml中设置之前获得的通义千问API key:
spring.ai.dashscope.api-key=${AI_DASHSCOPE_API_KEY}

通过上述步骤,您已经成功地创建了一个基于Spring Boot的应用程序,它集成了Spring AI Alibaba,并提供了一个能够接收用户输入、生成响应文本并以流的形式返回结果的服务。此服务位于http://localhost:8080/ai/steamChat?input=...路径下,并且支持跨域请求。当用户通过这个URL发送带有input参数的GET请求时,系统将调用阿里云通义大模型处理该请求,并即时输出处理结果给客户端。

构建前端应用

构建前端

根据提供的我了解的信息,我们可以基于React创建一个简单的前端应用来支持流式数据输出。该应用将通过与后端的交互(使用http://localhost:8080/ai/steamChat?input=…作为请求地址),接收并显示以流形式返回的数据。下面是详细的构建步骤及所需代码。

创建新项目

首先,你需要在本地机器上设置一个新的React应用程序,并安装必要的依赖包。这可以通过运行以下命令完成:

npx create-react-app frontend
cd frontend
npm install

这些命令会生成一个新的名为frontend的React项目,并自动安装所有必需的基础依赖。

修改基本文件结构

接下来,我们将调整一些基础文件的内容以适应我们的需求。主要涉及修改public/index.htmlsrc/index.js以及新增组件ChatComponent用于处理聊天功能。

public/index.html

确保你的HTML文档头部包含正确的字符集声明和视口配置,以保证最佳的跨设备兼容性。这部分内容应该类似于:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Stream Chat App</title>

</head>

<body>
  <div id="root"></div>

</body>

</html>

src/index.js

保持默认的入口点配置不变,这样React就可以正确地渲染我们的根组件App了:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

src/App.js

定义App组件为一个简单的容器,它将包含我们即将实现的聊天组件ChatComponent

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

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

  );
}

export default App;

实现聊天组件

最后,我们需要开发核心的聊天组件ChatComponent,它负责用户输入处理、消息发送至服务器以及从服务器接收流式响应并在界面上展示。

src/components/ChatComponent.js

这个组件利用了React的状态管理机制来跟踪用户输入的消息和接收到的服务端响应。它还包含了向指定URL发起GET请求的功能,并实时更新界面显示最新的信息片段。

import React, { useState } from 'react';

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

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

  const handleSendMessage = async () => {
    try {
      const response = await fetch(`http://localhost:8080/ai/steamChat?input=${input}`);
      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((preMessages) => preMessages + chunk);
      }

      // 在每次请求完成后添加换行符
      setMessages((preMessages) => preMessages + '\n\n=============================\n\n');
    } catch (error) {
      console.error('Failed to fetch', error);
    }
  };

  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;

启动应用

一旦上述设置全部完成,你可以通过执行如下命令启动开发服务器,从而在浏览器中查看你的应用程序:

npm start

以上步骤描述了一个完整的流程,从初始化React项目到最终实现能够与提供流式数据服务端通信的应用程序。注意,在实际部署时,请确保后端服务已经启动并且允许来自前端应用的CORS请求。