#给 AnythingLLM 实现本地文件夹自动同步

背景

AnythingLLM 是一个本地部署的 RAG(检索增强生成)知识库工具,支持将文档上传后进行向量化,然后通过对话的方式检索知识。但它本身不支持监控本地文件夹------每次新增或修改文档都需要手动上传,用起来很不方便。

我的需求很简单:在本地维护一个 Obsidian 笔记文件夹,文件有任何变化时自动同步到 AnythingLLM 的指定工作区,不需要任何手动操作。

方案

基于 watchdog 的实时文件监控守护进程,彻底解决重复上传问题。

核心架构

scss 复制代码
文件系统事件 → 防抖(2s) → MD5 对比(SQLite) → 清理旧向量 → 上传新文件 → 更新 SQLite
     ↑
  启动时追赶扫描(处理离线期间的变更)

关键设计决策

1. watchdog 替代轮询

watchdog 是一个 Python 库,封装了 macOS 的 FSEvents / Linux 的 inotify API,让操作系统内核在文件变化时主动推送事件,不需要周期性扫描。进程绝大多数时间在睡眠,CPU 和 I/O 开销近乎为零。

2. SQLite 替代 JSON 状态文件

存储结构:(rel_path TEXT PK, hash TEXT, mtime REAL, doc_name TEXT, doc_location TEXT)

SQLite 的原子事务保证了进程崩溃时状态不会损坏。上传成功后记录 AnythingLLM 返回的 doc_location,下次更新时用它精确删除旧版本,不再依赖模糊的文件名匹配。

3. 2 秒防抖

Obsidian 等编辑器保存文件时会触发多次写入事件,防抖机制将其合并,只处理最后一次。

4. 正确的 API 调用链

研究了 AnythingLLM 源码后,确认正确的更新流程是:

bash 复制代码
① 从工作区移除旧嵌入(向量数据库)
   POST /api/v1/workspace/:slug/update-embeddings
   { "deletes": ["custom-documents/xxx.json"] }

② 删除旧文档文件
   DELETE /api/v1/system/remove-documents
   { "names": ["custom-documents/xxx.json"] }

③ 上传新文件并自动嵌入到工作区
   POST /api/v1/document/upload
   multipart: file + addToWorkspaces=slug

步骤 ① 是关键------不清除旧向量的话,LLM 检索到的仍然是旧内容。

5. 启动追赶扫描

守护进程启动时对比本地文件和 SQLite 记录,处理离线期间的所有变更,保证即使进程临时停止,重启后也不会漏掉任何变化。

6. LaunchAgent 守护进程

macOS 用 KeepAlive: true 的 LaunchAgent,崩溃自动重启,开机登录后自动启动,不依赖终端。

xml 复制代码
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>

坑:macOS 文件夹访问权限

macOS Catalina 以后,对"文稿"等目录的 FSEvents 监控需要显式授权。进程没有权限时 watchdog 会静默失败------不报错,但完全收不到任何文件事件。

解决方法:在「系统设置 → 隐私与安全性 → 完全磁盘访问」中添加 /usr/bin/python3 或终端 App。

配置说明

ini 复制代码
[anythingllm]
base_url = http://localhost:3001      # AnythingLLM 服务地址
api_key = ...                         # API 密钥
workspace_slug = ...                  # 目标工作区标识

[sync]
watch_folder = /path/to/folder        # 监控的本地文件夹(绝对路径)
delete_removed = false                # 本地删除文件后是否同步删除远程文档

api_key 获取方式

在 AnythingLLM 界面:设置 → 工具 → 开发者 API → 生成新的 API 密钥

workspace_slug 获取方式

workspace_slug 不是工作区名称,需要通过 API 查询:

bash 复制代码
curl -s http://localhost:3001/api/v1/workspaces \
  -H "Authorization: Bearer 你的API-Key"

返回结果中的 slug 字段即为所需值:

json 复制代码
{
  "workspaces": [
    {
      "name": "我的知识库",
      "slug": "my-kb-a1b2c3",
      "id": 1
    }
  ]
}

效果

  • 保存文件后约 2 秒内自动同步到 AnythingLLM
  • 不再出现重复文档
  • 更新文档后 LLM 能正确检索到新内容
  • 后台常驻,内存占用约 25MB,平时 CPU 占用 0%

依赖

  • Python 3(系统自带)
  • requests:HTTP 请求
  • watchdog:文件系统事件监听
  • sqlite3:Python 标准库自带,无需安装
bash 复制代码
pip3 install requests watchdog
相关推荐
金伟API10246 小时前
如何从零打造一个极简的DeepSeek-R1大模型
人工智能·ai
江畔柳前堤7 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Shockang7 小时前
智能体环路工程实战
人工智能
美摄科技7 小时前
美摄美颜特效SDK Skill:以AI赋能智能视音频新视界
人工智能
Web3_Daisy7 小时前
Pump.fun 与 FOMO 竞争背后的 Meme 市场变局
大数据·人工智能·金融·web3·区块链
AI创界者7 小时前
MiniMax-H3 本地一键部署整合包:8G 显存玩转文图生视频、视频参考、角色替换与超分补帧全流程
人工智能·深度学习
江畔柳前堤7 小时前
HBM:大语言模型时代的「算力血液」——从内存墙到带宽革命的深度拆解
服务器·人工智能·windows·目标检测·语言模型·自然语言处理·软件工程
美摄科技8 小时前
视频一键成片SDK Skill:AI智能分析与语义理解
人工智能
fthux9 小时前
装闭 RenoPit 源码解析(05):FastAPI与Celery如何执行AI装修分析
人工智能·ai·开源·github·open source·renopit
格数致用9 小时前
数据库设计与表结构详解|信息化项目全流程管理系统源码逐行精讲(五)
人工智能·政务·数据库设计·外键约束