eviso's thinking

团队知识库同步方案

CONTENTS

这是和 memory-layer-hosting 商业方向一脉相承的实践——先解决"自己的团队怎么共享 memory",再考虑"对外做产品"。

背景

我维护了一个 1410 篇笔记的 Obsidian vault,里面有结构化的 LLM Wiki(19 个 topic)、持续积累的 Clippings、还有大量项目笔记。团队伙伴也想用 AI Agent 干活,但每个人都从零开始——他们不知道团队在研究什么、决策过什么、踩过什么坑。

直接扔一个 vault 链接过去?不行。里面有 04_Archive/扶持资金申请、01_Projects/西安城建学院不良债权 这种绝对不能共享的内容。

那就只挑几个文档?也不行。团队成员用 agent 提问时,agent 还是不知道上下文。

核心矛盾:我的 vault 是单兵作战的,团队需要的是可共享的、有边界的、实时的知识层。

设计原则

我把"个人 vault → 团队共享"想清楚后,提炼出 4 条核心原则:

  1. 源 vault 永远只读——同步引擎碰都不碰源 vault,绝对不写回
  2. 白名单 + 黑名单 + 灰名单三段式——什么能共享、什么不能、什么打标后共享,每条规则都在 YAML 里写清楚
  3. 实时 + 周期双保险——watchdog 5 秒内增量 + 每周日凌晨全量对账
  4. 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 配置