0


复制下来就能跑:Java智能问答系统-介绍与代码实践 - 基于springboot_springai_国产大模型

本文的目的是在5分钟内能把智能问答系统的原理和实践讲明白

代码可执行,复制粘贴即可,可以快速跑起来。

智能问答系统简介

智能问答系统是一种人工智能应用,它能够理解用户提出的问题,并通过自然语言处理技术来分析和理解问题的含义。随后,系统会在其知识库中搜索相关信息,以生成一个或多个可能的答案。这些答案基于系统对问题的理解和知识库中的信息生成。

该系统的关键组成部分包括:

  1. 自然语言处理(NLP):这是系统的核心部分,负责理解用户的输入。NLP 涉及分词、词性标注、句法分析和语义理解等多个步骤,确保系统准确地解析用户意图。

  2. 知识库:存储了大量的结构化和非结构化数据,为系统提供解答问题所需的知识基础。这可以是事实数据库、规则集合或更复杂的概念框架。

  3. 检索与匹配算法:利用高效的搜索策略,在庞大的知识库中快速找到与用户查询最相关的信息片段。此过程可能涉及关键词匹配、向量空间模型或其他高级技术。

  4. 答案生成:结合从知识库中获取的数据,以及上下文信息,构建出易于理解且符合逻辑的回答。在某些情况下,还可能需要进行推理才能得出正确结论。

  5. 评估与反馈机制:持续监测生成答案的质量,并允许根据用户反馈调整模型参数或更新知识库内容,从而不断提高系统的性能和服务水平。

通过上述组件协同工作,智能问答系统能够在多种场景下发挥作用,比如在线客服支持、虚拟个人助理、教育培训领域等,极大地提升了用户体验和工作效率。

我们可以看到,随着大语言模型的落地,问答系统完全可以使用大语言模型来做,里面的自然语言处理,答案生成部分,就可以用大模型来做,而知识库和检索匹配算法,则可以用RAG检索增强技术来做。

后面的例子,我们使用 spring ai alibaba + 通义千问Qwen api 来构建这个智能问答系统 , qwen有100万免费Token额度,可以快速实现需求。同时,因为qwen 也是个开源的模型,我们可以自己搭建模型来实现免费使用

Spring AI Alibaba框架介绍

Spring AI Alibaba 是由Spring官方团队维护的一个针对AI工程的应用框架,专为Java开发者设计。它旨在通过标准化不同AI提供者(如OpenAI、Azure、阿里云等)的接口实现,让开发者能够“写一次代码,支持所有模型”,极大减少了迁移和开发的工作量。

此外,它还特别集成了阿里云百炼平台上的大模型服务,包括对话生成、文生图、文生语音等功能,并提供了检索增强生成(RAG)能力以利用私有知识库提高响应质量。这不仅体现了Spring生态系统的设计原则,也融入了阿里云在大规模AI应用中的最佳实践。

这套系统也是开源的,免费用。

通义千问大模型在多项基准测试中超越Llama 3 70B,获广泛认可

通义千问大模型在MMLU、TheoremQA、GPQA等基准测评中表现出色,超越了Llama 3 70B。这些评测指标被Claude和OpenAI广泛认可,能够客观地衡量模型的能力。此外,通义千问还在Hugging Face开源大模型排行榜Open LLM Leaderboard上荣登榜首,进一步证明了其卓越的性能。这一成就彰显了通义千问在处理复杂问题、理解和生成自然语言方面的强大能力,为用户提供了更加准确和可靠的帮助。

另外,在真人参与评测的arena里面,它不仅在思南平台 CompassArena 上仅次于国际知名的GPT和Claude系列,还在 Hugging Face的视觉模型竞技场 https://huggingface.co/spaces/lmarena-ai/chatbot-arena-leaderboard 中稳居中国首位。

检索增强生成(RAG)技术介绍:利用私有知识库提高LLM回复准确性

检索增强生成 (RAG) 是一种结合了检索模型和生成模型的技术,通过从私有知识库中检索相关信息来辅助大型语言模型生成更准确、具体的文本回复。它主要解决了使用大模型时的两个问题:一是减少因缺乏最新或特定信息而产生的“幻觉”现象;二是让模型能够利用企业特有的私有数据进行回答,从而提高回复的精准度与实用性。通过将企业的私有知识库与强大的生成能力相结合,RAG技术确保了输出内容既丰富又贴合实际情况。

检索增强后端代码开发:

为了实现通过检索增强 (RAG) 的方式读取名为“智能问答的问题集.docs”的PDF文件,构建向量索引,并对外提供服务,您需要按照以下步骤操作。这包括环境设置、依赖添加、API密钥配置、代码编写等环节。下面是详细的执行步骤:

1. 硯境准备

  • JDK版本:确保您的开发环境使用的是 JDK 17 或更高版本。

  • Spring Boot版本:项目需基于 Spring Boot 3.3.x 版本或以上。

2. 阿里云账号及API密钥申请

