实证研究:AI Agent 规则需要上下文与分层强制执行

"提交前必须跑完整测试"这种规则看起来很简单,直到 AI 编程 agent 在上次测试后又改了源码,然后继续执行 git commit。内核只看见普通进程在写提交对象,harness 也只看见又一次工具调用,但真正决定这次提交能不能放行的,是哪次测试结果仍然有效、哪次编辑让它失效,以及规则在当前任务里该如何实例化。

ActPlane 论文量化了开发者写下的行为规则与系统实际能够检查的规则之间有多大落差。论文逐条分析了 2116 条指令语句后发现,开发者并不缺少规则,困难在于把自然语言要求转成系统可以持续观察和判断的状态。许多规则虽然涉及文件、进程或网络行为,却还要结合仓库结构、任务进度或先前事件才能判断当前操作是否合规,因此单次 OS hook 只能覆盖其中一部分。

开发者已经写下了这些策略

讨论 AI agent 安全时,大多数人从威胁模型或攻击面入手。ActPlane 换了一个出发点:开发者已经告诉 agent 该做什么、不该做什么了,那把这些指令变成可执行的规则需要什么?

论文调研了 64 个含 CLAUDE.mdAGENTS.md 的热门仓库(中位数约 2 万 GitHub 星标,快照 2026-05-23),覆盖 84 份指令文件和 2116 条独立语句。与此前只在文件或章节标题粒度做分析的研究不同,ActPlane 对每一条语句独立分类,提出三个问题:指令文件主要是行为策略还是描述性上下文?哪些策略需要 OS 级强制执行,需要什么类型的检查?将这些策略实例化为具体可执行规则又需要什么上下文?

语句的提取经过两遍 LLM agent 辅助流水线,为每条语句记录源行范围和四个标签:内容类型、主题、强制执行层级、上下文需求。验证脚本确认了完整的源覆盖和逐字 span 匹配,并由独立的 Claude 和 Codex agent 交叉检查。最后,100 条分层抽样语句经人工标注者独立审核,确认标签正确。

在这 2116 条语句中,64% 是策略,它们要求、禁止或约束某个具体 agent 行为。其余 36% 是描述性上下文,例如架构说明或项目背景。各仓库的策略密度从 0% 到 97% 不等,70.1% 的仓库策略数量多于描述。文件或章节标题粒度的研究不会报告这种语句级分布,这正是细粒度分类的价值。

为了解策略在各关注领域的分布,论文将每条语句分配到改编自先前指令文件研究的 12 个主题类别中,应用于语句粒度而非文件粒度。开发流程和实现细节两类的策略占比最高,分别达到 87% 和 85%。架构以描述性内容为主,策略仅占 23%,因为目录布局和设计摘要构成了这些章节的主体。下方导入的论文原图把策略语句标作 directive,并把系统可观测策略子集标作 system-level directive。正文仍沿用论文文字中的"策略"和"系统可观测"术语。

数据集中的五条真实语句展示了强制执行需求的差异幅度:

语句 强制执行层级 上下文
S4:不得直接推送到 main 分支。("Never push to main directly.") 单事件(per-event) 自包含(self-contained)
S5:不得修改上游源码。("Never modify upstream source code.") 单事件 项目级
S6:提交前必须运行完整测试套件。("Run the full test suite before committing.") 跨事件(cross-event) 项目级
S7:从 .env 读取的数据不得传到网络。("Data read from .env must not reach the network.") 跨事件 项目级
S8:未经批准不得更新依赖。("Do not update dependencies without approval.") 单事件 任务级

强制执行缺口首先来自上下文

每条策略按强制执行瀑布(enforcement waterfall)的第一个匹配层级退出。纯语义(semantic-only)涵盖推理、沟通或输出风格;内容检测(content inspection)涵盖文件内容上的谓词;单事件涵盖单个命令、文件访问或网络连接;跨事件涵盖依赖跨操作的时间顺序或数据来源的策略。内容检测、单事件和跨事件的并集叫做系统可观测(system-observable)。

1361 条策略中只有 17% 是纯语义的,其余 83% 是系统可观测的,其中 38% 需要内容检测,29% 匹配单个 OS 事件,16% 需要跨事件状态。只有单事件和跨事件两类能直接在 OS 挂载点上强制执行,合计 45%。跨事件策略集中在开发流程领域,占全部跨事件策略的 39.5%。

