让 AI Agent 直接对生产仓库执行 write / rm,一次幻觉就可能变成删库、泄露密钥或半写入的损坏配置。Virtual File System(VFS) 的核心思路是:Agent 永远只在一个可丢弃、可审查、可回滚的视图里改文件,真实磁盘在人工或 CI 验收后才合并。本文从工程实践出发,说明 VFS 分层、权限边界与落地检查清单。
1. 为什么 Agent 不能直接改真文件
编码 Agent(Cursor、Claude Code、OpenClaw、自研 Runner)的工具调用看起来只是「改几个文件」,但失败模式与人工误操作不同:模型会自信地批量执行,且常在无监督循环里重试。
| 风险 | 典型触发 | 后果 |
|---|---|---|
| 路径越界 | ../../.env、误写 /etc | 密钥泄露、系统配置损坏 |
| 破坏性命令 | rm -rf、覆盖 package-lock.json | 仓库不可构建、数据丢失 |
| 半写入 | 多文件重构中途崩溃 | 类型检查失败、线上灰度踩雷 |
| 不可审计 | 直接 shell 改文件无 diff | 无法 Code Review、合规不过关 |
站内 Agent 时代账单拆解 里强调过:Agent 的隐性成本不仅是 Token,还有误操作后的回滚与值班。文件安全是 FinOps 的底座——比多路由一个便宜模型更重要。
2. VFS 是什么:三层视图
Virtual File System 在 Agent 场景里通常不是内核级 VFS,而是用户态文件抽象层:把「读」「列目录」「写」「删」封装成 API,背后可以是 overlay、git worktree、容器层或远程沙箱。
可操作的 mental model 是三层:
- Base(只读):克隆的仓库快照、镜像层或
git checkout的干净树。Agent 不应能永久修改这一层。 - Overlay(可写):Agent 所有修改只落在这里;CoW(写时复制)或 union mount 让「看起来像在改原文件」。
- Publish(合并出口):经 diff 审查、测试通过后,才把 overlay 变更
git apply/ PR / 部署到真实工作区。
这与 多 Agent 四种架构 里的「Planner 出计划、Executor 在隔离环境执行」一致:VFS 是 Executor 的物理边界。
3. 四种常见实现模式
| 模式 | 机制 | 优点 | 注意点 |
|---|---|---|---|
| Git worktree / 分支沙箱 | 新 worktree + 临时分支 | 与现有 Git 流程无缝;diff 即 PR | 需防 .git 外写、大文件 LFS |
| OverlayFS / 容器层 | Docker、Podman 可写层 | 强隔离;易销毁 | 挂载卷要白名单;注意 UID 映射 |
| 远程沙箱(e2b、Firecracker) | 每次任务新 VM | 最强隔离;适合不可信代码 | 冷启动与网络策略成本 |
| IDE 虚拟层(Cursor 等) | 工具 API + 工作区规则 | 低摩擦;人机协同好 | 规则要写进 .cursor/rules 与 hooks |
选型时先问:任务生命周期是秒级补全还是小时级自主循环?短任务可用 worktree;长驻 Agent(OpenClaw、Hermes)更适合专用机器 + 固定沙箱目录,与 MCP 工具边界 一起设计。
4. 权限与白名单:最小可写面
再完善的 VFS,若允许写 ~/.ssh 或项目外路径也会失效。生产建议:
- 根目录锁死:仅允许
$WORKSPACE/**;拒绝..逃逸与符号链接指向外部。 - 扩展名 / 路径 denylist:
.env*、*.pem、id_rsa、secrets/默认只读;写入需显式人类批准。 - 命令与工具双闸:文件 API 白名单 + shell 禁止(或
git/npm test允许列表)。 - 速率与批量上限:单次任务最多改 N 个文件、M 行,超限转人工。
Cursor 用户可把「禁止改 backend」「commit 需用户确认」写进项目规则;自研 Runner 则在 MCP Server 层实现同样的 allowed_paths。参考 ECC 与 Claude Code 的 hooks 思路:在工具真正落盘前拦截。
5. 原子写入、Diff 预览与回滚
安全不只是「别删库」,还包括变更可理解、可撤销:
- Staging:所有写入先进 overlay 暂存区,不直接 touch 工作树。
- Unified diff:合并前生成 diff;超过阈值(如 500 行)强制人工确认。
- 原子提交:用临时文件 +
rename(2)或单事务git commit,避免读者看到半截文件。 - 快照 ID:每次 Agent 运行绑定
run_id,一键git reset --hard或 overlay 丢弃。
CI 里可要求:Agent 产出只能是 PR 分支,合并前跑 lint / test。这与 OpenClaw + self-hosted Runner 的「Webhook 触发、制品进 PR」同构。
6. 密钥与敏感路径隔离
Agent 读取 .env 做调试是常见需求,但写入密钥等于把保险柜钥匙交给概率模型。
- 运行环境用占位符注入(
SECRET_*来自 orchestrator),仓库内永不出现真值。 - 日志与 tracing 对文件内容做红action;diff 展示时屏蔽
API_KEY=行。 - 沙箱网络 egress 限制,防止「读到密钥后 exfil 到外部 URL」。
若 Agent 部署在共享 VPS,邻居进程可能读到同一文件系统——这也是很多团队把 Agent Runner 迁到独享主机的原因之一(见文末)。
7. 落地示例:沙箱 Workspace
# 极简 VFS:只允许在 sandbox/ 下读写,合并前 diff
from pathlib import Path
import shutil, tempfile, subprocess
ROOT = Path("/data/repo").resolve()
SANDBOX = Path(tempfile.mkdtemp(prefix="agent-"))
ALLOWED = (ROOT,) # 只读镜像用 copy 或 bind mount
DENY = {".env", ".git", "node_modules", "secrets"}
def safe_resolve(path: str) -> Path:
p = (SANDBOX / path).resolve()
if not str(p).startswith(str(SANDBOX)):
raise PermissionError("path escape")
return p
def write_file(rel: str, content: str) -> None:
if any(part in DENY for part in Path(rel).parts):
raise PermissionError("denied path")
p = safe_resolve(rel)
p.parent.mkdir(parents=True, exist_ok=True)
tmp = p.with_suffix(p.suffix + ".tmp")
tmp.write_text(content, encoding="utf-8")
tmp.replace(p) # 原子替换
def publish_diff() -> str:
return subprocess.check_output(
["git", "diff", "--no-index", str(ROOT), str(SANDBOX)],
text=True,
)
生产还需:并发锁、二进制文件处理、大文件 streaming、与真实 git 状态同步。核心不变:工具层强制路径语义,而不是在 prompt 里「请小心」。
8. 生产级 Agent 文件安全清单
- ☐ Agent 无裸
rm -rf /与无限制 shell - ☐ 可写路径白名单 + 符号链接检查
- ☐ 敏感文件默认 deny;例外需人工 token
- ☐ 每次运行有
run_id、diff 存档、可回滚 - ☐ 合并前自动化测试(与 Copilot 开放后验收五件事 同类纪律)
- ☐ 日志脱敏;密钥不进训练上下文
- ☐ 长驻 Agent 跑在独享、可快照的机器上
9. 常见问题
VFS 会不会拖慢 Agent?
overlay 或 worktree 的开销通常是毫秒到秒级,远低于一次 LLM 往返。瓶颈在模型推理,不在文件层。
小团队没有基础设施怎么办?
最低配:专用分支 + PR,禁止 Agent 推 main;配合 IDE 规则拒绝写 .env。已能挡住大部分事故。
和 Docker 卷挂载冲突吗?
不冲突:只读挂载代码,可写层或命名卷承载 Agent 修改;发布时再把 diff 打回主机 git。
多 Agent 并行怎么隔离?
每 Agent 一个 worktree 或 sandbox 目录,禁止共享可写全局状态;合并由单一「integrator」角色处理冲突。
Cursor 算 VFS 吗?
产品层提供受控工具与工作区规则,本质仍是「抽象文件 API + 策略」。自研系统应实现同等或更严的边界。
云端 Mac 和 VFS 有什么关系?
长驻 Agent、Xcode 构建与沙箱常需要稳定、独占的文件系统与快照;共享 VPS 难以保证隔离与性能,独享 Mac mini 更适合作为 Agent Runner 节点。
Agent Runner 需要可快照的独享环境
OpenClaw、Claude Code 远程任务、MCP 工具链往往在单机上长时间持有工作区。共享主机上跑 VFS 沙箱,容易遇到磁盘争用、权限错乱和难以做的系统级快照。Apple Silicon Mac 上 APFS 快照、原生 Unix 权限与 xcodebuild 工具链,适合作为「Agent 可写层」的物理底座。
若你在搭建自主编码 Agent 或 self-hosted Runner,Nuvcloud 云端 Mac mini M4 提供独享算力与固定环境——查看套餐方案,让 VFS 沙箱跑在可预期的硬件上。