本文主旨介绍:
本文教你怎样用Spring AI给Java项目加上通义千问的AI功能。 按照流程说明,复制下来就能跑,比较简单的入门。
本例子基于spring ai alibaba 和 QWen千问API实现。QWen现在提供100万免费Token额度,方便你快速上手。另外,QWen是开源模型,自己搭建也能免费使用。
Spring AI:简化AI应用开发的Java框架
在过去,Java 缺乏一个优秀的 AI 应用框架。这给开发者带来不少困扰。Spring AI 的出现解决了这个问题。它是一个专为 AI 工程设计的应用框架。Spring AI 标准化了不同 AI 提供者的接口实现。这样,只需编写一次代码,通过修改配置就能轻松切换不同的 AI 服务。这个特性极大地简化了开发工作。Spring AI 与 Java 的面向对象编程理念完美契合。同时,它也与 Spring 生态系统兼容得非常好。使用 Spring AI 可以减少程序员在对接不同 AI 提供者时查阅大量文档的工作量。总的来说,Spring AI 让开发变得更加高效便捷。
Spring AI与阿里云集成介绍
Spring AI Alibaba 是一个基于 Spring AI 的实现。它支持接入阿里云的百炼大模型服务。通过这个框架,开发者能够轻松使用通义提供的聊天、图片或语音生成等AI功能。它的优势在于标准化了不同AI供应商的接口,简化了开发流程。使得程序员只需编写一次代码,通过修改配置即可切换不同的AI服务提供者。此外,它还提供了诸如OutputParser、Prompt Template等功能,方便处理和解析AI模型的输出。这样极大减少了开发者在对接各种AI接口时的工作量。
通义千问基模介绍
本例采用的是阿里通义千问是由阿里集团提供的开源大模型服务,支持全尺寸、多模态的大规模语言模型。在中文开源模型领域中,通义千问表现卓越,在国内的思南大模型竞技场排名上名列前茅。
通义千问的核心优势包括:首先,在MMLU、TheoremQA、GPQA等客观评测指标上超越了Llama 3 70B,位居国产大模型第一梯队;其次,具备较高的可访问性和合规性,通过API调用时有安全保护措施;此外,完全开源,提供了多种尺寸的多模态大模型版本供用户选择,并且不贵,提供100万免费token,构建成本较低。
对于大模型的能力评估,通常采用基准测试和人类评估两种方法。基准测试如GSM-8K、MMLU等可以深入考察特定领域的技能掌握情况,而人类评估则更贴近实际应用场景,能更直观地体现机器回答对人类的帮助。更多相关信息可参考以下链接:
- 国际竞技场排行榜: https://lmarena.ai
- 国内思南平台: https://arena.opencompass.org.cn/
基于Spring Boot整合Spring AI Alibaba实现对话模型
要基于Spring Boot集成Spring AI Alibaba完成一个简单的对话模型,并构建一个支持prompt的流返回接口,首先我们需要确保项目环境符合要求,并按步骤配置依赖、API密钥等信息。根据提供的我了解的信息内容,下面将详细介绍具体步骤。
前置条件
- JDK版本:17或以上。
- Spring Boot版本:3.3.x或更高。
步骤一:申请通义千问API密钥
访问阿里云百炼页面,登录您的账号并开通“百炼大模型推理”服务,按照指引创建一个新的API密钥。记录此密钥值,用于后续步骤中的配置。
步骤二:设置环境变量
在本地环境中设置环境变量AI_DASHSCOPE_API_KEY
,其值为上一步获取到的API密钥。
export AI_DASHSCOPE_API_KEY=你的API密钥
步骤三:添加仓库与依赖
由于Spring AI Alibaba当前版本尚未提交至Maven中央仓库,因此需要手动添加Spring相关的仓库以及依赖项到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>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0-M3.1</version>
</dependency>
<!-- 其他依赖 -->
</dependencies>
步骤四:配置application.properties
编辑src/main/resources/application.properties
文件,加入以下配置来指定API密钥及允许跨域请求:
spring.ai.dashscope.api-key=${AI_DASHSCOPE_API_KEY}
spring.mvc.cors.allowed-origins=*
步骤五:编写Controller
创建一个新的Controller类ChatController.java
,用于处理HTTP GET请求,并通过ChatClient
实例调用AI服务。同时支持基于流的方式返回结果:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import javax.servlet.http.HttpServletResponse;
@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, HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
PromptTemplate promptTemplate = new PromptTemplate(resource);
Prompt prompt = promptTemplate.create(Map.of("input", input));
return chatClient.prompt(prompt).stream().content();
}
}
上述代码片段定义了一个名为/steamChat
的GET接口,它接受一个input
参数作为用户输入,并利用ChatClient
对象发起对AI服务的请求。该接口还启用了CORS以允许跨域请求。
通过遵循以上步骤,您就可以成功地基于Spring Boot集成了Spring AI Alibaba,创建出能够处理简单对话请求并通过流式响应提供输出的服务端点。这包括了从环境准备到最终编码实现的所有关键环节。
构建React前端项目
在基于React构建一个简单的支持流输出的前端项目时,我们需要完成几个步骤:首先创建React应用并安装必要的依赖;接着修改或创建项目文件来实现聊天组件的功能,该组件能够发送请求到指定后端URL,并实时显示从服务器接收到的消息。根据提供的知识我了解的信息,下面将详细介绍如何操作。
构建项目并填写代码
1. 创建新的React应用
打开终端,运行以下命令来创建一个新的React应用,并进入项目目录:
npx create-react-app frontend
cd frontend
npm install
这会为你设置好基础的React环境。
2. 修改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>Chat App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
3. 设置src/index.js
作为应用程序入口点
保持默认内容不变即可,这段代码负责渲染App组件到页面上:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
4. 定义主应用组件src/App.js
这个组件将包含我们的聊天界面。目前只需要简单地导入并展示ChatComponent
:
import React from 'react';
import ChatComponent from './components/ChatComponent';
function App() {
return (
<div className="App">
<ChatComponent />
</div>
);
}
export default App;
5. 创建聊天功能组件src/components/ChatComponent.js
这里是处理与后端交互逻辑的地方。我们使用useState
钩子管理输入值和消息列表状态,通过点击按钮触发向后端发起请求的行为,然后监听响应流,每次接收数据片段时更新UI。
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
此时,你应该能够在浏览器中看到一个基本的聊天界面,用户可以输入信息并通过点击“Send”按钮发送给后端服务。后端返回的数据将以流的形式被客户端读取并在界面上逐步展示出来。
请注意,本示例假设后端服务已正确配置并允许来自前端应用的跨域请求(CORS)。如果遇到问题,请检查后端的相关设置。