Qwen-Agent 文档解析实战:PDF/Word 自动分块与 RAG 问答,把 47 页 PDF 变成可直接提问的文档

📅 发布时间:2026/9/10 14:24:40
Qwen-Agent 文档解析实战:PDF/Word 自动分块与 RAG 问答,把 47 页 PDF 变成可直接提问的文档
Qwen-Agent 文档解析实战PDF/Word 自动分块与 RAG 问答把 47 页 PDF 变成可直接提问的文档【免费下载链接】Qwen-AgentAgent framework and applications built upon Qwen3.0, featuring Function Calling, MCP, Code Interpreter, RAG, Chrome extension, etc.项目地址: https://gitcode.com/GitHub_Trending/qw/Qwen-Agent上周三有人问我一份 47 页评估报告里三个实验组各自的结论是什么我翻了 20 分钟页码手动复制粘贴拼参考资料中途还被上下文长度截断。Qwen-Agent 把这类手工把文档喂给大模型的活儿变成了一条标准链路文档解析、分块、RAG 检索都预置成了工具你只需要调几行代码。它是什么给文档解析加了一条解析 → 分块 → 检索的默认链路Qwen-Agent 是基于 Qwen 系列的 Agent 框架内置了文档解析DocParser / SimpleDocParser与 RAG 检索retrieval工具支持 pdf / docx / pptx / txt / html / csv / tsv / xlsx 九种格式的内容提取按 token 预算自动分块并做本地缓存分块结果可直接喂给任意大模型配套 BasicDocQA、ParallelDocQA 等 Agent实现丢一个文件 提一个问题直接出答案适合谁需要让大模型回答长文档问题、想把一批文档转成可检索语料、或者在自研 RAG 管线里找现成解析分块模块的开发者。核心能力拆解从一个文件到可回答的文档上面这张图对应的能力拆开看是下面这几层每层都省掉一类手工操作多格式内容提取simple_doc_parser.py按文件类型分发到对应解析器表格统一转成 markdown 管道格式。省掉的是Word 表格、Excel 逐格复制再手动排版的活。token 预算分块doc_parser.py按可配置的单块 token 上限切分长段落先按句子拆切点处自动带一段重叠内容到下一块。省掉的是手工数哪段该和哪段放一起、别让句子被拦腰截断的活。本地缓存解析结果以文件哈希 分块参数为 key 写入workspace/tools/目录同一文件二次调用直接读缓存。省掉的是同一个 PDF 每问一个问题就重新解析一遍的等待。混合检索retrieval.py默认组合关键词检索与首页加权检索从所有分块里召回与问题相关的片段。省掉的是自己在几百个 chunk 里 CtrlF的活。开箱的问答 AgentAssistant挂上retrieval工具即是 RAG 问答parallel_doc_qa.py 提供并行长文档方案。省掉的是手写检索-拼装-提示词整条胶水代码。从能力清单到跑起来只需要三步。上手路径Qwen-Agent 文档解析命令速查第 1 步装环境提取第一份 PDF 的文本这段做两件事拉取仓库安装带 RAG 依赖的最小运行集[rag]会补上 pdfplumber、jieba 等检索依赖。git clone https://gitcode.com/GitHub_Trending/qw/Qwen-Agent cd Qwen-Agent pip install -U qwen-agent[rag]跑完你会看到依赖安装完成注意大模型调用还需要export DASHSCOPE_API_KEY你的keyDashScope 服务时。下面这段从本地 PDF 里提取结构化内容from qwen_agent.tools import SimpleDocParser parser SimpleDocParser({structured_doc: True}) doc parser.call({url: report.pdf}) print(doc[0][page_num], len(doc[0][content])) # 第一页编号与内容元素数 print(doc[0][content][0]) # 第一个段落或表格跑完你会看到按页组织的内容每页含page_num和content列表段落是{text: ...}表格是已转成 markdown 的{table: ...}。第 2 步用 DocParser 把文档变成分块这段演示核心分块参数默认每块 500 token全文不超过 20000 token 时整篇作为一个 chunk 返回。from qwen_agent.tools import DocParser parser DocParser() # 默认 parser_page_size500, max_ref_token20000 record parser.call({url: report.pdf}) print(record[title]) # 文档标题取不到时回退为文件名 print(len(record[raw])) # 分块数量 print(record[raw][0][content]) # 第一块内容含 [page: n] 页码标记跑完你会看到每个分块都是content/metadata/token结构metadata里带source、title、chunk_id再跑一次同一文件会直接读缓存秒回。第 3 步问出第一个 RAG 问题这段把retrieval工具挂到Assistant上文件路径放在消息的file字段里检索由模型自动发起。from qwen_agent.agents import Assistant bot Assistant(function_list[{name: retrieval}], llm{model: qwen-plus-latest}) msgs [{role: user, content: [{text: 三个实验组各自的结论是什么}, {file: report.pdf}]}] for rsp in bot.run(msgs): print(rsp[-1][content])跑完你会看到模型先调用检索工具拉取相关分块再基于召回内容作答日志里能看到Read chunked ... from cache说明第一次的解析结果被直接复用了。能跑通问答之后下面两个场景展示了不同形态的数据流。场景实战看数据怎么流进去、又怎么出来场景 1对一份上百页的 PDF 直接提问输入是什么一份 120 页的技术报告 PDF加一个问题报告引用了哪些数据集各自的规模是多少执行了什么操作Assistant收到消息后自动把文件路径交给retrieval工具retrieval内部调用DocParser完成解析分块120 页会按 500 token/块切成约 150 个 chunk缓存到本地再用关键词检索召回 Top 相关片段拼进上下文交给模型。输出长什么样一段条理化的答案列出数据集名称与规模因为是检索而非整篇塞入答案只引用了真正相关的几个分块输入 token 远低于全文长度。追问第二段引用的数据来自哪一节时缓存命中解析耗时归零。场景 2把一批会议纪要转成可复用的分块语料输入是什么目录下若干份.docx会议纪要。执行了什么操作循环调用DocParser把返回的raw落盘为 JSON后续接自己的向量库或 BM25 索引即可import json from qwen_agent.tools import DocParser parser DocParser() for f in [meeting_01.docx, meeting_02.docx]: record parser.call({url: f}) json.dump(record[raw], open(f.split(.)[0] .chunks.json, w), ensure_asciiFalse, indent1)跑完你会看到每份纪要对应一个 JSON 文件里面是带chunk_id的分块列表。输出长什么样chunks.json中的每个元素含content带页码标记的文本、token数、metadata来源与标题字段自包含不依赖 Qwen-Agent 也能被其他系统消费——这就是解析工具和问答 Agent解耦的好处。分块行为看着省心它背后其实只有三个关键设计。原理速览一份 PDF 是怎么变成分块的为什么这样设计分块以 token 为预算而不是固定页数保证每个 chunk 都能放进模型上下文窗口max_ref_token内的短文直接整篇返回省掉了为 3 页文档硬切 5 块的碎片化分块切点自动带回上一块末尾的句子作为重叠_get_last_part在 doc_parser.py 中实现避免跨块引用时语义断裂。最后所有结果写本地缓存让解析从每次问答的成本变成一次性成本。理解这条链路后有两个地方值得按你的场景微调。进阶玩法两处可改到你自己场景1. 按章节而非 token 预算分块——改split_doc_to_chunk这一个方法即可from qwen_agent.tools.doc_parser import DocParser class SectionDocParser(DocParser): # 默认按 token 预算切块可能把同一章节拦腰切开 # 这里改为按 markdown 标题/章节号正则切分保证一节一块 def split_doc_to_chunk(self, doc, path, title, parser_page_size500): ... # re.split 按标题模式切逐节生成 Chunk为什么这样改如果你的下游提示词要求按章节引用比如法律条款、论文小节token 预算切分会让引用边界错乱按章节切后每个 chunk 自带完整语义单元检索召回的片段可以直接当引用来源展示。2. 用配置而非继承调大检索窗口——官方并行方案 parallel_doc_qa.py 里就是这么做的retrieval_cfg { name: retrieval, parser_page_size: 1000, # 块更大减少答案跨块引用 max_ref_token: 4500, # 一次召回更多 token容忍更长的上下文 rag_searchers: [keyword_search, front_page_search], # 混合检索 } bot Assistant(function_list[retrieval_cfg], llm{model: qwen-plus-latest})改哪里、为什么parser_page_size和max_ref_token直接决定每块多大和一次能召回多少问总结全文思路这类需要跨段落的问题时默认 500 token 的块偏碎调到 1000 会让答案的引用更连贯短问短句场景保持默认即可省 token。调参跑起来之后有几个高频问题值得提前知道。常见问题Qwen-Agent 文档解析的 3 个高频疑问现象第二次调用 DocParser 秒回但改了一个参数后又变慢了。原因缓存 key 是文件哈希 parser_page_size见 doc_parser.py 中cached_name_chunking参数一变就是新的 key等于重新解析。解法同一批问答保持分块参数一致确实需要多种粒度时用cfg里的path指定不同缓存目录隔离。现象RAG 依赖报错The dependencies for RAG support are not installed。原因pip install qwen-agent最小安装不含 RAG 依赖。解法装pip install qwen-agent[rag]pdfplumber、jieba、rank_bm25 等会一并补上。现象扫描版 PDF 解析出来是空的或报错。原因内置解析器只走文本层提取pdfminer pdfplumberextract_imageTrue目前会直接抛ValueError不内置 OCR。解法扫描件先过一道 OCR 生成带文本层的 PDF 再解析这也是当前格式支持表里pdf的实际边界simple_doc_parser.py 里各解析函数对图片提取的报错是刻意的显式失败方便你定位这类文件。 顺带一提解析缓存默认落在workspace/tools/下清理缓存或换机器迁移语料时从这里入手即可。收束Qwen-Agent 的文档解析本质上是把提取 → 分块 → 缓存 → 检索 → 问答这条最容易写脏的链路标准化了你真正要做的只剩选参数和提问。把上面第 2 步的那段DocParser代码对着你手边任意一份 PDF 跑一遍30 秒内你会看到标题、分块数和第一个 chunk 的完整内容——剩下的调参就都建立在这个具体输出了。【免费下载链接】Qwen-AgentAgent framework and applications built upon Qwen3.0, featuring Function Calling, MCP, Code Interpreter, RAG, Chrome extension, etc.项目地址: https://gitcode.com/GitHub_Trending/qw/Qwen-Agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考