|
ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;letter-spacing: 1.5px;text-align: center;white-space: normal;background-color: rgb(255, 255, 255);-webkit-tap-highlight-color: transparent;outline: 0px;caret-color: red;">RAG 应用架构概述 - Embedding 模型:nomic-embed-text:latest,用于将文本数据向量化。
- Ollama Chat 模型:deepseek-r1:8b,生成最终答案。
Docker Compose 启动 Ollama:(同时启动一个模型前端系统,和 Ollama 模型交互。)services:
ollama: container_name: ollama image: ollama/ollama:latest ports: - 11434:11434
open-webui: image:ghcr.io/open-webui/open-webui:main container_name: open-webui ports: - 3005:8080 environment: - 'OLLAMA_BASE_URL=http://host.docker.internal:11434' # 允许容器访问宿主机网络 extra_hosts: - host.docker.internal:host-gateway
dockerexec-itollamaollamapulldeepseek-r1:8bdockerexec-itollamaollamapullnomic-embed-text:latest
在 open-webui 中调用 deepseek-r1:8b 模型:services:
elasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:8.16.1container_name: elasticsearchprivileged: trueenvironment:- "cluster.name=elasticsearch"- "discovery.type=single-node"- "ES_JAVA_OPTS=-Xms512m -Xmx1096m"- bootstrap.memory_lock=truevolumes:- ./config/es.yaml:/usr/share/elasticsearch/config/elasticsearch.ymlports:- "9200:9200"- "9300:9300"deploy:resources:limits:cpus: "2"memory: 1000Mreservations:memory: 200M
cluster.name: docker-esnode.name: es-node-1network.host: 0.0.0.0network.publish_host: 0.0.0.0http.port: 9200http.cors.enabled: truehttp.cors.allow-origin: "*"bootstrap.memory_lock: true
# 关闭认证授权 es 8.x 默认开启xpack.security.enabled: false
至此,便完成搭建一个简单 RAG 应用的所有环境准备步骤。下面开始搭建项目。<!-- Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.3.4</version></dependency>
<!-- Spring AI Ollama Starter --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId><version>1.0.0-M5</version></dependency>
<!-- 向量存储 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-elasticsearch-store</artifactId><version>1.0.0-M5</version></dependency>
<!-- PDF 解析 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-pdf-document-reader</artifactId><version>1.0.0-M5</version></dependency>
spring:
ai:# ollama 配置ollama:base-url: http://127.0.0.1:11434chat:model: deepseek-r1:8bembedding:model: nomic-embed-text:latest# 向量数据库配置vectorstore:elasticsearch:index-name: ollama-rag-embedding-indexsimilarity: cosinedimensions: 768
elasticsearch:uris: http://127.0.0.1:9200
- dimensions 为向量模型生成的向量维度(需要和向量模型生成的向量维度一致,默认值为 1576);
- similarity 定义了用于衡量向量之间相似度的算法或度量方式,这里使用余弦相似度,使用高维稀疏向量。
如果您想自定义 es 的实例化配置,需要引入 spring-ai-elasticsearch-store:<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-elasticsearch-store</artifactId><version>1.0.0-M5</version></dependency>
你是一个MacOS专家,请基于以下上下文回答:
---------------------{question_answer_context}---------------------
请结合给定上下文和提供的历史信息,用中文 Markdown 格式回答,若答案不在上下文中请明确告知。
ingFang SC", system-ui, -apple-system, system-ui, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 1.75em;visibility: visible;margin-bottom: 0px;"> 在 Spring AI 和 Spring AI Alibaba 中,几乎可以将任意数据源作为知识库来源。此例中使用 PDF 作为知识库文档。Spring AI Alibaba 提供了 40+ 的 document-reader 和 parser 插件。用来将数据加载到 RAG 应用中。public class KnowledgeInitializer implements ApplicationRunner {
// 注入 VectorStore 实例,负责向量化数据的增查操作private final VectorStore vectorStore;
// 向量数据库客户端,此处使用 esprivate final ElasticsearchClient elasticsearchClient;
// .....
@Overridepublic void run(ApplicationArguments args) {
// 1. load pdf resources.List<Resource> pdfResources = loadPdfResources();
// 2. parse pdf resources to Documents.List<Document> documents = parsePdfResource(pdfResources);
// 3. import to ES.importToES(documents);}
private List<Document> parsePdfResource(List<Resource> pdfResources) {
// 按照指定策略切分文本并转为 Document 资源对象for (Resource springAiResource : pdfResources) {
// 1. parse documentDocumentReader reader = new PagePdfDocumentReader(springAiResource);List<Document> documents = reader.get();logger.info("{} documents loaded", documents.size());
// 2. split trunksList<Document> splitDocuments = new TokenTextSplitter().apply(documents);logger.info("{} documents split", splitDocuments.size());
// 3. add res listresList.addAll(splitDocuments);}}
// ......}
接下来,将使用 Spring AI 中的 Ollama Starter 来完成和模型交互。构建 RAG 应用。@Servicepublic class AIRagService {
// 引入 system prompt tmpl@Value("classpath:/prompts/system-qa.st")private Resource systemResource;
// 注入相关 bean 实例private final ChatModel ragChatModel;
private final VectorStore vectorStore;
// 文本过滤,增强向量检索精度private static final String textField = "content";
// ......
public Flux<String> retrieve(String prompt) {
// 加载 prompt tmplString promptTemplate = getPromptTemplate(systemResource);
// 启用混合搜索,包括嵌入和全文搜索SearchRequest searchRequest = SearchRequest.builder().topK(4).similarityThresholdAll().build();
// build chatClient,发起大模型服务调用。return ChatClient.builder(ragChatModel).build().prompt().advisors(new QuestionAnswerAdvisor(vectorStore, searchRequest, promptTemplate)).user(prompt).stream().content();}}
编写用户请求接口,处理用户请求,调用 service 获得大模型响应:@RestController@RequestMapping("/rag/ai")public class AIRagController {
@Resourcepublic AIRagService aiRagService;
@GetMapping("/chat/{prompt}")public Flux<String> chat(@PathVariable("prompt") String prompt,HttpServletResponse response) {
//解决stream模式下响应乱码问题。response.setCharacterEncoding("UTF-8");
if (!StringUtils.hasText(prompt)) {return Flux.just("prompt is null.");}
return aiRagService.retrieve(prompt);}}
这里以 我现在是一个mac新手,我想配置下 mac 的触控板,让他变得更好用,你有什么建议吗?问题为例,可以看到直接调用模型的回答是比较官方,实用性不高。
可以看到 RAG 应用的输出更加准确且符合用户需求。使用本地 Ollama 部署模型服务时,模型运行速度收到本地资源限制,思考过程会花费大量时间。因此我们可以通过一些云平台上的模型来增强使用体验。spring:application:name: ollama-rag
ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} chat: options: model: deepseek-r1 embedding: enabled: false
ollama:base-url: http://127.0.0.1:11434chat:model: deepseek-r1:8benabled: falseembedding:model: nomic-embed-text:latest
vectorstore:elasticsearch:index-name: ollama-rag-embedding-indexsimilarity: cosinedimensions: 768
elasticsearch:uris: http://127.0.0.1:9200
此处关闭 Ollama 的 Chat 功能,通过 Spring AI Alibaba Starter 依赖使用 DashScope 平台上的 DeepSeekR1 模型。<!--SpringAIAlibabaDashScope--><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M6.1</version></dependency> public Flux<String> retrieve(String prompt) {
// Get the vector store prompt tmpl.String promptTemplate = getPromptTemplate(systemResource);
// Enable hybrid search, both embedding and full text searchSearchRequest searchRequest = SearchRequest.builder().topK(4).similarityThresholdAll().build();
// Build ChatClient with retrieval rerank advisor: ChatClient runtimeChatClient = ChatClient.builder(chatModel).defaultAdvisors(new RetrievalRerankAdvisor(vectorStore, rerankModel, searchRequest, promptTemplate, 0.1)).build();
// Spring AI RetrievalAugmentationAdvisor Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder().queryTransformers(RewriteQueryTransformer.builder().chatClientBuilder(ChatClient.builder(ragChatModel).build().mutate()).build()).documentRetriever(VectorStoreDocumentRetriever.builder().similarityThreshold(0.50).vectorStore(vectorStore).build()).build();
// Retrieve and llm generate return ragClient.prompt().advisors(retrievalAugmentationAdvisor).user(prompt).stream().content();}
Spring AI Alibaba RAG 文档:https://java2ai.com/docs/1.0.0-M5.1/tutorials/rag/ 在使用 Spring AI 搭建 RAG 应用时,我们可以在构建 QuestionAnswerAdvisor 时,通过设置一些个性化参数,来让我们的 RAG 应用在检索向量数据时达到最佳状态。- 删除不相关的文档。噪音数据,特殊字符等来清理数据文本;
A:检查 Embedding 模型是否与文本类型匹配Q:spring-ai-alibaba-starter依赖拉取失败<repositories><repository><id>spring-milestones</id><name>SpringMilestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>SpringSnapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories> - 数据加载与清洗:从外部知识库加载数据,向量化后存储到 Elasticsearch。
- 模型调用优化:通过检索增强技术(RAG),为大模型提供上下文信息。
- 交互服务搭建:构建 REST API,实现应用与用户的高效交互。
通过 RAG 的检索增强,模型回答可以更具上下文关联性,最终提升用户体验。
|