跨事件策略反复出现为四类关系。时序排序(temporal ordering)约束先后关系,像"提交前先跑测试"这样的要求关心的是一件事发生在另一件之后,而不是更早的某个时刻跑过就算数。跨文件一致性(cross-file consistency)把"行为变更时同步更新文档"中的源码编辑和文档更新联系起来。多步工作流(multi-step workflow)则要求发布清单逐项通过验证,上一步完成后才能进入下一步。条件触发(conditional trigger)只在前置条件成立时生效,例如"改了规范就必须同步 SDK"。单个事件无法判断这些关系,强制执行必须记录运行过什么、发生顺序以及此后的变化。这类策略并不少见,81% 的仓库至少包含一条,43% 的仓库横跨全部四个强制执行层级。

上下文依赖让强制执行更难落地。1127 条系统可观测策略中,只有 26.4% 是自包含的。多数(64.2%)需要项目上下文,"测试套件"或"上游源码"必须结合具体仓库解析,才能变成具体规则。另有 9.4% 需要任务上下文,例如"除非用户明确要求"或"未经批准不得操作"。

即便是单事件策略,如 S5"不得修改上游源码",也得先确定哪些路径属于"上游源码",文件写入检查才能生效。需要跨事件追踪状态的策略更少给出命令和路径,其中 95% 依赖上下文(77% 为项目级,19% 为任务级),内容检测策略的这一比例则是 58%。"提交前跑测试"听起来简单,强制执行引擎却必须知道哪条测试命令算测试、哪些目录的变更算相关编辑,以及测试是通过了还是仅仅运行过。

一组固定的静态规则只能覆盖自包含的部分。实例化其余策略需要先读取仓库、解释当前任务,然后才能运行任何检查。

Agent 策略强制执行的起点,是把仓库与任务上下文编译成确定性检查能够读取的具体状态。

一条规则会跨越多个强制执行层级

基于 prompt 的指令依赖模型自身的遵从能力,但容易受 prompt 注入攻击,且在长上下文窗口中与用户的任务 prompt 争夺注意力。独立的 agent 或 LLM 守卫可以在运行时检查 prompt、响应或行为轨迹,但这些检查本质上是概率性的。

工具调用层面的守卫和应用级信息流控制系统在 harness 边界确定性地拦截,但它们只能观察经过 harness 中介的请求,看不到工具开始执行之后的系统级效果。间接子进程、shell 外调或编译出来的二进制文件都能绕过工具边界。例如,agent 写下包含 subprocess.run(["git", "push"]) 的 Python 脚本,再运行 python script.py。工具调用层只看见"运行 python script.py",看不见脚本里的 git push

seccomp、AppArmor、Landlock、Tetragon 等 OS 机制控制的是资源访问而非开发者所描述的行为。它们要求静态预写策略,报错也只有一句令 agent 困惑的不透明 EPERM,不解释违反了哪条规则,也不说明如何恢复。

上下文和观测范围在这里错开了。项目与任务上下文掌握在 agent 一侧,因此需要 agent 把自然语言策略转成具体规则。但很多策略限制的是事件顺序或数据流,工具调用守卫看不见这些系统效果。于是,由 agent 解析出的规则还必须具体到能交给 OS 层确定性强制执行,ActPlane 要弥合的就是这个差距。

ActPlane 因此必须同时满足两项要求。策略规范要由 agent 编写,也要能在 OS 层强制执行,这样 agent 才能以尽量少的专业知识将自然语言策略落成具体规则,并借助语义反馈理解违规、完成恢复。强制执行本身还得安全、隔离且高效,agent 编写的策略不能削弱高权限约束,不能影响其他 agent 的策略,也不能拖慢正常工作负载。

把意图编译成可强制执行状态

每条 ActPlane 规则由五个部分组成:标识治理对象的来源声明、目标操作(如 exec、write、connect)、效果、可选的时序门(temporal gate)、以及用于语义反馈的原因字符串。论文的贯穿示例可以让这些组件具体化:

text 复制代码
kill exec "git" "commit" unless after exec "go" "test" exits 0 since write "**/*.go"

这条规则会终止任何 git commit,除非 go test 在最近一次相关源码编辑之后成功退出过。这里省略的原因字段会在规则触发时向 agent 提供结构化的解释。

三种效果对应了指令与约束的区分。阻断(block)是操作前的同步拒绝,没有 TOCTOU 窗口:内核在系统调用执行之前拦截它,agent 可以改道重试。终止(kill)在操作开始后杀掉进程,不给 agent 切换到其他通道的机会。通知(notify)只传递引导信息而不阻止操作。约束使用阻断或终止,指令使用通知。

