
当 Agent 开始直接修改你的工作区,谁来给它配一层隔离与回滚?CensorFS 只做一件事:写入真正落地之前,先把它放进一层看得见、随时可以丢弃的私有空间。
在 OpenAtom openEuler(简称:“openEuler”或“开源欧拉”)【Agent 可观测 & 治理】系列的开篇文章《》中我们提出过一个判断:把生产环境的写入权限交给 Agent 时,需要给它配一层可管控的执行面——每一次写入都要先经过隔离、留痕与判定,再决定要不要真正落地。AgentCensor 用几个组件拼起了这层执行面,其中负责「隔离与可逆」、并回答「它改了什么」的,正是 CensorFS。
CensorFS 构建了一个具备隔离、回滚与恢复能力的闭环,是 AgentCensor 整体架构中的重要组成部分,用于完善 Agent 安全执行所需的工程基础设施。本文将围绕 CensorFS 的设计思路、核心机制及实际应用展开介绍。
来看一个经典的场景:为了让 Agent 比较三种实现方案的优劣,我们让它并行起三个 subagent,各给一套独立思路,同时对着同一个工程目录动手。结果往往不是三份方案的对照,而是一团纠缠——有人覆盖了别人改到一半的文件,有人跑到一半崩溃,在真实工作区里留下一堆半成品;即使当场没出事,事后也很难分清一个改动出自谁、为了哪个任务。

*本图由AI生成,仅供示意
需要隔离的场合并不止这一种。同一个工作区上出现并发写入者,通常包括以下三种情况:
一个 Agent 自己分叉——为并行比较方案或反复试错,今天主流的编码 Agent 都支持起多个 subagent;
多个 Agent(或多个会话)同时在一个仓库上工作;
人和 Agent 共用同一个工作目录。
三种情形的严重程度不同,撞上的却是同一个结构性问题:写入是并发的,而工作区只有一份。目前社区最常用的应对办法是「一个任务一个分支、一个工作目录」(git worktree 这一类做法),它简单有效,但也有自己的边界。
回到故障本身。起因各异,缺口却落在同一个位置:破坏发生在 Agent 那一串工具调用的内部。把「请你小心」写进提示词拦不住它;能兜底的还是文件这一层——写完了吗、写进了哪里、能不能回到写之前,这三个问题答不上来,Agent 的探索与改造就始终带着不确定性。
CensorFS 的做法是:Agent 看到的还是熟悉的目录结构,每一次写入却先落进只属于它的私有层。多个 Agent 在同一目录下分叉出各自独立的分支视图,未提交的结果彼此看不见。探索结束,成果先固化成候选,失败的探索直接丢弃、主线不受影响;最后由三方合并汇聚成果,需要时可随时回滚。

图1 CensorFS 多 Agent 并行探索与成果汇聚
选在哪一层做这件事,决定了它能不能真的兜住。CensorFS 把隔离与回滚放进文件系统这一层,理由不复杂——这一层离写入最近,也最难被绕过。具体而言,这样做有以下四个好处:
所有写入都在保护范围内: Agent 不只是改代码,还要执行命令、装依赖、生成产物、写缓存与日志;落在这一层就一并覆盖,不必逐一枚举。
提示词拦不住的动作,这里拦得住:应用层与提示词层的约束都依赖 Agent 配合,而绕过正是它的强项;内核的命名空间与凭证边界不吃这一套。
进程崩了、断电了,改动也丢不了: 写入先落盘、先记日志、带校验、重启后接续——这些保证只能在持久化层拿到。
Agent 和调度框架都不用改:POSIX 是编译器、脚本、IDE、shell 的公共接口,语义放在这一层;对调度框架而言,CensorFS 只是一层可以直接插入的组件(分层见图2)。
具体到 CensorFS,其核心能力主要集中在三个方面:写入只落在私有层(每个 Agent 拿到自己的目录视图,碰不到基线,也碰不到别人的改动)、发布是一次带校验的原子提交(基线被推进过就拒绝,历史不可改写)、中途断掉也能确定性接续(先记日志、关键结构冗余、全链路校验)。三者共用同一份核心实现——版本、隔离、持久化各写一处、彼此复用,全部由系统侧完成。
这套实现组织成分层结构(见图2):最上层是 Agent 进程,只看得到自己的目录;中间的系统侧组件负责建立隔离环境、维护状态与控制接口;版本、隔离、持久化的语义收敛在同一份实现;命令行与调度框架作为控制面接入,与数据面分离。