访问阿里云百炼页面,登录账号后开通“百炼大模型推理”服务。成功开通后,创建一个新的 API KEY 并妥善保存,用于后续的开发配置中。

3. 配置API KEY

在本地环境变量中配置刚刚获得的API KEY:

export AI_DASHSCOPE_API_KEY=这里替换为实际的API Key值

同时,在

application.properties

文件内增加如下配置行来注入API KEY:

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

4. 添加仓库与依赖

在项目的pom.xml文件中添加必要的仓库和依赖项,以便能够引用到

spring-ai-alibaba-starter

等相关组件。

<repositories>
    <!-- 忽略其他repository定义 -->
    <repository>
      <id>sonatype-snapshots</id>

      <url>https://oss.sonatype.org/content/repositories/snapshots</url>

      <snapshots><enabled>true</enabled></snapshots>

    </repository>

    <!-- 更多repository省略... -->
</repositories>

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>

        <artifactId>spring-ai-alibaba-starter</artifactId>

        <version>1.0.0-M2.1</version>

    </dependency>

    <!-- 其他依赖 -->
</dependencies>

5. 编写RAG服务相关代码

RagService类

此部分实现了对指定PDF文档的处理、向量存储以及基于文档内容的查询功能。

public class RagService {
    private final ChatClient chatClient;
    private final VectorStore vectorStore;
    private final DashScopeApi dashscopeApi = new DashScopeApi("你的API KEY");
    DocumentRetriever retriever;

    public RagService(ChatClient chatClient, EmbeddingModel embeddingModel) {
        this.chatClient = chatClient;
        vectorStore = new DashScopeCloudStore(dashscopeApi, new DashScopeStoreOptions("问题集知识库"));
        retriever = new DashScopeDocumentRetriever(dashscopeApi,
                DashScopeDocumentRetrieverOptions.builder().withIndexName("问题集知识库").build());
    }

    public String buildIndex() {
        String filePath = "路径/智能问答的问题集.docs";
        DocumentReader reader = new DashScopeDocumentCloudReader(filePath, dashscopeApi, null);
        List<Document> documentList = reader.get();
        vectorStore.add(documentList);
        return "SUCCESS";
    }

    public StreamResponseSpec queryWithDocumentRetrieval(String message) {
        return chatClient.prompt().user(message)
            .advisors(new DocumentRetrivalAdvisor(retriever, DEFAULT_USER_TEXT_ADVISE)).stream();
    }
}
RagController类

负责接收客户端请求并调用相应的服务方法。

@RestController
@RequestMapping("/ai")
public class RagController {
    private final RagService ragService;

    public RagController(RagService ragService) {
        this.ragService = ragService;
    }

    @GetMapping("/steamChat")
    public Flux<String> generate(@RequestParam("input") String input, HttpServletResponse response) {
        StreamResponseSpec chatResponse = ragService.queryWithDocumentRetrieval(input);
        response.setCharacterEncoding("UTF-8");
        return chatResponse.content();
    }

    @GetMapping("/buildIndex")
    public String buildIndex() {
        return ragService.buildIndex();
    }
}

解释

上述步骤首先设置了正确的开发环境并获取了必要的认证信息(API KEY)。然后,通过添加适当的Maven仓库和依赖项使得项目可以引用所需的Spring AI Alibaba组件。接着,我们定义了一个

RagService

类来处理PDF文件的数据提取与索引建立工作,以及一个简单的控制器

RagController

用来暴露RESTful接口供外部调用。最后,用户可以通过先访问

/buildIndex

端点初始化索引,再利用

/steamChat?input=...

进行实际的聊天式查询。

增强检索的前端代码实现

在你需要构建的项目中,将基于React创建一个简单的前端应用,该应用通过调用后端接口(URL:

http://localhost:8080/ai/steamChat?input=...

)来实现流式数据接收,并显示给用户。此过程包括创建新的React应用程序、配置文件结构以及编写必要的组件代码以支持流输出。

构建项目并填写代码

首先,按照以下步骤创建一个新的React应用并安装所需的依赖:

npx create-react-app frontend
cd frontend
npm install

然后,在你的项目中定义几个关键文件及其内容如下:

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应用的入口点:

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

设置主应用组件,它会渲染聊天组件:

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

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}`);
      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('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;

运行项目

完成以上配置之后,你可以通过执行以下命令启动前端开发服务器:

cd frontend
npm start

这段代码和配置使得你的React应用能够向指定的后端服务发送请求,并且以流的形式读取返回的数据,实时地将其展示给用户。每当有新的字符到达时,页面上的消息区域就会自动更新。此外,还提供了清除消息的功能以便于测试或实际使用中的需求。


本文转载自: https://blog.csdn.net/whisperzzza/article/details/143573537
版权归原作者 沈询-阿里 所有, 如有侵权,请联系我们删除。

“复制下来就能跑:Java智能问答系统-介绍与代码实践 - 基于springboot_springai_国产大模型”的评论:

还没有评论