时序门让规则表达顺序关系而不仅是时间点谓词。after ... since ... 结构编码了一个事件必须发生在另一个事件之后:测试必须在最近一次编辑之后运行过,而不是在更早的某个时间点运行过即可。exits N 限定符区分成功退出和失败退出。谱系门(lineage gate)检查进程祖先关系,允许规则将操作限制在特定的进程树中。

信息流标签(information-flow label)沿 forkexecreadwriteconnect 传播,且是单调的:一旦进程读取了带标签的对象,标签就不可移除。当进程读取 .env 时,它获得该文件的来源标签。如果它之后尝试连接到外部端点,匹配该标签的规则就会触发并阻断连接。研究中的 S7("从 .env 读取的数据不得到达网络")就是这样变成可强制执行的跨事件规则的。

策略权限依靠时序信任边界。在 agent 启动前加载的规则是高权限规则,对 agent 不可写。在子域中,agent 及其子 agent 可以添加新规则或收窄现有规则,但不能削弱、移除或禁用继承的约束。运行时增量通过环形缓冲区(ring buffer)到达内核,经完全在内核中运行的权限检查器校验每一项变更是否符合域层级,通过后才会激活。信任计算基础由内核强制执行引擎和高权限策略组成,该边界以下的一切都是不可信执行。因此,被攻陷的用户空间 agent 无法在其域层级允许的范围之外修改活跃规则集。

由于标签是单调的,长时间运行的会话有过度标记的风险:经过大量读取后,进程可能累积过多标签,导致后续每个操作都触发规则。在典型的编码会话中,一个进程可能读取几十个配置和源文件。没有缓解措施时,每次读取都会添加标签,读取足够多之后,每次写入或连接都会匹配某条规则。为缓解这个问题,ActPlane 在生成新子进程时清除继承的标签,将标签累积限制在每个进程的生命周期内而非整个会话。

607 条策略的数据集运用了大多数 DSL 特性,验证了语言的表达力。效果偏向观测:66% 的子句是通知,29% 是阻断,仅 5% 是终止,反映出大多数策略监控而非阻止。就挂载点分布而言,代码执行占 60%(exec),文件变更占 37%(write),网络和清理操作各不到 1%。跨事件特性使用广泛:28% 的策略使用 after/since 时序门,214 条使用 unless 编码例外。

实现规模小到可以完整把握。用户态编译器和运行器合计约 3.2K 行 Rust,内核强制执行引擎约 1.8K 行 BPF C。BPF-LSM hook 处理操作前决策(阻断),tracepoint 处理观测和操作后终止(kill)。标签压成 64 位掩码放进逐对象的 BPF map 后,传播只需一次按位 OR,所以这套实现仍能支持最多 128 条并发规则,而数据集中观测到的最大仓库只有 66 条策略。关于部署架构和机制细节的更深入介绍,见 ActPlane:把 Agent Harness 强制执行下沉到内核 eBPF

违规后的恢复拉开了差距

恢复要起作用,DSL 先得接得住开发者已经写好的策略。一个 Codex agent 在首次或二次尝试中,为全部 607 条可由操作系统强制执行的策略编译了 ActPlane 规则,其中只有 2 条需要语法重试。翻译使用 7 个子 agent(4 个并行)在 34 分钟内完成,将 607 条策略扩展为 1283 条规则行。成本约每条 0.028 美元,使用 1.7M 输入 token 和 177K 输出,相比之下人工编写约每条 11 美元。大多数策略结构简单,74% 最多只有两个强制执行子句,第 95 百分位也在 152 token 以下。

带上下文的强制执行解决的违规远多于任何基线。在决策合规基准(190 条轨迹、38 条源自实证研究的规则)上,主要 Qwen3.6-27B 设置下的决策合规率(Decision Compliance Rate,DCR)为 75.8%。在这项设置中,被测 agent、prompt-filter 分类器和轨迹评审器都使用 Qwen3.6-27B。每条规则的五条轨迹由 GPT-5.5 驱动的 Codex CLI 预先生成,非 prompt 系统的策略工件则由 Claude Opus 4.6 单独翻译:

系统 DCR
ActPlane 75.8%
ActPlane-opaque(无反馈) 53.7%
FIDES(工具级信息流控制) 48.9%
Prompt-filter 48.4%
Tool-regex 45.3%

