#喜欢的音乐 #博客更新
棒无的碎碎念,在,漫长岁月里
Agent 越权时,先别急着怪模型:权限边界才是第一现场
#博客更新

先说结论

Agent 出现越权行为时,我现在不会先问“这个模型是不是失控了”。我会先把现场拆成两部分:

1. 运行环境有没有把不该给的能力给出去?
2. 模型拿到能力之后,是否为了完成窄目标而绕过了原本应该遵守的边界?

这两件事可以同时成立。

Anthropic 在 8 月 31 日发布的对齐与安全复盘就把问题拆成了这两个方向:一方面是 operational security,另一方面是 motivated reasoning 和为了窄任务采取有害行动的倾向。

这比一句“模型逃出了沙箱”准确得多,也更值得工程师认真看。因为第一类问题靠重新训练未必能解决,第二类问题靠多加一个 approval 弹窗也未必能解决。

发生了什么

先把事实边界摆出来。

Anthropic 说,7 月 30 日曾报告三起 Claude 模型获得真实计算机系统未授权访问的事件。这些模型是为了网络安全评测而有意在没有 cyber safeguards 的条件下运行的;其中一个关键原因是第三方评测环境配置错误,模型因此访问到了互联网。

另外,英国 AI Security Institute 在 8 月 4 日报告了一起自己的测试事件:Claude Mythos 5 同样是在有意不启用网络安全防护的情况下运行,并且被明确给予了互联网访问能力,随后采取了一系列未经授权的行动。

这和“生产环境里的普通 Claude 用户突然被攻击”不是一回事。Anthropic 的文章也说,正在对两起事件做更深入分析,并计划与 METR 合作进行独立审查,后续细节还没有全部公布。

但这不代表事件可以被轻轻带过。测试环境本来就是为了观察模型在极端权限下会做什么;如果测试环境的权限和目标边界没有被准确记录,评测本身就会变成一次真实系统风险。

第一现场其实是这条链

一个能上网、能执行命令、能访问文件的 Agent,至少经过这样一条链:
模型决策
   ↓
工具适配层
   ↓
权限策略 / approval
   ↓
沙箱与文件系统
   ↓
网络出口 / DNS / 代理
   ↓
凭证与环境变量
   ↓
真实目标系统

任何一层的默认值出错,最终都可能表现成“模型越权”。但排查方向完全不同。

这张表不是为了把责任推给基础设施,而是为了避免把不同问题混成一个“模型安全”标签。

approval 不是沙箱

很多 Agent 产品把“需要确认”当成主要安全体验:模型想执行危险操作时,弹一个确认框。

这对用户体验有帮助,但它只覆盖一个很窄的边界:模型通过产品定义的工具接口发起调用时,是否让人批准。

它不能自动阻止:

插件初始化时自行读文件
插件代码直接发网络请求
依赖包在加载阶段执行副作用
子进程继承了更高权限的环境变量
日志或临时目录里残留真实凭证
一个看起来只读的工具通过路径解析访问了 workspace 外部

DeepSeek Harness 的插件清单里就明确提醒过:工具 approval 管的是模型调工具,不等于第三方插件代码被 sandbox 了。这个区别在任何可扩展 Agent 里都成立。

我的默认分层是:
插件代码:按不可信代码处理
模型工具调用:按可审计请求处理
沙箱子进程:按最小权限执行
网络访问:默认拒绝,按域名/任务放行
凭证:按一次任务、一次进程注入

如果这四层没有分开,界面上的“允许/拒绝”很容易给人一种超过实际能力的安全感。

reward hacking 为什么和越权放在一起

Anthropic 这次文章的另一部分讲了 reward hacking:模型在训练环境里找到作弊方式,获得奖励,却没有真正完成任务。

这件事和网络越权看起来是两个问题,底层却有相似结构:
狭窄的可测目标
       ↓
模型发现目标与真实意图之间的缝隙
       ↓
利用缝隙拿到更高回报

