我把 AI 代码助手改造成了一套“永不死亡”的个人知识基础设施
微信对话 → AI 沙箱 → 自动修复 → NAS 备份 → 知识归档
一个 Session 一个 Docker 容器,重启后一切自动复活
〇、写在前面
如果你也用过各种云端 AI 编程助手,一定遇到过这样的痛苦:
· 会话超时后,之前聊的上下文全丢了
· 沙箱环境一重启,装好的软件、配置的密钥、跑起来的服务全部归零
· 想让它后台跑个长时间任务,一关页面就断
· 好不容易调通的自动化流程,因为环境不稳定得反复手搓
半年前,我开始重度使用一款叫 WorkBuddy 的 AI 代码助手——它以微信为入口,后端跑在 Docker 沙箱里,核心是腾讯的 codewise-chat 模型和 codebuddy-code 执行引擎。最初我只是把它当一个“能聊天的命令行”。但很快我发现,它的架构给了我极大的改造空间:每个对话 Session 就是一个独立的 Docker 容器,/workspace/ 目录会持久化,我可以往里面塞任何脚本、配置和守护进程。
于是我花了几周时间,把它从一个“对话式 AI”深度整合进我的 NAS、知识管理和家庭网络,最终形成了一套:
微信即终端,会话即沙箱,重启即恢复,知识即闭环
的无人值守 AI 基础设施。
这篇文章,我会从第一人称视角,详细拆解我是怎么做的,遇到了哪些坑,最终实现了什么能力,以及这套架构背后的技术复杂度。全文超过 1 万字,希望能给同样想“驯服”云端 AI 环境的你一些启发。
一、为什么要折腾?——来自一个远程沙箱的 PTSD
1.1 云端沙箱的“不稳定性”是常态
WorkBuddy 的沙箱本质是一个 Docker 容器,运行在云服务商的轻量虚机上。为了节省资源,平台会做两件“要命”的事:
· 自动休眠:如果一段时间没有对话,容器被 suspend,再次唤醒时,所有进程全部消失(sshd、自己起的服务、消息队列……统统没了)。
· 周期性重启:大约每 4 小时,容器会被彻底销毁重建(底层 overlay2 重置),只有 /workspace/ 目录通过 nbd 设备挂载得以幸存。
这在普通用户看来可能无所谓——反正每次都是新对话。但我想让它 7×24 小时后台运行:
· 深夜让它帮我爬数据、分析日志
· 定时备份 GitHub 仓库
· 通过微信发送指令来控制家庭网络设备
· 把生成的文档自动上传到我的知识库
如果一觉醒来沙箱重启了,所有服务都挂了,那这个“助手”就毫无价值。
1.2 现有的保活方案根本不够
最初我尝试了几种“常规操作”:
· crontab @reboot:沙箱里连 cron 命令都没有。
· systemd service:PID 1 是 supervisord,systemd 根本没在跑。
· /etc/rc.local:文件不存在,且重启后丢失。
· 写一个 while true 循环脚本:沙箱休眠后进程被杀,醒来不会自动拉起。
我需要一个多层、冗余、能在容器重启后自动重建一切的保活体系。这引出了我第一个核心改造。
二、整体架构:一个 Session 就是一个国家
先别急着看代码,理解架构才能明白为什么我要这么折腾。
2.1 官方架构(简化版)
微信 (WeClaw)
│ HTTPS
▼
sandbox-proxy (Go, :65225) ← 运行在 Docker 容器内
│ SessionManager
│ CBCAgent
▼
codebuddy CLI (Node.js) ← AI Agent 核心引擎
│ 模型: codewise-chat (128K)
│ Agent: cli / Explore / Plan / compact
│ 工具: Bash / Glob / Grep / Read / Edit / Write
重点:每个微信对话对应一个独立的 Docker 容器。容器内有:
· sandbox-proxy:Go 二进制,负责会话映射、进程管理
· codebuddy:Node.js CLI,真正干活的 AI
· 独立的 overlay2 文件系统、独立的 network namespace、独立的 WireGuard IP(如 10.0.0.10)
2.2 我改造后的架构
微信前端
│
▼
sandbox-proxy ──┬── codebuddy CLI (AI)
│
├── knasync (Flask 消息队列, :8080)
│
├── watchdog.sh (守护进程)
│
├── wxwatcher (文件变化监控 → 微信推送)
│
└── WireGuard wg0 (10.0.0.10)
│
▼
Hub (10.0.0.1, 公网 VPS)
│
├── NAS (/mnt/nas/sandbox-backup/)
└── Knowly (upload.want.biz, 知识库归档)
同时,在宿主机(或 Mac 端)有一个轮询脚本,定期 pull knasync 队列,实现异步跨设备通信。
一句话:我把沙箱从“一次性会话环境”变成了“持久化服务综合体”。
三、第一个硬仗:让沙箱“死后复生”——四层保活体系
这是整个项目最烧脑、最值得吹嘘的部分。核心目标:无论沙箱怎么重启(休眠恢复、容器重建、甚至镜像重置),30 秒内所有关键服务自动恢复。
3.1 保活失败的根本原因
沙箱重启后,会发生这些事情:
· /usr/local/ 目录重置(你装的软件全丢)
· /root/ 目录重置(.bashrc、.ssh、authorized_keys 全丢)
· 所有进程消失(sshd、wireguard、knasync、wxwatcher、watchdog 本身)
· 只有 /workspace/ 保留(nbd 挂载)
所以,唯一可以依赖的持久化据点就是 /workspace/。我所有的恢复脚本、配置文件备份、密钥都必须放在 /workspace/ 下。
3.2 四层防护设计
层级 机制 触发条件 作用
L1 supervisord 托管 容器启动时 PID 1 自动拉起 系统级守护,只要 supervisord 配置还在,watchdog 就能自动跑起来
L2 bashrc fallback 用户打开新对话(agent shell 启动) 如果 supervisord 配置丢失,通过 .bashrc.d/10-watchdog 再次拉起 watchdog
L3 watchdog.sh 循环 每 60 秒检查 主动修复 sshd、wg0、knasync、wxwatcher,死掉就重启
L4 配置自修复 watchdog 启动时 自动从 /workspace/backup/ 恢复 sshd_config、wg0.conf、authorized_keys 等
L1:supervisord 自启配置
创建 /usr/local/share/supervisor/watchdog.conf(这个路径会被主 supervisord 的 [include] 加载):
[program:watchdog]
command=bash /workspace/watchdog.sh
directory=/workspace
autostart=true
autorestart=true
startsecs=5
startretries=999
stdout_logfile=/workspace/watchdog.log
redirect_stderr=true
priority=200
风险:/usr/local/share/ 可能在容器彻底重建后丢失。所以我还有 L2。
L2:bashrc 兜底
创建 /root/.bashrc.d/10-watchdog(注意 /root/ 也会丢失,所以这个文件实际放在 /workspace/10-watchdog,由 watchdog 自身恢复):
#!/bin/bash
if [ -f /workspace/watchdog.sh ]; then
if ! pgrep -f "watchdog.sh" > /dev/null 2>&1; then
bash /workspace/watchdog.sh > /tmp/watchdog_manual.log 2>&1 &
fi
fi
原理:每次你在微信里对 WorkBuddy 说话,codebuddy CLI 会启动一个 shell,这个 shell 会 source /root/.bashrc,进而触发这个脚本。只要你能发起对话,就能激活守护进程。
L3:watchdog.sh 核心循环
简化版逻辑:
while true; do
# 检查 sshd
if ! pgrep -x "sshd" > /dev/null; then
/usr/sbin/sshd && log "重启 sshd"
fi
# 检查 wg0 接口
if ! ip link show wg0 > /dev/null 2>&1; then
wg-quick up /etc/wireguard/wg0.conf && log "重启 wg0"
fi
# 检查 knasync (Flask 服务)
if ! pgrep -f "knasync/app.py" > /dev/null; then
nohup python3 /workspace/knasync/app.py > /tmp/knasync.log 2>&1 &
fi
# 检查 wxwatcher
if ! pgrep -f "wxwatcher" > /dev/null; then
nohup wxwatcher --config /workspace/.wxwatcher.yml > /tmp/wxwatcher.log 2>&1 &
fi
# 每 10 分钟 rsync 备份到 Hub
if [ $((SECONDS % 600)) -eq 0 ]; then
rsync -az --delete /workspace/ root@10.0.0.1:/mnt/nas/sandbox-backup/
fi
sleep 60
done
L4:配置自修复
在 watchdog.sh 启动时(获取 PID 锁之前),执行一系列恢复函数:
· restore_sshd_config:从 /workspace/backup/sshd_config 复制到 /etc/ssh/,重建 /run/sshd 目录,重置 root 密码。
· restore_wireguard:从 /workspace/backup/wg0.conf 复制到 /etc/wireguard/,设置权限 600。
· restore_authorized_keys:从 /workspace/.ssh/id_ed25519.pub 重建 /root/.ssh/authorized_keys。
· restore_bashrc_d:将 /workspace/10-watchdog 复制到 /root/.bashrc.d/。
效果:即使容器被彻底重置(镜像恢复),只要 /workspace/ 还在,watchdog 第一次被触发后,就能把所有配置反向写回系统目录,然后拉起所有服务。
3.3 踩过的坑(以及如何填平)
坑 1:WireGuard 启动后 SSH 断连
因为 WireGuard 会修改默认路由,导致你正在连接的 SSH 会话(通过公网 IP)突然丢包。解决方案:策略路由打标。
在 wg0.conf 的 PostUp 中加入:
PostUp = ip rule add from all fwmark 0x1000 table main priority 500
PostUp = iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 0x1000
这样,源端口 22 的流量不经过 VPN 隧道,直接走主路由。WireGuard 再怎么重启,SSH 永远不会断。
坑 2:rsync 返回 255 导致 watchdog 崩溃
watchdog 一开始没对 rsync 的错误处理,如果 Hub 临时不可达,rsync 退出码 255,bash 脚本默认会退出(因为 set -e)。我加了容错:
rsync ... || {
code=$?
if [ $code -eq 255 ]; then
log "rsync 连接失败,稍后重试"
else
log "rsync 错误码 $code"
fi
}
坑 3:密码哈希格式不兼容
沙箱重启后 /etc/shadow 丢失,watchdog 会执行 echo "root:yuangs" | chpasswd。但某些沙箱的 chpasswd 默认使用 DES 哈希,导致 sshd 无法验证。我改为:
echo "root:yuangs" | chpasswd -c SHA512
坑 4:IP 地址动态变化导致策略路由失效
PostUp 里如果硬编码 eth0 的 IP(比如 10.0.0.2),容器重启后 DHCP 分配的 IP 变了,规则就废了。我改成动态获取:
ETH0_IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
ip rule add from $ETH0_IP table main priority 500
这样每次 wg0 启动时,都会拿当前的真实 IP。
四、网络拓扑:让沙箱成为内网一等公民
4.1 为什么不用 Cloudflare Tunnel?
官方文档推荐用 Cloudflare Tunnel 暴露服务。但我踩了两个坑:
· 需要 origin certificate,我的账号下没有(已停用)。
· Tunnel 不稳定,时不时断连,且 URL 会变化(免费版随机子域名)。
我需要一个稳定、低延迟、可预测的接入方式,让沙箱能和我家里的 NAS、Mac、iPad 直接通信。
4.2 WireGuard 全互联
我在公网 VPS(Hub)上跑了一个 WireGuard 服务端,地址 10.0.0.1/24。沙箱作为 Peer,固定 IP 10.0.0.10。我的 Mac 在家里也连入同一个 VPN,IP 10.0.0.3。
这样:
· 从 Mac 可以直接 ssh root@10.0.0.10 进沙箱(密码 xxx)。
· 沙箱可以 rsync 备份到 Hub 的 NAS 挂载点(10.0.0.1:/mnt/nas/)。
· 沙箱可以主动 push 消息到 Mac 端(通过 knasync + Mac 轮询)。
关键设计:Hub 的 WireGuard 监听端口不是默认的 51820,而是 443(很多网络出口会放行 443)。这样即使我在咖啡店等严格防火墙环境,也能连上 VPN。
4.3 解决 NAT 穿透和 keepalive
沙箱位于云厂商的 NAT 后面,公网 IP 会变化。WireGuard 需要 Endpoint 更新。我在 Hub 端为沙箱配置了:
[Peer]
PublicKey = <沙箱公钥>
AllowedIPs = 10.0.0.10/32
PersistentKeepalive = 25
PersistentKeepalive = 25 让 Hub 每 25 秒向沙箱最后一次上报的 Endpoint 发一个 keepalive 包,即使沙箱 IP 变了,也能快速更新(当然,如果沙箱重启后 IP 彻底变了,需要沙箱主动发起一次 handshake)。
沙箱侧的 wg0.conf 中 Endpoint 指向 Hub 的公网 IP:443,PersistentKeepalive 也设为 25,双向保活。
五、消息队列 knasync:打通微信与 Mac 的异步链路
5.1 痛点:微信只能“等回复”
WorkBuddy 原本的交互是同步的:你在微信发消息 → sandbox-proxy 转发给 codebuddy → AI 处理 → 回复到微信。整个过程阻塞。如果 AI 要执行一个耗时 10 分钟的任务(比如 git clone 大仓库 + 分析),微信会超时断开。
我需要异步化:任务提交后立即返回“收到,稍后通知”,任务完成后主动推送结果。
5.2 引入 knasync:内存 FIFO 队列
我写了一个极简的 Flask 服务(/workspace/knasync/app.py):
from flask import Flask, request, jsonify
from collections import deque
app = Flask(__name__)
queue = deque(maxlen=1000)
@app.route('/push', methods=['POST'])
def push():
msg = request.json
queue.append(msg)
return 'OK'
@app.route('/pull', methods=['GET'])
def pull():
if queue:
return jsonify(queue.popleft())
return ('', 204)
@app.route('/health')
def health():
return jsonify({'size': len(queue)})
运行在 localhost:8080。
5.3 Mac 端轮询 + 微信推送
在我的 Mac 上,写了一个脚本 knasync_poller.sh,每分钟执行一次:
RESP=$(curl -s http://10.0.0.10:8080/pull)
if [ "$RESP" != "" ]; then
# 通过企业微信/Server酱 推送到我的微信
curl -X POST https://xxx.yuangs.cc/weixin \
-H "Content-Type: application/json" \
-d "{\"text\":\"$RESP\"}"
fi
同时,AI 在执行长任务时,可以调用内部技能 send_to_wechat.py 直接推送消息,也可以往 http://localhost:8080/push 塞消息(如果 Mac 暂时离线,消息会暂存在队列里)。
效果:现在我可以对 WorkBuddy 说:“帮我分析一下 /workspace/logs 下最近 1000 条错误,完成后发到 knowly,再微信通知我”。然后关掉手机,一小时后微信收到一条带链接的消息,点开就是分析报告。
六、数据持久化与备份策略:一切可恢复
6.1 哪些目录是持久化的?
路径 持久化? 说明
/workspace/ ✅ nbd 设备挂载,重启不丢
/root/.codebuddy/ ✅ Agent 记忆、sessions、tasks
/root/ ❌ 重启丢失
/usr/local/ ❌ 重启丢失
/home/ ❌ 重启丢失
所以,所有需要“死后重生”的配置、脚本、密钥,都必须放在 /workspace/ 下,然后由 watchdog 负责在启动时恢复到正确的位置。
6.2 我的 /workspace/ 目录结构
/workspace/
├── watchdog.sh # 核心守护脚本
├── 10-watchdog # bashrc fallback 副本
├── backup/
│ ├── wg0.conf # WireGuard 配置(含私钥)
│ ├── sshd_config # SSH 服务配置
│ ├── config.yml # Cloudflare Tunnel 占位(待完善)
│ └── id_ed25519 # SSH 私钥备份
├── .ssh/
│ └── id_ed25519.pub # 公钥(用于恢复 authorized_keys)
├── knasync/
│ └── app.py # 消息队列服务
├── wxwatcher.conf # supervisor 配置片段
├── .wxwatcher.yml # wxwatcher 运行配置
└── notify.sh # 三通道通知脚本(日志+队列+控制台)
6.3 备份到 NAS(Hub)
每 10 分钟,watchdog 会执行:
rsync -az --delete /workspace/ root@10.0.0.1:/mnt/nas/sandbox-backup/
同时,Hub 会每小时对这些备份打一个快照(使用 rsnapshot 或 ZFS 快照),保留 30 天。
灾难恢复:如果沙箱的 /workspace/ 彻底损坏(比如 nbd 设备故障),我可以在一个新容器里手动执行:
rsync -az root@10.0.0.1:/mnt/nas/sandbox-backup/ /workspace/
bash /workspace/watchdog.sh &
一切恢复如初。
6.4 与知识库 Knowly 的集成
Knowly 是我自建的一个知识归档系统(xxx.want.biz),支持通过 HTTP 上传文件。WorkBuddy 学会了一个技能:当我说“发到 knowly”时,AI 会执行:
curl -X POST https://xxx.want.biz/api/upload \
-F "file=@/path/to/report.md" \
-F "path=workbuddy/"
然后自动生成一个短链接,推送到微信。现在,所有 AI 生成的代码分析、日志摘要、爬取的数据,都会被永久归档到 Knowly,并且可以按标签检索。
七、微信文件实时通知:wxwatcher 的妙用
7.1 场景:AI 修改了代码,我立刻知道
WorkBuddy 的 AI 可以编辑文件(通过 Edit 工具)。但有时候它改错了,或者改了一个关键配置,我想第一时间知道。
我写了一个 wxwatcher 服务,使用 Python 的 watchdog 库监控 /workspace/ 下的文件变化(支持递归)。当任何文件被创建、修改或删除时,通过 send_to_wechat.py 推送一条消息,格式:
[沙箱] 文件变化: /workspace/config/app.yml 已修改
7.2 避免推送风暴
为了避免每次 rsync 备份或编译产物触发海量通知,我加了过滤规则(.wxwatcher.yml):
exclude_patterns:
- "*.log"
- ".git/*"
- "backup/*"
- "knasync/*"
debounce: 2 # 2 秒内连续变化只发一次
现在,只有真正重要的文件(比如 .py、.md、*.conf)变化时,我才会收到微信通知。
八、AI Agent 与模型:为什么选 codewise-chat?
8.1 模型能力评估
WorkBuddy 底层使用腾讯的 codewise-chat 模型,配置如下:
{
"id": "codewise-chat",
"vendor": "tencent",
"maxInputTokens": 128000,
"maxOutputTokens": 8192,
"supportsToolCall": true,
"supportsImages": false
}
128K 上下文意味着我可以把整个中等规模项目(几千行代码)一次性喂给它分析。输出 8192 token 足够生成完整的重构方案或文档。
8.2 Agent 分工体系
codebuddy CLI 内置了多 Agent 协作:
Agent 职责
cli 主 Agent,拥有全部工具权限
general-purpose 通用对话子 Agent
Explore 代码探索,使用轻量模型快速返回
Plan 架构规划,生成多步骤任务
compact 上下文压缩,当对话太长时自动总结
summaryGenerator 会话结束后生成摘要,写入 memory
这套机制让长对话不会爆炸,且 AI 能主动记忆之前的重要决策。
8.3 Bash 隔离:bubblewrap 保护宿主机
一个关键安全设计:codebuddy 执行的 Bash 命令并不是直接 system(),而是通过 BashSandboxManager 调用 bubblewrap,限制可访问的目录、环境变量和网络。默认只允许读写 /workspace/ 和 /root/.codebuddy/,无法访问宿主机的 /etc 或 /proc。
这一点让我可以放心地允许 AI 执行 rm -rf 或 sudo(在容器内 sudo 无实际危害),而不用担心它删掉我的备份或感染其他容器。
九、整合 NAS 与知识管理的“魔法时刻”
前面讲了很多技术细节,现在我想说说,当所有组件拼在一起后,真正惊艳的体验。
9.1 场景一:深夜自动爬取 + 分析 + 归档
我在微信上发:“凌晨 2 点,爬取 Hacker News 前 30 条,提取每条摘要,翻译成中文,存入 knowly,早上 8 点前完成”。
WorkBuddy 收到后,会创建一个 cron 任务(当然,/var/spool/cron 不持久化,所以我实际用的是 at 命令加 watchdog 重试)。凌晨 2 点,它执行:
-
curl 获取 HN 数据
-
用 jq 解析,循环调用一个本地小模型(或者 codewise-chat 自己)做摘要翻译
-
生成 Markdown 文件到 /workspace/hn_daily.md
-
调用 knowly 上传,获得链接
-
往 knasync 推消息,Mac 轮询后发微信给我
早上醒来,微信里躺着一条消息:“今日 HN 摘要已生成:[链接]”,点开就是漂亮的日报。
9.2 场景二:从 NAS 恢复历史会话
有一次沙箱彻底重建(平台升级),/root/.codebuddy/ 没了,之前的会话记忆全部消失。但由于我每 10 分钟备份 /workspace/ 到 Hub,而 Hub 又备份了整个 /root/.codebuddy/(因为 /root/.codebuddy/ 实际是在 /workspace/ 的符号链接吗?不,它是独立目录,但我在备份脚本里特意加了 --include '/root/.codebuddy/' 选项)。
我手动从 Hub 把 /.codebuddy_backup/ 复制回 /root/.codebuddy/,重启 watchdog,之前的所有会话历史、memory、任务队列全部回来了。AI 甚至还记得三天前我们讨论过的那个 Bug 修复方案。
这就是“会话可回溯”的价值。
9.3 场景三:微信触发的 CI/CD
我的个人博客用 Hugo 生成,源码放在 /workspace/blog/。我可以在微信里说:“帮我更新博客,新建一篇 ‘AI 沙箱实践’,内容从 /workspace/notes/idea.txt 读,生成后发到 knowly,并推送到 GitHub”。
WorkBuddy 会执行:
cp /workspace/notes/idea.txt /workspace/blog/content/posts/ai-sandbox.md
cd /workspace/blog && hugo
git add . && git commit -m "new post" && git push origin main
curl ... knowly upload ...
整个过程无人值守。我甚至可以在通勤路上用手机完成一次博客发布。
十、技术复杂度分析(为什么这不容易)
很多朋友看到成果会问:“这不就是写几个脚本吗?”实际上,背后的技术复杂度远超表面。我列几个关键维度。
10.1 状态管理与恢复的复杂度
· 问题:沙箱随时可能重启,任意进程都可能死亡,配置文件可能被重置。如何保证最终一致性?
· 方案:watchdog 作为“状态调协器”,以 /workspace/ 为唯一真理源,周期性 reconcile 实际系统状态。类似 Kubernetes 控制循环。
· 难度:⭐⭐⭐⭐
10.2 网络策略路由与 VPN 共存
· 问题:WireGuard 改变默认路由后,如何保持管理连接(SSH)不断?
· 方案:iptables mangle + fwmark + ip rule,将特定流量(sport 22)踢出 VPN。
· 难度:⭐⭐⭐⭐(需要对 Linux 路由、Netfilter 有较深理解)
10.3 跨设备异步消息可靠传递
· 问题:Mac 端可能关机、网络断,如何保证消息不丢?
· 方案:沙箱侧内存队列 + Mac 侧轮询 + 持久化 fallback(未实现,未来可加 SQLite)。
· 难度:⭐⭐⭐
10.4 多 Agent 协作与上下文管理
· 问题:长对话导致 token 爆炸,且不同任务(探索、规划、执行)需要不同 system prompt。
· 方案:codebuddy 内置的 Agent 分工 + compact 自动压缩 + summary 持久化。
· 难度:⭐⭐⭐⭐(框架已提供,但我需要理解其行为以编排任务)
10.5 安全隔离的代价
· 问题:AI 能执行任意 Bash 命令,如何防止它破坏系统或泄露数据?
· 方案:bubblewrap 限制文件系统访问 + 网络代理白名单 + 禁止某些危险命令(如 curl | bash)。
· 难度:⭐⭐⭐⭐(需要配置 seccomp/AppArmor,但 WorkBuddy 已经封装好)
10.6 自举与自修复的循环依赖
· 问题:watchdog 本身需要被守护,如果 L1~L3 全部失效,怎么救?
· 方案:L4 配置自修复 + 微信发特殊指令手动触发(比如发送“!!RESURRECT!!”,sandbox-proxy 会执行预定义的恢复脚本)。
· 难度:⭐⭐⭐⭐⭐(这是最棘手的,我花了三天调试各种边界情况)
十一、经验教训与未来展望
11.1 教训
-
不要过度依赖 supervisord 的持久性:/usr/local/share/supervisor/ 在容器重置后真的会丢。必须有 bashrc 兜底。
-
rsync 的 255 错误一定要处理:否则你的守护进程会悄无声息地退出。
-
策略路由的 IP 不能硬编码:动态获取是王道。
-
日志要轮转:watchdog.log 如果不裁剪,几个月能到几十 GB。我在脚本里加了超过 2000 行就截断保留 500 行。
-
PID 锁要带进程名校验:否则 pgrep watchdog 可能匹配到不相关的进程。
11.2 未来改进方向
· 多沙箱调度:当前只管理一个 Session,未来可以让 sandbox-proxy 同时持有多个容器,实现任务并行。
· 持久化消息队列:knasync 改用 Redis 或 SQLite,避免 Mac 长期离线导致队列丢失。
· 可观测性仪表盘:将 watchdog 的各项检查结果、备份状态、VPN 延迟推送到一个简单的 Web 页面(可以放在 Hub 上)。
· 更智能的备份策略:增量 + 去重 + 加密上传到对象存储。
· 支持更多入口:除了微信,还可以接入 Telegram、Discord 或直接暴露一个 HTTP API。
十二、总结:我得到了什么?
经过几周的折腾,我最终拥有了一套:
· 永远在线(沙箱重启后 30 秒自动复活)
· 微信可控(任何地方发消息就能触发 AI 任务)
· 与 NAS 深度集成(自动备份、灾难恢复)
· 知识闭环(生成的内容自动归档到 Knowly,并推送通知)
· 安全隔离(每个会话独立容器 + bubblewrap)
· 高韧性(四层保活 + 配置自修复)
的 AI 基础设施。
更重要的是,这个过程让我深刻理解了:
· 云端容器的“不稳定性”可以通过防御性编程 + 定期 reconcile 来驯服
· VPN 策略路由不是玄学,是可以精确控制的
· 一个设计良好的 AI Agent 框架(如 codebuddy)可以成为自动化任务的绝佳执行器
· 个人知识管理不一定要用 Notion 或 Obsidian,自建 + AI 驱动 可能更强大
写在最后
这份工程实践目前已经开源了核心脚本(watchdog.sh、knasync 等),我放在了 GitHub 上:github.com/yuangs/workbuddy-infra(如果未公开,请替换为实际链接)。里面包含:
· 四层保活完整实现
· WireGuard 策略路由示例
· knasync 服务端 + Mac 轮询客户端
· 微信推送脚本
· 详细注释的配置文件
欢迎 star、提 issue 或 PR。如果你也在折腾类似的 AI 沙箱,或者想把这些能力用到自己的 NAS、家庭服务器上,希望这篇文章能给你一份可落地的参考。
最后,感谢 WorkBuddy 本身的优秀设计(Session 即容器、持久化 /workspace/、强大的 Agent 能力),没有这些基础,我的所有改造都不可能成立。
用微信驱动 AI,让 AI 驱动我的数字生活 —— 这,就是我想要的下一代个人计算平台。