vailsen/paperless-brain

GitHub: vailsen/paperless-brain

为 Paperless-ngx 文档归档系统提供基于视觉 LLM 的文档阅读、对话式检索、智能提取和深度研究能力的 AI 智能助手。

Stars: 12 | Forks: 0

PaperlessBrain logo

PaperlessBrain

你的 Paperless-ngx 归档系统的智能大脑。
与你的文档对话,让视觉 LLM 阅读每一页,再也不会错过任何截止日期。
可安装的 PWA —— 为移动端和桌面端打造。

License: MIT Python 3.12+ Status: alpha Built with NiceGUI

Chatting with the archive — the assistant searches, reads and cites documents through an agentic tool loop

## 功能简介 Paperless-ngx 负责存储和组织你的文档。PaperlessBrain 则负责阅读它们 —— 通过视觉 LLM 阅读每一页 —— 并将你的归档转化为可以互动交流的智能库。 - **与你的归档对话** —— 一个 agentic 工具循环(Claude API 或你本地的 Ollama 模型),可以搜索、阅读、交叉比对并引用你的文档。 - **视觉 LLM 摄入** —— 每一页都会被渲染成图片,并由视觉 模型阅读:根据 文档类型提取全文摘要、表格、操作事项和截止日期。如果你愿意,可以完全在本地 Ollama 上运行,或者使用云端 模型 —— 选择器与聊天功能相同。 - **截止日期与操作事项** —— 提取出的待办事项(“在……前取消”、“在……前支付”) 将展示在仪表板上。 - **大脑记忆** —— 助手会将关于你的信息以纯 Markdown 文件的形式记录下来,并在每次对话中通过 embedding 进行回忆检索。 - **Vault 笔记** —— 你专属的 Markdown 知识库,可在聊天中与归档一起 搜索。兼容任何编辑器;Obsidian 为可选项。 - **深度研究** —— 自主的多步骤研究,但最关键的是数据 来源:除了网络,agent 还会跨**你自己的文档**进行研究。 确定性的 orchestrator 会将任务拆分为子任务,运行特定范围的 agent,并 综合生成经过审查的结果。 - **文档生成** —— DIN-5008 信函(针对德国市场)、电子邮件草稿、 将聊天内容转换为 PDF 并保存回 Paperless。 - **邮件与日历工具** —— 每个用户独立的 IMAP 和 CalDAV 凭证,经过加密; 当你提问时,助手可以查看邮件和日程安排。 - **网络搜索** —— 通过你自托管的 SearXNG 实例,支持 全网页阅读(trafilatura,对于包含大量 JS 的页面,可选使用 headless Chromium)。 - **PWA** —— 可安装在手机和桌面上,支持用户自定义语言(英语/德语), 包含暗色/亮色主题。 ## 开发动机 这是我为自己的文档系统构建的一个小项目。在 2026 年初,我 尝试了多款现有工具,但没有一款能满足我的需求 —— 它们缺少我想要的高级功能: 高效利用高端消费级硬件、更深入的 LLM 摄入分析、信息丰富的向量数据库, 以及真正实用的文档详情视图。随着功能不断增加,现在的功能已经足够完善, 我觉得值得将其分享给社区。 我个人使用体验最好的是 **Qwen3.6-35B-A3B (MTP, Q4)** 作为聊天 模型 —— Multi-Token Prediction 使它比我尝试过的任何云端模型都要快, 同时在工具调用方面依然保持出色。你的体验会因你 的硬件和模型而异;这里的内容并不绑定任何特定模型。 ## 截图
Dashboard showing extracted deadlines and actions
Dashboard — deadlines & actions extracted from every document
Document detail dialog with vision-read pages, tables and actions
Document detail — vision-read pages, tables, actions, cross-references
Deep research — autonomous multi-step research module in action
Deep research — autonomous multi-step research, reviewed before persist
## 架构 ``` flowchart LR P[Paperless-ngx] <-->|REST API| B(PaperlessBrain) B <--> C[(ChromaDB
+ JSON sidecars)] B <-->|vision ingest
+ local chat| O[Ollama] B <-->|cloud chat
optional| A[Claude API] B <--> V[/"Vault (Markdown + git)"/] B -->|web search| S[SearXNG] ``` 同步功能会将 Paperless 与索引进行比对,新文档会逐页进行渲染并由 视觉模型阅读;结果保存在 JSON sidecars 和 ChromaDB embeddings(`multilingual-e5` —— 支持多语言检索)中。聊天后端 (Claude / Ollama)共享一套工具集和一个流式事件协议。 ## 快速开始(Docker) ``` git clone https://github.com/Vailsen/paperless-brain && cd paperless-brain cp .env.example .env # fill in: PAPERLESS_URL, PAPERLESS_SUPERUSER_TOKEN, STORAGE_SECRET docker compose up -d # pulls the prebuilt image from GHCR (no local build) ``` 首次启动前,请编辑 `docker-compose.yml` 中的 **vault 挂载**路径,使其 指向存放现有 Markdown 笔记的目录 —— 每个 Paperless-ngx 用户对应一个子文件夹 (例如用户 `alice` 对应 `/srv/obsidian/alice` → 挂载 `- /srv/obsidian:/mnt/vaults`)。如果不修改,应用会在 `./vaults` 下创建一个空的 vault,而你真正的笔记永远不会被索引。 `.env.example` 是精简版配置;`.env.example.full` 包含了每个键的详细文档说明。 克隆仓库仅仅是为了获取 compose 文件和 `.env.example`;应用本身以 预构建镜像的形式提供。如果想改为从源码构建,请编辑 `docker-compose.yml` (将 `image:` 替换为 `build: .`)。 打开 `http://localhost:8080` 并使用你的 **Paperless-ngx 用户名和 密码** 登录 —— 用户、权限和会话均直接来自 Paperless 本身。 首次启动会将 embedding 模型(约 2.2 GB)下载到 Docker volume 中; 容器在此过程中需要一次网络访问权限。 镜像变体:默认标签(`:latest`)包含用于处理包含大量 JS 的网页的 headless Chromium;`:lean` 标签的体积小了约 1 GB,其网页阅读 仅回退使用 trafilatura。通过指定 `:1.2.3`(或 `:1.2.3-lean`)来锁定版本, 以便实现可复现的部署。 ## 前置条件 | 你需要 | 说明 | |---|---| | Paperless-ngx | 任何近期版本 + 一个超级用户的 API token | | 支持视觉的模型 | 用于文档摄入 —— 可通过 Ollama 在本地运行(例如 Qwen-VL 类模型,可在另一台机器上运行)或使用云端模型(Claude、GPT、MiniMax 等)。在 Settings > Processing 中选择 | | Anthropic API key | 可选 —— 启用 Claude 作为聊天后端(在 Settings > AI Models 中配置用户专属的密钥) | | SearXNG | 可选 —— 启用网络搜索工具 | | 支持 Wake-on-LAN 的 GPU 服务器 | 可选 —— 参见 [电源管理](#power-management-optional) | ## 配置(`.env` 参考) 将 `.env.example` 复制为 `.env`(这是大多数安装所需的简短配置项列表); `.env.example.full` 是带有注释的完整参考,包含所有配置键及其默认值。 没有默认值的键是**必需的**。标记为 *UI* 的键也可以在应用的 Settings 页面中更改(应用内的值优先; 环境变量仅作为初始回退值)。 | 键 | 必需 | 默认值 | 说明 | |---|---|---|---| | `APP_PATH` | ✅ | — | 应用根目录的绝对路径,需以斜杠结尾。在 Docker 中:`/app/` | | `PAPERLESS_URL` | ✅ | — | 你的 Paperless-ngx 实例的 Base URL | | `PAPERLESS_SUPERUSER_TOKEN` | ✅ | — | Paperless 超级用户的 API token(用于同步;聊天请求使用每个用户自己的 session token) | | `IGNORE_INBOX_TAG_AT_SYNC` | | `Inbox` | *UI* —— 在同步期间跳过带有此标签的文档 | | `EMBEDDING_MODEL` | ✅ | — | Sentence-transformers 模型 id;默认为 `intfloat/multilingual-e5-large-instruct` 进行优化 | | `CHROMA_PATH` | ✅ | — | ChromaDB 目录,相对于 `APP_PATH`(请保留在 `data/` 下) | | `CHROMA_COLLECTION` | ✅ | — | 用于文档 embeddings 的 collection 名称 | | `EXTRACTION_SIDECAR_PATH` | ✅ | — | 用于存放每个文档 JSON 提取 sidecars 的目录 | | `THUMB_PATH` | ✅ | — | 用于存放缩略图的目录 | | `CHROMA_MAX_RESULTS` | | `20` | *UI* —— 每次查询的最大搜索结果数 | | `BRAIN_HINT_SIMILARITY_THRESHOLD` | | `0.70` | *UI* —— 搜索中记忆提示的最小相似度 | | `BRAIN_HINT_WINDOW_FACTOR` | | `1.5` | *UI* —— 记忆提示的窗口因子 | | `OLLAMA_SERVER` | | empty | *UI* —— 用于视觉摄入的 Ollama base URL;同时也指定 WoL/关机按钮控制的主机(否则从你的第一个本地模型推断) | | `OLLAMA_INGEST_MODEL` | | empty | *UI* —— 用于阅读文档的视觉模型 | | `EXTRACTION_PROFILE` | | `en` | *UI* —— 提取规则配置:`en` 或 `de`(参见[提取规则](#extraction-rules)) | | `ARCHIVE_LANGUAGE` | | `en` | *UI* —— AI 生成的摘要语言(归档级别 —— sidecars 由所有用户共享) | | `TZ` | | system | 生成文档上时间戳的 IANA 时区 | | `ANTHROPIC_API_KEY` | | empty | *UI* —— 全局回退密钥;用户可以存储自己的密钥 | | `OLLAMA_HOST_LAN_MAC_ADDRESS_WOL` | | empty | 用于 Wake-on-LAN 的 MAC 地址(留空 = 隐藏该功能) | | `OLLAMA_SSH_USER` | | empty | 用于远程关闭 Ollama 主机的 SSH 用户(留空 = 隐藏该功能)。需要配置 `/usr/bin/shutdown` 的免密 sudo;在 Docker 中,需将 SSH 密钥挂载到容器中 | | `OLLAMA_IDLE_SHUTDOWN_MINUTES` | | `30` | Ollama 主机关机前的空闲分钟数 | | `AI_GENERATED_TAG_NAME` | | `AI-generated` | *UI* —— 应用在 Paperless 中创建文档时应用的标签 | | `AI_GENERATED_CORRESPONDENT` | | `PaperlessBrain AI` | *UI* —— AI 生成文档的 correspondent | | `AI_GENERATED_DOC_TYPE` | | `Information` | *UI* —— AI 生成文档的文档类型 | | `SEARXNG_HOST` | | `http://localhost:8888` | 用于网络搜索工具的 SearXNG base URL | | `VAULT_ROOT` | | `/mnt/vaults` | 存放 vault 子文件夹的根目录,每个用户一个。**在 Docker 中,这是容器内的路径 —— 请保持为 `/mnt/vaults`,并在 volume 映射的左侧设置宿主机路径。** | | `BRAIN_SUBFOLDER` | | `PaperlessBrain Memory` | 为 agent 策划的记忆保留的 Vault 子文件夹(命名一个真实的文件夹 —— 仅在全新安装时更改) | | `VAULT_SYNC_COOLDOWN_S` | | `3` | 每个用户两次 vault 同步之间的最小秒数 | | `STORAGE_SECRET` | ✅ | — | 用于加密服务端 session 的密钥 —— 使用 `python -c "import secrets; print(secrets.token_hex(32))"` 生成 | | `SHUTDOWN_PASSWORD` | | empty | 关机按钮执行前的确认提示。**留空 = 无提示**,点击一次即可关闭机器。隐藏该按钮的是留空的 `OLLAMA_HOST_LAN_MAC_ADDRESS_WOL` / `OLLAMA_SSH_USER` | | `HOST` / `PORT` | | `0.0.0.0` / `8080` | 绑定地址和端口 | ## Vault 与记忆 助手的长期记忆和你的个人笔记都存放在一个**普通的 Markdown 文件夹**中 —— 在 `VAULT_ROOT` 下每个用户对应一个子文件夹: ``` vaults/ └── alice/ ├── PaperlessBrain Memory/ ← agent-curated facts (one fact = one file) └── ... your notes ... ← searchable knowledge base ``` - 该文件夹**由应用本身进行 git 追踪** —— 集成了变更检测、同步 书签和审计追踪。你无需手动操作 git。 - **并非必须使用 Obsidian。** 任何编辑器都可以;这些文件都是带有少量 YAML frontmatter 的普通 Markdown 文件。 - 用于在其他设备上编辑的可选拓扑:将 WebDAV 服务器指向 同一目录,并使用 Obsidian + Remotely Save 进行同步。WebDAV 服务器 必须提供与应用挂载目录*相同*的路径 —— 应用会保留唯一的 权威副本。 磁盘上的 Markdown 是事实来源;ChromaDB 仅作为索引, 随时可以从文件中重建。 ## 提取规则 摄入提示词是根据你的 Paperless **文档类型**名称进行匹配的。因为 这些名称是*你*自定义的,所以这些规则在 `config/extraction_rules/` 中以可选配置的形式提供: | `EXTRACTION_PROFILE` | 内容 | |---|---| | `en`(默认) | 约 13 种常见的国际类型 —— Invoice、Receipt、Contract、Bank Statement、Payslip、Insurance Policy、Tax Assessment、Notice、Certificate、Letter、Report、Rental Agreement | | `de` | 约 46 种适用于德国法律/行政领域的类型 | 任何没有专属配置的文档类型都会回退到 `_default`,这依然 能产生可用的提取结果 ——缺少针对特定类型的指导。**如果你的类型不匹配也不会导致任何错误**;只是提取结果会更为通用。 要进行定制,请编辑配置模块,并根据你确切的 Paperless 文档类型名称添加条目: ``` # config/extraction_rules/en.py RULES["Warranty"] = { "prompt": BASE_INSTRUCTIONS + """ Document type: Warranty certificate. Pay particular attention to: - Product, serial number and purchase date - Warranty period and expiry date - What is covered and what voids the warranty """, } ``` 如果要添加全新的配置,可以在其他文件旁边放置一个导出 `RULES` 字典的 `.py` 文件,并在 `__init__.py` 中将代码添加到 `AVAILABLE_PROFILES` 中。随后它会自动 出现在配置选择器中。 该配置遵循的是**你 Paperless 文档类型的名称**,而不是 文档使用的语言。一份被归档为 `Rechnung` 的英文发票依然会匹配 `de` 规则 —— 因此混合语言的归档无需进行特殊处理。 `ARCHIVE_LANGUAGE` 用于单独控制生成摘要的语言; 无论原文件是什么语言,提取的页面文本始终保留文档的原始语言。两者均可在 **Settings > Processing** 中设置,并以 `.env` 中的值作为 回退。 ## 语言(i18n) UI 目前支持**英语和德语**;每个用户可以在 Settings 中选择自己的语言 (聊天回答会自动跟随该设置)。添加新语言的步骤: 1. 在 `i18n.py` 中将代码添加到 `SUPPORTED_LANGUAGES`(例如 `"fr": "Français"`)。 2. `pybabel init -i locales/messages.pot -d locales -l fr` 3. 翻译 `locales/fr/LC_MESSAGES/messages.po`。 4. `pybabel compile -d locales` ## 电源管理(可选) 针对 homelab GPU 服务器:应用可以在首次使用时通过 Wake-on-LAN 唤醒 Ollama 主机,并在空闲后通过 SSH 将其关闭。设置 `OLLAMA_HOST_LAN_MAC_ADDRESS_WOL` 和 `OLLAMA_SSH_USER` 即可启用 —— 在 Docker 环境下 这需要使用 `network_mode: host`(magic packets 无法跨桥接网络传输)。 ## 安全说明 - **超级用户 token** 仅用于同步/摄入;每个聊天请求 均使用已登录用户自己的 Paperless session token 运行,因此 Paperless 的 对象权限依然适用。 - 会话使用 `STORAGE_SECRET` 在服务端进行加密。 - 用户的 IMAP/CalDAV 凭据和 API 密钥均使用从用户会话派生的密钥进行加密存储 —— 绝不使用明文。 - 本应用专为局域网 / reverse-proxy 部署设计;未实现 速率限制或针对公共互联网的硬化防护。如果你将其暴露在公网中,请将其置于你的代理 + SSO 之后。 ## 裸机安装 WeasyPrint(PDF 生成组件)在渲染时会加载 Pango,因此如果缺失库, 表现为 PDF 导出失败,而不是启动报错。请预先安装该库以及 字体家族: ``` # Debian/Ubuntu sudo apt install libpango-1.0-0 libpangoft2-1.0-0 fonts-dejavu-core # Fedora sudo dnf install pango dejavu-sans-fonts # Arch sudo pacman -S pango ttf-dejavu # macOS brew install pango ``` 在依赖它之前,请先进行验证: ``` python -c "from weasyprint import HTML; HTML(string='

ok

').write_pdf(); print('PDF OK')" ``` ``` python3.12 -m venv .venv && source .venv/bin/activate # 3.12–3.14 pip install --extra-index-url https://download.pytorch.org/whl/cpu -e ".[crawl]" playwright install chromium # only for the [crawl] extra cp .env.example .env # edit values, APP_PATH = repo root python main.py ``` 在 GPU 机器上,去掉 `--extra-index-url` 以获取支持 CUDA 的 torch。建议使用 systemd unit 作为服务运行。 ## 许可证 [MIT](LICENSE) —— 随意使用、fork、发布或出售。仅要求保留署名。 所有运行时依赖均采用宽松的开源许可(MIT / BSD / Apache-2.0)。 PDF 渲染使用 [pypdfium2](https://github.com/pypdfium2-team/pypdfium2) (BSD-3/Apache-2.0),PDF 生成使用 [WeasyPrint](https://weasyprint.org/) (BSD-3)。
标签:AI, AI风险缓解, DLL 劫持, LLM评估, Ollama, RAG, 信息抽取, 大语言模型, 文档管理, 自动化代码审查, 请求拦截, 逆向工具