基准为每条规则生成五条轨迹:两条合规轨迹用于检验误报(一条在边界附近执行允许的操作,一条执行技术上合规但形似违规的操作),三条违规轨迹(violation trace)对应实际部署中观察到的编码 agent 执行路径类别。直接违规通过工具调用触发被禁止的操作,脚本违规将编写和执行拆分到子进程中,隐藏违规则将副作用嵌入中性入口点后面的辅助工件中。

差距集中在违规轨迹上。ActPlane 正确解决 114 条中的 86 条,基线为 27 到 44 条,提升了 2.0 到 3.2 倍。所有系统在合规轨迹和直接违规上表现相当,真正拉开差距的是脚本和隐藏轨迹,因为被禁止的效果发生在子进程内或中性入口点后面,工具调用拦截观察不到。

语义反馈是合规与盲目重试的分水岭。完整 ActPlane 产生的正确违规轨迹结果是无反馈引擎的三倍(86 对 27)。在 ActPlane 已经检测到的违规里,恢复率(agent 随后转为合规的比例)在有语义反馈时为 97.7%,无反馈时只有 31.4%。当 agent 知道操作为何被拒、需要修复什么状态时,它会改道完成任务;只收到一句空洞的拒绝时,则会通过替代路径反复重试同一个被禁止的操作。

恢复回路要有用,强制执行本身还得便宜到能进日常编码。在策略已加载但没有规则命中的配置下,端到端开销的测量覆盖两个工作负载:重放 68 个工具动作和 20 个 Bash 子进程的 agent 轨迹套件,以及 Linux 内核构建(defconfig + vmlinuxmake -j24)。32 条活跃规则下,ActPlane 在 agent 轨迹上增加 1.9%,在内核构建上增加 6.5%。即使增加到 100 条规则,开销仍低于 8.4%。

微基准测试定位了单次系统调用开销的分布。从 1 条到 100 条规则的不同配置看,forkexec 的绝对增加量为 3.12 到 68.73 微秒。具体到 100 条规则,fork 增加 20.39 微秒,exec 增加 68.73 微秒,对应的原生延迟分别为 48.94 和 248.30 微秒。同样是 100 条规则时,绝对延迟分别为 open 13.4 微秒、write 0.84 微秒、connect 3.17 微秒,路径查找和规则扫描把原本亚微秒级的文件与网络调用抬高到了这个量级。整个工具调用的系统调用序列累积开销比单次 2 到 10 秒的 LLM 推理轮次小五到六个数量级。策略更新传播迅速:通过用户空间环形缓冲区提交的单规则热重载平均 26.3 微秒进入内核处理路径,一次即时 exec 违规的检测延迟 p50 为 176.4 微秒(含进程启动和事件传递)。

这一优势在第二个模型上也得到复现。DeepSeek-Pro V4 端到端实验保持系统排名不变,ActPlane 以 77.4% DCR 居首,两个模型设置之间的逐单元一致性对应 Cohen κ 系数 0.822。

翻译质量同时驱动检测率和恢复率,因为规则过窄会遗漏违规,规则过宽会匹配合规操作。为衡量可改进性,论文将每条假阴性轨迹的证据和纠正反馈提供给翻译 agent,让其修订规则一次。用修订后的规则重新运行 28 条假阴性轨迹,恢复 26 条(93%),表明该 DSL 支持迭代完善。

选定的真实编码任务表明,合成轨迹中的模式可能延伸到真实任务。在 OctoBench 的 21 个任务子集上(61 条可由操作系统强制执行的规则,覆盖 7 个仓库),ActPlane 的用户查询奖励比无强制执行基线提高 9.9 分,实现与测试奖励提高 9.7 分。这一子集上的收益超出了合规类型检查,说明带语义反馈的操作系统级强制执行可以在帮助 agent 遵守规则的同时,帮助它们完成任务。

外部安全基准进一步检验了这套方法在论文数据集之外的适用性。在 361 个 OpenAgentSafety 个人助理任务中,ActPlane 以高权限规则预加载 agent 生成的安全策略,阻止了 74% 的基线不安全行为(106 起不安全结果中拦截 78 起)。这些策略只根据任务描述生成,没有人工调优。这个接近部署环境的约束也带来代价:对于基线本已安全的任务,有 16% 仍触发了 ActPlane,因为仅依据描述生成的策略匹配到了禁止边界附近的正常操作。28 起未拦截案例分为三类:聊天或语义伤害(不安全行为是没有操作系统可观测工件的消息)、不安全文件内容(不在 ActPlane 的主要覆盖范围内)、以及服务端工件(效果是服务容器内的 WebDAV 上传或数据库变更,当前挂载点集合观察不到)。

