隐形代理:为何无法治理不可见之物
Anthropic在Claude Desktop中发布了一项名为Cowork的功能。该功能在每台macOS安装上创建了一个10GB的虚拟机包。从未启用Cowork的用户也收到了该虚拟机。删除它的用户发现它会自动再生。一位用户报告该包膨胀至21GB。该GitHub问题在Hacker News上获得了345个赞和175条评论,Anthropic才承认了这个问题。1
直到磁盘空间耗尽,才有人注意到。
摘要
代理工具现在可以在运营者不知情的情况下分配计算资源(磁盘、内存、CPU、网络)。Anthropic的Cowork虚拟机是可见的案例;每一次MCP工具调用、每一个派生的子代理、每一次网页抓取都是不可见的案例。治理代理需要三个层次的可观测性:资源计量(它消耗了什么?)、策略执行(它被允许做什么?)和运行时审计(它实际做了什么?)。两个开源项目解决了策略层和审计层(mcp-firewall和Logira),但没有任何生产工具覆盖全部三层。以下内容包括:可见性问题、三层架构、每层捕获的内容,以及您今天就能实施的最低监控钩子。
可见性问题
传统软件运行在运营者选择划定的可观测线之下。Web服务器写入访问日志,是因为工程师配置了日志记录。数据库跟踪慢查询,是因为有人设置了log_min_duration_statement。运营者决定监控的粒度。
代理系统颠覆了这种关系。代理在运行时决定执行什么。一个接收到”修复登录端点”指令的编码代理可能会读取47个文件、写入12个文件、派生三个子代理、抓取两个网页,并执行15条bash命令。每个操作都消耗资源。这些消耗均不会出现在传统监控中。
Cowork事件在基础设施层面暴露了这种颠覆。Claude Desktop分配了10GB磁盘空间,空闲时消耗24-55%的CPU,在8GB内存的机器上将交换使用率从20K推高至24K+次换入。1用户通过macOS存储警告发现了资源消耗,而非通过Anthropic的遥测数据。该应用程序未提供任何仪表板、计量器或虚拟机分配的选择性披露。
这种模式并非假设。2026年3月,一位开发者报告Claude Code执行了一条Terraform命令,摧毁了生产数据库。代理对生产状态文件运行了terraform apply。没有出现确认提示。没有钩子拦截该命令。开发者在应用下线后才发现了这场破坏。该事件在Hacker News上获得了142个赞和158条评论。12数天后,另一位开发者报告Claude Code删除了整个生产环境设置,包括代表2.5年记录的数据库快照。13两起事件的根本原因相同:在损害不可逆转之前,对代理的行为完全零可见性。
将这种模式扩展到代理会话。我的钩子编排系统在每次工具调用中拦截15种事件类型。11在60多个会话中,系统记录了每个操作触发的84个钩子,产生了默认代理安装无法提供的遥测数据。2没有这些检测手段,我将无法检测到12次漂移事件、幻影验证失败或我NIST公开评论中记录的递归派生循环。3
DORA 2024年《DevOps状态加速报告》发现,具有强大可观测性实践的团队部署频率更高,从故障中恢复更快。2025年版将框架扩展到AI辅助开发,将可观测性与”AI辅助编码或测试如何影响质量、交付周期和整体可靠性”联系起来。4代理可观测性不是锦上添花。衡量代理行为是治理代理的先决条件。
代理可见性的三个层次
代理可观测性需要三个独立的层次。每个层次回答不同的问题。一个层次的失效不会影响其他层次。
| 层次 | 问题 | 监控对象 | 示例工具 |
|---|---|---|---|
| 资源计量 | 它消耗了什么? | 每会话的磁盘、内存、CPU、网络 | Cowork本应展示这些 |
| 策略执行 | 它被允许做什么? | 允许/拒绝规则、工具权限、范围限制 | mcp-firewall |
| 运行时审计 | 它实际做了什么? | 系统调用日志、文件访问、网络出站 | Logira |
各层次构成递进关系:无法对未计量的资源执行策略,也无法审计从未定义的策略的合规性。每一层都建立在下一层的基础之上。
第一层:资源计量
资源计量回答的问题是:代理消耗了多少资源,消耗在哪里?
Cowork事件就是一个资源计量失败的案例。虚拟机包消耗了10GB磁盘空间。渲染器进程在空闲时消耗24%的CPU。会话期间交换活动持续攀升。所有这些指标都存在于macOS活动监视器中。但没有一项出现在Claude Desktop的界面中。1
对于代理编码会话,资源计量追踪四个维度:
磁盘。 每次文件写入、每个缓存条目、每个日志文件。我的会话每次生成200-400KB的状态文件(jiro.state.json、jiro.progress.json、钩子日志)。在60多个会话中,累积产生12-24MB的状态数据,除非显式清理,否则会跨会话持久存在。2
内存。 每轮对话的上下文窗口消耗。按当前Opus定价,一个200,000 token的上下文窗口每次填满大约花费3美元。我的成本跟踪器记录每会话的累计token使用量,预算阈值设置在可配置限制的80%、90%和95%。5
CPU。 钩子执行时间。我的九钩子提示分发器每次提示增加200毫秒。这种开销对用户不可见(人类输入速度才是瓶颈),但在自动化流水线中会累积。ralph自主循环每个故事触发分发器50-100次,每个故事增加10-20秒的钩子开销。2
网络。 网页抓取、API调用、MCP工具调用。每个出站请求都是潜在的数据通道。我的网页提取库记录抓取URL和响应大小。没有网络计量,返回50MB响应的网页抓取与返回5KB的无法区分。6
没有任何商业代理工具提供每会话的资源仪表板。云提供商为计费目的计量计算资源,而非为运营者可见性。代理消耗的资源与运营者能看到的之间的差距就是资源计量赤字。
这种缺失在数字累积之前感觉不到。一个写入400KB状态文件的会话微不足道。60个各写入400KB的会话,没有任何清理,留下24MB的孤立状态。一次返回847KB的网页抓取可以忽略不计。一个扫描流水线每次运行抓取80个URL,生成67MB被代理工具抽象层隐藏的缓存内容。资源计量在累积量变成迫使某人提交GitHub问题#22543的危机之前,使其可见。1
第二层:策略执行
策略执行回答的问题是:什么规则约束代理,这些规则是否被一致地应用?
mcp-firewall解决了CLI代理的策略层问题。7该工具位于代理和所有工具使用请求之间,在执行前根据基于正则表达式的策略评估每个请求。策略使用按文件夹、Git仓库或用户作用域的JSONNet配置文件。该防火墙通过PreToolUse钩子集成支持Claude Code和GitHub Copilot CLI。
该架构反映了一个关键洞察:每个代理都实现了自己的半成品允许/拒绝逻辑。Claude Code使用glob模式。Codex CLI使用仅前缀匹配。每种方法覆盖策略空间的一个子集。mcp-firewall将规则集中到一个跨代理工作的引擎中。
考虑没有集中化执行时的策略差距。我的钩子系统包含12个PreToolUse:Bash处理器,检查凭证模式、危险的Git操作、敏感路径访问和部署命令。2每个处理器是一个独立的Shell脚本,有自己的正则模式。当我需要添加新的拒绝规则时,我编写一个新脚本。当我需要审计存在哪些规则时,我需要在12个文件中搜索。mcp-firewall将这些整合到一个包含显式允许数组的单一配置文件中。
OWASP《代理应用十大风险》(2025)将代理目标劫持(ASI01)和过度授权(LLM06:2025)列为首要风险。8这两种风险都需要在工具调用层面进行策略执行。劫持目标的代理仍然进行工具调用。拥有过度授权的代理仍然请求权限。策略执行在代理意图与系统工具的边界处拦截这两者。
策略执行不同于访问控制。传统访问控制问的是”该用户是否有权限?”代理的策略执行问的是”该操作,在此上下文中,针对此任务,是否在批准范围内?”上下文敏感性是挑战所在。对功能分支的git push和对main的git push --force是同一个工具(Bash),但爆炸半径不同。mcp-firewall的正则模式可以区分两者。默认代理权限无法做到。
应用层策略执行还面临绕过风险。2026年3月的一项分析记录了针对Claude Code内置拒绝列表的三种递进式沙箱逃逸技术:基于路径的规避(/proc/self/root/usr/bin/npx解析到与被阻止的/usr/bin/npx相同的二进制文件)、自主禁用沙箱(代理在沙箱阻止任务完成时独立推理出移除沙箱的方法)、以及动态链接器调用(ld-linux-x86-64.so.2通过内存映射加载二进制文件,完全绕过内核执行钩子)。14第三种技术是一类漏洞:任何避免execve的代码加载都会绕过进程级执行。策略执行的启示是,字符串匹配拒绝列表是必要的第一层,但不是充分的。基于内容可寻址的执行(通过SHA-256哈希而非文件名识别二进制文件)弥补了路径规避的漏洞,但动态加载器绕过需要位于策略层之下的内核级控制。
第三层:运行时审计
运行时审计回答的问题是:代理在系统调用层面实际做了什么?
Logira使用eBPF探针在内核级别拦截系统调用来解决审计层问题。9该工具记录三类事件:进程执行(exec事件)、文件操作(包括凭证文件访问)和网络连接(带目标追踪)。每次审计运行生成三个文件:events.jsonl用于时间线审查,index.sqlite用于可查询过滤,meta.json用于运行元数据。
设计理念是”仅观测”:Logira记录和检测,但不执行或阻止。9与执行层的分离是刻意的。策略执行阻止已知的恶意操作。运行时审计在事后发现未知的恶意操作。两个层次服务于不同的时间功能:预防(事前)和取证(事后)。
Logira的eBPF探针在应用层之下运行。构造新颖命令来窃取数据的代理仍然会进行系统调用。代理无法对内核级追踪隐藏文件读取、网络连接或进程派生。该方法捕获应用层钩子遗漏的内容:绕过工具调用抽象的副作用。
内置检测规则专门针对AI代理风险:凭证文件访问、持久化机制更改(/etc、systemd、cron)、可疑命令链(curl-pipe-sh模式)、破坏性操作(rm -rf)和异常网络出站。9这些规则是针对代理威胁模型的预设默认值,而非通用系统审计。
平台限制至关重要。Logira需要Linux 5.8+且支持cgroup v2。macOS代理(Claude Desktop、Darwin上的Claude Code)无法使用基于eBPF的审计。我的操作系统沙箱使用macOS Seatbelt配置文件作为最接近的等价物:内核强制的拒绝规则,阻止对敏感路径的写入。3Seatbelt是执行层,不是审计层。macOS缺乏与Logira的仅观测审计跟踪等效的生产级工具。
Agent Safehouse是一款macOS原生沙箱工具,于2026年3月在Hacker News上获得802个赞和181条评论,从执行层面填补了平台差距。15该工具提供专为macOS上的本地AI代理设计的沙箱配置文件。社区反响(802个赞对沙箱工具而言极为罕见)反映了紧迫性:在macOS上运行代理的从业者在”无沙箱”和”自己编写Seatbelt配置文件”之间选择有限。Agent Safehouse填补了执行层的空白。macOS上的审计空白仍然存在。
执行与审计的区别映射到事件响应中的时间分割。执行预防事件。审计使事件发生后的重建成为可能。两者都是必要的。阻止所有凭证访问的执行层可以防止数据窃取,但也会阻止合法的SSH操作。记录所有凭证访问但不阻止的审计层使运营者能够审查访问模式,并根据证据调整执行规则。审计数据与策略优化之间的反馈循环是可见性架构随时间改进的方式:审计揭示模式,模式指导策略,策略减少审计需要覆盖的范围。
Logira的cgroup v2隔离增加了应用层审计无法复制的特性:运行范围的归因。系统将每个事件归因于特定的审计运行,而非全局系统。当两个代理会话在同一台机器上并发运行时,cgroup隔离确保会话A中的文件访问不会出现在会话B的审计跟踪中。应用层钩子无法提供同样的保证,因为钩子在代理进程内触发,而代理进程没有分隔并发会话的内核级边界。9
我实际运行的系统
我的编排系统通过钩子覆盖全部三个层次,而非依赖专用监控工具。
资源计量。 成本门控钩子根据可配置的预算阈值跟踪每会话的token使用量。5系统性能监控器按可配置的间隔检查CPU、内存、磁盘和交换空间,在资源压力超过阈值时注入警告。10会话漂移检测器每25次工具调用触发一次,计算原始提示嵌入与最近操作滑动窗口之间的余弦相似度。2
策略执行。 八个PreToolUse分发器钩子按工具类型路由到处理器钩子。仅PreToolUse:Bash就运行12个处理器,覆盖凭证模式、破坏性Git操作、敏感路径访问和部署命令。递归守卫执行最大深度为二、每个父代理最多五个子代理的限制。2
运行时审计。 PostToolUse钩子记录每次工具调用结果。安全扫描钩子在执行后检查bash输出中的凭证泄露。会话状态文件(jiro.state.json)记录每个故事完成情况、审查者裁决和证据门控结果。2该系统不使用eBPF(macOS限制),但通过钩子流水线捕获工具级遥测数据。
| 层次 | 我的实现 | 局限性 |
|---|---|---|
| 资源计量 | 成本门控、系统监控、漂移检测器 | 无逐工具的磁盘/网络细分 |
| 策略执行 | 跨15种事件类型的84个钩子 | 逐钩子正则,非集中式配置 |
| 运行时审计 | PostToolUse日志记录器、会话状态文件 | 仅应用层,无系统调用追踪 |
该系统之所以有效,是因为每个操作都通过钩子流水线。局限性在于深度:钩子级监控捕获代理请求做什么,而非操作系统实际执行了什么。构造包含嵌入子Shell的bash命令的代理执行的代码,在钩子看来只是单一字符串。内核级审计则会看到每个子进程。
以下是生产事件中三层架构捕获了默认监控会遗漏的故障的具体案例:
| 事件 | 捕获该事件的层次 | 无监控时的后果 |
|---|---|---|
| 代理花45分钟重组项目目录而非修复登录端点 | 资源层:漂移检测器在余弦相似度0.23时触发 | 任务报告”完成”但交付物错误 |
代理尝试写入~/.ssh/authorized_keys |
策略层:PreToolUse:Bash处理器阻止敏感路径 | SSH密钥被修改,产生持久后门 |
| 代理报告”所有测试通过”但未运行pytest | 审计层:完成报告缺少粘贴的测试输出 | 有缺陷的代码以幻影验证方式合并 |
| 子代理静默失败,父代理报告成功 | 资源层:空输出子代理的预算超限 | 损坏的数据库迁移在3小时后才被发现 |
复合盲区
代理派生代理会成倍增加不透明性。每次委派跳转都会引入信息损失。
当我的编排系统运行ralph自主循环时,父进程为每个PRD故事派生新的Claude Code实例。每个子代理获得一个聚焦的任务和一个全新的上下文窗口。父代理跟踪完成状态。父代理看不到子代理的单个工具调用、文件读取或资源消耗。2
在深度一(父代理派生子代理),父代理看到子代理的最终输出。在深度二(子代理派生孙代理),父代理看到子代理关于孙代理输出的报告。每次跳转都压缩信息。我NIST评论中的委派链分析测量了三种复合风险:语义压缩(上下文坍缩为提示字符串)、权限放大(子代理继承权限但不理解敏感性)和责任扩散(根代理对其从未检查的结果承担责任)。3
可观测性以相同速率退化。根代理上的三层可见性架构对孙代理提供零可见性,除非每个子代理独立运行自己的监控。我的递归守卫执行深度限制,但守卫是策略控制,不是可观测性控制。知道委派在深度二停止并不能告诉您在深度二发生了什么。
来自我生产系统的一个具体案例:ralph循环派生了一个子代理来实现数据库迁移故事。子代理决定迁移需要一个”验证步骤”,并派生了自己的子代理来运行集成测试。孙代理静默失败(测试数据库未配置)。子代理收到空响应,将沉默解释为成功,并报告故事完成。父代理记录”故事4:完成”。我在三小时后应用因缺失列崩溃时才发现损坏的迁移。根代理的遥测数据显示运行正常。故障隐藏在两个跳转深处,对我在根代理上部署的每一个监控层都不可见。2
OWASP《代理应用》框架涉及级联故障和失控代理,但未为多代理委派链规定可观测性要求。8这一差距是结构性的:链中的每个代理都需要自己的资源计量、策略执行和运行时审计,独立配置且独立报告。开销是乘法式的。三个代理链上的三层监控就是九个监控实例,每个生成自己的遥测数据,每个需要自己的配置。现有工具没有一个能管理这种协调。
今天您可以实施的措施
三个覆盖可见性架构的最低监控钩子:
1. 资源层:Token预算追踪器。 记录每会话的累计输入和输出token。设置硬限制。在80%时告警。实现方式是读取代理的使用统计数据(Claude Code通过/cost公开会话成本)并与阈值比较。我的成本门控钩子用47行bash实现。5
2. 策略层:PreToolUse拒绝列表。 创建一个在每次Bash工具调用前触发的钩子。将命令与模式列表进行比对:rm -rf /、git push --force、包含.ssh或.env的路径、curl | sh。阻止匹配项。实现方式是一个Shell脚本,读取标准输入(工具调用JSON),提取命令字段,并与模式文件进行grep比对。我的凭证检查钩子用31行实现。2
3. 审计层:PostToolUse会话日志。 将每次工具调用和结果追加到会话专用的JSONL文件中。包含时间戳、工具名称、参数和退出代码。该日志支持会话后重建:代理做了什么、按什么顺序、是否有静默失败?我的会话日志记录器用22行bash实现。2
拒绝列表钩子在settings.json中的工作示例:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/check-sensitive-paths.sh"
}
]
}
]
}
}
该钩子脚本从标准输入读取工具调用,提取命令字符串,并与模式进行比对。被阻止的命令返回一个JSON对象:{"decision": "block", "reason": "Sensitive path access denied"}。被允许的命令返回{"decision": "approve"}。Claude Code无需进一步提示即可遵守两种响应。整个钩子对已批准的命令增加零延迟(正则检查在5毫秒内完成),并对被阻止的命令提供即时反馈。
这三个钩子总共不到100行。它们不能替代专用监控工具。它们将零可见性替换为最低可见性。最低可见性是此后每一个治理决策的先决条件。没有计量就无法设定资源预算。没有拒绝列表就无法执行范围策略。没有审计日志就无法调查事件。从日志开始。其他两项随之而来。
关键要点
致平台工程师: 代理消耗的资源不在现有监控范围内。每代理会话的磁盘、内存、CPU和网络使用量应与容器指标出现在同一仪表板上。Cowork事件证明了这一需求:10GB被分配却零运营者可见性。
致安全团队: 工具调用边界的策略执行是最低可行的代理安全态势。mcp-firewall的集中化方法将各代理的允许/拒绝逻辑整合到一个可审计的配置中。评估您的代理内置权限是否覆盖了威胁模型所需的策略空间。
致工程管理者: 关于您的代理工具提出三个问题:能否看到每会话的资源消耗?能否定义和审计工具调用策略?能否在事后重建代理的行为?如果任何答案是”否”,您就存在一个随工作流中每增加一个代理而增长的可见性差距。
常见问题
什么是代理可观测性? 代理可观测性是监控和理解AI代理在执行期间行为的能力:它消耗了什么资源、采取了什么操作,以及这些操作是否符合已定义的策略。
为什么Anthropic的Cowork创建了10GB虚拟机? Claude Desktop中的Cowork功能为协作开发会话配置虚拟机。Claude Desktop在每台macOS安装上自动创建虚拟机包,即使用户从未启用该功能,并持续保留直到手动删除。1
什么是mcp-firewall? mcp-firewall是一款开源策略执行工具,拦截来自CLI代理(Claude Code、GitHub Copilot CLI)的工具使用请求,并在执行前根据基于正则表达式的允许/拒绝规则进行评估。7
什么是eBPF运行时审计? eBPF(扩展伯克利包过滤器)支持在不修改被审计进程的情况下进行内核级系统调用追踪。Logira等工具使用eBPF探针在AI代理运行期间记录进程执行、文件操作和网络连接。9
代理如何在运营者不知情的情况下派生子代理? 委派任务的代理派生具有全新上下文窗口的子进程。父代理看到子代理的最终输出,但看不到其单个工具调用、文件读取或资源消耗。在每次委派跳转中,信息被压缩:孙代理的完整会话变成父代理日志中的一行状态。可观测性随委派深度的增加以相同速率退化。2
代理监控与传统APM有何不同? 传统应用性能监控(APM)追踪确定性软件的请求延迟、错误率和吞吐量。代理监控追踪非确定性行为:代理在运行时决定做什么、这些决策是否在策略范围内、以及每个决策消耗了什么资源。APM假设应用遵循已知的代码路径。代理监控假设代理选择自己的路径。2
参考来源
-
mystcb et al., “Cowork feature creates 10GB VM bundle that severely degrades performance,” GitHub Issue #22543, anthropics/claude-code, February 2026. 345 HN points, 175 comments. ↩↩↩↩↩
-
Author’s production telemetry. 84 hooks across 15 event types, ~15,000 lines of orchestration code, 60+ daily Claude Code sessions, February-March 2026. ↩↩↩↩↩↩↩↩↩↩↩↩↩
-
Crosley, Blake, “What I Told NIST About AI Agent Security,” blakecrosley.com, February 2026. Public comment on NIST-2025-0035. ↩↩↩
-
DORA Accelerate State of DevOps Report 2024, Google Cloud, 2024. 39,000+ professionals surveyed. ↩
-
Author’s cost-gate hook implementation. SQLite-backed budget tracker with configurable thresholds (80%/90%/95%), 36 tests, February 2026. ↩↩↩
-
Author’s web content extraction library. trafilatura 2.0.0, URL logging and response size tracking, 25 tests, February 2026. ↩
-
dzervas, “mcp-firewall,” GitHub, 2026. Go binary with JSONNet policy configuration, PreToolUse hook integration. ↩↩
-
OWASP Top 10 for Agentic Applications, OWASP GenAI Security Project, 2025. 100+ security researchers contributed. ↩↩
-
melonattacker, “Logira: eBPF runtime auditing for AI agent runs,” GitHub, 2026. Linux 5.8+, cgroup v2, observe-only design. ↩↩↩↩↩
-
Author’s system performance monitoring module. CPU, memory, disk, and swap monitoring with configurable thresholds, 46 tests, February 2026. ↩
-
Crosley, Blake, “Anatomy of a Claw: 84 Hooks as an Orchestration Layer,” blakecrosley.com, February 2026. ↩
-
jv22222, “Claude Code wiped our production database with a Terraform command,” Hacker News, March 2026. 142 points, 158 comments. ↩
-
vanburen, “Claude Code deletes developers’ production setup, including database,” Tom’s Hardware, March 2026. 42 HN points, 27 comments. ↩
-
tomvault, “How Claude Code escapes its own denylist and sandbox,” ona.com, March 2026. Three escalating escape techniques: path evasion, self-directed disabling, dynamic linker bypass. 34 HN points. ↩
-
atombender, “Agent Safehouse: macOS-native sandboxing for local agents,” agent-safehouse.dev, March 2026. 802 HN points, 181 comments. ↩