隐形代理:为什么看不见的东西无法治理
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的遥测数据。该应用没有提供任何仪表板、计量器,也没有关于虚拟机分配的选择性披露。
将这种模式扩展到代理会话。我的钩子编排系统在每次工具调用中拦截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
内存。每轮对话的上下文窗口消耗。一个200,000 token的上下文窗口按当前Opus定价,填满一次大约花费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该工具位于代理和所有工具使用请求之间,在执行前根据基于正则表达式的策略评估每个请求。策略使用JSONNet配置文件,按文件夹、Git仓库或用户进行范围划定。该防火墙通过PreToolUse钩子集成支持Claude Code和GitHub Copilot CLI。
这种架构体现了一个关键洞察:每个代理都实现了自己的半成品允许/拒绝逻辑。Claude Code使用glob模式。Codex CLI使用前缀匹配。每种方法覆盖策略空间的一个子集。mcp-firewall将规则集中到一个跨代理通用的引擎中。
考虑一下没有集中执行时的策略差距。我的钩子系统包含12个PreToolUse:Bash处理器,用于检查凭据模式、危险的Git操作、敏感路径访问和部署命令。2每个处理器是一个独立的shell脚本,拥有自己的正则表达式模式。当我需要添加新的拒绝规则时,我编写一个新脚本。当我需要审计哪些规则存在时,我需要在12个文件中进行grep。mcp-firewall将这一切整合到一个包含显式允许数组的单一配置文件中。
OWASP 2025年代理应用十大风险将代理目标劫持(ASI01)和过度授权(LLM06:2025)列为顶级风险。8这两种风险都需要在工具调用层面进行策略执行。劫持目标的代理仍然会发起工具调用。拥有过度授权的代理仍然会请求权限。策略执行在代理意图与系统工具交汇的边界上拦截两者。
策略执行不同于访问控制。传统访问控制问的是”该用户是否有权限?”代理的策略执行问的是”在此上下文中,针对此任务,该操作是否在批准的范围内?”上下文敏感性是挑战所在。对功能分支执行git push和对main分支执行git push --force使用的是同一个工具(Bash),但影响范围截然不同。mcp-firewall的正则表达式模式可以区分两者。默认代理权限无法做到。
第三层:运行时审计
运行时审计回答的问题是:代理在系统调用层面实际做了什么?
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的仅观察审计追踪等效的生产就绪工具。
执行与审计之间的区别对应于事件响应中的时间维度划分。执行预防事件发生。审计使事件发生后的重建成为可能。两者都是必要的。阻止所有凭据访问的执行层可以防止数据泄露,但也会阻止合法的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命令的代理所执行的代码,在钩子看来只是一个字符串。内核级审计则会看到每个子进程。
复合盲区
代理派生代理会使不透明性倍增。每次委托跳转都引入信息损失。
当我的编排系统运行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脚本,读取stdin(工具调用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"
}
]
}
]
}
}
钩子脚本从stdin读取工具调用,提取命令字符串,并与模式进行比对。被阻止的命令返回一个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(扩展Berkeley数据包过滤器)能够在不修改被审计进程的情况下实现内核级系统调用追踪。Logira等工具使用eBPF探针在AI代理运行期间记录进程执行、文件操作和网络连接。9
来源
-
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. ↩