给 Agent 接工具这件事,第一版通常很顺:读接口加上写接口,提示词里写一句“高风险操作前请先确认”,demo 就能跑起来。真正出问题是在上线之后。腾讯云开发者社区那篇企业 Agent 落地文章列的几条差不多是所有团队都会撞上的:提示注入一句越权调用、出了事说不清是谁让它做的、退款改配置这类动作直接执行、一个死循环把接口和预算一起烧光。
这些问题的共同点是,它们都不是模型能力问题。提示词里的“请不要”不是权限控制系统,它只是一段上下文,可以被覆盖、被忽略、被长对话挤出窗口。权限得在模型输出之后、工具真正执行之前拦住。
三层拦法:工具级、数据级、参数级
我看过不少实现只做了最外面一层:给每个工具打一个 risk 标签,read 放行、write_low 放行、write_high 转人工。这套骨架不难,腾讯云那篇里的 guard 函数就是十几行——查工具表、看风险等级是否在白名单、不在就拒绝。难的是它拦不住真正的事故。
企业场景里更高发的是第二层:Agent 逻辑完全正确,但它看到了不该看的数据。比如工单分类任务,工具调用本身合法,可它拿到的是别的部门的工单。所以 guard 里得再加一条判断,args["ticket_id"] not in ctx["visible_tickets"] 就直接拒绝。这一层的输入不是角色,是当前用户可见数据集合,需要从业务侧传进来,而不是让 Agent 自己决定。
第三层是参数级别。枚举值越界、ID 格式不对、日期范围离谱、金额为负,这些都应该在执行前拦掉。set_category 只接受四个值这一条枚举约束,一个正则就够,比事后让模型自查可靠得多。
黑白名单之外,还要处理优先级
只有一个白名单时,加一条策略就是改一次代码,很快就乱。Progent 是较早系统化处理这个问题的方案,它把策略做成可编程的表达式:每条策略带工具 ID、条件表达式、Effect(allow 或 forbid)和回退函数。调用前先筛出目标工具的策略子集,按优先级排序,优先级相同时 forbid 优先——这一条很重要,默认行为是“无任何策略匹配就阻止该工具调用并走回退函数”。
默认拒绝,而不是默认放行。安全策略写错的一端应该落在“用不了”上,而不是“什么都放行”。
forbid 优先加默认拒绝,是两个朴素的工程习惯。但要注意副作用:策略热更新失败、规则加载为空、正则写错导致匹配不到,都会直接表现为工具不可用。上线前得有一套“策略加载成功但规则为空”的告警,否则模型会不停生成长度正常的拒绝对话,你没收到任何报错。
这也是 RBAC 和 ABAC 取舍的现实:RBAC 简单,角色边界清晰的内部系统够用;一旦出现跨地域访问、晚间时段限制、资源敏感度判断,就得引入上下文属性。CSDN 那篇文章给了一个风格很直接的例子,Resource.Sensitivity == "high" 且 Location.RiskScore > 0.7 时就要求多因素认证。这种检查要放在权限服务里,不要写进工具实现,否则同一个能力分散在不同工具里,很难保证一致。
参考 Claude Code 的三段分离
Claude Code 的工具系统有一处值得借鉴的设计:权限检查被拆成三层——输入验证 validateInput 在权限检查之前单独跑,只做数据合法性判断,不关心谁能调;hasPermissionsToUseTool + checkPermissions 处理工具特定权限,不同工具粒度不同,读类工具查路径允许列表,Bash 类工具得解析命令、评估风险等级;再往后是并发调度相关的运行时属性判断,比如 isConcurrencySafe()。
把数据验证和权限策略分开做,好处是出了问题好定位。参数非法返回给模型的是“这个入参不对”,权限不足返回的是“这个动作被禁止”,两种回退的处理方式不一样,模型能不能自我修正也不一样。混在一个函数里,你就会看到日志里全是模糊的“被拒绝”,根本没法定性。
Per-tool 自定义检查这件事也别省。一张全局工具表能把读类和写类分开,但拦不住 rm -rf / 这种。高危工具要允许挂在 ACL 钩子上做更细的检查,代价是每加一个工具就多一处代码,维护成本会涨。我的建议是第一版只允许不超过 5 个工具,全部手写检查,先把边界摸清再考虑抽象。
审计和人工确认是容错的一部分
腾讯云那篇文章的审计结构给得比较完整:任务 ID、时间、模型版本、提示词版本、每一步的工具调用和参数、护栏判定结果、人工审批记录、最终输出、耗时与 token。字段多的意义在于,出事后能复现当时的上下文——换过模型版本还是改过提示词,一看就知道。
人工确认这里我见过不少走形式的产品:弹个框写“是否允许此操作”,审批人根本看不到 Agent 想做什么、依据是什么、影响范围多大,只能凭印象点同意。有效的审批界面至少要让审批人理解这三件事,否则高风险动作人审只是把风险从 Agent 挪到了更疲惫的人身上。
还有个细节容易漏:拒绝之后 Agent 怎么继续。如果你的所有 request_approval 失败都当成“工具出错”,Agent 会陷入重试循环,白白消耗步数。正确的做法是把“被拒绝”作为一种终止性语义返回给模型,让它走兜底分支转人工。
最后是预算,不是安全意识问题
步数上限、总超时、单任务预算、同一工具重复调用上限——这些很多人把它当安全问题,其实是成本控制。一条死循环路径烧掉整月额度,在我见过的团队里起码发生过两次。护栏的取值不要凭感觉定,应该按线上 P99 的实际步数往上留 30% 的余量,每次改了工具或提示词都要重新核算。
总结下来,工具调用权限分级的正面清单大致是:工具级权限、数据级权限、参数合法性、forbid 优先加默认拒绝、高危动作强制人审、每一步可审计、步数预算双上限。这七件里任何一件缺失都可能埋坑,尤其数据级权限和人工确认还原上下文这两项,最容易用“还好没出事”的方式忽视。用腾讯云那篇文章里的一句话收尾比较合适:Agent 的能力上限由工具决定,可信下限由护栏和审计决定。
转载请注明出处: 皮哈皮阿
本文的链接地址: https://blog.phpat.com/ai-frontier/643.html
微信或手机浏览器扫一扫,随时随地随心阅读与分享
-
多智能体不是银弹:编排、通信与成本取舍
我们试过让五个 Agent 开会,结果它们花了二十分钟争论谁该先说话,最后交上来的方案还不如一个单 Agent 加两个工具。多智能体不是不能做,是很多团队做早了。
2026/10/18
-
AI 浏览器用了一个月,我还是回到了地址栏
我试着把 AI 浏览器当主力用了一个月。模型不差,功能也不少,但最后让我放弃的是一件很朴素的事:地址栏比对话框更快、更确定。AI 浏览器到底卡在哪?
2026/10/20
-
世界模型被吹了两年,真正难的不是生成视频
看世界模型的演示视频,很容易产生“就差一点”的错觉。可一旦你试图在里面做一个动作,问题就全暴露了。生成一段像世界的视频,和拥有一个能交互的世界,是两件难度完全不同的事。
2026/10/20
-
个人 Agent 与常驻智能体:长期记忆、主动性与隐私边界
我让一个常驻 Agent 帮我盯快递。包裹签收三天后,它还在提醒我“预计今天送达”。长期记忆、主动性和隐私边界,决定了个人 Agent 是助手还是负担。
2026/10/20
-
思维链压缩到 20%,还能保住数学推理的准确率吗
把推理模型的思维链砍到原来的 20%,多数压缩方法会崩,但 Extra-CoT 在 MATH-500 上还保住了近半准确率。拆一下它怎么用公式原子性和分层奖励,以及这些结果在别的任务上不一定成立。
2026/10/22
-
投机解码落地:草稿模型对齐与逐利陷阱
草稿模型选型、对齐和接受率曲线决定了投机解码的最终收益。批量越大加速衰减越多,低接受率、短输出和高温采样可能让线上请求更慢。草稿对齐和持续监控接受率是基础工作量,而不是换个配置文件就能兑现一次加速。
2026/10/23
京公网安备11011402053654 
@muffin:链接已更新,分类图像功能...
AI网址导航模版图标库更换指南
作者大大,图标库邀请链接失效了,麻烦更新...
AI网址导航模版图标库更换指南
太好看了,快点更新!
友情链接
@戴墨镜的刘备:哈喽,路过点赞。
vue.js组件之手写签名板vue-signature-simple
太好看了,快点更新!太棒了!👍真的很赞!
vue.js组件之手写签名板vue-signature-simple
你写得非常清晰明了,让我很容易理解你的观...
Emlog插件RSS订阅器发布