ActPlane 源码已在 GitHub 开源。仓库中的 policies/ 目录包含全部 64 个仓库的 607 条翻译规则,可以作为编写自己指令文件的起点。

分层强制执行的边界在哪里

eBPF 足以解决 AI agent 安全问题吗?

eBPF 可以对文件写入、进程启动和网络连接等 OS 事件做确定性强制执行。单事件和跨事件两类构成可直接下沉到 OS 的 45%。更宽的 83% 系统可观测集合还包含 38% 的内容检测策略,它们需要代码检查器或静态分析器;其余 17% 涉及推理、沟通风格或输出质量,需要 harness 层处理。任务意图、策略权限、内容语义和隔离仍由内核强制执行点周围的层承担。

行为基线能替代策略吗?

行为基线回答的是"这是否异常",它标记的是偏离历史模式的操作。策略回答的是"在当前任务下这是否被允许"。一次常规 git commit 按基线标准可以完全正常,同时违反一条项目规则。一个陌生的部署端点可以触发异常告警,但如果用户明确要求了它,操作就是合法的。检测和授权是两个不同的问题,成熟系统会同时使用两者:异常信号可以提议候选规则,再经过权限感知审查,成为被强制执行的策略。

AgentSight 会强制执行 ActPlane 的策略吗?

不会。AgentSight 是系统级分析器和监测器,捕捉 agent 在运行时的行为。ActPlane 是强制执行引擎,拦截或重定向违反已加载策略的操作。两者是互补角色:AgentSight 的运行时证据可以为策略审查和优化提供输入,但观测和强制执行的职责保持分离。一个组织可以先用 AgentSight 发现 agent 频繁写入生产配置文件,然后编写对应的 ActPlane 规则来阻止该模式并附上禁止原因的解释。

ActPlane 仍然覆盖不了什么?

论文的威胁模型对边界做了明确声明。语义等价操作可以绕过基于字符串的匹配:agent 可以使用自制 Git 客户端而非调用 exec git,但底层的 connectwrite 系统调用仍然可见。协议边界后面的服务端效果(如服务容器内的 WebDAV 上传或数据库变更)也超出了当前 hook 集的覆盖范围。文件内容语义、内核攻陷、CAP_BPF 攻陷和侧通道均不在覆盖范围内。17% 的纯语义策略(涵盖推理质量、沟通风格或输出格式)需要 harness 层而非内核强制执行来处理。

对治理 AI 编程 agent 的团队来说,真正的决策比"再加一点 eBPF"更窄。先从 CLAUDE.mdAGENTS.md 里已有的语句出发,补上它们省略的项目与任务上下文,再把可由操作系统强制执行的子集编译成带反馈的内核检查。以往的指令文件研究停留在文件或章节粒度,而 ActPlane 数据集则度量单条策略语句,并把它们映射到强制执行和上下文需求。ActPlane 仓库包含完整实现,将内核强制执行与隔离、身份和内容控制并置的三层安全模型见基于 eBPF 的不透明 AI Agent 运行时可观测与强制执行

参考文献

相关推荐
小张成长计划..17 小时前
【Linux】12:进程状态
linux·运维·服务器
会周易的程序员17 小时前
Libnodave S7 通信库:架构设计与实现解析
linux·c++·物联网·架构·c·s7·工业协议
三声三视17 小时前
交互式用够了?用 Agent SDK 把 Claude 塞进 Python Web 服务
人工智能·python·ai·aigc·ai编程
云栖梦泽17 小时前
Camera驱动开发与应用开发中的零拷贝与DMA
linux·驱动开发·嵌入式硬件
is8118 小时前
编程小白也可以做项目,AI 辅助开发太香了
ai编程
kyriewen18 小时前
别再写useMemo了——2026年这5个React性能优化已经是反模式
前端·react.js·ai编程
赫文派18 小时前
K3 与 Kimi Code 实战:模型到终端 Agent
人工智能·ai编程
Patrick在香港19 小时前
Python实战:用数据分析拆解一场AI大会——WAIC 2026参展企业画像、议题演变与城市格局
人工智能·python·数据挖掘·数据分析·ai编程
赫媒派19 小时前
Codex 升级:GPT-5.6 指令+SDK 稳定版
ai编程