Hermes读PDF不再卡死!2400页文档token从450万降到2千


为 Hermes 构建本地 PDF/DOCX 解析技能:将上下文信息从 270 万个词元减少到 2200 个词元(SQLite FTS5)

本地基准:
测试 PDF: AMD 技术文档
页数: 3,799 页 | 105 万字 | 746 万字符
解析时间: ~14 分钟(在 AMD FireRange CPU 上)

测试: 我向 LLM 提出了一个非常具体、略带口语化的问题,关于特定寄存器的位功能(模拟工程师在现实世界中实际提问的方式)。

不包含该技能(全文转储): ~2,794,829 tokens 。上下文信息爆炸,模型完全失去焦点,开始胡思乱想。
运用技能(目标片段检索): ~2,244 tokens 。智能体检索到了确切的片段,并提供了正确、精确的答案。

我的配置:
操作系统: Windows 11
LLM runner: Ollama
型号: Qwen3.6:27b

文档结构化工具:把PDF当数据库查

你有没有试过让AI读一份几千页的PDF?结果AI直接摆烂,要么胡说八道,要么直接告诉你“内容太多我记不住”。这玩意儿就是来解决这个问题的。它把PDF和Word文档切碎、标号、存进数据库,让AI不再“硬读”整篇文章,而是像查字典一样精准抓取需要的段落。

这玩意儿到底在干啥

把一份几百页甚至几千页的技术文档扔进去。它先扫描文档结构,把每一章、每一节、每一个小标题都认出来。然后按照标题层级把文档切成一块一块的Markdown格式碎片。每一块都有编号:第几章、第几节、标题是什么、从第几页开始、存成了哪个文件。

接着它把这些碎片信息全部塞进一个SQLite数据库里。数据库里建了两张核心表,一张记文档基本信息,一张记每个碎片的具体内容。同时它还启用了SQLite的FTS5全文搜索引擎,给所有碎片内容建了索引。

最后你只要输入关键词,它就能在零点几秒内告诉你:这个词出现在哪个章节、上下文是什么、文件在哪儿。整个过程就像在Google里搜东西一样简单。

它解决了什么要命问题

一般的AI读文档,你只能把整篇PDF一股脑塞进它的上下文窗口。这就好比让你把整本新华字典背下来再去查一个字,脑子不炸才怪。

对于一份2400页的PDF,直接喂给AI大概要消耗450万个token。这是什么概念?用主流付费模型处理一次可能就得花掉几十块钱,关键是AI还不一定能答对。

因为信息太多了,AI根本不知道重点在哪儿。你问一个具体问题,它可能把文档里所有沾边的段落都拼凑起来给你,里面还夹杂着一堆无关的废话。

更离谱的是,AI经常会编造答案。本来文档里根本没有的内容,它为了凑字数自己脑补出来一段。这种情况在技术文档领域尤其致命——你问的可能是芯片寄存器的位定义,它给你一个完全不存在的寄存器名字,你要真信了去写代码,硬件可能直接烧了。

但用这个工具就不一样了。你问一个问题,它先去FTS5索引里搜关键词,找到最相关的3到5个碎片,只把这几个碎片喂给AI。AI需要处理的token数量从几百万骤降到两三千。它只需要阅读那几段关键内容就能给出精准回答,不会再胡说八道。

怎么把文档吃进去

这个工具的操作分成四步走,每一步都有专门的处理逻辑。

第一步是解析。针对PDF文件,它用的是PyMuPDF库配合pymupdf4llm这个转换器。这个组合能把PDF里的文字、标题、页码、段落结构全部识别出来,转成结构清晰的Markdown格式。针对Word文档,它用python-docx库来读取。不管你扔什么格式进去,最终都会变成统一的Markdown片段。

第二步是切块。切块的依据是标题层级。文档里的H1大标题、H2中标题、H3小标题全部被识别。工具按照这些标题把文档切成独立单元。每个单元包含完整的标题、正文内容、起始页码和层级关系。

第三步是入库。所有切好的碎片被写入SQLite数据库的chunks表。每个碎片分配一个唯一编号,同时记录它属于哪个文档、章节号是多少、对应哪个物理文件。documents表则记录文档的整体信息,包括文件名、上传时间、碎片总数。

第四步是建索引。这一步用到的是SQLite的FTS5扩展模块。它会对每个碎片的标题和正文内容建立全文索引,支持布尔检索、前缀匹配、短语查询等高级搜索语法。索引建好后,搜索速度比直接遍历数据库快了上百倍。

怎么把信息查出来

工具提供了好几套查询方式,适应不同的使用场景。

最核心的是关键词搜索。你输入一个查询词,比如ACPI或者某个寄存器名字,工具会返回所有匹配的碎片列表。每个匹配结果都包含碎片编号、章节标题、匹配内容片段、所在文件路径。搜索范围可以单独限定在标题里,也可以扩大到正文全文。

如果你已经知道了某个碎片编号,可以直接根据编号获取完整内容。这个操作会返回整个碎片的原始Markdown文本,包含完整的章节标题和正文,不需要加载整篇文档。

还有一个专门查看目录结构的功能。你能看到整篇文档的章节树形结构,每节对应哪个文件、层级关系是怎样的、总共有多少章节。这在做文档概览或知识导航的时候特别有用。

所有查询返回的内容都是结构化的,可以直接被LLM Agent读取和处理。如果搜索结果不够精准,还可以用LIKE模糊匹配作为兜底方案。

整个系统的底层逻辑

这套工具的本质是一个轻量级的文档ETL系统。

ETL是数据工程里的术语,代表抽取、转换、加载三个步骤。在这里,抽取指的是从PDF和Word文件里提取文字内容和结构信息。转换指的是按照标题层级切分、转成Markdown格式。加载指的是写入SQLite数据库并建立FTS5索引。

