赵公口网站建设北京网站设计lnmpa wordpress ssl
赵公口网站建设北京网站设计,lnmpa wordpress ssl,设计案例网,淄博建网站多少钱七大场景 企业级RAG检索实战#xff08;附源码#xff09;
RAG 落地生产环境#xff0c;如何解决 “检索准确性”#xff08;事实一致性/语境完整性/领域术语召回#xff09;和 “多模态解析”#xff08;PDF 图表、图片甚至视频#xff09;两大难题#xff1f;
本文通…七大场景 企业级RAG检索实战附源码RAG 落地生产环境如何解决“检索准确性”事实一致性/语境完整性/领域术语召回和“多模态解析”PDF 图表、图片甚至视频两大难题本文通过 Llama-Index 七大企业实战场景全面解析高精准文本检索与Excel/PDF/视频全模态处理。拒绝理论空谈全篇代码实战完整源码可免费领取️ Part 1. 快速热身3分钟搭建 RAG 基线在开始介绍进阶技术之前我们先用最精简的代码跑通一个基础 RAG 流程。这几行代码在后台完成了 ETL、索引构建、检索生成的全流程。1.1 环境准备importosfromdotenvimportload_dotenvimportllama_index.core# 1. 加载环境变量load_dotenv()# 2. 检查 Llama-Index 版本print(fLlama-Index Version:{llama_index.core.__version__})1.2 加载数据与查询importos file_path./data/创新科技股份有限公司员工手册.txtwithopen(file_path,r,encodingutf-8)asf:md_contentf.read()# 预览前1000字符md_content[:1000]fromllama_index.coreimportVectorStoreIndex,SimpleDirectoryReader# 1. 数据摄入 (Loading)documentsSimpleDirectoryReader(data).load_data()# 2. 索引构建 (Indexing)indexVectorStoreIndex.from_documents(documents)# 3. 引擎配置 (Query Engine)query_engineindex.as_query_engine()# 4. 执行查询 (Execution)responsequery_engine.query(请问我们公司有病假政策么请用中文进行回复。)# 配置 LLM (如 GPT-4o)fromllama_index.coreimportSettingsfromllama_index.llms.openaiimportOpenAI base_urlos.getenv(BASE_URL)api_keyos.getenv(OPENAI_API_KEY)Settings.llmOpenAI(modelgpt-4o,api_keyapi_key,api_basebase_url) Part 2. 拒绝断章取义Small-to-Big 策略 (Sentence Window)痛点切片太小LLM 看不懂上下文切片太大检索全是噪声。解法“搜的时候用句子给的时候用窗口”。索引时只存单句向量保证精准检索后将该句前后的上下文大窗口提供给 LLM保证完整。2.1 核心代码# 检查数据ifnotos.path.exists(./data/创新科技股份有限公司员工手册.txt):print(❌ 错误请确保 ./data 目录下存放了员工手册 txt 文件)else:print(✅ 环境检查通过正在加载数据...)documentsSimpleDirectoryReader(./data).load_data()print(f 成功加载文档共{len(documents)}页/部分。)# 构建进阶 RAG (Small-to-Big) fromllama_index.core.node_parserimportSentenceWindowNodeParserfromllama_index.core.postprocessorimportMetadataReplacementPostProcessorimportreprint( 正在构建进阶 RAG 索引 (Small-to-Big)...)# --- ️ 关键修复定义中文句子切分函数 ---defchinese_sentence_splitter(text):# 按中文标点切分保留标点returnre.split(r(?[。\n]),text)# 1. 定义窗口切分器node_parserSentenceWindowNodeParser.from_defaults(sentence_splitterchinese_sentence_splitter,window_size3,# 核心前后各取3句window_metadata_keywindow,original_text_metadata_keyoriginal_text,)# 2. 手动切分文档nodesnode_parser.get_nodes_from_documents(documents)print(f 文档被切分为{len(nodes)}个句子节点)# 3. 建立索引 (对单句进行向量化)advanced_indexVectorStoreIndex(nodes)# 4. 创建引擎 (带偷梁换柱功能的后处理器)advanced_engineadvanced_index.as_query_engine(similarity_top_k5,node_postprocessors[MetadataReplacementPostProcessor(target_metadata_keywindow)])print(✅ 进阶 RAG 系统就绪)2.2 效果对比# 效果对比展示 fromIPython.displayimportdisplay,Markdown# 建立一个普通 Baseline 对比base_indexVectorStoreIndex.from_documents(documents)base_enginebase_index.as_query_engine(similarity_top_k2)test_questions[Q1: 如果我这个月迟到了 4 次会受到什么样的具体处理如果连续 3 天没打卡呢,Q2: 我想周末和春节都来公司加班多赚点钱工资分别怎么算我一年最多能加多少小时班有没有封顶,Q3: 我还在试用期最近家里有事想请半个月15天的假按规定可以请吗会不会影响我转正]defcompare_answers(question):response_basebase_engine.query(question)response_advadvanced_engine.query(question)display(Markdown(f### ❓ 提问:{question}))table_mdf | 普通 RAG (Baseline) | 进阶 RAG (Small-to-Big) | | :--- | :--- | |{response_base.response}|{response_adv.response}| display(Markdown(table_md))display(Markdown(---))forqintest_questions:compare_answers(q) Part 3. 拯救“搜不到”混合检索 (Hybrid Search)痛点搜“ROWE工作制”或具体人名向量模型完全懵圈因为它只懂语义不懂字符。解法“左手向量右手关键词”。结合 Vector Search懂语义和 BM25懂字面用 RRF 算法进行排名融合专治各种生僻词和精准匹配。3.1 核心代码importnest_asyncioimportjiebafromtypingimportListfromllama_index.core.node_parserimportSentenceSplitter nest_asyncio.apply()# 1. 定义中文分词函数 (给 BM25 用)defchinese_tokenizer(text:str)-List[str]:returnlist(jieba.cut(text))# 2. 切分文档splitterSentenceSplitter(chunk_size512,chunk_overlap50)nodessplitter.get_nodes_from_documents(documents)# 3. 构建向量索引vector_indexVectorStoreIndex(nodes)# 构建混合检索系统 importinspectfromllama_index.retrievers.bm25importBM25Retrieverfromllama_index.core.retrieversimportVectorIndexRetriever,QueryFusionRetrieverfromllama_index.core.query_engineimportRetrieverQueryEngineprint( 正在构建混合检索系统 (Hybrid Search)...)# --- ️ 自动侦测 FusionMode 类型 (防御性编程) ---try:siginspect.signature(QueryFusionRetriever.__init__)ModeEnumsig.parameters[mode].annotationifhasattr(ModeEnum,RECIPROCAL_RANK):target_modeModeEnum.RECIPROCAL_RANKelse:target_modereciprocal_rankexceptException:target_modereciprocal_rank# 1. 创建 BM25 检索器 (字面匹配)bm25_retrieverBM25Retriever.from_defaults(nodesnodes,similarity_top_k2,tokenizerchinese_tokenizer)# 2. 创建向量检索器 (语义匹配)vector_retrieverVectorIndexRetriever(indexvector_index,similarity_top_k2)# 3. 创建融合检索器 (RRF 算法)fusion_retrieverQueryFusionRetriever([vector_retriever,bm25_retriever],similarity_top_k4,num_queries1,modetarget_mode,use_asyncTrue)# 4. 组装引擎hybrid_engineRetrieverQueryEngine.from_args(retrieverfusion_retriever)print(✅ 混合检索就绪)3.2 效果对比# 针对生僻词和实体的测试questions[Q1: 请问法务合规部的负责人是谁我想发邮件给他邮箱是多少,Q2: 公司关于 BYOD (自带设备) 的具体政策要求是什么,我是研发部的老员工听说有个‘ROWE’工作制具体需要满足哪些硬性条件才能申请]# 普通向量引擎vector_enginevector_index.as_query_engine(similarity_top_k2)defcompare_hybrid(question):response_basevector_engine.query(question)response_hybridhybrid_engine.query(question)display(Markdown(f### ❓ 提问:{question}))table_mdf | 普通 RAG (Vector Only) | 混合检索 (Vector BM25) | | :--- | :--- | |{response_base.response}|{response_hybrid.response}| display(Markdown(table_md))display(Markdown(---))forqinquestions:compare_hybrid(q) Part 4. 告别“一刀切”智能路由 (Router Query Engine)痛点问细节如“补贴多少钱”需要精准切片问总结如“公司价值观”需要全文档摘要。普通 RAG 只能二选一。解法“给系统装个大脑”。构建两个工具细节工具 总结工具让 Router 根据用户问题自动判断该派谁上场。4.1 核心代码fromllama_index.coreimportSummaryIndex,VectorStoreIndex# 1. 构建双索引# 向量索引 (查细节)vector_indexVectorStoreIndex(nodes)# 摘要索引 (查全貌)summary_indexSummaryIndex(nodes)fromllama_index.core.toolsimportQueryEngineToolfromllama_index.core.selectorsimportLLMSingleSelectorfromllama_index.core.query_engineimportRouterQueryEngine# 2. 定义工具 (Description 是关键写给 AI 看的)vector_toolQueryEngineTool.from_defaults(query_enginevector_index.as_query_engine(similarity_top_k2),description专门用于查询具体的、特定的事实细节例如补贴金额、电话号码、具体政策条款等。)summary_toolQueryEngineTool.from_defaults(query_enginesummary_index.as_query_engine(response_modetree_summarize),description专门用于对文档进行宏观的总结、概括全文主题、分析整体结构或提取跨章节的综合信息。)# 3. 构建 Router 引擎print( 正在构建智能路由引擎...)router_engineRouterQueryEngine(selectorLLMSingleSelector.from_defaults(),query_engine_tools[summary_tool,vector_tool],verboseTrue# 开启日志看它怎么思考)print(✅ Router 引擎就绪)4.2 智能分发测试questions[# 宏观总结题 - 应该走 Summary ToolQ1: 这份员工手册主要包含了哪几个章节请简要列出目录结构并概括每个章节的主题。,# 微观细节题 - 应该走 Vector ToolQ2: 公司的健身房补贴每年最高是多少钱]base_enginevector_index.as_query_engine(similarity_top_k2)defclean_text(text):returnstr(text)[:300].replace(\n,br)...forqinquestions:display(Markdown(f### ❓ 提问:{q}))response_basebase_engine.query(q)response_routerrouter_engine.query(q)table_mdf | 普通 RAG (Top-2) | 智能路由 (Router) | | :--- | :--- | |{clean_text(response_base.response)}|{clean_text(response_router.response)}| display(Markdown(table_md))display(Markdown(---)) 中场小结从文本到多模态如果说前四章解决了“非结构化文本”的检索难题那么接下来的四章我们将挑战更复杂的数据形态——表格、PDF、图片和视频。让我们看看 LlamaIndex 如何“降伏”这些异构数据。 Part 5. 让 RAG 看懂 ExcelPandas 结构化数据分析实战痛点问“流失用户平均消费多少”普通 RAG 只会搜文本不会算数。解法Pandas Query Engine。它不是去搜答案而是把自然语言翻译成 Python 代码直接在 DataFrame 上执行运算精准度 100%。5.1 核心代码importpandasaspdfromllama_index.experimental.query_engineimportPandasQueryEnginefromllama_index.coreimportSettingsfromllama_index.llms.openaiimportOpenAIfromdotenvimportload_dotenv load_dotenv(overrideTrue)Settings.llmOpenAI(modelgpt-4o)# 1. 加载数据dfpd.read_csv(telco_data.csv)# 2. 注入中文指令 (让 AI 用中文回答且代码不许乱写)chinese_instruction_str(你是一位精通 Python Pandas 的数据分析专家。\n你的任务是将用户的自然语言问题转换为可执行的 Python 代码并基于执行结果回答问题。\n请严格遵守以下规则\n1. 代码必须是有效的 Pandas 操作。\n2. 代码的最后一行必须是一个返回结果的表达式不要用 print()。\n3. **最终结果必须强制使用中文回答**。\n)# 3. 初始化引擎query_enginePandasQueryEngine(dfdf,verboseTrue,# 显示生成的代码方便调试synthesize_responseTrue,# 让 LLM 把运算结果翻译成人话instruction_strchinese_instruction_str)# 4. 复杂统计提问query_str按合同类型(Contract)分组统计流失和未流失用户的数量。print(f❓ 问题:{query_str})responsequery_engine.query(query_str)print(\n 分析结果:)print(response)print(\n 生成的代码:)print(response.metadata[pandas_instruction_str])5.2 进阶让 AI 画图# 明确要求画图query_str_viz(Visualize the churn count by Contract type using a bar chart. Use distinct colors for Churn vs Non-Churn. Make sure to set the title as Churn Distribution by Contract Type.)response_vizquery_engine.query(query_str_viz)print(\n AI 已执行绘图操作) Part 6. 图表不再是盲区MinerU Qwen-VL 搞定复杂 PDF痛点PDF 里的架构图、统计表普通解析工具直接丢弃导致关键信息丢失。解法MinerU (解析) Qwen-VL-Embedding (向量化)。先用 MinerU 提取出 markdown 和图片再用多模态模型把图文都变成向量存起来。6.1 定义 MinerU 解析器importrequestsimportzipfileimportshutilimportosfrompathlibimportPathfromtypingimportListfromllama_index.coreimportDocumentfromllama_index.core.schemaimportImageDocumentclassMinerUAPIReader:def__init__(self,api_key:str,output_dir./mineru_output):self.api_keyapi_key self.base_urlhttps://mineru.net/api/v4self.output_dirPath(output_dir)defload_data(self,pdf_url:str)-List[Document]:# 1. 提交任务print(f [MinerU] 提交解析任务...)headers{Authorization:fBearer{self.api_key}}data{url:pdf_url,model_version:vlm,is_ocr:True,lang:auto}resprequests.post(f{self.base_url}/extract/task,headersheaders,jsondata)task_idresp.json()[data][task_id]# 2. 轮询等待 (简化版代码生产环境需增加超时处理)importtimewhileTrue:time.sleep(3)statusrequests.get(f{self.base_url}/extract/task/{task_id},headersheaders).json()[data]ifstatus[state]done:result_urlstatus[full_zip_url]break# 3. 下载解压并封装 Document (代码略见完整版)returnself._process_zip(result_url,str(task_id))# _process_zip 方法实现略核心逻辑是读取 full.md 和 images 目录6.2 构建多模态索引与问答fromllama_index.core.indices.multi_modalimportMultiModalVectorStoreIndexfromllama_index.llms.openaiimportOpenAI# 1. 解析数据readerMinerUAPIReader(api_keyos.getenv(MINERU_API_KEY))documentsreader.load_data(https://example.com/tech_report.pdf)# 2. 构建图文索引 (需自定义 Qwen Embedding 类见完整版)indexMultiModalVectorStoreIndex.from_documents(documents,embed_modelqwen_embed_model,# 文本向量化image_embed_modelqwen_embed_model# 图片向量化)# 3. 多模态问答llmOpenAI(modelgpt-4o)query_engineindex.as_query_engine(llmllm,image_similarity_top_k1)responsequery_engine.query(根据文档内容LangChain 的整体架构包含哪几个核心层请结合架构图进行说明。)display(Markdown(f### AI 回答:\n\n{response.response}))️ Part 7. 以图搜图构建企业级多模态图片知识库痛点只有一张家具照片想在产品库里找同款或者想用文字搜“男士穿搭推荐”。解法CLIP / Qwen-VL 向量空间对齐。将图片和文本映射到同一个向量空间计算 Cosine 相似度。7.1 核心代码fromllama_index.coreimportSimpleDirectoryReaderfromllama_index.core.indicesimportMultiModalVectorStoreIndex# 1. 加载图片库documentsSimpleDirectoryReader(test_images).load_data()# 2. 构建索引indexMultiModalVectorStoreIndex.from_documents(documents,image_embed_modelqwen_embed_model# 使用 Qwen2.5-VL)# 3. 文搜图retrieverindex.as_retriever(image_similarity_top_k1)resultsretriever.text_to_image_retrieve(最近家里装修希望推荐一些好看的家具)# 4. 图搜图resultsretriever.image_to_image_retrieve(./test_images/query_chair.png) Part 8. 视频也能 RAGTwelve Labs 带来的时空对齐技术痛点传统方法把视频切成图片丢失了动作连贯性和声音信息。解法Twelve Labs (Marengo/Pegasus)。专门为视频设计的向量模型能理解“时空”概念直接返回精确到秒的视频片段。8.1 核心代码fromtwelvelabsimportTwelveLabs# 1. 初始化客户端clientTwelveLabs(api_keyos.getenv(TL_API_KEY))# 2. 创建索引 (Marengo Pegasus)indexclient.indexes.create(index_namevideo_rag,models[{model_name:marengo2.6,model_options:[visual,audio]},{model_name:pegasus1.1,model_options:[visual,audio]}])# 3. 上传视频withopen(DeepSeek-V3.mp4,rb)asf:taskclient.tasks.create(index_idindex.id,filef)client.tasks.wait_for_done(task.id)# 4. 语义检索 (找片段)resultsclient.search.query(index_idindex.id,query找到解释模型架构的部分,options[visual,audio])forclipinresults.data:print(f 片段:{clip.start}s -{clip.end}s (置信度:{clip.score}))# 5. 生成式问答 (Pegasus)answerclient.generate.text(video_idresults.data[0].video_id,promptDeepSeek-V3 的模型架构有什么创新点)print(f AI 回答:{answer.data}) 总结与展望从Small-to-Big的上下文窗口优化到Hybrid Search的混合检索增强从Router Engine的智能意图分发到Pandas Engine的精准数据分析再到MinerU Qwen-VL的复杂文档解析、CLIP的以图搜图以及Twelve Labs的视频理解。我们通过七大实战场景完整构建了一个能处理文本、表格、图片、视频的全能型 RAG 系统。LlamaIndex 强大的组件化设计让我们能够像搭积木一样灵活组合这些核心技术。RAG 的进化还在继续希望这份指南能成为你打造企业级 AI 应用的坚实基石