電腦銷售網(wǎng)站開發(fā)論文企業(yè)網(wǎng)站seo推廣方案
rag 需求產(chǎn)生的背景介紹:
在使用大模型時(shí),常遇到的問題之一是模型可能產(chǎn)生幻覺,即生成的內(nèi)容缺乏準(zhǔn)確性。此外,由于大模型不直接訪問企業(yè)的專有數(shù)據(jù),其響應(yīng)可能會(huì)顯得泛泛而談,不夠精準(zhǔn)或具體,無法充分利用企業(yè)內(nèi)部的特定信息進(jìn)行個(gè)性化回答。這些問題限制了大模型在某些需要高精度和定制化場景中的應(yīng)用效果。
整體說明
我們使用了Spring AI來做檢索增強(qiáng),選擇Spring AI是因?yàn)樗鉀Q了過去用Java編寫AI應(yīng)用時(shí)缺乏標(biāo)準(zhǔn)化封裝的問題。Spring AI提供了一套兼容市面上主要生成任務(wù)的接口,極大簡化了開發(fā)流程。通過Spring AI,開發(fā)者可以輕松實(shí)現(xiàn)對(duì)多種模型的支持,僅需更改配置即可切換不同的AI服務(wù)提供者,從而極大地提高了開發(fā)效率和靈活性。此外,Spring AI與Spring生態(tài)系統(tǒng)的無縫集成,進(jìn)一步確保了應(yīng)用程序的可移植性和模塊化設(shè)計(jì)。
Spring AI alibaba介紹
Spring AI Alibaba是專為Java開發(fā)者設(shè)計(jì)的一個(gè)框架,它集成了阿里云的AI能力,特別是通義大模型服務(wù),使得開發(fā)者能夠快速實(shí)現(xiàn)諸如文本生成、繪畫等基于AI的功能。其核心優(yōu)勢在于標(biāo)準(zhǔn)化了不同AI提供者(如OpenAI、Azure、阿里云)的接口,這意味著開發(fā)者只需編寫一次代碼,通過簡單的配置調(diào)整即可切換不同的AI服務(wù)。對(duì)于繪畫或圖像生成而言,Spring AI Alibaba簡化了與阿里云萬象模型交互的過程,允許用戶輕松調(diào)用API生成高質(zhì)量圖像。此外,框架還提供了包括OutputParser、Prompt Template在內(nèi)的實(shí)用功能,進(jìn)一步降低了開發(fā)復(fù)雜度,讓開發(fā)者可以專注于業(yè)務(wù)邏輯而非底層技術(shù)細(xì)節(jié)??傊?#xff0c;Spring AI Alibaba極大提升了使用Java進(jìn)行AI應(yīng)用開發(fā)的效率和靈活性。
檢索增強(qiáng)的后端代碼編寫
根據(jù)提供的我了解的信息,為了實(shí)現(xiàn)通過檢索增強(qiáng)(RAG)方式讀取阿里巴巴的財(cái)務(wù)報(bào)表PDF,并對(duì)外提供服務(wù),需要按照如下步驟進(jìn)行配置和編碼。這將允許你先調(diào)用/buildIndex
構(gòu)建索引,之后能夠通過訪問http://localhost:8080/ai/rag?message=...
來獲取基于該文檔內(nèi)容生成的回答。
前置條件
確保你的開發(fā)環(huán)境滿足以下要求:
- JDK版本為17或更高。
- Spring Boot版本為3.3.x或以上。
- 從阿里云獲取通義千問API key并設(shè)置環(huán)境變量
AI_DASHSCOPE_API_KEY
或者直接在application.properties
中配置spring.ai.dashscope.api-key
。
添加Spring AI Alibaba依賴
在項(xiàng)目中添加必要的倉庫以及spring-ai-alibaba-starter
依賴項(xiàng):
<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-M2</version></dependency><!-- 其他必要依賴 -->
</dependencies>
同時(shí),請(qǐng)確保您的pom.xml
文件中定義了正確的Spring Boot父項(xiàng)目版本。
RAG服務(wù)類實(shí)現(xiàn)
創(chuàng)建一個(gè)名為RagService
的服務(wù)類,用于處理向量存儲(chǔ)、文檔檢索等邏輯:
public class RagService {private final ChatClient chatClient;private final VectorStore vectorStore;private final DashScopeApi dashscopeApi = new DashScopeApi("YOUR_API_KEY_HERE");private DocumentRetriever retriever;public RagService(ChatClient chatClient, EmbeddingModel embeddingModel) {this.chatClient = chatClient;vectorStore = new DashScopeCloudStore(dashscopeApi, new DashScopeStoreOptions("financial-reports"));retriever = new DashScopeDocumentRetriever(dashscopeApi,DashScopeDocumentRetrieverOptions.builder().withIndexName("financial-reports").build());}public String buildIndex() {String filePath = "/path/to/your/AlibabaFinancialReport.pdf";DocumentReader reader = new DashScopeDocumentCloudReader(filePath, dashscopeApi, null);List<Document> documents = reader.get();vectorStore.add(documents);return "SUCCESS";}public StreamResponseSpec queryWithDocumentRetrieval(String message) {return chatClient.prompt().user(message).advisors(new DocumentRetrievalAdvisor(retriever, """上下文信息如下。---------------------{documents}---------------------根據(jù)上下文回答問題。如果答案不在上下文中,請(qǐng)告知用戶無法回答。""")).stream();}
}
控制器類實(shí)現(xiàn)
最后,實(shí)現(xiàn)一個(gè)REST控制器以暴露/buildIndex
與/rag
端點(diǎn):
@RestController
@RequestMapping("/ai")
public class RagController {private final RagService ragService;@Autowiredpublic RagController(RagService ragService) {this.ragService = ragService;}@GetMapping("/buildIndex")public String buildIndex() {return ragService.buildIndex();}@GetMapping("/ragChat")public Flux<String> generate(@RequestParam(value = "input") String message, HttpServletResponse response) {response.setCharacterEncoding("UTF-8");return ragService.queryWithDocumentRetrieval(message).content();}
}
通過上述步驟,您已經(jīng)成功設(shè)置了使用RAG技術(shù)處理PDF文檔并提供問答服務(wù)的基礎(chǔ)架構(gòu)。記得首先運(yùn)行/buildIndex
來初始化數(shù)據(jù)索引,隨后可以通過/rag?message=...
發(fā)起查詢請(qǐng)求獲取結(jié)果。
檢索增強(qiáng)的前端代碼編寫
構(gòu)建項(xiàng)目并填寫代碼
首先,創(chuàng)建一個(gè)新的 React 應(yīng)用并安裝所需的依賴:
npx create-react-app ragChatFrontend
cd ragChatFrontend
npm install
public/index.html
編輯public/index.html
文件以確?;A(chǔ)HTML結(jié)構(gòu)正確設(shè)置。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>RAG Chat App</title></head><body><div id="root"></div></body></html>
src/index.js
配置React應(yīng)用入口點(diǎn)。
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
定義主應(yīng)用組件,并引入聊天組件。
import React from 'react';
import RAGChatComponent from './components/RAGChatComponent';function App() {return (<div className="App"><RAGChatComponent /></div>);
}export default App;
src/components/RAGChatComponent.js
這是核心的聊天組件,實(shí)現(xiàn)了與后端流式接口的交互。這里我們假設(shè)后端支持GET
方法來接收查詢參數(shù)input
并返回flux<String>
格式的數(shù)據(jù)流。
import React, { useState } from 'react';function RAGChatComponent() {const [input, setInput] = useState('');const [messages, setMessages] = useState('');const handleInputChange = (event) => {setInput(event.target.value);};const handleSendMessage = async () => {try {// 注意這里的URL和請(qǐng)求方式要與你的后端服務(wù)相匹配const response = await fetch(`http://localhost:8080/ai/ragChat?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 data:', error);}};const handleClearMessages = () => {setMessages('');};return (<div><inputtype="text"value={input}onChange={handleInputChange}placeholder="輸入您的問題..."/><button onClick={handleSendMessage}>發(fā)送</button><button onClick={handleClearMessages}>清空</button><h3>聊天記錄:</h3><pre>{messages}</pre></div>);
}export default RAGChatComponent;
運(yùn)行項(xiàng)目
完成以上步驟后,您可以通過以下命令啟動(dòng)前端應(yīng)用進(jìn)行測試:
cd ragChatFrontend
npm start
這將打開一個(gè)本地服務(wù)器,默認(rèn)訪問地址為 http://localhost:3000,您可以在這里查看到構(gòu)建好的應(yīng)用程序界面。
上述實(shí)現(xiàn)基于React框架,并通過fetch API
調(diào)用后端提供的流式數(shù)據(jù)接口。每當(dāng)用戶點(diǎn)擊“發(fā)送”按鈕時(shí),會(huì)觸發(fā)對(duì)指定后端服務(wù)的HTTP GET請(qǐng)求,隨后從前端逐段讀取返回的流數(shù)據(jù)并顯示給用戶。請(qǐng)注意調(diào)整實(shí)際部署時(shí)可能涉及的跨域策略(CORS)以保證前后端之間通信順暢。