流程可以画成这样:原始PDF或DOCX文件进去,经过结构解析和标题分块处理,变成一堆Markdown片段。这些片段入库的同时生成全文索引。最终对外暴露的是查询API和命令行工具。

这种架构的好处是处理过程完全离线,不需要依赖任何云服务。所有数据都保存在本地,隐私安全有保障。性能方面,SQLite本身是经过高度优化的嵌入式数据库,对于单机场景完全够用。

这套设计还带来了一个额外优势:删改特别方便。如果你更新了文档,只要重新上传同名的文件,工具会自动删除旧数据并重建索引,不会产生脏数据。

用在什么地方最合适

技术手册是头号适用场景。硬件厂商经常发布几千页的编程指南,工程师需要频繁查阅特定寄存器的定义。把这堆文档扔进去以后,查一个寄存器定义只需要几秒钟。

论文库也适用。学术论文往往有清晰的章节结构,每篇论文可以被切分成摘要、引言、方法、实验、结论等独立单元。研究者可以根据关键词快速定位到相关论文的特定章节。

API文档同样不在话下。大型API文档动辄几百个接口定义,每个接口都有独立的描述和参数说明。把API文档结构化存储以后,开发者搜索某个函数用法的时候可以直接定位到对应的接口说明。

企业内部的知识库也能用上。很多公司有大量的内部技术文档和合规资料,平时很难被充分利用。有了这套工具,员工可以用自然语言提问的方式快速获取答案,不用在海量文档里逐篇翻阅。

跟其他类似工具有啥不一样

市面上有个叫Unstract的产品,它主打的是企业级文档数据抽取。它的工作方式是自动识别文档里的关键字段,比如发票号、日期、金额这些,然后以JSON格式输出结构化数据。它更适合做业务流程自动化,比如自动处理财务单据。

但这个工具完全不同。它的核心目标是让LLM Agent能够高效检索和理解文档内容。它不关心文档里有哪些关键字段,只关心文档的章节结构。它输出的不是JSON而是可被AI读取的Markdown片段和搜索结果。

更直白地说,Unstract解决的是文档数据抽取的问题,而这个工具解决的是文档知识检索的问题。前者适合做自动化流程,后者适合做AI知识库。

实际跑起来效果咋样

开发者用一份AMD技术文档做了测试。文档有3799页,约105万个单词,总字符数超过746万。在AMD FireRange CPU上跑完整个解析流程花了大概14分钟。

测试的问题是关于某个特定寄存器的位功能。这个问题特意用了一种偏口语化的问法,模仿工程师在实际工作中会用的表达方式,不是那种标准的术语查询。

在不使用这个工具的情况下,直接把整份文档塞进LLM的上下文窗口,消耗了279万多个token。模型的回答逻辑混乱,而且编造了不少不存在的寄存器信息,根本没法用。

但用了这个工具以后,Agent先通过FTS5搜索找到匹配的碎片,只把那几个相关的碎片喂给模型。最终的上下文窗口只用了2244个token,还不到原来的千分之一。模型的回答精准地描述了寄存器各个位的功能定义,全部有据可查。

从279万降到两千多,这个压缩比例相当惊人。意味着同样的一份硬件文档,原来处理一次可能就耗尽预算,现在可以反复查询几百上千次。

背后的关键技术点

PyMuPDF4llm这个库是整套解析流程的核心。它不是普通的PDF转文本工具,而是专门针对LLM场景优化的转换器。它输出的Markdown保留了原始文档的层级结构,标题、列表、表格、代码块都能被正确识别和转换。

SQLite的FTS5模块提供了企业级的全文搜索能力,但不需要额外部署任何服务。它支持BM25相关性评分算法,可以对搜索结果按相关度排序。对于技术文档里经常出现的专业术语和缩写词,FTS5的精确匹配能力特别重要。

基于碎片的架构设计是整个系统的灵魂。工具始终不处理整篇文档,只处理被切分后的独立单元。每个碎片在内容上是完整的,在上下文上是独立的。这种设计让系统具备了极强的可伸缩性,文档数量增加的时候只要扩展数据库记录就行。

建好以后怎么扩展

这套工具可以和RAG系统无缝对接。RAG的全称是检索增强生成,是目前主流的知识问答系统架构。这个工具本质上已经提供了RAG系统里最关键的检索组件。只需要把它的查询结果喂给任意LLM,就构成了一个完整的RAG流水线。

如果想让LLM Agent直接调用这套工具,可以把它封装成MCP工具。MCP全称是模型上下文协议,是一种标准化的Agent工具调用规范。封装以后,Agent可以像调用内部函数一样调用文档查询功能,整个过程对用户完全透明。

实际的部署方式也很灵活。可以直接用命令行工具执行查询,也可以写成API服务供其他程序调用。对于本地部署场景,最简单的就是把查询命令集成到Agent的工作流里。

如果你想进一步深挖,还有几个方向可以探索。比如碎片的粒度控制:切得太细可能丢失上下文,切得太粗又影响检索精度。还有搜索结果的排序优化:如何根据问题的语义找到最匹配的碎片,而不是仅仅依赖关键词命中。这些都会直接影响最终的回答质量。

总结一下

对于技术手册、论文库、API文档这类内容,用传统方式让AI处理就是给自己找麻烦。

这工具把PDF和Word变成可查询的结构化知识库,让LLM不再硬读整篇文档,而是像查数据库一样精准定位内容。一份3799页的硬件文档,处理时间14分钟,查询消耗从279万token降到2244token。

本质上就是把文档阅读问题变成了数据库查询问题。