尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
【Agent】【workflow】4.纠正性RAG工作流案例
1. 案例目标本案例展示了如何使用LlamaIndex工作流实现纠正性RAG(Corrective Retrieval Augmented Generation, CRAG)系统。主要目标包括实现一个能够自动评估检索文档相关性的RAG系统当检索到不相关文档时自动进行查询转换和网络搜索结合本地文档和网络搜索结果生成更准确的答案展示如何使用工作流构建复杂的多步骤AI处理流程提供完整的端到端实现从数据加载到查询响应理论基础本案例基于论文Corrective Retrieval Augmented Generation该方法旨在通过评估和增强检索文档的相关性来提高语言模型生成的鲁棒性。它通过评估器和大规模网络搜索来确保生成过程中使用更准确和可靠的信息。2. 技术栈与核心依赖from llama_index.core.workflow import ( Event, Context, Workflow, StartEvent, StopEvent, step, ) from llama_index.core import ( VectorStoreIndex, Document, PromptTemplate, SummaryIndex, ) from llama_index.llms.openai import OpenAI from llama_index.tools.tavily_research.base import TavilyToolSpec核心依赖包括LlamaIndex工作流框架用于构建和编排多步骤处理流程向量存储索引用于文档的向量化存储和检索OpenAI模型使用GPT-4作为相关性评估器和查询转换器Tavily AI搜索用于网络搜索获取外部信息摘要索引用于从相关文本和网络搜索结果中生成最终答案3. 环境配置# 安装依赖 %pip install -U llama-index llama-index-tools-tavily-research # 设置API密钥 os.environ[OPENAI_API_KEY] sk-proj-... tavily_ai_api_key # 下载示例数据 !mkdir -p data/ !wget https://arxiv.org/pdf/2307.09288.pdf -O data/llama2.pdf环境配置包括安装最新版本的LlamaIndex库和Tavily研究工具设置OpenAI API密钥确保能够访问GPT-4模型获取Tavily AI API密钥用于网络搜索下载示例数据(Llama 2论文PDF)创建数据存储目录4. 案例实现4.1 工作流设计纠正性RAG工作流包含以下步骤数据摄取 - 将数据加载到索引中并设置Tavily AI检索 - 根据查询检索最相关的节点相关性评估 - 使用LLM确定检索到的节点是否与查询相关相关性提取 - 提取LLM确定为相关的节点查询转换和Tavily搜索 - 如果节点不相关则使用LLM转换查询以适应网络搜索响应生成 - 根据相关节点和Tavily搜索结果构建摘要索引并生成答案4.2 定义事件为了处理这些步骤需要定义以下事件PrepEvent表示索引和其他对象已准备就绪的事件。RetrieveEvent包含检索到的节点信息的事件。RelevanceEvalEvent包含相关性评估结果列表的事件。TextExtractEvent包含从相关节点提取的相关文本连接字符串的事件。QueryEvent包含相关文本和搜索文本的事件。4.3 提示模板相关性评估提示模板DEFAULT_RELEVANCY_PROMPT_TEMPLATE PromptTemplate( templateAs a grader, your task is to evaluate the relevance of a document retrieved in response to a users question. Retrieved Document: ------------------- {context_str} User Question: -------------- {query_str} Evaluation Criteria: - Consider whether the document contains keywords or topics related to the users question. - The evaluation should not be overly stringent; the primary objective is to identify and filter out clearly irrelevant retrievals. Decision: - Assign a binary score to indicate the documents relevance. - Use yes if the document is relevant to the question, or no if it is not. Please provide your binary score (yes or no) below to indicate the documents relevance to the user question. )查询转换提示模板DEFAULT_TRANSFORM_QUERY_TEMPLATE PromptTemplate( templateYour task is to refine a query to ensure it is highly effective for retrieving relevant search results. Analyze the given input to grasp the core semantic intent or meaning. Original Query: ------- {query_str} ------- Your goal is to rephrase or enhance this query to improve its search performance. Ensure the revised query is concise and directly aligned with the intended search objective. Respond with the optimized query only: )4.4 工作流实现步骤1: 数据摄取step async def ingest(self, ctx: Context, ev: StartEvent) - StopEvent | None: 摄取步骤用于摄取文档和初始化索引。 documents: list[Document] | None ev.get(documents) if documents is None: return None index VectorStoreIndex.from_documents(documents) return StopEvent(resultindex)步骤2: 准备检索step async def prepare_for_retrieval( self, ctx: Context, ev: StartEvent ) - PrepEvent | None: 为检索做准备。 query_str: str | None ev.get(query_str) retriever_kwargs: dict | None ev.get(retriever_kwargs, {}) if query_str is None: return None tavily_ai_apikey: str | None ev.get(tavily_ai_apikey) index ev.get(index) llm OpenAI(modelgpt-4) await ctx.store.set(llm, llm) await ctx.store.set(index, index) await ctx.store.set( tavily_tool, TavilyToolSpec(api_keytavily_ai_apikey) ) await ctx.store.set(query_str, query_str) await ctx.store.set(retriever_kwargs, retriever_kwargs) return PrepEvent()步骤3: 检索step async def retrieve( self, ctx: Context, ev: PrepEvent ) - RetrieveEvent | None: 检索查询的相关节点。 query_str await ctx.store.get(query_str) retriever_kwargs await ctx.store.get(retriever_kwargs) if query_str is None: return None index await ctx.store.get(index, defaultNone) tavily_tool await ctx.store.get(tavily_tool, defaultNone) if not (index or tavily_tool): raise ValueError( Index and tavily tool must be constructed. Run with documents and tavily_ai_apikey params first. ) retriever: BaseRetriever index.as_retriever(**retriever_kwargs) result retriever.retrieve(query_str) await ctx.store.set(retrieved_nodes, result) await ctx.store.set(query_str, query_str) return RetrieveEvent(retrieved_nodesresult)步骤4: 评估相关性step async def eval_relevance( self, ctx: Context, ev: RetrieveEvent ) - RelevanceEvalEvent: 评估检索到的文档与查询的相关性。 retrieved_nodes ev.retrieved_nodes query_str await ctx.store.get(query_str) relevancy_results [] for node in retrieved_nodes: llm await ctx.store.get(llm) resp await llm.acomplete( DEFAULT_RELEVANCY_PROMPT_TEMPLATE.format( context_strnode.text, query_strquery_str ) ) relevancy_results.append(resp.text.lower().strip()) await ctx.store.set(relevancy_results, relevancy_results) return RelevanceEvalEvent(relevant_resultsrelevancy_results)步骤5: 提取相关文本step async def extract_relevant_texts( self, ctx: Context, ev: RelevanceEvalEvent ) - TextExtractEvent: 从检索到的文档中提取相关文本。 retrieved_nodes await ctx.store.get(retrieved_nodes) relevancy_results ev.relevant_results relevant_texts [ retrieved_nodes[i].text for i, result in enumerate(relevancy_results) if result yes ] result \n.join(relevant_texts) return TextExtractEvent(relevant_textresult)步骤6: 转换查询step async def transform_query( self, ctx: Context, ev: TextExtractEvent ) - QueryEvent: 使用Tavily API搜索转换后的查询。 relevant_text ev.relevant_text relevancy_results await ctx.store.get(relevancy_results) query_str await ctx.store.get(query_str) # 如果发现任何文档不相关则转换查询字符串以获得更好的搜索结果 if no in relevancy_results: llm await ctx.store.get(llm) resp await llm.acomplete( DEFAULT_TRANSFORM_QUERY_TEMPLATE.format(query_strquery_str) ) transformed_query_str resp.text # 使用转换后的查询字符串进行搜索并收集结果 tavily_tool await ctx.store.get(tavily_tool) search_results tavily_tool.search( transformed_query_str, max_results5 ) search_text \n.join([result.text for result in search_results]) else: search_text return QueryEvent(relevant_textrelevant_text, search_textsearch_text)步骤7: 查询结果step async def query_result(self, ctx: Context, ev: QueryEvent) - StopEvent: 使用相关文本获取结果。 relevant_text ev.relevant_text search_text ev.search_text query_str await ctx.store.get(query_str) documents [Document(textrelevant_text \n search_text)] index SummaryIndex.from_documents(documents) query_engine index.as_query_engine() result query_engine.query(query_str) return StopEvent(resultresult)4.5 运行工作流# 加载文档 documents SimpleDirectoryReader(./data).load_data() # 创建工作流实例 workflow CorrectiveRAGWorkflow() # 摄取文档并创建索引 index await workflow.run(documentsdocuments) # 运行查询 response await workflow.run( query_strHow was Llama2 pretrained?, indexindex, tavily_ai_apikeytavily_ai_api_key, )5. 案例效果本案例实现了以下效果自动相关性评估系统能够自动评估检索到的文档与查询的相关性智能查询转换当检索到不相关文档时系统能够自动转换查询以获得更好的搜索结果多源信息融合结合本地文档和网络搜索结果生成更全面的答案自适应处理流程根据检索结果的质量动态调整处理流程示例查询结果对于查询How was Llama2 pretrained?系统返回Llama 2 was pretrained using an optimized auto-regressive transformer with several modifications to enhance performance. These modifications included more robust data cleaning, updated data mixes, training on 40% more total tokens, doubling the context length, and using grouped-query attention (GQA) to improve inference scalability for larger models.关键特性本案例中的纠正性RAG系统具有以下特点使用GPT-4作为相关性评估器提供高质量的文档相关性判断集成Tavily AI搜索能够获取最新的网络信息基于工作流的模块化设计便于扩展和维护自动化的查询转换提高搜索结果的准确性6. 案例实现思路本案例的实现思路如下工作流设计将纠正性RAG过程分解为七个主要步骤每个步骤负责特定的功能事件驱动使用事件系统在工作流步骤间传递数据和状态相关性评估使用LLM评估检索文档与查询的相关性提供二元判断自适应处理根据相关性评估结果决定是否需要进行查询转换和网络搜索多源融合将相关文档和网络搜索结果融合生成更全面的答案工作流数据流StartEvent(文档) → ingest步骤 → StopEvent(索引)StartEvent(查询, 索引, API密钥) → prepare_for_retrieval步骤 → PrepEventPrepEvent → retrieve步骤 → RetrieveEvent(检索到的节点)RetrieveEvent → eval_relevance步骤 → RelevanceEvalEvent(相关性结果)RelevanceEvalEvent → extract_relevant_texts步骤 → TextExtractEvent(相关文本)TextExtractEvent → transform_query步骤 → QueryEvent(相关文本, 搜索文本)QueryEvent → query_result步骤 → StopEvent(最终答案)7. 扩展建议基于本案例可以考虑以下扩展方向多模态支持扩展支持图像、表格等多模态内容的检索和评估高级相关性评估实现更细粒度的相关性评分而非简单的二元判断多搜索引擎集成集成多个搜索引擎提高网络搜索的覆盖面缓存机制为网络搜索结果添加缓存提高响应速度个性化调整根据用户反馈调整相关性评估和查询转换策略领域适应针对特定领域优化相关性评估和查询转换提示实时更新实现文档索引的实时更新确保信息时效性性能优化并行化处理步骤提高系统响应速度8. 总结本案例展示了如何使用LlamaIndex工作流实现一个纠正性RAG系统通过评估和增强检索文档的相关性来提高语言模型生成的鲁棒性。案例中的关键技术点包括工作流编排使用LlamaIndex工作流框架构建复杂的多步骤处理流程相关性评估使用LLM评估检索文档与查询的相关性查询转换当检索到不相关文档时自动转换查询以获得更好的搜索结果多源融合结合本地文档和网络搜索结果生成更全面的答案通过这种方式系统能够自动识别和处理不相关的检索结果通过查询转换和网络搜索获取更准确的信息从而显著提高RAG系统的可靠性和准确性。这种纠正性RAG方法特别适用于需要高准确性和可靠性的信息检索和问答场景。
RELATED

