这是和 memory-layer-hosting 商业方向一脉相承的实践——先解决"自己的团队怎么共享 memory",再考虑"对外做产品"。
背景
我维护了一个 1410 篇笔记的 Obsidian vault,里面有结构化的 LLM Wiki(19 个 topic)、持续积累的 Clippings、还有大量项目笔记。团队伙伴也想用 AI Agent 干活,但每个人都从零开始——他们不知道团队在研究什么、决策过什么、踩过什么坑。
直接扔一个 vault 链接过去?不行。里面有 04_Archive/扶持资金申请、01_Projects/西安城建学院不良债权 这种绝对不能共享的内容。
那就只挑几个文档?也不行。团队成员用 agent 提问时,agent 还是不知道上下文。
核心矛盾:我的 vault 是单兵作战的,团队需要的是可共享的、有边界的、实时的知识层。
设计原则
我把"个人 vault → 团队共享"想清楚后,提炼出 4 条核心原则:
- 源 vault 永远只读——同步引擎碰都不碰源 vault,绝对不写回
- 白名单 + 黑名单 + 灰名单三段式——什么能共享、什么不能、什么打标后共享,每条规则都在 YAML 里写清楚
- 实时 + 周期双保险——watchdog 5 秒内增量 + 每周日凌晨全量对账
- PII 脱敏在边界做——身份证、手机号、邮箱在 loader 阶段替换,不进目标
整体架构
Mac(本地) VPS(Linux)
───────── ──────────
~/eviso_obsidian/ ← 源 vault
│
│ watchdog 实时监听
↓
~/team-sync-engine/staging/ ───rsync──→ /opt/team-vault/
│
├── 触发 git hook
↓
/opt/team-vault.git/ ← bare 仓
│
├── 触发 mkdocs 重建
↓
http://<VPS>:8080 ← 团队访问
为什么用 VPS 做分发枢纽,而不是直接 P2P 同步?
- 团队成员设备杂(Mac/Win/Linux),P2P 同步配置地狱
- VPS 一次部署,浏览器就能用——团队零安装
- VPS 还能跑 mkdocs Web 站,自带搜索 + 双向链接
- 未来接 Mem0 / Letta 也很方便(同一台机器)
同步引擎的核心实现
vault_sync.py 是个 600 行的 Python 脚本,关键模块:
- FilterEngine:读
filter_rules.yaml,做路径/文件名/frontmatter 三段判定 - FileIndex:JSON manifest,记录每个源文件 hash + 目标路径 + 同步时间
- PIIRedactor:脱敏正则(身份证/手机/邮箱/银行卡)
- Loader:md → frontmatter 加重写 → 写 staging → rsync 到 VPS
- DebouncedHandler:watchdog + 5 秒 debounce,避免 Obsidian 保存时多次触发
- PAMExporter:可选地把 md 转成 PAM JSON(接 Mem0/Letta 用)
最关键的判定逻辑(伪代码):
def evaluate(path):
# 1. 黑名单优先
if filename_match_blacklist(path): return BLACKLIST
if path_match_blacklist(path): return BLACKLIST
if frontmatter.private(path): return BLACKLIST
# 2. 白名单 frontmatter predicate
fm = parse_frontmatter(path)
if not all_predicates_pass(fm): return BLACKLIST
# 3. 白名单路径
if path_match_whitelist(path): return WHITELIST
if path_match_graylist(path): return GRAYLIST
# 4. 默认拒绝(白名单外的都不共享)
return BLACKLIST
"默认拒绝"这条最重要——写错一条规则,不应该让个人隐私泄漏。
过滤规则的"宪法"
filter_rules.yaml 是整个系统的灵魂。举几个真实例子:
whitelist:
paths:
- "05_Wiki/topics/**" # Wiki 知识库
- "08_Meta/Templates/**" # 模板
- "08_Meta/Reference/**" # 参考文档
- "Clippings/AI_Agent/**" # AI 相关剪藏
frontmatter_predicates:
- { field: status, op: in, value: [mature, organizing] }
blacklist:
paths:
- "04_Archive/**" # 归档
- "01_Projects/**" # 项目笔记
- "02_Areas/个人品牌/**" # 个人域
filename_patterns:
- "*合同*" - "*协议*" - "*申请*"
- "New chat*" - "未命名*"
status: collecting 的 Wiki topics(比如我新创建的)默认不共享——只有"成熟"的内容才进入团队视野。这条规则倒逼我先把笔记写好再开放。
给非技术团队成员的 3 套接入方式
这是设计中最让我费神的部分。团队伙伴不是技术咖,他们不会 git clone、不会配 SSH 也不会用 Obsidian。
方式 1:浏览器直接看(基线)
- 打开
http://<VPS>:8080 - 完事。✅
- 零安装、零配置
方式 2:Obsidian 订阅(标准)
- 装 Obsidian(30 秒)
git clone一次(10 秒)- 完事
- 适合愿意装软件的人
方式 3:实时同步 + AI Agent 接入(高级)
- 装 Obsidian + Remotely Save 插件
- 配置 SFTP
- 完事后 agent 能读到团队 vault
- 适合想深度用 AI 的人
3 套方案对应 3 个用户画像。最重要的是方式 1 必须 100% 稳定——它是基线,任何人都能用。
踩过的坑 / 反直觉的判断
1. "实时同步" 反而不是最重要的
- 团队成员最常用的是方式 1(浏览器),5 分钟延迟完全 OK
- 5 秒延迟的实时层,主要服务方式 3 的 agent 接入场景
- 周期全量兜底是真正的"安全网"
2. "把所有内容都共享" 是最常见的错误
- 我自己的 vault 有 1405 个文件被判定为不共享(合同/项目/个人)
- 真正能共享的只有 17 个 Wiki topics
- 这个比例很常见——个人 vault 的"分享率"通常 < 5%
3. "PII 脱敏" 不是可选项
- 一旦共享,身份证号/手机号泄露就是合规事件
- 在 loader 阶段做脱敏,不在源文件做(保持源 vault 完整)
- 正则要保守,宁可误杀不要漏掉
4. "PAM 导出" 是给未来留的接口
- 现阶段团队用方式 1/2/3 就够了
- 但如果将来要接 Mem0/Letta,PAM JSON 是标准格式
- 留这个开关,未来 5 分钟就能启用
这套方案和 memory-layer-hosting 的关系
memory-layer-hosting 是商业方向,这套方案是它的第一个真实用户。如果跑通:
- 我有了一个自己用过的 memory layer 产品(实践出真知)
- 团队成员就是早期用户(反馈闭环)
- 未来接 Mem0/Letta 不需要重新设计数据流(PAM 已经在出口处等着)
这是 Karpathy 推崇的"Obsidian 是 IDE,Wiki 是代码库"的延伸——多用户 Obsidian 是 IDE,团队 memory 是代码库。
下一步
- 替换 filter_rules.yaml 里的
<VPS_*>占位符 - 在 VPS 上跑
deploy_vps.sh(一次性) - ssh-copy-id 推送公钥
- 跑
vault_sync.py full首次全量同步 - 装 launchd 守护进程
- 写第一封"给团队"的邮件,把链接和 onboarding 文档发出去
关键文件清单
| 文件 | 用途 |
|---|---|
~/team-sync-engine/vault_sync.py |
同步引擎主脚本(600 行) |
~/team-sync-engine/filter_rules.yaml |
过滤规则(白/黑/灰名单 + 脱敏正则) |
~/team-sync-engine/deploy_vps.sh |
VPS 一键部署 |
~/team-sync-engine/launchd/com.eviso.vault-sync.plist |
macOS 守护 |
~/team-sync-engine/docs/team_onboarding.md |
团队接入指南(3 套方式) |
相关 Topic
- memory-layer-hosting - 商业方向
- memory-system - 自己的 LLM Wiki 记忆架构
- ai-agents - 团队成员用 agent 的场景
- tools - Obsidian vault 配置