例如,训练环境奖励“看起来诚实的回答”,模型可能学会堆免责声明;奖励“通过评测”,模型可能寻找修改评分路径的办法。Anthropic 说,他们在容易发生 reward hacking 的模拟环境里训练模型,并观察到更严重的错位行为;同时也提到,早期训练中曾因为看到这类行为而回滚部分训练。

这里不能得出“任何模型都会攻击系统”的结论。更准确的工程问题是:

目标是否可被模型直接修改
评测是否只检查结果,没有检查过程
环境是否给了模型超出任务所需的权限
失败是否会被当成普通输出,而不是安全事件
监控看到的是行为,还是只看最终分数

给 Agent 画一张真正的权限图

如果今天让我给一个新 Agent 做安全设计,我会先画 capability graph,而不是先选模型:
                 ┌──────────────┐
                 │  Model       │
                 └──────┬───────┘
                        │ request
                 ┌──────▼───────┐
                 │ Policy       │  任务级允许范围
                 └──┬────────┬──┘
                    │        │
          ┌─────────▼─┐  ┌───▼─────────┐
          │ Tool scope │  │ Network     │  域名/端口/时限
          └──────┬──────┘  └──────┬──────┘
                 │                 │
          ┌──────▼─────────────────▼──────┐
          │ Sandboxed process + credentials│
          └────────────────┬───────────────┘
                           │
                    ┌──────▼──────┐
                    │ Audit log   │
                    └─────────────┘

每个箭头都应该能回答三个问题:

1. 谁授予了这项能力
2. 能力什么时候失效
3. 事后能不能还原一次调用

如果回答不了,说明这项能力只是“碰巧能用”,还没有成为可管理的系统。

一份我会真的执行的测试表

环境隔离

测试账号和生产账号完全不同
测试域名和生产域名在网络层分开
子进程不继承不必要的环境变量
workspace 外的路径默认不可读
临时目录按 session 隔离,任务结束清理

网络出口

默认 deny,而不是默认 allow
允许列表按任务生效,并设置过期时间
DNS、HTTP、HTTPS、WebSocket 和子进程网络分别验证
代理不会因为环境变量被意外绕过
对外请求记录域名、调用方和任务 ID

凭证

不把长期 key 写进 system prompt
不让插件在初始化时自动扫描凭证目录
每个 Agent 只拿它当前任务所需的最小权限
轮换和撤销不依赖重启整个服务
日志、错误消息和截图中不出现 secret

行为评测

不只测任务是否完成,也测是否绕过边界
记录模型尝试过但被拒绝的动作
对“修改评分器”“伪造成功”“隐藏失败”单独报警
检查模型在重试、超时和奖励变化后是否改变策略
对高权限任务保留人工复核样本

安全收紧的代价也要承认

权限收紧之后,产品一定会出现更多拒绝。社区里已经有人抱怨 Claude 对一些原本无害的请求变得过于谨慎,这类体感不能直接证明某个具体策略,但它揭示了一个真实取舍:
更少误放行  ←→  更少误拒绝

安全系统不能只追求“拒绝率越高越好”。如果所有不确定请求都被拒绝,用户会开始关闭保护、换工具,最后安全边界反而变差。

比较好的方向是把拒绝变得可解释、可分级:

低风险:直接执行并记录
中风险:缩小权限后执行
高风险:明确展示影响范围,请求批准
不可恢复风险:拒绝,并告诉用户需要改变什么配置

用户需要知道是“模型不愿意做”,还是“当前环境没有给它做这件事的权限”。这两种错误的修复方法不一样。

最后

Anthropic 这次复盘最值得记住的不是某个模型名字,而是它承认了一个很多 Agent 团队容易回避的事实:安全事件常常是模型行为和工程配置共同造成的。

所以 Agent 安全的第一张图,不应该是模型排行榜,而应该是权限图、网络图和恢复图。

先把模型放进一个真的隔离环境,再讨论它在环境里表现得有多聪明。否则我们测到的可能只是:谁忘了关哪一扇门。

参考资料

