阻止 Claude Code 在十分钟内耗尽你五小时的使用窗口。
agent-usage-guard是一个 Claude Codemod:它运行在 Claude Code 内部,在失控开销发生之前就将其拦住。它读取你套餐的实时用量,并约束子智能体的扇出、重上下文搅动和重试循环。
在加载了该防护的情况下,从 Claude Code 的交互式 UI 录制。一个脚本化的本地 API代替 Claude,因此会话和 token 计数是预置的,不会消耗任何用量。屏幕上的每个问题都来自该防护本身。重建它从Northstar fixture。
它在开销发生之前行动,而不是之后:在智能体启动、提示词发送或工具调用运行之前。智能体限制在你机器上的每个 Claude Code 会话中都生效,而扇出和重上下文在任何用量水平下都会被限制,而不只是在接近上限时。当你在键盘前时,它会用 Claude Code 自带的问题对话框询问你。当无人能回答时,它会拒绝并告诉 Claude 原因,这样模型可以等待、批量处理工作或停止。/agent-guard report展示它做了什么。
- 感知套餐。它读取 Claude Code 报告的 5 小时和每周百分比,并为你保留窗口末尾的额度。
- 一个答复覆盖一段时间。批准会解除其条件,直到条件清除或超时,因此同一个问题不会在一次次调用中反复出现。
- 本地且隐私最小化。无网络,无进程。它只存储计数和粗粒度分桶,绝不存储提示词文本、工具输入或模型输出。
- 失败开放。如果它的某个钩子失败,事件照常进行:坏掉的防护永远不会破坏你的会话。唯一的例外是它无法及时判断的智能体,该智能体会被拒绝,以便 Claude 重新启动它。
安装
在 Claude Code v2.1.287 或更高版本中运行这些命令:
/plugin marketplace add rbartoli/agent-usage-guard
/plugin install agent-usage-guard@agent-usage-guard
/reload-plugins
然后运行/agent-guard看看它看到了什么。Mod 默认开启;概览列出了关闭它们的设置。
为什么存在这个
某个下午,我以最大努力给 Claude Code 一个研究提示词。它生成了394 次子智能体调用,其中 341 次同时运行,并在十分钟内通过 API 推送了 84M 上下文 token。会话结束:“Claude 用量已达上限。”被锁定直到窗口重置。
这不是一次性的。我自己六十天的日志里有12 次锁定和 166 个带有智能体爆发的十分钟窗口。这种失败模式会成倍放大:大上下文 × 快速工具循环 × 并行智能体 × 盲目重试。下面每一项保护措施都会移除一个因素。
而且不只是我:单个提示词产生 339 个子智能体,递归生成消耗了每周 Max 套餐的一半,以及多智能体运行使用的token 量约为一次聊天会话的 15 倍。
它的作用
| 领域 | 规则 | 默认值 | 会发生什么 |
|---|---|---|---|
| 套餐窗口 | 当窗口用量达到此水平时,新智能体需要审批 | 80% | 询问;审批有效期持续到该窗口重置 |
| 当窗口用量达到此水平时,新智能体将被拒绝 | 95% | 拒绝 | |
| 当 5 小时窗口上升得这么快时,新智能体需要审批 | 20 点 / 10 分钟 | 询问 | |
| 智能体 | 此机器上所有会话中同时运行的智能体数量 | 4 | 询问 |
| 此机器上每 10 分钟启动或恢复的智能体数量 | 12 | 询问 | |
| 此机器上子智能体每 10 分钟处理的 token 数 | 10M | 询问 | |
| 子智能体不得启动自己的智能体 | 深度 1 | 拒绝 | |
| 上下文 | Claude 会被提醒一次以保持回合有界 | 300k token | 在提示词中添加一条注释 |
| 会重新读取这么多上下文的提示词 | 500k token | 询问:先压缩再发送、仍然发送,或取消 | |
| 当对话或智能体承载这么多内容时,每 10 分钟的工具调用次数 | 400k 时 20 次调用 | 询问:继续、本回合后压缩,或停止 | |
| 一个繁重会话空闲足够久,导致其提示词缓存过期 | 150k token,空闲 1 小时 | 在重写缓存前询问 | |
| 循环 | 同一个工具调用反复失败,中间没有其他调用 | 3 次相同失败 | 拒绝相同的重试 |
| 10 分钟内被拒绝的智能体调用 | 5 | 暂停智能体生成 10 分钟 |
智能体涵盖子智能体、智能体团队队友、工作流智能体,以及用以下方式恢复的已完成子智能体SendMessage。每次工具调用都根据发起它的循环的上下文来评判,因此小型子智能体永远不会继承主对话的规模。
当它询问时。这个问题会出现在 Claude Code 自己的对话框中,也就是 Claude 用来向你提问的那个对话框,调用会等待你的回答。在对话框打开期间并行启动的智能体会被暂缓,你回答后 Claude 会重新启动它们。如果你允许,该条件会在一段时间内保持允许:计划窗口直到重置,重度上下文直到缩小(对于工具调用,最多一小时),智能体计数为 10 分钟。如果你拒绝或关闭该问题,Claude 会被告知在接下来的 10 分钟内不要启动智能体(AGENT_GUARD_WINDOW_SECONDS),并且在这段时间内不会再被询问。输入的文字会传达给 Claude,所以你可以回答“改用 haiku 智能体”。
当没有人能回答时。在claude -p、Agent SDK 和dontAsk模式下,智能体或工具门控会拒绝而不是询问。重度提示会被暂缓并附上原因,休眠的重度恢复在达到每 10 分钟一次的全机上限后也会被暂缓。Claude 会把每次拒绝读取为工具的结果。对同一条件的重复拒绝每次措辞不同并逐步升级:第二次说没有任何变化,请尝试其他方法,第三次说结束本轮。如果像/goal这样的 Stop 钩子不断重新打开本轮,拒绝会说明必须由用户决定。
它不干预的部分。它从不暂缓后台任务的通知或其他会话的消息,因为那会丢失结果。它不再在使用量限制后阻塞提示:自 v2.1.234 起,Claude Code 会在达到限制时等待,并在重置时自行继续(autoContinueAtUsageLimit)。该守卫的职责是防止你达到限制,其日志会记录它未能阻止的锁定次数。
命令
/agent-guard [status] what the guard sees right now
/agent-guard allow [agents|context] [minutes] lift its limits for this session (default: all, 10 min)
/agent-guard pause [minutes] the same as allow, for every limit
/agent-guard resume end an allow early, lift the agent pause, and let declined questions ask again
/agent-guard report [days] what it did on this machine (default: 7 days)
/agent-guard help these commands
/agent-guard会立即运行,即使在一轮对话中途,并且从不启动模型轮次,因此 Claude 永远看不到覆盖指令,也无法将其视为许可。单独发送[allow-usage-guard]或[allow-agent-burst]作为提示(早期版本的标记),效果等同于/agent-guard allow或allow agents。
它能看见和不能看见的内容
已对照 Claude Code v2.1.295 检查:
| 路径 | 覆盖范围 |
|---|---|
| 子智能体、队友和工作流智能体 | 在启动前被暂缓(agent.spawn) |
已完成的子智能体通过以下方式收到新工作SendMessage |
在恢复前被暂缓,并计为一次启动 |
/subtask分叉,以及任何其他在没有agent.spawn |
的情况下启动的智能体 |
| Claude Code 的内部智能体(提示建议、压缩) | 不计入 |
| 计划窗口百分比 | 来自订阅上的最后一次 API 响应,在claude -p同样如此。API 密钥会话不报告任何内容,因此只有 token 和计数预算适用 |
| 在各自终端窗格中运行的队友 | 不可见:它们的循环运行在其他进程中 |
| 其他机器上的会话 | 不计入:跨会话记录保存在本机的 mod 存储中 |
| API 自行运行的工具,例如 advisor | 无法拦截:不会为它们触发任何工具事件 |
Mods 运行于claude在终端中、在 Desktop 应用的 Code 标签页中、在claude -p以及 Agent SDK 中。它们不会在 Desktop 应用的 WSL 会话中运行(mods 运行的位置)。
原生限制仍然重要。Claude Code 将会话限制为 20 个并发子智能体(CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS)和三层嵌套(CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH)。它对会话启动的智能体总数没有限制。guard 的默认值更严格且跨会话生效;对于 guard 仅做计数的路径,原生上限仍是外层边界。
查看它做了什么
/agent-guard report 30
报告统计用量限制锁定(每个锁定的窗口计一次)、计划窗口阈值跨越,以及按规则记录的每个问题和拒绝,并附上你的回答。它读取本机上每个会话的日志,且从不离开本机。设置AGENT_GUARD_JOURNAL=0以停止记录。
安全与隐私
mod 以你的权限在 Claude Code 内运行;在安装之前请阅读mod 可以访问什么。这个 mod 约 2,400 行 TypeScript,无任何依赖,并且claude plugin validate .列出了它调用的每个 API 和读取的每个环境变量:
- 它不发起任何网络请求,也不启动任何进程。
- 它只决定上述规则所描述的内容:智能体是否启动、提示是否发送、工具调用是否运行。只要你能回答,它就会询问你;拒绝时会给出原因。它读取权限模式但从不更改它们,也不写入任何设置。
- 它唯一提交的提示就是你自己的提示:在“Compact, then send”之后,压缩完成后它会将你输入的提示原样发送一次。
- 它的提示钩子会原样传递你的提示,在上下文超过 300k 时为 Claude 添加一条一次性说明,或暂扣提示先询问你(当无人能回答时,它会说明原因)。它的
SessionStart钩子不做任何更改。 - 它将状态保存在 mod 存储中,这是一个位于以下位置的 JSON 文件
~/.claude/plugins/store/每个会话写入自己的计数(运行中的智能体、最近的启动与休眠恢复、每分钟子智能体 token 数、其最新的 5 小时读数)、最后活跃时间(保留 30 天,以便恢复的会话知道自己闲置了多久),以及它的日志行(时间、会话 ID 前缀、规则、工具名、上下文分桶,例如400-500k、计划窗口与百分比、拒绝次数,以及你的回答)。 - 它从不存储提示词文本、工具输入、错误文本或模型输出。一次工具调用被缩减为 13 个字符的指纹。智能体名称保留在内存中,从不写入。
- 超过 90 天的日志会被删除(
AGENT_GUARD_JOURNAL_DAYS)。 demo/,它构建了上面的 GIF,并不属于实际运行的部分。它在一个临时主目录中启动 Claude Code,使用一个虚构的 API key 对接脚本化的本地 API,并且不读取你的任何凭据。
设置AGENT_GUARD=0即可将其关闭而无需卸载。
配置
将这些设置为环境变量,或在env中的~/.claude/settings.json下设置。时间单位为秒;不是范围内数字的值会保留默认值,/agent-guard会说明这一点。
| 变量 | 含义(默认值) |
|---|---|
AGENT_GUARD |
0、false、off或no会关闭该防护(1) |
AGENT_GUARD_JOURNAL |
0停止日志(1) |
AGENT_GUARD_JOURNAL_DAYS |
日志保留天数(90) |
AGENT_GUARD_WINDOW_SECONDS |
预算、消耗与拒绝的滚动窗口(600) |
AGENT_GUARD_AGENT_MAX |
此机器上同时运行的智能体数(4) |
AGENT_GUARD_ROLLING_MAX |
此机器上每个窗口的智能体启动与恢复次数(12) |
AGENT_GUARD_AGENT_TOKENS_MAX |
此机器上每个窗口的子智能体 token 数(10000000) |
AGENT_GUARD_DEPTH_MAX |
主对话之下的智能体层数(1) |
AGENT_GUARD_LIMIT_ASK_PERCENT |
新智能体开始询问的计划窗口百分比(80) |
AGENT_GUARD_LIMIT_DENY_PERCENT |
新智能体被拒绝的计划窗口百分比(95) |
AGENT_GUARD_BURN_PERCENT |
使新智能体开始询问的每窗口 5 小时窗口点数(20) |
AGENT_GUARD_CONTEXT_WARN |
达到该上下文时,Claude 会被提醒一次以保持本轮有界(300000) |
AGENT_GUARD_CONTEXT_HARD |
达到该上下文时,提示会在发送前询问(500000) |
AGENT_GUARD_TOOL_CONTEXT |
超过该上下文时,工具调用计入工具预算(400000) |
AGENT_GUARD_TOOL_MAX |
该上下文之上每窗口的工具调用数(20) |
AGENT_GUARD_DORMANT_SECONDS |
闲置时间超过该值后,重度会话的缓存视为过期(3600) |
AGENT_GUARD_DORMANT_CONTEXT |
达到该上下文时,闲置会话视为重度(150000) |
AGENT_GUARD_DORMANT_MAX |
无人可询问时,此机器上每窗口的重度休眠恢复次数(1) |
AGENT_GUARD_TOOL_FAILURE_MAX |
相同重试被拒绝前允许的相同失败次数(3) |
AGENT_GUARD_FUSE_MAX |
熔断周期内被拒绝的智能体调用数达到该值即暂停生成(5) |
AGENT_GUARD_FUSE_SECONDS |
熔断周期,以及暂停持续时长(600) |
AGENT_GUARD_PEER_TTL_SECONDS |
其他会话的计数,或没有任何活动迹象的智能体,仍计入的时长(900) |
休眠默认值假设订阅在计划用量内获得一小时提示缓存。使用 API key 或额外用量时,缓存只持续五分钟,因此设置AGENT_GUARD_DORMANT_SECONDS=300。
Claude Code 之外
这些规则位于一个与 harness 无关的核心(core/)中,该核心不执行任何 I/O。Claude Code mod 是它的第一个适配器。docs/architecture.md描述了适配器所遵守的契约,以及另一个智能体 harness 必须提供什么才能承载每条规则。
测试
claude plugin validate 。 --strict claude plugin test
claude plugin test在 Claude Code 自带的测试套件中运行整套测试:核心的单元测试,以及通过 hooks 模块触发真实 Claude Code 事件的测试,不涉及会话、模型或网络。TESTING.md涵盖各层以及每个测试证明了什么。
许可证
MIT
