
不知道你们有没有这种经历纸质文件一旦攒起来整理、归档、查找就变成了一个永远在还的债。我之前用 Paperless-ngx 做无纸化管理把扫描件、电子发票、合同全部丢进去OCR 识别倒是做得挺准但真正用起来总觉得差一步——文件是“看得见”了但系统本身并不知道这堆文件“是什么”“该归到哪儿”。每次归档还是得靠手动建标签、改标题、选对应方大几百份文件整理下来手是真的会累。后来我找到了 clusterzx/paperless-ai 这个开源项目简单说它就是在 Paperless-ngx 和 LLM大语言模型之间搭了一层桥让 AI 自动完成文档的标题生成、摘要提取、标签分类、对应方识别这些原本靠人工判断的工作。如果你跟我一样已经有一套 Paperless-ngx 在跑又想让历史积压的文档和每天新入的扫描件都自动整理得明明白白那这篇文章应该能帮你少走不少弯路。下面我把自己的部署过程、配置细节和踩过的坑都整理出来。1. 项目思路与整体设计拆解1.1 Paperless-ngx 还不够“无纸化”的地方Paperless-ngx 本身已经很强了它自带 OCR、全文搜索、标签、对应方、文档类型、存储路径规则还有一套还算完整的 REST API。我最早用它的默认流程是扫描件丢进消费目录Paperless 自动 OCR然后按我设定的匹配规则归档。这套流程在文件量少的时候没毛病但一旦涉及合同、收据、说明书混在一起的内容就有几个尴尬的地方标题常常是一串日期加文件名比如“20240512_001.pdf”搜索的时候很难一眼认出这是哪份材料。标签和对应方依赖手工维护不同的人归档习惯不一样最后标签体系就会很乱。匹配规则本质是关键词面对表述灵活的内容比如同一家公司的各种英文名、简称经常匹配不上。这些问题不是 Paperless-ngx 做得差而是它本身定位是“索引型”系统它擅长把扫描件变成可检索的文本但不太擅长“理解”这些文本的语义。而 LLM 恰好能补上这一块。1.2 paperless-ai 的角色与工作方式clusterzx/paperless-ai 这个项目的设计思路很直接它不是一个重新发明的文档系统而是一个介于 Paperless-ngx 与模型之间的自动化处理层。它通过 Paperless-ngx 的 REST API 读取文档把文本内容发给 LLM再拿模型返回的结果去更新对应的文档元数据。换句话说Paperless-ngx 继续负责存储、检索和展示而 paperless-ai 负责“理解”。这个分工的好处是你不用改动现有的文档管理流程Paperless-ngx 该怎么做还是怎么做paperless-ai 只是在旁边帮你的文档自动补上更聪明的标题、标签、摘要和对应方。从架构角度理解这套设计有几个值得借鉴的地方它是独立部署的服务和 Paperless-ngx 解耦出问题不会影响主系统正常工作。它通过 API 集成而不是直接改数据库避免绕过业务逻辑导致的数据不一致。它把 LLM 调用集中在一个地方处理方便统一控制模型、提示词、频率和成本。1.3 适合谁用不适合谁用先说适合谁。如果你手头已经跑着 Paperless-ngx并且每天或者每周都在往里面塞新文件同时对 AI 自动分类、自动摘要这种功能有一定兴趣那 paperless-ai 是一个非常合适的补充工具。它尤其适合那种积压了大量历史文档、标签体系混乱、靠手工整理要花好几天时间的场景。不太适合的情况也有几种。如果你只管理几十份文件手工整理也就半小时的事那引入 AI 反而有点画蛇添足。另外如果手头的文档涉及高度敏感的隐私信息直接把文本发给云端 API 前一定要慎重评估这一点后面我会单独展开说。但如果你只是普通家庭文档、个人收据、产品说明书这类的就没什么顾虑。2. 部署准备与关键配置解析2.1 前置条件三样东西缺一不可要跑起来 paperless-ai你至少需要三样东西一套已经正常运行的 Paperless-ngx 实例并且确认 REST API 可以访问。一个 LLM 接口OpenAI 官方 API、Azure OpenAI 或本地跑 Ollama 都行。Docker 环境因为 paperless-ai 官方推荐的部署方式就是 Docker Compose。我自己用的是 Paperless-ngx 的 Docker 部署版本是较新的稳定版配合 Ollama 的本地模型后文会详细对比为什么我这样选。如果你用旧版本 Paperless-ngx要注意检查 API 端点是否有变化接口路径不对会导致 paperless-ai 无法读取文档。2.2 用 Docker Compose 快速部署我一般习惯把 paperless-ai 和 Paperless-ngx 放在同一个 Docker 网络里这样服务名可以直接互相访问省去暴露端口和配防火墙的麻烦。下面是我实际使用的 docker-compose 配置的简化版本services: paperless-ai: image: ghcr.io/clusterzx/paperless-ai:latest container_name: paperless-ai restart: unless-stopped ports: - 3008:3000 environment: - PAPERLESS_API_URLhttp://paperless-ngx:8000 - PAPERLESS_API_TOKEN你的APIToken - OPENAI_API_KEY你的APIKey - OPENAI_MODELgpt-4o-mini volumes: - ./paperless-ai:/data注意这里有几个点要说明PAPERLESS_API_URL如果是跨容器访问建议用 Docker 服务名而不是 localhost因为在容器里 localhost 指向的是容器自己。端口映射左边是你宿主机访问用的端口右边 3000 是容器内默认端口可以根据自己情况改。如果用的是 Ollama那环境变量会换成 Ollama 相关的地址和模型名后面我会专门列出来。启动命令很简单docker compose up -d启动之后访问http://localhost:3008应该能看到 paperless-ai 的 Web 界面它本身自带一个简单的管理页面可以用来查看处理日志和触发任务这个相比纯命令行操作会友好很多。2.3 从 Paperless-ngx 获取 API Token这一步值得专门说一下因为很多人配置的时候容易卡在这里。Paperless-ngx 的 API Token 在管理后台的底部找到“API 访问”或者对应位置创建。流程如下登录 Paperless-ngx 后进入管理后台找到“API 访问令牌”或等同于“API Token”的入口创建一个新 Token生成后立刻复制保存好因为它只显示一次。然后把这个 Token 填到 paperless-ai 的环境变量PAPERLESS_API_TOKEN里。提示如果 Paperless-ngx 开启了额外的访问控制比如反向代理层的基础认证需要确保 paperless-ai 在访问 API 时已经能通过认证否则会出现 401 错误。2.4 网络模式与访问权限控制我强烈建议不要把 Paperless-ngx 的管理后台直接暴露到公网这个和部署模式相关。paperless-ai 和 Paperless-ngx 之间通过内网 API 通信不需要也不能让公网直接来回访问。如果你有反向代理可以选择只暴露 paperless-ai 的 Web 界面到内网或加一层访问认证同时把 Paperless-ngx 的 API 留在内网环境里。这一点对家庭用户来说尤其重要很多人的 Paperless-ngx 和 NAS 跑在同一台机器上只要不把 8000 端口映射到公网正常内网使用就够了。3. 核心功能拆解与实操记录3.1 自动标题生成与文档摘要我自己最常用的功能就是文档自动标题和摘要。paperless-ai 会读取文档 OCR 后的文本然后让模型生成一个简洁准确的标题和一段摘要。原来的“20240512_001.pdf”经过处理后标题变成了“西门子冰箱说明书_型号KA62NV20TI”摘要里还会写明这份说明书主要涵盖哪些功能模块和注意事项。这个功能表面上看起来只是改了个名字但实际体验提升非常大。Paperless-ngx 默认的搜索已经被善用了但搜索质量很大程度上依赖文档标题和内容中是否有明确的词。有了 AI 自动生成的标题之后即使你只记得“冰箱”和“西门子”也能很快找到那份说明书。实操中值得注意的一点是标题长度的控制。我试过一次让模型生成“简洁标题”和不限制长度的效果后者会把标题写得像一段小作文在文件列表里非常难看。解决方法是在配置界面里把“标题最大长度”限制在 50 到 80 个字符之间摘要控制在 2 到 3 行。这个参数不同模型理解能力有差异建议实测调一下。3.2 自动标签分类解决“标签体系崩溃”问题标签是 Paperless-ngx 里组织文档的核心手段。但人工维护标签的问题前面提到了每个人对同一类文件的叫法可能完全不一样而且不专门维护标签很快就变成一个垃圾场——什么“发票”、什么“发票2024”、“发票报销”同时存在。paperless-ai 能在处理文档时根据内容自动推荐标签。它既可以给新文档打标签也可以给历史文档补打标签。我让模型顺手把标签统一到了几大类发票、合同、说明书、保修卡、银行单据、个人证件、其他。这样分类粒度不会细到没意义也不会粗到区分不出差别。这个功能最让我舒服的一点是模型会看内容而不是只看文件名。比如一个文件名是“scan_00345.pdf”的文件里面是某电商平台的电子发票人工不去打开还真不知道这是什么而模型读完正文后可以直接给它打上“发票”标签顺手还能识别出这张发票的开票方。3.3 对应方识别省去手工选填的麻烦Paperless-ngx 里的“对应方”概念简单说就是文档的来源方或者相关方。以前我要在归档时手动从下拉列表里选或者输入新名称。文件少的时候还行文件多了实在费神。paperless-ai 的对应方识别是让我决定长期使用它的最大原因。它能把合同里的甲方乙方、发票上的销售方、说明书的品牌方都提取出来填到对应方字段里。如果 Paperless-ngx 里已经有同名的对应方它通常会直接复用不会反复创建重名记录这一点处理得不错。我试过的几个典型场景一张京东发票提取出“京东”作为对应方。一份租房合同把出租方名字提取出来而不是用“房东”这种模糊的词。汽车保养单据直接识别出 4S 店全名。3.4 历史文档的批量处理如果已经有积压的几千份文档手动一篇篇让模型处理肯定效率太低。paperless-ai 支持按条件筛选一批文档然后批量触发处理。我通常按“未处理过”或者“最近 30 天新增文档”来筛选这样避免每次批量处理时把旧文档都重新扫一遍浪费 API 配额。批量处理的时候要留意限流和超时。调用云端 API 接口比如 OpenAI有每分钟请求数限制而 paperless-ai 本身也支持一定的并发控制。我的做法是把并发调到 2 到 3避免一下子发太多请求触发 429 限流错误。注意处理大量历史文档前建议先拿几十份做小范围测试观察标题和标签的生成质量再确认是否全量执行。不然如果 prompt 没调好可能会把已有的标签搞乱。4. 模型选型、Prompt 调优与成本控制4.1 云端 API 还是本地模型paperless-ai 支持接入多种 LLM 后端主流的有 OpenAI、Groq、Ollama、LM Studio、Mistral、Google Gemini 等。用哪个要看你自己的场景和接受度。云端 API如 OpenAI GPT 系列的优势是识别质量高、响应速度快、不需要自己准备高配置硬件。缺点是文档文本要送到第三方服务器对数据敏感度高的用户来说会有隐私顾虑同时每一万 token 都要计费大量文档批量处理时账单容易让你惊一下。本地模型如 Ollama 上跑的 Qwen、Llama 等的好处是数据不用出内网处理大量文档时没有按量计费压力只要机器内存和显存够就能跑。缺点是模型吞吐量和响应质量参差不齐配置要求高一些。比如我自己的小服务器是 64G 内存、没有独立显卡跑 7B 规模的量化模型响应速度能接受但质量确实比云端旗舰模型差一截。给到大家的建议很简单对隐私要求高或文档全是内部资料的优先本地模型。对归档质量要求高、不介意少量 API 费用、文档内容又不敏感的选云端模型。如果介于两者之间可以“云端处理敏感度低的”本地模型处理敏感度高的这属于进阶玩法需要灵活配合规则做路由复杂度高一些但效果也不错。4.2 我用 Ollama 时的配置参考如果你跟我一样打算先拿本地模型跑通流程可以参考下面的环境变量配置environment: - PAPERLESS_API_URLhttp://paperless-ngx:8000 - PAPERLESS_API_TOKEN你的APIToken - OLLAMA_BASE_URLhttp://ollama:11434 - OLLAMA_MODELqwen2.5:7b - OPENAI_BASE_URLhttp://ollama:11434/v1 - OPENAI_API_KEYollama - OPENAI_MODELqwen2.5:7b这里稍作解释OpenAI 兼容接口是目前各类模型服务的事实标准Ollama 1.x 之后原生支持了/v1兼容端点所以 paperless-ai 接 Ollama 的时候可以直接把OPENAI_BASE_URL指向 Ollama 的/v1地址然后 API Key 填一个任意值Ollama 不校验它模型名填你已经拉取好的本地模型名即可。这样比走 Ollama 原生接口更稳妥paperless-ai 也少识别一套 API 规范。如果跑在同一个 Docker 网络里base URL 直接用服务名如果你的 Ollama 暴露在宿主机端口上那用http://宿主机IP:11434/v1也行。注意别把宿主机 IP 写成 localhost容器里访问不到宿主机上的 localhost。4.3 本地模型选型经验我在 Ollama 上实测了几款模型之后有比较明显的感受差异模型参数量标签识别准确率标题生成质量中文理解资源占用qwen2.5:7b7B良好中上优秀中等llama3.1:8b8B中等中等一般较高mistral:7b7B一般中等较弱中等gemma2:9b9B中等中上一般较高如果文档以中文为主Qwen 系列的表现会明显优于同量级的其他模型在标签提取和标题生成上更贴近我手动整理的习惯。如果是纯英文文档Llama 和 Mistral 也够用差距没有中文场景那么明显。4.4 Prompt 配置与微调技巧paperless-ai 提供了自定义 prompt 的入口这个配置文件对最终输出质量影响非常大。默认 prompt 能做基础工作但如果你想更贴合自己的业务场景务必自己调整。我的 prompt 大概包含这几层结构角色设定说明你是一名文档管理助手职责是分析给定文档内容。任务说明要求生成标题、标签、摘要、对应方。格式约束明确输出格式为 JSON包含 title、tags、summary、correspondent 这些字段。约束条件标题不超过 XX 字标签控制在 3 到 5 个之间不要虚构文档中不存在的信息。附加要求如果是发票把金额和日期提取出来如果是合同提取合同双方名称。这个 prompt 写好后即使切换不同模型整体格式也能保持稳定。唯一要注意的是不同模型对 JSON 输出格式的遵循能力不一样稳定性差的模型偶尔会多输出解释文字导致 paperless-ai 解析失败。这时候要嘛换更强的模型要嘛在 prompt 末尾加一句“只输出 JSON不要解释”。4.5 成本估算与批量处理建议云端 API 的成本主要取决于文档的字符长度。一个典型 A4 扫描件 OCR 后大概是 1500 到 3000 token用 gpt-4o-mini 这类便宜模型单份文档成本约 0.002 到 0.005 美元。如果处理一万份文档总成本大约 20 到 50 美元这个量级对多数个人用户是能接受的。但如果你用的是 gpt-4o 这类高价模型成本会翻好几倍建议日常批量处理用便宜模型偶尔对疑难文档做二次处理再换贵模型。或者干脆用本地模型跑历史积压文档云端模型只跑每天新增的少量文件。另一个省钱技巧是paperless-ai 只处理匹配规则的文档或者只处理你不希望重复处理的文档避免每次批量都扫全库。我自己是设成只处理“没有标题”或“没有标签”的文档这样模型不会把已有整理的文档反复读一遍。5. 常见问题与排查技巧实录5.1 认证失败与 Token 权限不足症状paperless-ai 日志里出现 HTTP 401 或 403文档列表拉不出来。这一般是PAPERLESS_API_TOKEN配置有误或者 Token 根本没有对应权限。检查方法在浏览器里直接访问http://你的Paperless地址/api/documents/?limit1在请求头里带上Authorization: Token 你的Token看看是否返回 JSON 数据。如果返回 401说明 Token 本身不对如果返回 403可能是权限不足需要在 Paperless-ngx 管理后台给对应用户分配 API 访问权限。5.2 OCR 质量差导致 AI 理解出错如果你手里的扫描件本身模糊或者原始文本是手写的那 AI 识别错字、乱猜内容几乎是必然的。这种情况不能怪 paperless-ai源头在 OCR。我的规避策略是尽量用 Paperless-ngx 自带的 OCR 先做一次完整识别确认文本质量符合要求后再跑 AI 处理。如果个别文档 OCR 出来全是乱码建议直接人工处理不要浪费模型调用次数。5.3 模型响应不稳定偶尔返回空结果Ollama 本地模型在长时间运行后偶尔会出现响应超时或返回空内容的问题。paperless-ai 本身对这种情况有重试机制但可以提前优化确保 Ollama 服务有足够内存别让其它任务把它挤到持续交换内存。如果批量处理大文档考虑调低并发数避免模型后端过载。在 Ollama 服务里调整 keep_alive 参数让模型保持加载状态减少频繁换入换出。5.4 标签污染与重复对应方AI 自动打标签之后偶尔会出现一个文档被打上十几个标签的情况这是因为 prompt 里没约束标签数量。在 prompt 里明确写“最多返回 3 个标签”能大幅改善。对应方重复的问题则大多是因为 Paperless-ngx 里已存在近似名称但模型生成的是略有差异的新名称。例如已存在“Apple 苹果”模型却返回“Apple Inc.”。要缓解这个问题可以尝试在 prompt 里明确要求“如果文件内容与系统已有对应方相似尽量复用名称”但实际效果有限。我目前的应对方案是定期手动在 Paperless-ngx 里合并重复对应方由于 AI 已经减少了大部分重复创建工作合并频率不需要太高一个月检查一次就够。5.5 数据安全与隐私考量这一点放在最后说但并不是最不重要。接入 AI 处理文档意味着文档内容需要被模型服务访问。如果用云端 API敏感文档的隐私保护就成了大问题。合同里的身份证号、电话号码、地址信息都会送到第三方服务器做推理。如果你管理的是比较敏感的材料建议优先考虑本地模型方案确保文档内容不离开内网。如果一定要用云端模型提前做好数据脱敏或干脆用脱敏规则绕开敏感字段。在 paperless-ai 的配置里可以设置只处理已选标签的文档避免所有文档自动流入模型。6. 写在最后的个人经验从开始用 Paperless-ngx 到接入 paperless-ai我最大的感受是文档管理的瓶颈其实不在存储和检索而在“人要不要花时间做那些琐碎的整理动作”。有了 AI 自动处理标题、标签、摘要、对应方之后我每天花在归档上的时间从二十分钟降到了基本等于零只需要偶尔扫一眼处理结果改正个别识别偏差。如果你也想搭建一套自己的无纸化系统我的建议是先别急着全量接入 AI。先把 Paperless-ngx 跑顺把扫描习惯建立起来积累一段时间后观察自己最常做的手工整理动作到底是什么——是改标题最多还是打标签最多还是选对应方最多——然后再针对性地用 paperless-ai 去补上那一个点。这样一步步来不会一上来就被各种配置和 prompt 调整搞得失去了折腾的兴趣。paperless-ai 目前迭代速度还算可以社区反馈也比较活跃。如果你在部署中遇到它自身的问题去 GitHub 仓库看 issue 比到处搜教程更有效很多坑前人已经帮你踩平了。这套组合拳打完我的文件柜和硬盘里的电子文档终于能和平共处了。