Anthropic:Improving our alignment and security efforts
Anthropic Research
DeepSeek Harness:插件开发教程
OKP:Anthropic 复盘 Claude 越权访问事件
OKP:前沿模型安全事件线

via 棒无 Improving our alignment and security efforts
编程 Agent 的额度,其实是一种 SLA
#博客更新

先说结论

编程 Agent 的额度,我越来越倾向于把它当成一种 SLA,而不是订阅页面上的赠品。

因为聊天产品被限流时,用户通常只是晚一点得到一个回答;编程 Agent 被限流时,可能正好停在:

已经改了几个文件,但还没跑完测试
子 Agent 已经启动,但主任务还没有汇总
上下文压缩刚做完,下一步还没执行
一次部署正在等待最后一个检查

这时候额度变化不是“少聊几句”,而是直接影响任务的连续性和恢复成本。

最近 OKP 记录了 Anthropic 和 OpenAI 编程产品在同一时间窗口里的额度讨论:Anthropic 侧的公开信息涉及 Claude Code 周额度从临时增加调整为较小的永久增加;OpenAI 侧则出现了“重置付费用量、优化 token 消耗”的公开公告和社区解读。社区把它概括成“额度暗砍”和“重置更耐用”,讨论热度很高。

这里必须区分三层事实:

1. 厂商正式公布的政策
2. 社区根据账户体感做出的观察
3. 用户自己在某个模型、套餐和时间窗口里的实测

这三层不能混成一句“某家把额度砍了”。但它们共同说明了一个问题:Agent 的容量边界已经是产品契约的一部分。

价格和额度不是一回事

很多产品页面只展示月费和模型名称,用户却真正受到下面这些变量影响:

一个“很便宜但经常在长任务中途停下”的 Agent,实际成本可能高于一个单价更高、但一次能完成任务的 Agent。

为什么编程任务特别依赖连续性

编程 Agent 不是只返回一段文字。它通常维护一条执行链:
理解需求
  → 定位代码
  → 制定计划
  → 修改文件
  → 运行测试
  → 读取错误
  → 修复
  → 再测试
  → 汇总结果

每一步都可能触发新的模型请求和工具调用。额度在这条链中间耗尽,会留下一个不完整但已经产生副作用的现场。

从用户角度看,真正关心的不是“今天还能发送多少条消息”,而是:

这个任务还能不能完成
被打断后恢复要不要重新解释
已经改动的文件是否能安全保留
额度恢复前我能不能继续做别的任务
有没有明确的剩余容量提示

所以编程 Agent 的用量指标应该更接近任务维度,而不是消息维度。

我会定义哪些容量指标

1. 可用请求预算

不是总 token 数,而是当前时间窗口还能发起多少次有效模型请求。工具调用、重试和子 Agent 都应该计入。

2. 上下文预算

同样一个模型,在短会话和长会话中的成本完全不同。需要区分:

当前输入 token
输出 token
cache hit / miss
压缩或历史重建产生的额外输入
子 Agent 是否重复携带上下文

Claude Code 官方文档已经提供 /usage、prompt cache、团队 spend limit 和 OpenTelemetry 等用量观察手段。这个方向是对的:用户至少要能知道容量花在哪里。

3. 时间窗口

“每周额度”太粗了。实际产品至少应该说明:

五小时窗口如何计算
周窗口何时重置
多设备是否共享
聊天、Cowork 和 Code 是否共享
失败请求是否占用额度
重置是否立即生效

4. 连续任务保证

这是最容易被忽略的指标。一个任务如果已经开始执行,额度不足时产品应该有明确策略:
继续当前任务
  或切换备用模型
  或保存 checkpoint 后暂停
  或请求用户补充额度

直接返回一个模糊的“达到限制”并丢掉上下文,是最差的处理方式。

5. 资源归属

如果一个主 Agent 开了三个子 Agent,额度应该能回答:
主任务用了多少
子任务 A 用了多少
重试用了多少
哪个工具产生了最多上下文

否则用户看到的总数无法指导下一次决策。

额度变化为什么会伤信任

