微信扫码
添加专属顾问
我要投稿
RAG技术如何突破传统AI局限?揭秘检索与生成协同工作的前沿方案。 核心内容: 1. RAG技术诞生的背景与解决的核心问题 2. 检索阶段的关键技术实现与优化策略 3. 生成阶段如何融合检索结果实现精准输出
引言
随着人工智能技术的飞速发展,信息处理和知识利用的效率与精度成为了科研与产业界关注的焦点。在这一背景下,RAG(Retrieval-Augmented Generation检索增强生成)技术应运而生。RAG 结合了检索(Retrieval)与生成(Generation)两大模块,为解决复杂信息处理和知识密集型任务提供了新的思路。本文将深入解析 RAG 的技术原理及关键要点,以帮助读者全面理解这一前沿技术。
RAG 技术的诞生背景
在大数据时代的浪潮中,信息如潮水般涌来,企业和个人面临着如何高效处理、理解和利用这些信息的巨大挑战。传统的人工智能生成模型,如基于规则的专家系统以及简单的统计语言模型,在面对复杂多变、知识更新迅速的现实任务时,逐渐暴露出诸多局限性。一方面,规则系统高度依赖人工设定的规则,缺乏灵活性与适应性,难以应对未预料到的输入情况,且规则的维护与更新成本极高;另一方面,统计语言模型虽然能依据历史数据生成具有一定连贯性的文本,但往往局限于自身训练时所吸收的固定知识范围,对于新出现的事件、概念或特定领域的深层次专业知识,很难做出准确且有价值的回应。在这样的背景下,研究者们迫切需要一种能够结合人类智慧与机器智能优势,既具备广泛知识覆盖又能在特定任务中精准响应的技术方案。RAG 应运而生,它巧妙地将信息检索系统与先进的生成模型相融合,通过这种协同工作模式突破传统技术瓶颈,满足日益增长的信息处理需求。
RAG 的工作原理
检索阶段(Retrieval)
1. 当接收用户输入的问题或任务请求时,RAG 系统利用检索模型对问题进行分析。检索模型基于向量相似性原理,将问题转化为高维向量表示,同时对预先构建的知识库中的内容也进行向量化处理。例如,在处理自然语言问题时,可以采用预训练的词嵌入模型(如 Word2Vec、GloVe)或上下文感知型预训练语言模型(如 BERT)来生成文本的向量表示。
2. 系统将问题向量与知识库中所有文档向量进行高效比对,计算它们之间的相似度,找出与问题最相关的若干条文档片段作为候选检索结果。在这个过程中,为提高检索效率,通常会采用倒排索引、近似最近邻搜索等优化的数据结构和检索算法。倒排索引能够快速定位包含特定关键词的文档集合,而近似最近邻搜索在保证一定检索质量的前提下,大幅缩短在高维向量空间中搜索相似向量的时间,这对于处理大规模数据集至关重要。
3. 检索结果的排序也是关键环节。除了基于向量相似度进行初步排序外,还可以结合额外的语义分析、文档权威性评估、时间戳等因素进一步优化排序结果,确保最相关、最有价值的知识被优先选取。
生成阶段(Generation)
1. 获取到一组与问题相关的检索结果后,这些结果与原始问题一同输入生成模型。生成模型一般是一个经过精心训练的深度学习模型,目前主流的生成模型架构包括基于 Transformer 的语言模型,如 GPT 系列及其变体。
2. 生成模型充分利用检索到的知识,将其与问题的语义信息进行深度融合,通过内部的多层神经网络结构对文本进行建模与生成。在这个过程中,模型会根据输入序列的上下文关系、词汇的语义关联以及语法结构等多方面因素,逐步构建出连贯、准确且符合用户意图的回答或输出内容。例如,当用户询问某个历史事件的详细经过时,生成模型会依据检索到的历史文献片段,按照时间顺序、事件发展脉络等逻辑关系,组织出一段完整且清晰的叙述文本。
3. 生成模型还可以通过调节超参数(如温度参数控制输出的概率分布平滑度)、采用不同的解码策略(如贪心解码、束搜索解码等)来优化生成结果的质量。
RAG 的关键技术组件
检索模型
1. 向量化技术:向量化是检索模型的核心基础。目前,基于预训练语言模型的语义向量化技术正日益受到重视。这些预训练模型通过在大规模文本语料上进行无监督训练,学习到了丰富的语言知识和语义信息,能够生成更具区分度和语义一致性的文本向量。例如,BERT 模型通过 Transformer 架构的多层编码器结构,对文本的各个层次语义特征进行提取和编码,使得生成的向量能够更好地捕捉文本的上下文语义,从而在相似性计算上更为精准。
2. 索引与存储结构:为了高效存储和查询大规模文档向量,需要设计合理的索引和存储结构。倒排索引仍然是信息检索领域中最广泛使用的索引结构之一,它通过建立关键词到文档的映射关系,能够快速定位包含特定关键词的文档集合,为后续的向量相似性计算缩小了搜索范围。此外,针对高维向量数据的特性,一些专门的向量数据库(如 Faiss、Milvus 等)应运而生。这些数据库采用了多种优化的存储策略和检索算法,如分区存储、量化压缩、多级索引等技术,能够在保证检索效率的同时,支持海量向量数据的高效管理和检索。
生成模型
1. 预训练与微调策略:生成模型通常基于预训练语言模型构建,并针对特定任务和领域数据进行微调。预训练阶段,模型在大规模通用文本语料上学习语言的通用模式和规律,包括词汇语法知识、常识性知识等;微调阶段,则是在预训练模型的基础上,利用任务相关的数据(如特定领域的问答对、文本生成样例等)对模型进行进一步训练,使其能够适应特定任务的语义要求和生成目标。
2. 注意力机制与记忆增强:注意力机制是 Transformer 架构中的关键组件,它使得生成模型能够在处理长序列文本时,动态地聚焦于与当前生成位置最相关的上下文信息,从而有效解决长距离依赖问题,提高生成文本的连贯性和准确性。此外,为了增强模型的记忆能力,一些研究工作引入了记忆增强机制,如外部记忆存储模块,允许模型在生成过程中临时存储和检索关键信息,进一步提升其对复杂任务的处理能力。
检索与生成的融合机制
1. 信息传递与交互设计:如何将检索到的知识有效地传递给生成模型,并在生成过程中实现两者的信息交互,是 RAG 技术的核心挑战之一。一种常见的方法是将检索到的文档片段拼接在问题文本之后,作为生成模型的输入序列的一部分。另一种方法是通过设计专门的融合层或适配器模块,对检索结果和问题进行特征融合和转换,使其能够以更合理的表征形式输入到生成模型中。例如,可以利用注意力池化技术对检索结果进行特征聚合,生成一个固定长度的向量表示,然后将其与问题向量进行拼接或逐元素相加操作,作为生成模型的初始输入隐藏状态,从而实现信息的有效融合。
2. 联合训练与优化方法:为了使检索模型和生成模型在 RAG 系统中能够协同工作、相互促进,联合训练方法被广泛应用。在联合训练框架下,检索模型和生成模型被视为一个整体,共享部分参数或通过特定的损失函数进行联合优化。例如,可以设计一个综合的损失函数,同时包含检索结果的相关性损失和生成结果的准确性损失,通过反向传播算法对整个系统进行端到端的训练。
Spring AI 实现 RAG 示例
创建 Spring Boot 工程
首先创建一个 Spring Boot 工程,并添加 Spring AI 相关的依赖,如spring-ai-core等。
添加配置文件
在application.yml文件中,添加向量数据库、模型等相关的配置:
spring:
ai:
model:
name: ${MODEL_NAME}
key: ${MODEL_KEY}
vector-store:
type: milvus
milvus:
address: ${MILVUS_ADDRESS}
port: ${MILVUS_PORT}
collection-name: ${COLLECTION_NAME}
user: ${MILVUS_USER}
password: ${MILVUS_PASSWORD}
创建文档嵌入和 RAG 逻辑处理类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.document.DocumentReader;
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/rag")
public class RAGController {
private static final Logger log = LoggerFactory.getLogger(RAGController.class);
@Value("classpath:/prompts/system-qa.st")
private Resource systemResource;
@Value("classpath:/data/spring_ai_alibaba_quickstart.pdf")
private Resource springAiResource;
@Autowired
@Qualifier("vectorStore")
private VectorStore vectorStore;
@Autowired
private ChatModel chatModel;
@Autowired
private RerankModel rerankModel;
/**
* 处理PDF文档的解析、分割和嵌入存储。
* 使用 PagePdfDocumentReader 解析PDF文档并生成 Document 列表。
* 使用 TokenTextSplitter 将文档分割成更小的部分。
* 将分割后的文档添加到向量存储中,以便后续检索和生成。
*/
@GetMapping("/insertDocuments")
public void insertDocuments() throws IOException {
// 1. parse document
DocumentReader reader = new PagePdfDocumentReader(springAiResource);
List<Document> documents = reader.get();
log.info("{} documents loaded", documents.size());
// 2. split trunks
List<Document> splitDocuments = new TokenTextSplitter().apply(documents);
log.info("{} documents split", splitDocuments.size());
// 3. create embedding and store to vector store
log.info("create embedding and save to vector store");
vectorStore.add(splitDocuments);
}
/**
* 根据用户输入的消息生成JSON格式的聊天响应。
* 创建一个 SearchRequest 对象,设置返回最相关的前2个结果。
* 从 systemResource 中读取提示模板。
* 使用 ChatClient 构建聊天客户端,调用 RetrievalRerankAdvisor 进行检索和重排序,并生成最终的聊天响应内容。
*/
@GetMapping(value = "/ragJsonText", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public String ragJsonText(@RequestParam(value = "message", defaultValue = "如何使用spring ai alibaba?") String message) throws IOException {
SearchRequest searchRequest = SearchRequest.builder().topK(2).build();
String promptTemplate = systemResource.getContentAsString(StandardCharsets.UTF_8);
return ChatClient.builder(chatModel)
.defaultAdvisors(new RetrievalRerankAdvisor(vectorStore, rerankModel, searchRequest, promptTemplate, 0.1))
.build()
.prompt()
.user(message)
.call()
.content();
}
/**
* 根据用户输入的消息生成流式聊天响应。
* 类似于 ragJsonText 方法,但使用 stream() 方法以流的形式返回聊天响应。
* 返回类型为 Flux<ChatResponse>,适合需要实时更新的场景。
*/
@GetMapping(value = "/ragStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ChatResponse> ragStream(@RequestParam(value = "message", defaultValue = "如何使用spring ai alibaba?") String message) throws IOException {
SearchRequest searchRequest = SearchRequest.builder().topK(2).build();
String promptTemplate = systemResource.getContentAsString(StandardCharsets.UTF_8);
return ChatClient.builder(chatModel)
.defaultAdvisors(new RetrievalRerankAdvisor(vectorStore, rerankModel, searchRequest, promptTemplate, 0.1))
.build()
.prompt()
.user(message)
.stream()
.chatResponse();
}
}
RAG 执行过程源代码解读
在 Spring AI 中,RetrievalRerankAdvisor类的before和doRerank方法是 RAG 执行过程的关键。
protected List<Document> doRerank(AdvisedRequest request, List<Document> documents) {
if (CollectionUtils.isEmpty(documents)) {
return documents;
}
var rerankRequest = new RerankRequest(request.userText(), documents);
RerankResponse response = rerankModel.call(rerankRequest);
logger.debug("reranked documents: {}", response);
if (response == null || response.getResults() == null) {
return documents;
}
return response.getResults()
.stream()
.filter(doc -> doc != null && doc.getScore() >= minScore)
.sorted(Comparator.comparingDouble(DocumentWithScore::getScore).reversed())
.map(DocumentWithScore::getOutput)
.collect(toList());
}
private AdvisedRequest before(AdvisedRequest request) {
var context = new HashMap<>(request.adviseContext());
String advisedUserText = request.userText() + System.lineSeparator() + this.userTextAdvise;
var searchRequestToUse = SearchRequest.from(this.searchRequest)
.query(request.userText())
.filterExpression(doGetFilterExpression(context))
.build();
logger.debug("searchRequestToUse: {}", searchRequestToUse);
List<Document> documents = this.vectorStore.similaritySearch(searchRequestToUse);
logger.debug("retrieved documents: {}", documents);
documents = doRerank(request, documents);
context.put(RETRIEVED_DOCUMENTS, documents);
String documentContext = documents.stream()
.map(Document::getText)
.collect(Collectors.joining(System.lineSeparator()));
Map<String, Object> advisedUserParams = new HashMap<>(request.userParams());
advisedUserParams.put("question_answer_context", documentContext);
return AdvisedRequest.from(request)
.userText(advisedUserText)
.userParams(advisedUserParams)
.adviseContext(context)
.build();
}
使用示例
在本地知识库检索的 RAG 示例中,将 PDF 文档解析、分割和嵌入存储后,即可调用上述控制器中的接口进行 RAG 查询。例如访问http://localhost:8080/rag/ragJsonText?message=如何使用spring ai alibaba,就可以得到基于文档内容的检索增强生成的回答。通过这些代码和配置,可以实现文档的嵌入存储以及基于检索增强生成的聊天响应功能,适用于构建智能问答系统或知识管理系统等应用场景。
RAG 的优势与挑战
优势
1. 知识覆盖广泛且动态更新:借助强大的检索能力,RAG 能够从海量的知识库中获取最新的、多样化的信息,打破了传统生成模型所依赖的固定训练数据集的知识局限性。这意味着 RAG 系统可以实时或近实时地融入新出现的知识、事件和研究成果,保持对知识更新的敏感性,为用户提供更加个性化的、与时俱进的信息服务。
2. 生成结果准确性与可靠性提升:由于生成过程紧密结合了检索到的可靠知识,生成模型在回答问题或创作内容时更有依据,能够有效减少胡编乱造、不符合事实或逻辑错误的情况。与仅依靠模型自身内部参数生成内容的方式相比,RAG 生成的结果往往更具可信度和权威性。
挑战
1. 数据质量与相关性评估难题:检索到的知识质量参差不齐,如何准确评估其与问题的相关性和可靠性是一个关键挑战。在实际应用中,知识库中的文档可能存在噪声、错误信息、过时内容等问题,检索模型如果不具备强大的甄别能力,可能会将这些低质量的知识片段传递给生成模型,从而导致生成结果出现偏差或错误。
2. 计算资源与效率问题:RAG 系统通常需要处理大规模的数据集,包括知识库的构建与存储、检索模型的高效查询以及生成模型的复杂计算等环节,这对计算资源提出了很高的要求。尤其是在面对实时性要求较高的应用场景时,如何在保证生成质量的前提下,优化系统的计算效率,降低延迟,成为亟待解决的技术难题。
综上所述,RAG 技术通过巧妙地结合检索与生成两大模块,在知识覆盖范围、生成结果准确性等方面展现出了显著优势,但也面临着数据质量评估、计算资源优化等挑战。尽管如此,随着技术的不断进步和创新,RAG 有望在众多领域发挥越来越重要的作用,为信息处理和知识利用带来新的突破。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-06-18
企业级RAG系统规模化部署十条经验
2025-06-18
RAG之父:企业级 RAG 系统落地的实战经验
2025-06-16
最新|Milvus_local_RAG,笔记本也能跑的本地知识库&RAG来了
2025-06-16
GraphRAG 在 CVTE 多业务场景下的探索与应用
2025-06-16
Dify+Firecrawl本地部署RAG知识库chatbot
2025-06-16
赢得企业RAG挑战赛的秘诀 —— 冠军方案剖析与感悟
2025-06-16
提升AI问答准确率:请在RAG前先做RAR,超越意图识别
2025-06-15
RAG不好用?试试MCP这个“知识库优化大师”
2025-03-21
2025-03-24
2025-03-24
2025-03-24
2025-03-28
2025-04-01
2025-03-23
2025-04-13
2025-04-19
2025-04-09
2025-06-13
2025-06-09
2025-06-06
2025-05-30
2025-05-29
2025-05-29
2025-05-23
2025-05-16