资讯详情

资讯详情

基于 LlamaIndex 与 Docling 的 Excel 表格 RAG:文档解析、向量索引与流式问答实战(ai-engineering-hub / rag-with-dockling)

基于 LlamaIndex 与 Docling 的 Excel 表格 RAG文档解析、向量索引与流式问答实战ai-engineering-hub / rag-with-dockling【免费下载链接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub本指南围绕 rag-with-dockling 项目讲解如何用 LlamaIndex 生态配合 IBM Docling对 Excel 表格等复杂办公文档构建本地 RAG 问答系统。读完本文你将掌握从 Docling 文档解析、Markdown 节点切分、向量索引构建到接入本地 Ollama 大模型并实现流式问答的完整链路并能直接复现app.py与rag_excel.py中的可运行方案。一、为什么表格类文档需要专门的 RAG 方案普通的文本切片工具在解析 Excel、PPT 这类结构化文档时往往水土不服Excel 包含多工作表Sheet、合并单元格、跨表引用、公式与复杂排版如果只是按纯文本粗暴切分表格的行列关系、表头语义会被彻底破坏检索阶段自然无法命中正确答案。本项目给出的解法是用IBM Docling作为文档理解层先把 Excel 等复杂文档解析为结构化的 Markdown再由 LlamaIndex 的MarkdownNodeParser基于 Markdown 结构切分节点从而保留表格的语义骨架。整套技术栈与角色如下表环节组件在本项目中的角色文档解析llama-index-readers-docling的DoclingReader将.xlsx等文件解析为结构化内容节点切分MarkdownNodeParser按 Markdown 结构生成检索节点向量化HuggingFaceEmbeddingBAAI/bge-large-en-v1.5将节点文本转为向量向量索引VectorStoreIndex存储向量并支持相似度检索生成回答Ollama本地 LLMqwen3 / llama3.2基于检索上下文流式作答交互界面Streamlit上传文件、预览表格、聊天对话从源码结构看项目由三个文件构成README.md安装与说明、app.pyLlama 3.2 版本和 rag_excel.pyQwen3 版本后者与 README 推荐的ollama pull qwen3保持一致。二、环境准备与依赖安装README 明确要求Python 3.11 或更高版本随后安装 LlamaIndex 生态的相关包pip install -q --progress-bar off --no-warn-conflicts llama-index-core llama-index-readers-docling llama-index-node-parser-docling llama-index-embeddings-huggingface llama-index-llms-huggingface-api llama-index-readers-file python-dotenv llama-index-llms-ollama各依赖包的作用如下便于按需裁剪llama-index-coreLlamaIndex 核心库提供Settings、VectorStoreIndex、PromptTemplate等基础能力llama-index-readers-doclingDocling 文档读取器源码中通过DoclingReader解析 Excelllama-index-node-parser-docling与 Docling 配套的节点解析器llama-index-embeddings-huggingface提供HuggingFaceEmbedding用于加载 bge 嵌入模型llama-index-llms-huggingface-api与llama-index-llms-ollamaLLM 接入层本项目实际使用的是 Ollamallama-index-readers-file与python-dotenv文件读取与环境变量支持。由于界面基于 Streamlit、表格预览依赖 pandas运行演示还需补充安装pip install streamlit pandas接下来在本地拉取 Qwen3 模型README 推荐的操作rag_excel.py正是基于该模型编写ollama pull qwen3如果选择运行 app.py则需准备对应模型ollama pull llama3.2三、整体处理流水线从上传到流式回答结合 app.py 与 rag_excel.py 的源码一次完整的问答流程可分为六个阶段上传与落盘用户在侧边栏上传.xlsx/.xls文件程序把字节内容写入临时目录tempfile.TemporaryDirectory文档解析SimpleDirectoryReader通过file_extractor把.xlsx映射给DoclingReader调用loader.load_data()得到文档对象索引构建配置 bge 嵌入模型与MarkdownNodeParser调用VectorStoreIndex.from_documents()完成切分、嵌入与建索引查询引擎index.as_query_engine(streamingTrue)创建支持流式的查询引擎并通过update_prompts注入自定义问答模板流式生成循环消费response_gen迭代器逐 token 渲染回答Qwen3 版本还会过滤思考标签会话缓存以session_id 文件名为键把查询引擎缓存在st.session_state避免同一文件重复建索引。下面逐环节深入源码细节。四、文档解析层DoclingReader 与 SimpleDirectoryReader解析逻辑位于 app.pyrag_excel.py 中逻辑相同with tempfile.TemporaryDirectory() as temp_dir: file_path os.path.join(temp_dir, uploaded_file.name) with open(file_path, wb) as f: f.write(uploaded_file.getvalue()) file_key f{session_id}-{uploaded_file.name} st.write(Indexing your document...) if file_key not in st.session_state.get(file_cache, {}): if os.path.exists(temp_dir): reader DoclingReader() loader SimpleDirectoryReader( input_dirtemp_dir, file_extractor{.xlsx: reader}, ) else: st.error(Could not find the file you uploaded, please check again...) st.stop() docs loader.load_data()三个要点值得展开file_extractor后缀映射SimpleDirectoryReader默认按扩展名选择解析器这里把.xlsx明确指向DoclingReader是哪些文件交给 Docling的关键开关同理若要让 PPT 走 Docling只需把.pptx也映射给该 reader——这与 README 中同样可用于 PPT 和其他复杂文档的说明相呼应input_dir传目录而非单文件上传的文件被写入临时目录后loader 扫描整个目录从而天然支持后续扩展为批量文档临时目录即用即销TemporaryDirectory会在 with 块退出后自动清理避免长期占用磁盘若目录异常不存在则通过st.errorst.stop()中止流程。五、索引构建Markdown 切分、bge 嵌入与向量索引建索引的核心代码在 app.pyllm load_llm() embed_model HuggingFaceEmbedding( model_nameBAAI/bge-large-en-v1.5, trust_remote_codeTrue, ) Settings.embed_model embed_model node_parser MarkdownNodeParser() index VectorStoreIndex.from_documents( documentsdocs, transformations[node_parser], show_progressTrue, ) Settings.llm llm query_engine index.as_query_engine(streamingTrue)逐项说明MarkdownNodeParser这是与 Docling 配合的关键一步。Docling 把 Excel 解析成结构化 Markdown 后MarkdownNodeParser依据标题层级、表格、代码块等 Markdown 元素切分节点让每个检索单元保留完整语义它通过transformations参数注入会在建索引前自动执行HuggingFaceEmbedding加载BAAI/bge-large-en-v1.5作为嵌入模型trust_remote_codeTrue允许执行模型仓库内的自定义代码。注意该模型面向英文若要处理中文表格可替换为BAAI/bge-large-zh-v1.5等中文模型Settings.embed_model/Settings.llmLlamaIndex 的全局配置对象分别注册嵌入模型与 LLM索引与查询引擎会自动继承VectorStoreIndex.from_documents默认在内存中完成切分 → 嵌入 → 建索引show_progressTrue会在建索引时输出进度as_query_engine(streamingTrue)开启流式模式后续通过response_gen逐块获取回答。需要指出源码中query_engine上方有一行使用 cohere reranker的注释但从实现看并未真正配置重排序器无NodePostprocessor相关代码实际效果等同于普通 top-k 检索。想引入重排序可自行添加llama-index-postprocessor-cohere-rerank并配置SimilarityPostprocessor/CohereRerank。六、LLM 接入Ollama 本地模型两个版本通过st.cache_resource缓存的工厂函数加载 LLMapp.pyst.cache_resource def load_llm(): llm Ollama(modelllama3.2, request_timeout120.0) return llmrag_excel.py 中对应改为st.cache_resource def load_llm(): llm Ollama(modelqwen3, request_timeout120.0) return llm实践要点request_timeout120.0指定单次推理的超时上限对长文档、复杂表格的生成尤为重要可依据机器性能调大st.cache_resource保证整个 Streamlit 会话内只创建一次 LLM 客户端避免每次重跑都重新加载模型本地模型需先通过ollama pull拉取见第二节若机器无 Ollama也可按 README 安装列表中的llama-index-llms-huggingface-api走远程推理 API代码仅需替换load_llm的实现。七、查询引擎与自定义 Prompt 模板为了得到更精准、克制的回答项目对默认 QA 模板做了定制app.pyqa_prompt_tmpl_str ( Context information is below.\n ---------------------\n {context_str}\n ---------------------\n Given the context information above I want you to think step by step to answer the query in a highly precise and crisp manner focused on the final answer, incase case you dont know the answer say I dont know!.\n Query: {query_str}\n Answer: ) qa_prompt_tmpl PromptTemplate(qa_prompt_tmpl_str) query_engine.update_prompts( {response_synthesizer:text_qa_template: qa_prompt_tmpl} )模板设计的三个要点{context_str}与{query_str}是必须保留的占位符前者由检索结果填充后者是用户问题缺一不可明确不知道就说不知道模板要求模型在缺乏依据时输出I dont know!降低表格数据问答中的幻觉风险update_prompts的键名response_synthesizer:text_qa_template是 LlamaIndex 中文本问答模板的注册名必须原样书写才能覆盖默认模板。rag_excel.py 针对 Qwen3 的思考模式额外在Answer:前加入了/no_think指令用于抑制思考内容与后文流式阶段的think过滤形成双保险。八、流式对话与思考标签过滤界面层使用 Streamlit 的st.chat_message渲染历史消息并模拟打字机效果app.pystreaming_response query_engine.query(prompt) for chunk in streaming_response.response_gen: full_response chunk message_placeholder.markdown(full_response ▌) message_placeholder.markdown(full_response)由于 Qwen3 默认带思考模式输出中会夹杂think.../think标签rag_excel.py 在流式循环中做了过滤for chunk in streaming_response.response_gen: if think in chunk or /think in chunk: continue full_response chunk message_placeholder.markdown(full_response ▌)实现细节query_engine.query()返回流式响应对象response_gen是逐块生成器配合st.empty()占位符可实现逐字刷新过滤逻辑采用整块跳过策略——若某个 chunk 恰好是think或/think则丢弃简单有效若思考内容与正文混在同一 chunk 中可进一步用字符串替换做清洗每条问答都会被追加进st.session_state.messages实现多轮对话历史右上角的 Clear ↺ 按钮触发reset_chat()清空消息并调用gc.collect()释放内存。九、会话缓存避免重复建索引应用在会话初始化时建立缓存容器app.pyif id not in st.session_state: st.session_state.id uuid.uuid4() st.session_state.file_cache {}file_key f{session_id}-{uploaded_file.name}以会话 ID 文件名作为缓存键不同用户上传同名文件互不干扰首次上传时构建索引并写入st.session_state.file_cache[file_key] query_engine再次上传相同文件时直接从缓存取出查询引擎app.py省去重复解析与向量化的耗时display_excel()用pd.read_excel(file)读取后经st.dataframe(df)渲染让用户在建索引的同时预览表格内容所见即所得。十、运行与使用在项目目录下启动 Streamlit 应用streamlit run app.py # Llama 3.2 版本 streamlit run rag_excel.py # Qwen3 版本与 README 推荐一致使用流程浏览器打开 Streamlit 提供的本地地址在左侧边栏点击 Choose your.xlsxfile上传.xlsx/.xls文件等待 Indexing your document... 完成出现 Ready to Chat! 提示并看到表格预览在底部输入框提问例如某月份各区域销售额合计是多少哪个产品的增长率最高应用会基于检索到的表格上下文流式作答点击右上角 Clear ↺ 清空对话、释放内存。前提条件Ollama 已安装且目标模型已拉取首次运行会下载 bge 嵌入模型需要网络连接。十一、扩展方向与注意事项支持更多复杂文档README 明确指出本方案同样适用于 PPT 等复杂文档。只需在file_extractor中增加对应扩展名映射如.pptx即可复用同一套 Docling 解析与检索链路替换嵌入模型BAAI/bge-large-en-v1.5面向英文处理中文数据时建议替换为BAAI/bge-large-zh-v1.5或BAAI/bge-m3并在HuggingFaceEmbedding中同步修改model_name引入重排序代码注释提及 reranker 但未实际配置检索质量敏感场景可自行接入CohereRerank或本地 bge-reranker长文档与超时request_timeout120.0对复杂表格推理可能偏紧生成超时可适当调大数据保密性本方案 LLM 与嵌入模型均在本地运行Excel 内容不会离开本机适合对数据隐私有要求的场景。总体而言rag-with-dockling 给出了一条Docling 解析 LlamaIndex 检索 本地 LLM 生成的完整可运行范式其架构同样可平移到 PPT、PDF 等更多办公文档的问答场景。【免费下载链接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →