马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
rag 需求产生的配景先容:
在利用大模子时,常遇到的标题之一是模子大概产生幻觉,即天生的内容缺乏准确性。别的,由于大模子不直接访问企业的专有数据,其相应大概会显得泛泛而谈,不敷精准或详细,无法充实利用企业内部的特定信息举行个性化答复。这些标题限定了大模子在某些必要高精度和定制化场景中的应用结果。
Spring AI 的团体阐明
我们利用了Spring AI来做检索加强,选择Spring AI是由于它办理了已往用Java编写AI应用时缺乏尺度化封装的标题。Spring AI提供了一套兼容市面上紧张天生使命的接口,极大简化了开辟流程。通过Spring AI,开辟者可以轻松实现对多种模子的支持,仅需更改设置即可切换差异的AI服务提供者,从而极大地进步了开辟服从和机动性。别的,Spring AI与Spring生态体系的无缝集成,进一步确保了应用步伐的可移植性和模块化操持。
Spring AI alibaba先容
Spring AI Alibaba是专为Java开辟者操持的一个框架,它集成了阿里云的AI本领,特殊是通义大模子服务,使得开辟者可以大概快速实现诸如文本天生、绘画等基于AI的功能。其焦点上风在于尺度化了差异AI提供者(如OpenAI、Azure、阿里云)的接口,这意味着开辟者只需编写一次代码,通过简单的设置调解即可切换差异的AI服务。对于绘画或图像天生而言,Spring AI Alibaba简化了与阿里云万象模子交互的过程,允许用户轻松调用API天生高质量图像。别的,框架还提供了包罗OutputParser、Prompt Template在内的实勤劳能,进一步低沉了开辟复杂度,让开辟者可以专注于业务逻辑而非底层技能细节。总之,Spring AI Alibaba极大提升了利用Java举行AI应用开辟的服从和机动性。
检索加强的后端代码编写
根据提供的我相识的信息,为了实现通过检索加强(RAG)方式读取阿里巴巴的财政报表PDF,并对外提供服务,必要按照如下步调举行设置和编码。这将允许你先调用/buildIndex构建索引,之后可以大概通过访问http://localhost:8080/ai/rag?message=...来获取基于该文档内容天生的答复。
前置条件
确保你的开辟情况满意以下要求:
- 从阿里云获取通义千问API key并设置情况变量 AI_DASHSCOPE_API_KEY 大概直接在application.properties中设置 spring.ai.dashscope.api-key。
添加Spring AI Alibaba依赖
在项目中添加须要的堆栈以及spring-ai-alibaba-starter依赖项:
- <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>
复制代码 同时,请确保您的pom.xml文件中界说了准确的Spring Boot父项目版本。
RAG服务类实现
创建一个名为RagService的服务类,用于处置处罚向量存储、文档检索等逻辑:
- 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}
- ---------------------
- 根据上下文回答问题。如果答案不在上下文中,请告知用户无法回答。
- """))
- .stream();
- }
- }
复制代码 控制器类实现
末了,实现一个REST控制器以袒露/buildIndex与/rag端点:
- @RestController
- @RequestMapping("/ai")
- public class RagController {
- private final RagService ragService;
- @Autowired
- public 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();
- }
- }
复制代码 通过上述步调,您已经乐成设置了利用RAG技能处置处罚PDF文档并提供问答服务的根本架构。记得起首运行/buildIndex来初始化数据索引,随后可以通过/rag?message=...发起查询哀求获取结果。
检索加强的前端代码编写
构建项目并填写代码
起首,创建一个新的 React 应用并安装所需的依赖:
- npx create-react-app ragChatFrontend
- cd ragChatFrontend
- npm install
复制代码 public/index.html
编辑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>RAG 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 RAGChatComponent from './components/RAGChatComponent';
- function App() {
- return (
- <div className="App">
- <RAGChatComponent />
- </div>
- );
- }
- export default App;
复制代码 src/components/RAGChatComponent.js
这是焦点的谈天组件,实现了与后端流式接口的交互。这里我们假设后端支持GET方法来吸收查询参数input并返回flux<String>格式的数据流。
- 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和请求方式要与你的后端服务相匹配
- 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>
- <input
- type="text"
- value={input}
- onChange={handleInputChange}
- placeholder="输入您的问题..."
- />
- <button onClick={handleSendMessage}>发送</button>
- <button onClick={handleClearMessages}>清空</button>
- <h3>聊天记录:</h3>
- <pre>{messages}</pre>
- </div>
- );
- }
- export default RAGChatComponent;
复制代码 运行项目
完成以上步调后,您可以通过以下下令启动前端应用举行测试:
- cd ragChatFrontend
- npm start
复制代码 这将打开一个当地服务器,默认访问地点为 http://localhost:3000,您可以在这里检察到构建好的应用步伐界面。
上述实现基于React框架,并通过fetch API调用后端提供的流式数据接口。每当用户点击“发送”按钮时,会触发对指定后端服务的HTTP GET哀求,随后从前端逐段读取返回的流数据并体现给用户。请注意调解实际摆设时大概涉及的跨域战略(CORS)以包管前后端之间通讯顺畅。
|