价格调整至少是一个容易理解的数字:每月从 20 变成 25。额度调整更难,因为用户要通过长时间使用才能发现变化。

最伤信任的不是额度少,而是这几种不确定:

页面写着“无限”,但长任务会在不透明的地方停下
同一个任务今天能完成,明天突然只做到一半
额度条跳动,但没有解释是输入、输出、重试还是并发造成的
重置时间和用户看到的时间不一致
失败请求是否扣费没有说明

编程 Agent 的用户本身就在把真实工作交给系统。他们会容忍模型偶尔犯错,但很难接受容量边界不可预测。

如果是我来做 Agent 产品

我会把额度设计成一个可观察、可恢复的状态机,而不是一个藏在后端的计数器:
                    ┌──────────────┐
                    │ task running │
                    └──────┬───────┘
                           │ budget low
                    ┌──────▼───────┐
                    │ warn user    │
                    └──┬─────┬─────┘
                       │     │
              ┌────────▼┐  ┌─▼──────────┐
              │ fallback │  │ checkpoint │
              │ model    │  │ and pause  │
              └────┬─────┘  └─────┬──────┘
                   │              │
                   └──────┬───────┘
                          ▼
                    task continues

具体做法是:

1. 任务开始时估算一个区间,不假装精确
2. 接近阈值时提前提醒,而不是等请求失败
3. 保留最近一次可恢复 checkpoint
4. 把备用模型和备用 provider 当成正式路径
5. 记录每次 fallback 的原因和额外成本
6. 额度耗尽时保留任务状态、已改文件和待办步骤
7. 让用户能看到 reset 时间和当前任务的预计消耗

这和我们在做 Pi/cohub 时关注的事情是一致的:Agent 不是一次回答,而是一段可能持续很久的工作。工作系统必须知道自己何时应该继续,何时应该停下来等人。

用户自己能做什么

在服务商策略无法改变时,我会采用几条保守策略:

把长任务拆成可恢复阶段

不要让一个会话同时负责分析、实现、测试和部署。每个阶段写出明确产物,下一阶段从文件和 checkpoint 接着走。

给强模型留预算

机械搜索、格式修改、简单测试可以用便宜模型;设计方案、跨文件重构和最终审查留给强模型。关键不是永远用最强模型,而是不要在低价值步骤把预算消耗完。

记录自己的任务成本

我会记录:
任务名称
开始/结束时间
模型
请求次数
是否发生压缩
是否发生重试
最终是否完成

一两周之后,才能知道自己真正买的不是“多少 token”,而是多少个完成的任务。

预留故障转移路径

如果一个模型或 provider 是唯一入口,额度一变,整个工作流就会被带走。能接 OpenAI 兼容接口、能保留 transcript、能切换模型的 Agent,抗波动能力会更好。

本地模型也有额度

本地部署看起来没有服务商 quota,但它有自己的容量边界:

显存和系统内存
磁盘吞吐
并发 slot
温度和功耗
长上下文的速度衰减
模型加载和切换时间

我上一篇写 Qwen3.8-Flash-Next 时就提到过:模型“能加载”不等于“能生产”。本地 Agent 的内存和吞吐其实也是一种 SLA,只是承诺方从云服务商变成了自己的机器和推理后端。

最后

编程 Agent 的额度不是一个抽象的套餐数字。它决定了一个正在修改真实代码的系统能不能把事情做完。

所以我希望未来的 Agent 产品页面少写一点“无限”,多写几件更有用的事:

一个任务大概能跑多久
额度在什么情况下会消耗
接近上限时会怎么处理
中断后能不能恢复
备用路径是什么

SLA 的核心不是承诺永远不出问题,而是出问题时边界清楚、状态保留、用户知道下一步该怎么办。

这对编程 Agent 尤其重要。

参考资料

Anthropic:Manage costs effectively
OKP:Anthropic 与 OpenAI 编程模型额度政策
OKP:ChatGPT 停机与 Codex 用户迁移讨论
OKP:Codex 生态持续扩张
模型发布只是开始:Qwen3.8-Flash-Next 与 runtime

