构建专属学英语的机器人,基于 spring AI Alibaba 和SpringBoot
学英语的机器人介绍
在学英语这个场景下,我们往往需要有个机器人跟我们对话,并能够实时告诉我我们每句话的语法错误,并引导我们做下一步的对话动作。
这时候就我们就可以自己做一个AI助手,不仅能够自动检测并纠正用户输入的英文错误,确保语言使用的准确性,还可以根据用户的兴趣点或特定需求生成相关话题,促进更自然流畅的对话交流。通过这种方式,学习者能够在模拟真实交流环境中得到充分练习,从而有效提高其英语听说能力。
我们使用基于通义千问等大模型实现高质量的文本生成和prompt能力来做到这件事。
Spring AI 是什么
Spring AI是一个专为AI工程设计的应用框架,它将Spring生态系统的设计原则如可移植性和模块化应用于AI领域。Spring AI的核心优势在于其标准化了不同AI提供者(例如OpenAI、Azure、阿里云等)的接口实现,允许开发者编写一次代码后,只需更改配置即可轻松切换不同的AI服务。这不仅简化了与多个AI平台对接的过程,还极大减少了开发和迁移工作量。此外,由于直接兼容Flux流输出,Spring AI可以无缝集成到基于流处理的各种机器人模型中。通过与SpringBoot的高度整合,Spring AI进一步提升了开发效率,使得在SpringBoot项目中添加强大的AI功能变得异常简单。
Spring AI alibaba 是什么?
Spring AI Alibaba 是 Spring AI 的一个实现,专为与阿里云的百炼系列云产品中的大模型进行集成而设计。它基于 Spring Boot 构建,并遵循 Spring 生态系统的设计原则,如可移植性和模块化。Spring AI Alibaba 允许开发者轻松地在 Spring Boot 项目中接入和使用阿里云通义大模型的各项能力,包括对话、文生图等,无需深入研究复杂的 API 文档。其核心优势在于通过标准化接口简化了不同 AI 提供商之间的切换过程,极大减少了开发和迁移工作量。同时,它还提供了诸如 Prompt Template 和 OutputParser 等实用功能,进一步增强了开发效率。
SpringBoot介绍
Spring Boot 是一个用于简化新 Spring 应用的初始搭建以及开发过程的框架。它通过约定大于配置的理念,使得开发者可以快速构建独立的、生产级别的基于 Spring 的应用,而无需过多配置。Spring Boot 内嵌了 Tomcat、Jetty 或 Undertow 等服务器,可以直接打包成可执行的 JAR 文件运行。
详细的构建步骤
构建后端
项目构建步骤
首先,我们需要创建一个基于 Spring Boot 的项目,并引入
spring-ai-alibaba-starter
依赖。然后,我们将配置支持 CORS 跨域的 GET 接口
/ai/chatStream
,该接口接受用户输入并返回 Flux 流数据。此外,我们将使用 Prompt 模板来处理用户的英文错误纠正和内容扩展。
步骤 1: 创建 Spring Boot 项目
确保你已经安装了 JDK 17 或以上版本,以及 Spring Boot 3.3.x 版本。你可以通过 Spring Initializr(https://start.spring.io/)创建新项目。选择以下依赖:
- Spring Web
- Spring AI Alibaba Starter
生成项目后,导入到你喜欢的 IDE 中。
步骤 2: 添加阿里云仓库与相关依赖
在项目的
pom.xml
文件中添加如下代码片段以启用 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>
接着,在
<dependencies>
部分加入对
spring-ai-alibaba-starter
的引用:
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0-M2</version>
</dependency>
同时,请确保你的项目继承了正确的 Spring Boot 父 POM。
步骤 3: 配置通义千问API密钥
你需要从阿里云获取通义千问 API 密钥。按照[知识]中的说明操作,并将获得的密钥设置为环境变量或直接写入
application.properties
文件中:
spring.ai.dashscope.api-key=YOUR_API_KEY
步骤 4: 编写Controller实现流式响应
接下来,我们将在项目中编写 Controller 类,它包含了一个 GET 请求处理器,该处理器利用
ChatClient
与通义大模型交互,并以 Flux 形式返回消息。
@RestController
@RequestMapping("/ai")
public class ChatController {
@Autowired
private ChatClient chatClient;
@Value("classpath:/prompts/correct-and-extend-prompt.st")
private Resource resource;
@GetMapping(value = "/chatStream")
public Flux<String> chat(@RequestParam String input) {
PromptTemplate promptTemplate = new PromptTemplate(resource);
Prompt prompt = promptTemplate.create(Map.of("input", input));
return chatClient.prompt(prompt)
.stream().content();
}
}
这里定义了一个名为
chat
的方法,它接收用户输入作为参数,并构造一个 Prompt,该 Prompt 不仅会纠正输入中的英文错误,还会基于此进行延展提问。最后,通过调用
content()
方法将结果以 Flux 流形式返回给客户端。
correct-and-extend-prompt.st
Correct the following English sentence: "{input}"
Then, extend the corrected sentence and ask a follow-up question in English.
步骤 5: 启动应用
完成上述所有配置后,可以启动你的 Spring Boot 应用了。如果一切正常,现在你应该能够访问
http://localhost:8080/ai/chatStream?input=your_message
来测试这个新的聊天接口了。
注意:别忘了确保前端请求时正确设置了跨域资源共享(CORS),可以通过在 Spring Security 配置类中开启全局CORS支持或者针对特定控制器增加注解方式解决。
以上就是整个过程的详细描述,希望对你有所帮助!
构建前端
为了构建一个基于React的前端项目,该前端项目能够与返回
flux<String>
流数据的后端接口进行交互,我们可以遵循如下步骤来设置我们的开发环境和编写必要的代码。这里,我们假设后端接口URL为
http://localhost:8080/ai/chatStream?input=...
,它支持通过GET请求接收输入参数,并以流的形式返回响应。
创建新的React应用
首先,您需要在您的机器上安装Node.js及npm(如果尚未安装的话)。之后,执行以下命令来创建一个新的React应用并切换至其目录:
npx create-react-app frontend
cd frontend
接下来,请确保安装所有必需的依赖项:
npm install
这将为您搭建好基础的React项目结构。
编写基本文件内容
public/index.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>
src/index.js
同样地,对于入口JS文件,通常不需要做太多修改:
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
此文件定义了应用程序的主要组件布局,我们将引入
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
这里是关键所在——处理用户输入、发送请求给服务器以及实时展示接收到的数据流。我们使用
useState
来管理状态变量
messages
用于存储消息历史记录。
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 () => {
try {
const response = await fetch(`http://localhost:8080/ai/chatStream?input=${input}`);
if (!response.ok) throw new Error(response.statusText);
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((prev) => prev + chunk);
}
} 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>
<pre>{messages}</pre>
</div>
);
};
export default ChatComponent;
请注意,在调用
fetch
时指定了正确的URL路径,并且我们在读取响应体的过程中逐步更新了
messages
状态。这种方式非常适合处理来自服务器的持续流式数据输出。
运行项目
一旦完成了上述设置和编码工作,您可以通过运行以下命令启动您的React应用:
npm start
现在,当您访问
http://localhost:3000
时,应该能看到一个简单的聊天界面,允许用户输入文本并显示从服务器获取到的消息流。请确保后端服务也已正确配置并且正在监听指定端口上的请求。
版权归原作者 沈询-阿里 所有, 如有侵权,请联系我们删除。