
如果你和我一样在办公室台式机和家里笔记本上各装了一份 WorkBuddy想着同一个账号登录就能像在手机上接着看聊天记录那样无缝续聊那你大概率会和我一样翻车。WorkBuddy 这类“本地优先”的 AI 助手工具账号只是身份的锚点真正影响你日常体验的记忆、技能、规则、项目笔记默认都落在各自的本地数据目录里。跨机双写同步并不是“两台机器的文件保持一致”这么简单它真正难的地方在于两台机器同时在写同一份记忆和规则文件时怎么合并不丢、不乱、不互相覆盖。这篇文章就是我折腾近一个月的完整心路包含从翻车到稳定运行的全套方案适合所有正在或准备在多台电脑上共用 WorkBuddy 账号的人。1. 先把问题说清楚同一个账号数据到底存在哪1.1 账号体系与本地数据的边界很多刚接触 WorkBuddy 的朋友会有一个错觉登录了同一个账号云端就会像微信一样把你的聊天记录、技能配置、记忆文件统统同步到所有设备。实际并不是这样。WorkBuddy 的账号体系主要负责三件事身份认证、订阅状态、以及部分云端的会话索引。它刻意把“重数据”留在本地也就是我常说的本地优先设计。这种设计的优势非常明显离线可用、启动快、隐私数据不出本机。但代价就是你换了机器以后账号是同一个AI 的“人格”却完全是另一套。你在公司电脑上辛辛苦苦调教出来的规则、沉淀下来的记忆、写好的技能回到家里电脑上统统不认账。你会发现这台机器上的 WorkBuddy 像一个刚从盒子里拆出来的新手机什么都不记得。默认情况下WorkBuddy 的数据目录分散在三个常见位置Windows 一般在%APPDATA%\WorkBuddymacOS 在~/Library/Application Support/WorkBuddyLinux 在~/.config/workbuddy。如果你在安装时指定过自定义目录那路径就按你的配置走。我建议你打开文件管理器先把这个目录结构摸清楚因为后面所有同步方案本质上都是在跟这个目录打交道。1.2 跨机双写冲突的本质多机共用同一个账号最核心的技术问题不是“怎么把文件复制过去”而是“两台机器同时在写同一份文件时怎么合并”。举个例子你就明白了你和同事同时在编辑一份会议纪要你负责补充第三项议程他负责补充第四项议程。你的电脑先保存他的电脑后保存。如果没有合并机制后保存的版本会直接覆盖先保存的版本你补充的第三项议程就无声无息地消失了。WorkBuddy 里的记忆文件、规则文件、技能目录就是这份“会议纪要”。我在实际使用中观察到的典型翻车场景是这样的白天在公司WorkBuddy 根据工作对话不断往记忆文件里写入条目晚上在家里另一台机器上的 WorkBuddy 也在根据阅读笔记和家庭事务写入记忆。两边都在写而且写入的往往是同一个 JSON 结构的不同条目。如果同步只是“整个文件覆盖”那结果一定是某一边的改动全部丢失。我把这类问题统称为“跨机双写冲突”。它和普通的单向备份是两码事。单向备份只需要关心“新文件覆盖旧文件”而双写场景下你必须回答三个问题谁先写、谁后写、谁的版本应该保留。这三个问题不解决任何同步方案都是定时炸弹。1.3 什么样的人需要“真正的双写”先别急着上方案我建议你对照一下自己的使用场景判断是否真的需要双向同步。如果你只是“一台主用、另一台偶尔翻阅”那根本不需要折腾 Git 和合并脚本一个简单的单向同步就足够了。但如果你属于下面这几类情况就需要认真处理双写白天在公司电脑上写工作日志晚上在家里电脑上写阅读笔记两边都会触发 WorkBuddy 的记忆写入。两台电脑轮流使用同一套技能和规则今天在 A 机上改了一个 skill明天在 B 机上又改了另一个 skill。你有一台台式机和一台笔记本并且希望不管坐在哪台机器前面和 WorkBuddy 对话时它都记得最近几天发生过什么。你想把 WorkBuddy 的数据目录直接放在 NAS 或同步盘里并且允许两边同时在线运行。我属于第二种和第三种的混合体所以最后选择了“主从 Git 定期合并”的架构。在展开实操之前先聊聊我对比过的几种主流同步方案帮你少走弯路。2. 三种主流同步方案先对比再选择2.1 方案 A官方账号自带的同步能力如果你完全不想折腾最省心的当然是直接用 WorkBuddy 账号体系自带的云同步。它的优点是开箱即用不需要懂命令行也不需要维护仓库。但我实测下来它更适合轻量使用而不是重度双写。问题在于云同步为了简化用户体验通常会采用“最后写入者胜”的策略。什么叫最后写入者胜就是同一份记忆文件谁后保存就以谁的版本为准。这个策略对手机聊天记录这种“追加式数据”没什么问题因为聊天记录天然只会新增不会互相修改同一行。但 WorkBuddy 的记忆文件里包含的是结构化条目两台设备的 AI 会在不同时间往里面插数据一旦同步触发后保存的设备很可能把先保存设备的几条新记忆一起冲掉。更头疼的是会话上下文。我曾经遇到两台设备同时在线WorkBuddy 的云会话把两边的对话历史串在一起A 机上的问题跑到 B 机上被回答了B 机的回答又出现在 A 机的历史记录里。那种感觉就像你打电话打到一半突然接入了另一个人的电话会议体验非常割裂。如果你只用单台设备官方同步没问题但只要你真的需要“两台都写”我建议往后看。2.2 方案 B第三方同步盘直接同步数据目录这也是很多人的第一反应把 WorkBuddy 整个数据目录丢进 OneDrive、Dropbox、坚果云或者自建 NAS 的同步文件夹里让网盘帮我同步。我最初也是这么干的但踩坑踩得最狠的就是这条路。同步盘最典型的问题是“冲突副本”。当两台机器同时改同一个文件时网盘不会帮你智能合并而是把两边的版本各自存成memory (冲突副本).json和memory.json。WorkBuddy 只认固定文件名根本不认识那个带“冲突副本”后缀的文件它只会安静地加载其中一个另一个就变成孤儿文件躺在目录里。等你发现不对劲的时候往往已经过去好几天冲突副本攒了一堆哪份是新的、哪份是旧的完全分不清。还有一个我之前完全没预料到的坑WorkBuddy 的缓存目录和索引文件变化非常频繁几乎每次对话结束都会有几毫秒的写盘动作。把这些文件放进同步盘意味着网盘客户端会持续监听到海量的小文件变更然后不停地上传下载。我那时候的笔记本风扇在夜里疯狂转打开网盘客户端一看后台正在同步几千个碎片文件。这不仅是性能浪费还会显著缩短笔记本的续航时间。同步盘适合低频更新的文档目录但不适合高频写入的本地优先应用。2.3 方案 CGit 版本管理 定时合并脚本如果说前两种方案都有天然的缺陷那 Git 就是目前我找到的最优解用版本控制来管理“人写的、可以合并的文件”用.gitignore把“机器生成的、容易冲突的缓存文件”挡在门外。这个思路可以把跨机双写变成一个有迹可循、可回滚、可解决冲突的流程。为什么 Git 能解决双写问题因为它不是简单覆盖整个文件而是基于文本差异做合并。两边都改了一个文件的不同区域Git 能自动把两边的改动拼在一起如果改了同一行它会明确标出冲突位置让你来决定保留哪个版本。这比“最后写入者胜”和“冲突副本”都要安全得多。代价是需要一点命令行基础以及每次合并冲突时花几分钟手动处理。我把三个方案的核心差异整理成一张表方便你快速决策对比维度官方云同步第三方同步盘Git 合并脚本冲突处理最后写入者胜生成冲突副本不会合并自动合并冲突时人工裁决可回滚一般不提供依赖网盘版本历史每次提交都是快照随时可回退离线可用依赖网络依赖本地缓存完全离线推送时才需网络适合人群单设备或轻中度使用低频更新场景需要双写、有一定动手能力风险点静默丢数据缓存风暴、文件错乱学习成本高遇冲突需人工处理我个人最终选择了方案 C因为它能同时满足我“两台机器都写”和“数据不能丢”这两个硬性要求。下面我把完整实操过程写出来每一步都可以直接照着做。3. 我的最终方案主从 Git 定期合并3.1 目录规划先分清三类文件在初始化仓库之前我先把 WorkBuddy 数据目录里的内容分成了三类这个分类是整个方案的地基。第一类是“可合并的人写文件”包括记忆文件、技能目录、规则文件、项目笔记。这类文件的特点是内容由你或你与 AI 的对话产生语义明确可以被 Git 做差异合并。第二类是“易冲突的机器文件”包括索引数据库、缓存文件、日志文件。这类文件是纯机器生成的很大、变更频繁、对用户体验没有直接价值应该直接排除在版本控制之外。第三类是“身份类文件”包括账号凭据、设备 ID、本地设置。这类文件每台机器应该有各自独立的一份不能强行同步否则会造成设备识别错乱。我实际整理出来的目录结构大概是这样的workbuddy/ ├── accounts/ # 账号与身份信息不同步 ├── memory/ │ ├── memories.json # 长期记忆纳入 Git │ └── index.db # 索引文件Git 忽略 ├── skills/ # 技能目录纳入 Git ├── rules/ # 规则文件纳入 Git ├── projects/ # 项目笔记纳入 Git ├── cache/ # 缓存目录Git 忽略 └── logs/ # 日志目录Git 忽略对应到仓库根目录下的.gitignore我写的是accounts/ cache/ logs/ *.db *.log *.tmp .DS_Store把accounts排除掉的原因很简单WorkBuddy 的登录凭据和本地设备标识如果跟着 Git 仓库跑到另一台机器可能触发账号安全机制要求重新登录而且每台机器的设备指纹本来就该不同。我一开始试图把整个目录都纳入 Git结果在 A 机上提交的凭据文件到了 B 机上导致登录态互相打架连续几天都遇到会话掉线。3.2 自动同步脚本commit - pull --rebase - push目录规划好之后我写了一个同步脚本放在每台机器的 PATH 目录下名字叫wb-sync。脚本核心逻辑只有 4 步先检查 WorkBuddy 是否在运行然后把本地改动提交接着从远端拉取并用 rebase 方式合并最后推送。#!/usr/bin/env bash set -euo pipefail WB_DIR$HOME/.config/workbuddy cd $WB_DIR # 1. 检查 WorkBuddy 进程是否在运行 if pgrep -f WorkBuddy /dev/null 21; then echo Warning: WorkBuddy is still running, please quit before sync exit 1 fi # 2. 先把本地改动提交 git add -A git commit -m sync from $(hostname) at $(date %F %T) || echo nothing to commit # 3. 拉取远端并变基 git pull --rebase --autostash || { echo Rebase conflict detected, please resolve manually. echo Files with conflict: git diff --name-only --diff-filterU exit 2 } # 4. 推送 git push echo Sync done at $(date %F %T)你可能会问为什么非要先 commit 再 pull顺序反过来的话如果远端有新提交直接 pull 可能会和你本地未提交的改动冲突Git 会拒绝操作。先把本地改动提交成一个快照再通过 rebase 把本地的这个提交“回放”到远端最新提交之上这样就把双写过程变成了一个有明确历史记录的流水线。--autostash这里是双保险即使有漏掉没提交的零散改动也会被 Git 临时保存起来rebase 完成后再自动恢复。如果 rebase 遇到真正的冲突脚本会停下来并列出冲突文件不会强行覆盖任何数据。我在两台机器上都配了同步频率公司台式机每 30 分钟执行一次家里笔记本每 1 小时执行一次。为什么这么定我统计过自己的数据写入量记忆文件平均 2MB 左右skills 目录几十个文件加起来不到 5MBrules 文件几百行单次同步的增量通常不超过 100KB。Git 对文本文件的增量同步非常高效每次同步实际耗时在 2 到 5 秒之间对正常办公几乎没有感知。如果你发现自己的数据量远大于这个数值建议先看是不是忘了把缓存文件加进.gitignore。3.3 让两台机器“错峰写入”Git 能解决文件层面的冲突但解决不了“会话上下文串线”的问题。两台机器如果同时在线并且同时与 WorkBuddy 的云端会话相连即使文件最终能合并对话体验也会很混乱。我的做法是给两台机器定了一个简单的“角色约定”公司台式机是主设备负责工作时间和白天的一切对话家里笔记本是从设备负责晚间和周末的阅读笔记、生活记录。这个约定落实在 WorkBuddy 的规则文件里AI 的判断逻辑大致是如果当前时间在工作日 9 点到 19 点并且在主设备上则正常回应并写入记忆如果在从设备上遇到同样的请求就优先读取记忆、暂缓写入。你可能注意到这本质上是在做“错峰写入”而不是“同时双写”。我个人的经验是真正的双写在 AI 助手场景里往往是伪需求因为人一天只有一个主要工作场景。策略上把时间切分好两台机器就不会抢着写同一个记忆文件Git 的冲突几率也会大大降低。当然周末有时候我也会把笔记本拿到书房这时候两台机器确实可能出现同时在线。遇到这种情况我依赖的就是下一节的语义级合并方案。3.4 会话和记忆的语义级合并文件级的自动合并只是第一步真正让我觉得“这方案成了”的是给记忆和技能条目增加source_device字段之后的语义级合并。WorkBuddy 导出的记忆文件通常是结构化的 JSON每条记忆有自己的时间戳、内容、关联技能等信息。如果直接用 Git 合并两个版本Git 会尝试把两个 JSON 文件的文本差异拼接起来结果往往是语法正确但语义混乱——同一轮对话的记忆被切成两半穿插进另一台机器的内容。我的解决办法是写了一个独立的 Python 小脚本在 Git 自动合并之后跑一次专门负责记忆条目的去重和排序。import json from collections import OrderedDict MEMORY_FILE memory/memories.json def load_entries(path): with open(path, r, encodingutf-8) as f: data json.load(f) return data.get(entries, []) def merge_entries(left_entries, right_entries): merged OrderedDict() for entry in left_entries right_entries: key entry.get(id) or entry.get(raw_text) if not key: continue if key not in merged: merged[key] entry else: old merged[key] # 保留时间戳较新的版本并合并 device 来源标记 if entry.get(timestamp, ) old.get(timestamp, ): merged[key] entry merged[key][devices] list( set(old.get(devices, []) entry.get(devices, [])) ) else: merged[key][devices] list( set(old.get(devices, []) entry.get(devices, [])) ) return list(merged.values()) if __name__ __main__: left load_entries(memory/memories.left.json) right load_entries(memory/memories.right.json) result merge_entries(left, right) with open(MEMORY_FILE, w, encodingutf-8) as f: json.dump({entries: result}, f, ensure_asciiFalse, indent2) print(fmerged {len(result)} entries)脚本的逻辑很简单用记忆条目的唯一 ID 或原始文本做 key先到先得如果同一个 key 出现在两边就保留时间戳比较新的版本同时把两个来源的设备标记合并到一个devices字段里。这样做的效果是每一条记忆都记录它从哪台机器来合并之后我还能通过devices字段知道哪些条目在家里的笔记本上补过内容。规则文件就更简单了。我约定规则只在主设备上修改从设备上的规则改动先写到rules/pending/待审区每隔几天人工合并一次。这个做法也回应了很多人都在问的“怎么给 WorkBuddy 定规则才不乱”——规则的生命周期需要明确的归属设备两边各写一套规则再让 Git 自动合并最终一定会出现互相矛盾的指令AI 的行为会变得非常难以预测。4. 踩坑实录五个让我抓狂的问题与排查方法4.1 坑一同步盘把记忆文件搞成“我中有你你中有我”这个问题出现在我还没切到 Git 方案之前用的是方案 B 的网盘同步。某天我突然发现 WorkBuddy 的回答开始前言不搭后语上午它还清楚记得我上周写的项目方案下午就问我要不要从零开始介绍。我打开记忆文件一看整篇 JSON 的结构已经被网盘冲突副本搞乱了同一个 ID 出现了多条记录时间戳互相穿插AI 读取的时候拿到了错乱的上下文。排查思路其实不复杂先看记忆文件里有没有重复的条目 ID再看每一条的时间戳是否大致按序排列。如果时间戳是无序的基本可以断定文件在同步过程中被多次覆盖和合并。那次我丢了好几天的规则沉淀因为没有版本历史可以回滚。也正是在这个教训之后我才彻底放弃了同步盘直接同步的路线。4.2 坑二Windows 和 macOS 文件名字段冲突我公司在 Windows家里是 macOS两台机器共用同一个 Git 仓库之后很快发现一个诡异的问题Rules.md和rules.md这两个文件在同步时一会儿消失一会又出现。原因是 Windows 文件系统默认大小写不敏感而 macOS 的默认文件系统大小写不敏感但保留大小写Git 会认为这是两个不同的文件但 WorkBuddy 加载规则时只认其中一个另一个就变成了无法引用的孤儿文件。这个问题的解决方案非常朴素统一命名规范。我花了一个下午把数据目录里所有文件都改成全小写英文、下划线分隔比如memory_work.md、skill_meeting_notes.md。从那以后再也没有因为文件名字段踩过坑。这里也提醒你如果未来加入第三台 Linux 机器Linux 文件系统对大小写完全敏感小写命名的好处会更加明显。4.3 坑三两台机器同时在线会话串线场景是这样的周五晚上我在客厅打开笔记本准备把这一周的阅读笔记整理进 WorkBuddy忘了关书房的台式机。结果两边同时连着云端会话我问笔记本上的 WorkBuddy“这周有哪些阅读笔记要整理”它回答我的是书房那台机器正在处理的工作任务内容。那一刻我真的以为 AI 出了灵异事件。排查方法是在 WorkBuddy 的设置里查看当前活跃设备列表关掉不必要的那台设备的云会话。长期来看我前面提到的“角色约定”才是根治方案。另外如果你用的是 Git 方案可以给两台机器的主机名加上不同前缀比如wb-office和wb-home这样每次同步的 commit message 里一眼就能看出改动来自哪台机器排查会话问题时非常有用。4.4 坑四git pull 报 non-fast-forward / 冲突标记刷屏切到 Git 方案之后最常见的报错是 pull 时提示non-fast-forward。这个问题的根源是远端已经有新的提交而本地也有新的提交Git 不知道该怎么把两边的历史接上。如果直接git pull他可能会拒绝或产生一个无意义的合并提交。正确做法就是我在 3.2 节脚本里写的先 commit 本地改动然后git pull --rebase。遇到真正的冲突时不要慌不要直接删冲突文件。先用git diff --name-only --diff-filterU查一下哪些文件有冲突再打开文件找、、这些标记。每次冲突的修复原则很固定把到之间的一段当作 A 机版本把到之间的一段当作 B 机版本结合内容决定保留哪个、或者两个都留。保存之后依次执行git add . git rebase --continue git push这个流程我走过至少十次熟练之后每次处理冲突不超过五分钟。我想再强调一遍看到冲突标记不要慌那说明 Git 保护了你的数据而不是弄坏了数据。最怕的是有人为了省事直接git checkout -- .回滚那才会真正丢掉另一台机器上刚写好的内容。4.5 坑五缓存目录膨胀同步变“硬盘搬运工”很长一段时间里我发现不管怎么优化Git 仓库的体积都在快速增长。查了半天才意识到是我某次调整.gitignore的时候漏了一个子目录导致索引数据库和大量临时文件被 Git 追踪了。WorkBuddy 运行一段时间后缓存目录里的碎片文件可能有几千上万个每次同步都在反复比对、上传、下载这些垃圾文件仓库体积很快膨胀到几百 MB。解决办法有两个一是把缓存目录、索引文件、日志全部彻底加进.gitignore然后执行一次git rm -r --cached cache logs把它们从 Git 追踪列表中移除二是定期清理本地的缓存目录WorkBuddy 的设置里一般有缓存大小显示我每周清一次腾出来的空间相当可观。把这个习惯养成之后我的 Git 仓库稳定在 30MB 以内同步速度快了很多。4.6 常见问题速查表我把这段时间遇到的所有问题浓缩成一张速查表方便你直接按图索骥现象可能原因解决方案记忆内容丢失回答断续同步覆盖了旧版记忆文件切换 Git 方案使用版本历史回滚规则文件时而失效大小写文件重名统一小写英文和下划线命名两台设备回复内容混在一起云端会话串线设置设备角色错峰写入git pull 失败本地和远端都有提交先 commit 再 pull --rebase仓库体积疯涨缓存/索引被 Git 追踪加入 .gitignore执行 git rm --cached登录状态频繁掉线账号凭据被同步把 accounts 目录排除在同步范围外5. 进阶技巧从“文件级同步”走向“体验级一致”5.1 先给 WorkBuddy 定一套设备规则很多人忽视了规则文件本身就是双写冲突的高发区。WorkBuddy 的规则决定了它的行为风格和边界也是“减少 AI 味”的关键所在。我后来把规则文件拆成了两个部分base_rules.md是全设备共用的基础规则比如语气、回答长度、禁用事项device_rules/是每台设备自己的补充规则比如公司设备上的规则会更偏向会议纪要和任务管理家庭设备上的规则更偏向阅读笔记和灵感收集。这样拆的好处是共用基础规则的修改频率很低不容易产生冲突设备补充规则各写各的Git 合并时几乎不会撞车。我还在规则文件里明确写了一条设备角色切换时AI 需要优先加载对应设备的规则段而不是把两套设备规则平等混在一起。这个小改动对体验的提升非常明显AI 不再“一会儿像工作助理一会儿像私人书童”。5.2 同步前的“冻结”魔法即使有了 Git 方案同步时机仍然很讲究。如果 WorkBuddy 正在后台执行任务比如正在生成长回答、正在写入记忆这时强行同步会导致文件在写入中途被读取容易产生半截 JSON。半截 JSON 即使能被 Git 提交后续合并脚本读到它时也会直接报错。我的做法是在同步脚本里增加进程检查也就是 3.2 节里那段pgrep -f WorkBuddy。如果检测到进程还在运行脚本就退出并提示你先退出 WorkBuddy 再执行同步。在工作日中我会把自动同步任务设在整点并且尽量避开自己正在连续提问的时间段。实际运行下来因为每 30 分钟才同步一次错过一次也无所谓真正需要的是“要么不同步一旦同步就保证数据完整”。5.3 从一个账号扩展到多项目、多人协作如果你和我一样只是一个人用多个设备前面的方案已经够用了。但如果你想把同一个 WorkBuddy 账号共享给家人或同事那就还需要额外的隔离机制。我的建议是利用 WorkBuddy 的项目目录做隔离每个项目有自己的rules/和skills/子目录并且每个项目单独建一个 Git 仓库而不是整个数据目录一个仓库。这样做的好处是不同项目的同步节奏可以不一样比如团队项目可以每天同步一次个人知识库可以每周同步一次一旦某个项目的仓库出现灾难性合并错误也不会影响其他项目的数据。如果你走得更远还可以给每个人单独建一个设备标识在记忆条目的devices字段里区分“谁参与了这条记忆”这样即使多人共用账号AI 也能大概判断出当前对话的人是谁、应该调用哪一套规则。我个人的体会是多机共用一个 WorkBuddy 账号完全可行但你不能把它当成“云笔记”来用而要从一开始就接受“本地数据为主、版本控制为辅”的架构理念。跨机双写同步的核心不是把文件复制得越快越好而是分清哪些文件允许双写、哪些文件只能单写、哪些文件压根不应该同步。这条界限想清楚了Git 只是工具真正的稳定来自你的约定和管理习惯。最后再分享一个小技巧每次手动同步之前先花十秒钟把当前 WorkBuddy 数据目录复制到带日期后缀的备份文件夹比如workbuddy_backup_20250607然后再执行wb-sync。这个习惯让我在遇到极端情况时永远有一条退路。我靠它少丢了至少三天的记忆数据也希望你能一直保留这个简单的后备动作。