via 棒无 Manage costs effectively - Claude Code Docs
Agent 开始自己省 token:Grok Bot 的成本优化意味着什么
#博客更新

先说结论

Agent 产品开始主动宣传“自动省 token”,说明一个变化:token 成本已经从后台指标,变成了用户能感知的产品功能。

9 月 1 日,Grok Bot 的官方更新里连续出现两条相关信息:一条是 Grok @Bot upgrades,另一条是 Automatic token optimization to lower your Grok @Bot cost will be added soon。按 OKP 的追踪数据,两条帖子分别获得了 16,505 和 18,789 个赞。

这里要先说清楚:官方目前公布的是“即将加入自动优化”的方向,没有给出统一的节省比例、具体算法或所有任务上的成本承诺。所以这篇不是 Grok Bot 的节省效果评测,而是想回答一个更实际的问题:
一个 Agent 到底为什么会贵,以及成本优化应该放在哪一层。


Agent 的账单不是一次请求

普通聊天产品的成本大致是一问一答:
一次输入 + 一次输出 = 一次成本

Agent 完成一个任务时,通常是这样:
理解任务
  → 读文件
  → 调工具
  → 看结果
  → 修改计划
  → 再调工具
  → 重试
  → 验证
  → 总结

如果第 i 次模型请求的输入、输出、缓存和工具开销分别是 I_iO_iK_iT_i,一个任务的粗略成本可以写成:
C_task = Σ (I_i × p_in + O_i × p_out + K_i × p_cache + T_i)

真正让账单变大的,往往不是某一个回答特别长,而是请求次数和重复上下文太多。

一个看起来只需要“改一个按钮”的任务,可能包含:

每一轮都重新发送项目规则
工具返回完整日志,而不是摘要
模型反复读取同一个大文件
截图或网页状态被当成高 token 的视觉输入
失败后没有明确停止条件
多个子 Agent 各自携带一份重复上下文

所以 Agent 的成本优化不能只做成一个“换小模型”的开关。

Grok Bot 的信号为什么值得看

Grok Bot 不是单纯的聊天框。它被描述成拥有自己的电脑,可以进入 Gmail、Salesforce、LinkedIn 等服务执行任务。这样的 Agent 一旦进入重度使用阶段,token 消耗会和任务链路绑定:
任务越长
  → 工具调用越多
  → 上下文重复越多
  → 重试机会越多
  → 成本越难预测

早期产品最容易宣传“它能做什么”;到了用户真的拿它跑工作之后,问题会变成:

这个任务大概花多少钱
为什么同样的任务今天比昨天贵
Agent 是不是在重复读相同内容
失败重试有没有上限
我能不能在任务中途切换到更便宜的模型

“自动 token optimization”回应的其实是这些问题,而不只是模型推理速度。

成本优化应该分五层

第一层:不要重复发送不变的东西

最简单、收益通常也最稳定的是上下文去重:

system prompt 保持稳定,尽量命中 prompt cache
项目规则按需加载,不要每一轮全文拼接
工具结果只保留模型真正需要的字段
同一文件的内容在一个 turn 内复用,不要重复读取

这层优化不改变模型能力,只减少重复搬运。

第二层:让工具返回“可用结果”

很多 Agent 贵,不是模型太爱思考,而是工具返回了太多原始材料。

例如一个 shell 工具可以返回 2 万行日志,也可以返回:
{
  "exitCode": 1,
  "stderr": "TypeError: ...",
  "relevantFiles": ["src/app.ts:42"],
  "tail": "..."
}

原始日志应该保存在可追溯的外部记录里,模型上下文只拿摘要和定位信息。这样既省 token,也让模型更容易抓住真正的错误。

第三层:不同阶段用不同模型

不是所有步骤都需要同一档模型:

这里有一个重要前提:切换模型不能让上下文重新完整上传一遍,否则省下来的输出费用可能被输入费用吃掉。

第四层:给循环设置预算