图2 CensorFS 核心设计:分层与协作
这套「先固化候选、再原子发布」的机制,让 CensorFS 能够回答「改了什么」。它怎么走完一次完整改动、又能用到哪些场景,下一节展开;文末还有一套实操案例。
这几层串起来,就是一次改动的完整链路——写入、发布、回滚都在系统侧完成:

图3 CensorFS 的一次写入:从私有层到原子发布,再到回滚
隔离、可逆、可恢复这三件事,最终都落在磁盘记录和内核边界上,成为 Agent 绕不开的硬约束。CensorFS 对 AgentCensor「隔离与可逆」这一块的交付,靠的就是这个。
在日常开发中,最常用的是五个场景:
多分支并行探索:多个 Agent 同时修改同一个工程,各自在独立的分支视图里工作,互不可见、互不干扰;
推测执行与失败试验:Agent 可以反复启动私有探索去验证想法,失败的探索整体丢弃,主线内容与版本记录毫发无损;
受控成果发布:探索结果先固化为候选,发布时校验基线未被他人推进,防止并发提交被静默覆盖;
多 Agent 成果汇聚:以最近共同祖先为基准做逐路径的三方合并,把不同路线的改动汇聚到一起,出现冲突时保持目标分支不变;
版本审计与回滚:每次发布都生成不可变版本,回滚以新版本落地、历史完整保留,全程可追溯。
概括来说:探索可以放开,主线始终可控;已经发生的改动,随时可以退回。
前文列了五个场景,这里把「多分支并行」与「受控发布」两者落到一个最简实例。
▐ 示例背景
以 DeepSeek Harness 为例:要给一个开源项目做一版网页首页,又不想一开始就把风格锁死,于是同时起三个 subagent,各给一套独立的交互方向:深色霓虹数据屏风、极简留白风、富信息文档风。三个 subagent 并行,各自在自己的私有目录里改 index.html 与 style.css,互不可见、也碰不到共享基线;等三份候选出炉,我们挑一版发布,剩下两份丢弃。全程不改原本的共享文件。
▐ 执行步骤
CensorFS 原生面向鲲鹏 AArch64 与 openEuler 系统,Rust 编写,安装后统一以 censorfs <子命令> 调用,具体参数以 censorfs --help 与 README 为准。构建与启动服务是:
# 构建只有一条命令bash scripts/build-openeuler-aarch64.sh --install-deps# 导入首页素材为 main 基线,并启动后台服务(命令行与插件都经它读写)export CENSORFS_STORAGE_ROOT=/data/homepage-demo/.censorfscensorfs init --import-root /data/homepage-demo/import --branch maincensorfs daemon
三个 subagent 并行产出,通过 DeepSeek Harness 的 /explore 一条命令,从同一个 main 基线拉起三个完整、隔离、可运行的世界:
/explore 3 为活动页 index.html 设计三个视觉风格差异明显、可一眼区分的版本。每个变体为实现自己的版本可同时修改 index.html 与 style.css,但不要动其他文件、不要互相影响。每个 world 都在自己专属的挂载命名空间里工作,subagent 看到的目录就是它的私有层,与别人改到一半的文件、共享基线完全隔离;
每份探索成果会先固化成一份不可变候选,并在独立的只读视图里跑验证(本场景为逐份解析各候选的 index.html);
三种风格、三份候选互不干扰——各出一版,由我们决定最终选哪个方案。
从图4 可以看到三个 subagent 在 DSH 的「Parallel Worlds」面板里并行:BASELINE → WORLDS → CANDIDATES → EVALUATION → MAIN 五个状态实时联动,每个世界各带「发布 / 放弃」按钮;右侧执行图可以看到相互隔离、谁先完成、候选是否就绪。

