上周我把公司笔记本带回家,想在台式机上用同一个WorkBuddy账号接着写白天没写完的方案。登录一看,差点没把咖啡喷到键盘上——它就像刚装完一样,用一句标准欢迎语把我白天攒的所有上下文、自定义规则、技能全给“格式化”了。那一刻我意识到:账号是同一个,但WorkBuddy的本地状态并没有跟着账号走。这篇文章就是围绕这个问题展开的实践记录:怎么在多台机器上共用一个WorkBuddy账号,怎么做跨机双写同步,以及我踩过的那些坑。
如果你也是一个把同一套AI工作流同时跑在办公室台式机和家里笔记本上的人,或者你在折腾换账号之后记忆丢失、规则和技能在不同机器上对不上号,那这篇文章应该能帮你省下好几个晚上的折腾时间。我先说结论:跨机共用一个WorkBuddy账号的关键,根本不在账号本身,而在你如何处理它散落在各台机器上的本地数据。
1. 账号是张身份证,数据却留在各自机器上
1.1 先搞清楚WorkBuddy把“记忆”放在哪
很多人想当然觉得,登录同一个WorkBuddy账号,云端就会把对话记忆、规则、技能全部同步到新设备。实际并非如此。WorkBuddy这种本地优先的工具,账号承担的更多是身份认证和授权,真正的工作产物——会话历史、长期记忆、自定义规则、技能定义、偏好设置——默认都写在本机的工作数据目录里。
以我用的Linux端为例,它的数据大概分布在这么几个位置:
~/.workbuddy/:主数据目录,包含会话历史、记忆文件、技能目录~/.config/workbuddy/:配置文件,比如settings.json、规则文件~/.cache/workbuddy/:临时缓存和模型产物,这一块不能乱动
Windows端通常在%APPDATA%\WorkBuddy,macOS在~/Library/Application Support/WorkBuddy。国际版和国内版的目录结构可能略有区别,如果你找半天找不到,先确认自己装的是哪个版本,再去对应路径下翻。
判断哪些文件值得同步,我建议先跑一个命令看清楚数据分布:
find ~/.workbuddy -type f -printf '%p %k KB\n' | sort -k2 -rn | head -30这样可以按大小列出最占空间的文件,大致就能知道重量级文件都堆在哪个子目录。我这边跑完发现,最大的永远是缓存和模型文件,而真正记录“我是谁、我做过什么”的记忆和规则文件,体积小得可怜。这一点很重要,因为很多人同步思路就是“整个目录打包”,结果把几十GB的模型缓存当成宝贝同步了半个月,真正的记忆文件反而不在同步清单里。
1.2 账号同步和“双写同步”是两回事
WorkBuddy本身不是没有云端同步能力,但它的云端同步更倾向于“账号维度的增量同步”,不是把你本地所有文件实时镜像到服务器。就算两端都登录同一个账号,本地产生的变化也要等它自己的同步机制触发。一旦网络环境不通、同步进程被系统杀掉,或者你手动改了本地文件却没触发同步,两边的状态就悄悄分叉了。这也是很多用户反馈“同一个账号,电脑A记得的事,电脑B完全不记得”的根本原因。
我采用的“跨机双写同步”,本质上是一种用户态的解决方案:让两台机器的WorkBuddy各自保有完整本地状态,同时把变更信息双向写到对方机器上。
双写有两个关键点。第一是“双向”,A机写入的新内容要推给B机,B机写入的新内容也要推给A机,单向同步在几天内就会造成记忆互相覆盖。第二是“各自为主”,不是A、B两台机器共同操作同一个远程目录,而是各自维护本地主副本,通过某种传输通道把变更对账。这么设计是因为,两个正在运行的WorkBuddy实例如果同时读写同一个共享数据库文件,轻则卡顿,重则直接报“数据库被锁”,我后面会详细讲这个坑。
你可以把账号和本地数据的关系理解成游戏存档:账号是身份卡,证明你是你;存档是本机的进度文件。拿着身份卡去了新机器,身份验证通过了,但存档没跟过来,一切从头开始。跨机双写要解决的,就是把“存档”以某种方式在两台设备之间保持同步。
2. 动手之前,先给数据分级
2.1 值得双向同步的四类核心数据
不是所有文件都值得跨机同步。我后来越用越发现,真正需要保证“两台机器一模一样”的,其实就四类:
第一类,会话历史与长期记忆。这是WorkBuddy用得越久越值钱的部分。它存放在~/.workbuddy/memory/和~/.workbuddy/history/下,通常是json、md、db或者纯文本格式。你换账号后找不到原来的记忆,问题多半出在这一块没有迁移。
第二类,自定义规则文件。很多人会给WorkBuddy定几条规则,用来控制回答长度、语气偏好、避坑清单,甚至通过调整提示词来减少AI味。这些规则如果只在办公电脑上配置过,回到家那台就是另一个性格,输出风格完全对不上。规则文件一般很小,全量同步也没有负担。
第三类,技能定义。WorkBuddy的技能体系是它区别于普通问答工具的核心,相当于给工具装上了可复用的能力包。技能定义通常是一系列结构化文件,包含触发条件、执行流程、参数说明。这类内容一旦更新不互通,跨机体验会非常割裂。
第四类,偏好设置与配置文件。比如sessions面板布局、默认模型选择、快捷键配置等。虽然这些不影响核心使用,但同步后能让你在两台机器上保持一致的交互习惯,减少适应成本。
2.2 必须排除的“三不碰”文件
与上述相反,有三类文件我建议绝对不要放进同步通道,否则会踩出各种匪夷所思的bug。
第一类,模型缓存和临时产物。这一块体积巨大,动辄几个GB到几十GB,而且它们可以被重新生成,同步它纯粹浪费空间和带宽。有人把整个WorkBuddy目录塞进网盘同步,结果网盘空间瞬间爆炸,设置同步排除项时又漏掉了大文件目录,最后磁盘满了才发现。
第二类,日志文件。日志是实时增长的,两台机器同时写、同时互相推送,会产生大量无意义的同步I/O。更麻烦的是,日志里可能带机器名和路径信息,两头一合并,排查问题的时候反而被噪音干扰。
第三类,数据库锁文件。WorkBuddy底层用到SQLite时,会在数据目录里生成*.db,*.db-wal,*.db-shm,*.lock之类的文件。这类文件如果被原样拷贝到另一台机器,程序很容易误判为“有另一个实例在占用数据库”,直接拒绝启动或降级为只读模式。这是跨机同步最容易翻车的地方。
我整理了一张简表,方便你对照过滤:
| 数据类别 | 是否同步 | 位置示例 | 说明 |
|---|---|---|---|
| 会话历史/长期记忆 | 同步 | memory/,history/ | 核心资产,优先保证 |
| 规则与提示词配置 | 同步 | rules/,prompts/ | 体积小、影响大 |
| 技能定义 | 同步 | skills/ | 能力包,不同步等于白装 |
| 偏好设置 | 同步 | settings.json | 一致性体验 |
| 模型缓存 | 不同步 | cache/,models/ | 体积大、可重建 |
| 日志 | 不同步 | logs/ | 噪音,无业务价值 |
| 数据库锁文件 | 绝不同步 | *.lock,*.db-* | 同步了必出问题 |
2.3 更改缓存目录的正确姿势
既然提到缓存目录,也有很多人问WorkBuddy缓存目录怎么改。改法是有的,但改完以降的期望值要说清楚:改缓存目录只能解决磁盘空间分布问题,不解决记忆同步问题。也就是说,你可以把模型缓存指到一个大容量机械盘,避免C盘爆掉,但你的长期记忆还是在原来的业务数据目录里,该同步的还得同步。
Linux/macOS下可以用符号链接把缓存目录挪走,减小同步压力:
# 把原缓存目录移到非同步盘 mkdir -p /data/workbuddy_cache mv ~/.cache/workbuddy /data/workbuddy_cache/ ln -s /data/workbuddy_cache ~/.cache/workbuddyWindows下类似,在资源管理器或cmd里操作:
mklink /D "%LOCALAPPDATA%\WorkBuddy\Cache" "D:\WorkBuddyCache"需要注意的是,做这种软链之前,先彻底退出WorkBuddy进程,改完再启动,否则程序可能已经持有了旧的句柄,改了等于没改。另外,缓存目录的权限要比数据目录严格一些,别把软链目标放到公共盘上。
3. 三套跨机同步方案,按你的动手能力自选
3.1 方案一:网盘同步目录加符号链接
最简单、最容易被接受的一套方案,就是把WorkBuddy的数据目录整体搬进一个网盘同步文件夹,再用符号链接指回去。这样两台机器都通过网盘客户端实时同步,逻辑上“共用一个目录”。
具体操作是这样的。先在网盘里建一个专用的WorkBuddy同步目录,比如D:\Sync\WorkBuddyData,然后把本机的~/.workbuddy目录完整移动到那里,再建符号链接:
# Linux mv ~/.workbuddy /path/to/CloudDrive/WorkBuddyData ln -s /path/to/CloudDrive/WorkBuddyData ~/.workbuddy # Windows mklink /D "%USERPROFILE%\.workbuddy" "D:\CloudDrive\WorkBuddyData"好处是零学习成本,动了目录之后,WorkBuddy完全无感知,正常读写就行,网盘客户端在背后做实时上传和下载。
但这个方法有几个明显的限制。第一,要求网盘文件夹的下载策略最好是按需下载而不是全量下载,否则那几十GB模型缓存会拖垮每一台机器。第二,两台机器不能同时改同一个文件,一旦同时写入,网盘会生成冲突副本,WorkBuddy只会认其中一个,另一个成了孤岛。第三,你仍然要在网盘客户端里设置排除项,把锁文件、日志、大模型文件排除掉,而不是整个目录一把梭。
我的建议是:如果你只有一台机器是主力工作机、另一台只是偶尔打开看一两个会话,那这个方案够用了。如果你两边的使用频率都很高,强烈建议往下看双写脚本方案。
3.2 方案二:Git仓库做记忆版本管理
第二套方案很适合喜欢“一切皆可回滚”的工程师。把WorkBuddy的数据目录初始化为一个Git仓库,每次改动手动或定时做一次提交,然后通过远程仓库把提交推送到另一台机器。
我的工作流大概是这样的。在数据目录下初始化仓库,再写好.gitignore排除掉不需要跟踪的东西:
# 排除缓存和大文件 cache/ *.bin *.gguf *.log *.lock *.db-wal *.db-shm然后用一个简单的脚本做自动提交和推送。别用复杂的钩子,先保证基本闭环:
#!/bin/bash cd ~/.workbuddy git add -A git commit -m "sync: $(date +'%Y-%m-%d %H:%M:%S')" || exit 0 git pull --rebase origin main || true git push origin main另一台机器上写好拉取脚本,开机或定时执行git pull。这样记忆就有了版本历史,哪天真弄丢了还能回溯。
Git方案的短板也很明显:并发冲突是常态。如果两台机器都改了同一个规则文件,git pull --rebase就可能弹出冲突提示,而WorkBuddy不会替你自动合并,你必须手动处理冲突标记。这个方案更适合规则文件、技能定义这类“低频变更”的内容,不适合非常高频的会话历史实时同步。我用它做每周快照备份,而不是日常实时同步。
3.3 方案三:自研双写脚本,更贴近“双写”语义
网盘方案容易在改数据库文件时翻车,Git方案不适合高频写入,最终我选择的自研方案,是一个简单的双向对账脚本。逻辑上不依赖任何单点中介,两台机器各自把数据目录作为“主副本”,脚本互相比对文件的修改时间和内容,时间较新的文件覆盖旧的,缺失的文件补齐。
下面是一个简化版本的示例,只做核心逻辑演示:
import hashlib import os import shutil import time LOCAL_DIR = os.path.expanduser("~/.workbuddy") REMOTE_DIR = "/mnt/remote/workbuddy" # 换成你的共享目录或挂载点 EXCLUDE = {".cache", "logs", "tmp", ".git", "models"} def md5(path): h = hashlib.md5() with open(path, "rb") as f: h.update(f.read()) return h.hexdigest() def should_skip(rel_path): parts = rel_path.split(os.sep) return any(part in EXCLUDE for part in parts) def sync_dir(local_root, remote_root): for dirpath, dirnames, filenames in os.walk(local_root): dirnames[:] = [d for d in dirnames if not should_skip(d)] rel_dir = os.path.relpath(dirpath, local_root) remote_dir = os.path.join(remote_root, rel_dir) os.makedirs(remote_dir, exist_ok=True) for fname in filenames: local_file = os.path.join(dirpath, fname) if should_skip(fname): continue remote_file = os.path.join(remote_dir, fname) if not os.path.exists(remote_file): shutil.copy2(local_file, remote_file) elif md5(local_file) != md5(remote_file): t1 = os.path.getmtime(local_file) t2 = os.path.getmtime(remote_file) if t1 > t2: shutil.copy2(local_file, remote_file) else: shutil.copy2(remote_file, local_file) if __name__ == "__main__": # 本地推远端 sync_dir(LOCAL_DIR, REMOTE_DIR) # 远端拉本地 sync_dir(REMOTE_DIR, LOCAL_DIR) print("sync done:", time.strftime("%Y-%m-%d %H:%M:%S"))这段脚本的核心思想是:以最后修改时间作为优先级,时间较晚的那个文件保留两个副本里较新的内容。如果发现两边内容都变了,而且修改时间几乎相同,它会把两边保留成不同哈希的文件,避免互相覆盖。
脚本本身不复杂,但工程化时候要考虑三件事:加日志、加锁、加增量扫描。日志能记录每次同步发生了什么;锁能防止多个同步进程同时跑;增量扫描能避免每次全量遍历几十万文件。真实环境我建议交给watchdog这类库监听文件变更事件,变更触发同步,而不是定时全量扫。
4. 换账号之后,怎么找回原来的记忆
4.1 账号和记忆为什么绑不到一起
搜“workbuddy 换账号如何获得原来账号的记忆”这个话题的人很多,我最初也踩过这个坑。换个账号再登录,哪怕是同一台机器,原来的记忆也不见了。原因是WorkBuddy把“用户身份”和“数据归属”做成了两个独立维度。
账号体系决定你能认证什么、能访问哪些云端能力;数据归属则取决于程序启动时读的是哪个用户数据目录。在很多版本里,切换账号时,程序会把数据目录切换到以新账号身份创建的独立路径下,旧账号的业务数据原封不动地留在老位置。看起来像失忆,其实是路径换了。
理解了这一点,找回记忆的本质就变成:把旧账号数据目录里那些业务数据文件,挪到新账号的数据目录里,或者让程序继续用旧数据目录启动。前者更稳妥,因为它不会把新旧账号的认证信息混在一起。
4.2 从旧账号“搬家”到新账号的完整流程
我的操作步骤是这样,全程不需要动缓存目录,也不需要重装。
先彻底退出WorkBuddy,然后完整备份旧账号的数据目录,备份永远放在第一步:
cp -a ~/.workbuddy ~/.workbuddy.bak接着用新账号正常登录一次,让程序自动建立新账号的数据目录骨架,再退出。这时候不要急着把旧目录整个覆盖回去,那会把新账号的令牌和身份文件一并带过去,造成账号窜号。
然后逐项迁移业务数据。重点复制memory/,history/,rules/,skills/和settings.json这些内容,对应路径直接覆盖到新账号的数据目录里。这里可以借助上一步备份完成:
for d in memory history rules skills; do cp -a ~/.workbuddy.bak/$d ~/.workbuddy/$d/ done cp ~/.workbuddy.bak/settings.json ~/.workbuddy/settings.json 2>/dev/null || true最后重新启动WorkBuddy,验证记忆是否恢复。为了保险,我会先问它“我们今天之前聊过的最重要的一件事是什么”,如果它能答上来,说明记忆串起来了。然后再随机抽一个自定义规则要求它复述,确认规则文件也生效了。
4.3 缓存目录不等于记忆仓库
再强调一次:改缓存目录和迁移记忆是两码事。缓存目录里存的是一些模型中间产物、临时会话快照,这些即使全删了,重启后只是稍微慢一点,不影响长期记忆。很多人误以为把缓存目录换到新盘、新机器就等于把“记忆”带过去了,我实测过,根本不对。
判断你有没有找错目录,有一个很朴素的鉴别方法:看目录里文件的变化频率和体量。记忆和规则文件是低频小体积变更,而缓存目录里的文件会随着每次对话快速膨胀。如果你准备同步的目录里全是动辄几百MB的.bin、.safetensors、.gguf,那基本可以确定你盯错对象了。
5. 常见问题与排查技巧实录
5.1 一张速查表解决大多数问题
跨机同步出问题的概率,比你想的高得多。我把这段时间遇到的高频问题整理成一张速查表,按图索骥会快很多:
| 症状 | 可能原因 | 处理办法 |
|---|---|---|
| A机新建的技能B机看不到 | 同步延迟或漏了skills/目录 | 检查同步日志,手动执行一次同步,重启WorkBuddy |
| 两边会话记忆互相打架 | 双向同步冲突,时间戳相近文件被覆盖 | 切换为“较新覆盖较旧”策略,冲突文件保留双副本 |
| 程序启动报数据库被锁 | .db-wal,.lock被同步到了另一台机器 | 排除锁类文件,清理目标机器上的残留锁文件后重启 |
| 同步盘空间被占满 | 把模型缓存和大文件也同步了 | 在同步设置里排除cache/,models/,*.bin |
| 换账号后记忆消失 | 数据目录仍然停留在旧账号路径下 | 按第四章流程迁移业务数据目录 |
| 文件一直同步中,占用CPU高 | 同步目录包含日志文件,改动太频繁 | 排除logs/,改为低频定时同步 |
这张表只覆盖了最常见的六种,真正的排查套路还在下面。
5.2 我实打实踩过的三个坑
第一个坑是把整个数据目录塞进网盘同步。第一天一切正常,第二天回家打开台式机,WorkBuddy直接卡死,一看网盘正在同步30多GB的模型缓存,磁盘读写跑满。更麻烦的是,两台机器同时生成了各自的.db-wal文件,被网盘当成冲突副本传过去传回来,最后程序起了三次才正常。从那以后,我的同步排除清单里永远明确写着:缓存和大文件一律不碰。
第二个坑是用了“单向同步”脚本,结果丢了一整天的上下文。那时候我只做了A推B的同步,写得很简单,以为能省事。结果有一天在B机上新建了好几个重要的会话片段,晚上A机的同步脚本一跑,按“本地文件更新时间更旧就覆盖”的逻辑,把B机上那些新内容全冲掉了。这个教训让我彻底改成双向对账。
第三个坑是忘了排除锁文件。某次我调试一个规则,连续在两台机器间同步了十几个版本,然后WorkBuddy开始频繁报错,打开日志一看,是SQLite拿不到写锁。原因很尴尬,.lock文件被同步到了远端,远端进程误以为本地还有活跃实例。这个问题的修复并不复杂,但排查起来极其消耗时间,因为表面症状跟同步毫无关系。
5.3 排查同步问题的固定套路
遇到跨机同步问题,我有一套固定的排查顺序,能减少很多无效操作。
第一步先分清是“数据没同步”还是“同步了但程序没读到”。如果是后者,重启WorkBuddy通常能解决;如果是前者,去看同步日志,确认哪些文件被跳过、哪些冲突被保留。
第二步检查文件占用。在Linux下用lsof看某个文件是否被进程占用,在Windows下看是否有进程锁住了目录。占用中的文件通常不会被同步工具正常替换,这就是很多修改“看着同步了,重启又变回去”的原因。
第三步看WorkBuddy自己的日志。日志文件里往往直接写着数据目录的加载路径、读取哪些配置文件失败、哪条规则解析出错。这些信息比任何推测都可靠。
第四步,临时关掉自动同步,单独手工操作一次。如果手工双写能成功、自动同步不行,问题大概率出在同步工具的过滤规则或写入权限上;如果手工操作也失败,那就是数据本身的路径或格式问题。
这套方法不能覆盖所有场景,但80%的跨机同步问题都能定位到具体文件。定位不到的那20%,基本发生在数据库或网络本身,那需要更深的排查手段。
我个人最终的方案是网盘软链加自研双写脚本混合:日常会话历史靠双写脚本即时对账,规则文件每改动一次就手动同步一次,每个周末再用Git做一次全量快照,防止哪天真出现灾难性覆盖。WorkBuddy这类工具用久了价值都在数据里,多花一点时间把数据通道搭稳,比之后反复找回记忆要划算得多。