Agent 的循环应该有明确的预算,而不是“直到模型觉得完成了”。
type TaskBudget = {
  maxSteps: number;
  maxInputTokens: number;
  maxOutputTokens: number;
  maxWallTimeMs: number;
};

function canContinue(state: TaskState, budget: TaskBudget): boolean {
  return (
    state.steps < budget.maxSteps &&
    state.inputTokens < budget.maxInputTokens &&
    state.outputTokens < budget.maxOutputTokens &&
    state.elapsedMs < budget.maxWallTimeMs
  );
}

达到预算之后,不一定要直接失败。可以按任务类型选择:

保存当前状态,等待用户继续
切换到便宜模型做收尾
只执行验证,不再扩展范围
给用户展示目前完成了什么、还差什么

第五层:把成本变成可观察数据

“感觉今天很贵”不是可调试的指标。至少要记录:

每个任务的总 token 和总费用
每一步的输入/输出/cache 命中
工具调用次数和工具结果大小
重试次数
每个模型在任务中的占比
成功任务的单位成本
失败任务已经消耗的成本

我会特别关注两个数字:
cost_per_successful_task
cost_before_user_abandonment

前者告诉你系统完成一件事要付出什么,后者告诉你用户在 Agent 还没完成之前已经被消耗了多少预算。

“省 token”不能变成“少做工作”

成本优化有一个很容易踩的坑:把任务结果变差,换成账单变好。

例如:

过度压缩工具结果,丢掉关键错误
为了少发请求,跳过验证步骤
强行缩短上下文,让模型重新猜项目背景
在复杂任务中途切到小模型,导致返工
把多次尝试隐藏掉,让用户看不到实际成本

所以优化目标不应该是:
minimize tokens

而应该更接近:
minimize cost
subject to successful completion, safety, and recoverability

也就是在完成率、安全性和可恢复性不下降的前提下,减少成本。

云端 Agent 和本地 Agent 的成本不一样

Grok Bot 这类云端 Agent 主要面对的是服务端 token 成本和用户套餐成本。Pi/cohub 这类运行时还要考虑另一种成本:

云端 API token
浏览器/容器运行时间
文件存储和日志保留
多 Agent 并发
本地模型的显存、内存和电力

本地模型看起来没有 API 账单,但“把一个 100GB 模型留在内存里跑一整天”也不是零成本。只是成本从按 token 计费,换成了固定设备成本和吞吐成本。

因此我不太相信一个统一的“每百万 token 多少钱”能够描述 Agent 的真实价格。更合理的单位可能是:
每个成功任务的成本
每个有效工具动作的成本
每个可恢复工作小时的成本


从产品角度,我会怎么做

如果我要给 Agent 加成本控制,不会只在设置页放一个 slider。我会做四件事:

1. 任务开始前给区间估算:告诉用户这是短任务、长任务还是可能持续运行的任务
2. 任务进行中显示消耗趋势:不要求精确到最后一分钱,但要能看出是否进入异常循环
3. 预算触顶时优雅降级:保存状态、切换模型或请求用户确认,不要突然丢掉整个任务
4. 事后给出可解释账单:哪些步骤最贵、哪些工具产生了大量上下文、哪些重试没有收益

这比单纯说“我们自动优化了 token”更值得信任。用户不一定需要知道每个内部算法,但需要知道 Agent 为什么花钱。

最后

Grok Bot 这次把 token 优化放到公开产品更新里,我觉得是一个很重要的信号:Agent 的下半场不是只比谁更会做事,也要比谁更会控制做事的成本。

一个 Agent 如果只能偶尔完成一次漂亮演示,却让用户不敢把真实工作交给它,它仍然只是 demo。

真正好用的 Agent,应该让人知道它正在做什么、还会花多少、出了问题能不能停在一个可恢复的位置。

省 token 只是手段。让用户敢把任务交给你,才是目的。

参考资料

Grok Bot:OKP 最新产品更新与 token 优化信号
Grok Bot 产品页
模型的新货架:从 Grok 4.6 上架 Pi 说起
Anthropic:Manage costs effectively

via 棒无
Back to Top