图4
三份候选各成一版——深色霓虹数据屏风、极简留白风、富信息文档风(同一份 index.html 与 style.css,三条彼此独立的改写路径)。见图5:

图5
三份候选在同一路径上的实际文件变更:三个 world 各自改了 style.css 的不同片段,彼此的改动没有重叠。见图6:

图6
我们比较完三份候选(图4—图6),选中深色这一版,只发布它,其余两份丢弃。这一步不一定要敲命令——Web UI 里每份候选都自带「发布 / 放弃」按钮,可以根据情况自行决策;也同样支持下面的命令行操作:
/censorfs-publish <run-id> <variant-id> # 发布选中候选:校验基线未被推进,防并发覆盖/censorfs-abort <run-id> # 丢弃其余候选(也可指定单个 variant)
这一步中的发布动作都会先校验基线版本,别人先落地的成果不会被静默覆盖。
体检与审计走同一条命令行(命令行提供底层构件,探索与发布本身由 DeepSeek Harness 承载):
censorfs head main # 查看当前版本头censorfs generation <gen> # 查看某个历史版本,留作审计censorfs fsck # 一致性体检(--repair 修复)
发布落地后,主线由 vN 前移到 vN+1——落盘一个全新的不可变版本,可回滚、可审计,原本的共享文件全程未动;这正好对应图1里「并行探索、成果汇聚」那件事。
▐ 实测状态
上述流程(三个 subagent 并行产出 → 各自候选 → 只读验证 → 校验后发布 → 主线内容更新为选中版本)已在 openEuler 24.03 AArch64 真机跑通。未发布时主线始终保持原版本——每个 subagent 的探索都不会自动发布,发布是一次显式的、可回退的决策。
Agent 的能力越强,对真实环境的操作就越深入,如何让它“敢于探索”,同时又让系统“守得住边界”,成为 Agent 工程化落地的重要课题。CensorFS 给出的解决思路,是把「隔离与可逆」能力下沉到文件系统层:让 Agent 的修改先进入独立的私有空间,探索结果经过验证后再受控发布,并通过版本机制保留完整的回滚路径。
因此,CensorFS 关注的并不仅仅是“如何保存一次修改”,更重要的是建立一套完整的修改生命周期:写入有边界、发布有控制、版本有记录、异常可恢复。
对于多 Agent 并行探索、代码执行和自动化任务等场景,这意味着 Agent 可以拥有更大的探索空间,同时将对主线环境的影响控制在明确范围内。CensorFS 也由此成为 AgentCensor“隔离与可逆”能力的重要基础,为 Agent 从实验环境走向真实生产环境提供底层支撑。

本篇为系列第三篇,聚焦 CensorFS:Agent 的写入如何先落进私有层,发布如何做到原子,系统侧如何完成回滚。
📌系列第四篇将聚焦 CensorScope 的富观测:把 Agent 的一次次改写变成看得见、说得清的证据——痕迹如何在调用链上采集、「一次命令执行改了什么」如何被追溯,证据链又如何串起审计闭环。


目前 CensorFS 已在 AtomGit 开源,仓库中提供了完整的构建脚本、systemd 部署文件与集成验证脚本。如果你正在构建 AI Agent、代码执行平台或多租户 Harness,欢迎基于示例流程跑一遍:隔离、原子发布、回滚,几步就能验证。
代码仓:
https://atomgit.com/openeuler/AgentCensor
开发&维护SIG:
sig-DevStaion
欢迎添加下方openEuler小助手,让小助手邀请你进DevStaion交流群



openEuler DevStation 是面向开发者快速尝鲜的创新版本,提供开箱即用的 AI 开发环境和 Agent 协同体验,帮助开发者更高效地开发传统软件、AI 应用与 Agent、硬件及基础软件。DevStation 将持续探索让系统环境、开发工具和异构算力更好地被 Agent 理解、调用和验证,并通过月度滚动发布持续带来前沿工具与技术。
-END-
供稿 | 杨云易
编辑 | 丘云
校审 | 袁礼鹏、郑振宇、刘彦飞
关注我们,了解更多
▼