相关推荐

TIP 2026 即插即用 | 注意力篇 | PWFB:可学习小波块,子带域卷积 + 软约束抑制重建混叠伪影,全局建模拉满!

TIP 2026 即插即用 | 注意力篇 | PWFB:可学习小波块,子带域卷积 + 软约束抑制重建混叠伪影,全局建模拉满!

文章目录 模块出处 模块介绍 模块提出的动机(Motivation) 适用范围与模块效果 模块代码及使用方式 模块出处 Paper:Global Modeling Matters: A Fast, Lightweight and Effective Baseline for Efficient Image Restoration Code:https://github.com/deng-ai-lab/PW-FNet …

📅 2026/10/5 2:23:41
srm32 , 6-2 :定时器中断与定时器外部时钟

srm32 , 6-2 :定时器中断与定时器外部时钟

(56) (57)(58)(59)(60) 采样滤波 :(61) 这几个函数很类似 :(62) (63&#…

📅 2026/10/5 2:23:41
AI Agent_10 Token 到底是什么、怎么来的、为什么这么重要

AI Agent_10 Token 到底是什么、怎么来的、为什么这么重要

一、什么是 Token:先建立直觉Token(词元) 大模型处理语言时的最小单位。它既不是 "字",也不完全是 "词",而是分词器(Tokenizer)从文本里切出来的 "小块"。示例&…

📅 2026/10/5 2:23:41
MORE NEWS

更多资讯

📰

Linux信号机制详解:从异步通知到sigaction实战与面试考点

写Linux系统编程,绕不开的一个坎就是信号。你程序跑得好好的,终端里按下CtrlC,进程就像被刀砍一样直接没了;有些老练的服务进程却完全不一样,收到终止信号以后会先停掉新请求、把任务队列收一收、记一笔日志&#xff0…

📰

Go语言实现OAuth2:从授权码到Token校验的完整工程实践

开始任何服务端项目之前,我总是先问自己一句:这套接口到底要暴露给谁用?如果是自家前端、自家App,那直接上 Session 或简单的 Token 就行;可一旦涉及到第三方应用接入、多端授权、甚至开放平台,OAuth2 就成…

📰

前后端分离项目实战:基于SpringBoot+Vue的厨艺交流平台开发部署

前后端分离厨艺交流平台系统做下来,我觉得最值得分享的还不是那一堆CRUD代码,而是这套从需求拆解到技术选型、再到前后端联调和最终部署的完整链路。先说清楚这个项目是什么:它本质上是一个以菜谱分享和用户互动为核心的社区型Web应用&#x…

📰

INT与gRPC网络遥测:精细化运维实战指南

简介:这份PDF文档面向HPC与下一代数据中心网络的运维工程师及架构设计人员,聚焦如何借助Network Telemetry技术打破“网络黑盒”,解决大规模复杂网络中流量精细可视、可控以及端到端秒级故障定位的难题。资源包共1个PDF文件,大小约…

📰

论文写作工具怎么选?生成型、检索型与学术规范一次讲透

这段时间又到了毕业季,后台收到不少私信,问的都是同一个问题:马上要交论文了,有没有能一键生成论文的工具?正好有人把千笔专业论文写作工具和学术猹这两个名字放在一起对比,我干脆把这事一次讲透。先说结论…

📰

Java数组全解析:基础用法、扩容原理、内存模型与面试避坑

有人问过我一个问题:都这个年头了,写“Java数组常见用法”还有人看吗?我的回答是:正因为常见,才真正值得往深里刨一刨。数组是Java里最容易被“以为会了”的基础知识点。增删改查谁都能写两行,可真到面试桌…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