关键词:Agent 工具白名单、Agent 越权调用工具、OpenAPI 直接给大模型、AI Agent 权限控制、工具可见性

一套运行多年的业务系统,通常不会只有几个接口。

以商城后台为例,它可能同时存在:

GET    /orders                 查询订单
POST   /refunds                创建退款
PATCH  /inventory/{sku}        调整库存
DELETE /staff/{id}             删除员工
PUT    /billing/config         修改结算配置
POST   /notifications/batch    批量发送通知

当团队准备接入 Agent 时,一个很自然的做法是:读取整份 OpenAPI,把每个 operation 转成模型可以调用的工具。

接口已经有名称、描述和参数 Schema,模型也能根据用户意图选择工具。既然如此,为什么还要额外维护工具白名单?把更多 API 交给模型,不是能让 Agent 更聪明、更万能吗?

真正进入生产环境后,团队往往会发现:

Agent 的能力,不取决于它能看见多少工具,而取决于它在当前场景中只看见正确的工具。

工具可见性不是单纯的体验配置,而是 Agent 行动链路中的第一道安全边界。

1. “系统里有这个 API”和“Agent 应该看见它”是两回事

传统后台中的 API,原本可能只服务于:

  • 一个受控的管理页面;
  • 一段固定的后端流程;
  • 内部定时任务;
  • 只有管理员才能进入的运维入口;
  • 其他经过身份和权限校验的服务。

接口存在,并不意味着它已经准备好进入模型的工具候选集。

Agent 的调用方式发生了变化:用户给出的往往不是一条确定指令,而是一个自然语言目标;模型需要理解目标、选择工具并生成参数。只要一个操作进入可见工具集合,它就可能被模型选中,也可能受错误上下文、模糊表达或提示注入影响而被错误触发。

因此,至少需要区分四个问题:

问题 回答的是什么
业务 API 是否存在并可访问? 接口与网络可用性
这项能力是否允许进入 Agent 的可见范围? Agent-facing 能力声明
当前路由或场景是否需要这项能力? 运行时工具白名单
当前主体此刻是否有权操作具体对象? 业务系统最终授权

这四件事不能用一个“接口已经鉴权”合并掉。

2. 工具越多,模型选择未必越准确

假设客服助手只需要:

order.read
order.logistics.read
ticket.create

如果运行时把退款、库存调整、员工管理、结算配置和批量通知也全部交给模型,首先出现的未必是攻击,而可能只是普通的选择错误:

  • order.cancelrefund.create 的描述相似;
  • staff.disablestaff.delete 都能让员工停止使用系统;
  • inventory.adjustinventory.overwrite 都能改变库存;
  • 同一业务动作存在旧接口、新接口和内部接口。

工具数量增加后,模型需要在更大的候选集合里消歧。描述稍有重叠,就可能选中“看起来能完成目标”、但后果完全不同的操作。

所以工具白名单同时改善两件事:

  1. 降低行动范围:模型无法选择没有进入当前候选集的能力;
  2. 提高选择质量:减少无关和相似工具带来的歧义。

最小能力集合不是在限制模型智力,而是在为当前任务提供更清晰的行动空间。

3. 提示词不能代替工具可见性控制

一种常见方案是把所有工具交给模型,再在系统提示词中写:

你是客服助手,只能查询订单和创建工单。
不要退款,不要修改库存,不要操作员工账号。

这段提示当然有价值,但它属于模型行为引导,不是可靠的执行边界。

原因很简单:

  • 提示词可能被后续上下文稀释;
  • 用户输入或外部内容可能包含提示注入;
  • 模型可能误解“只能查询”的语义;
  • 不同模型或版本对同一提示的服从程度不同;
  • 工具调用链路最终仍然看到了那些高后果操作。

如果某个工具在当前场景下绝不应该被调用,更可靠的做法不是反复要求模型“不要选”,而是根本不把它放进候选集合。

提示词负责帮助模型正确行动;工具可见性负责限定模型最多可以尝试什么。

4. 同一套 API,在不同 Agent 场景中应该呈现不同能力

业务系统通常只有一套 API,但 Agent 入口可能有很多:

Agent 场景 合理的能力范围
匿名网页助手 商品查询、帮助中心搜索
登录后的客户助手 本人订单查询、售后申请
商家运营助手 商品维护、库存调整、订单处理
财务助手 对账查询、退款审批相关能力
内部 HR 助手 员工查询、状态变更

如果工具集合只在全局维护一份,就会出现两个极端:

  • 为了安全,只开放少量只读接口,Agent 永远无法进入真实业务;
  • 为了能力完整,把大量后台 API 全部暴露给每一个 Agent 场景。

更合理的模型是取交集:

当前可见工具
  = 显式声明允许面向 Agent 的能力
  ∩ 当前路由或场景的 allowlist
  ∩ 当前运行时策略允许的范围
  ∩ 已满足主体等前置要求的能力

任何一层不满足,能力都不应该进入模型的工具列表。

5. 显式 opt-in 到底声明了什么

显式 opt-in 的意思不是“这个 API 已经完成最终授权”,而是:

API 所有者明确确认,这个 operation 可以作为一项 Agent-facing 能力被兼容运行时读取。

在 ACC v1 的 OpenAPI 绑定中,可以这样声明:

paths:
  /orders/{id}:
    get:
      operationId: order_get
      summary: Query one order by ID.
      x-agent-capability:
        version: 1
        enabled: true
        scope: order.read
        risk:
          level: low
        subject:
          required: true
        execution:
          readonly: true
          idempotent: true

这里有两个容易误解的字段。

enabled 不是服务启停开关

enabled: true 表示该 operation 显式加入 Agent-facing 能力候选范围。

enabled: false 表示运行时不得把它暴露成 Agent 可调用能力。它不等于 HTTP API 下线,也不影响传统后台继续调用这个接口。

scope 不是最终业务权限

scope: order.read 提供一项稳定的能力标识,让路由 allowlist 和治理策略可以引用它。

它不表示“任何看到 order.read 的用户都可以读取任何订单”。当前用户能否查询这个订单,仍然必须由业务系统根据登录身份、租户归属、数据权限和实时状态判断。

ACC 管的是 Reach:这项能力是否可以进入 Agent 的触达范围。

业务系统保留 Authority:当前主体是否真的可以完成这次具体操作。

6. 为什么默认不暴露比默认全部暴露更合理

如果系统采用“OpenAPI 中的 operation 默认都能成为工具”,每新增一个后台接口,就可能无意间扩大 Agent 的行动范围。

这种变化很隐蔽:

  1. 业务团队新增一个内部管理接口;
  2. OpenAPI 自动更新;
  3. 工具生成器重新编译;
  4. 新工具悄悄进入模型候选集;
  5. Agent 的能力边界在没有安全评审的情况下发生变化。

显式 opt-in 把流程反过来:

  1. API 可以正常开发和发布;
  2. 只有完成 Agent-facing 评审的 operation 才增加声明;
  3. 运行时只读取显式启用且具有有效 scope 的能力;
  4. 当前路由再用 allowlist 缩小范围;
  5. 业务系统继续执行最终授权。

这使“新增 API”和“扩大 Agent 能力”成为两个独立动作。后者必须被明确看见、审查和记录。

7. 一份可以直接落地的最小检查表

准备把 OpenAPI 编译成 Agent 工具时,可以先检查:

  • 是否只有显式 opt-in 的 operation 才能成为工具?
  • 当前 Agent 场景是否有独立的 scope allowlist?
  • 未知或缺少治理声明的接口是否默认跳过?
  • 没有可信主体时,要求主体的能力是否会被隐藏?
  • 模型提示词是否只承担引导,而不承担安全边界?
  • 即使绕过工具列表直接请求 API,业务系统是否仍会做最终授权?
  • 新增 OpenAPI operation 时,是否不会自动扩大 Agent 权限?
  • 日志能否说明某个工具为什么被暴露或跳过?

如果这几个问题没有明确答案,“把 OpenAPI 全量转成工具”就不应该直接进入生产环境。

8. 工具白名单不是终点,但它是必要的起点

工具可见性无法替代身份认证、参数校验、审批、审计和业务授权。一个工具被隐藏,也不意味着业务 API 可以放弃自己的权限校验。

但反过来,业务系统有权限校验,也不意味着 Agent 应该看到全部 API。

两层防线解决的是不同问题:

  • 可见性控制减少 Agent 可以尝试的行动范围;
  • 业务授权决定当前主体是否真的可以执行。

当 Agent 开始操作真实订单、库存、员工和资金时,第一步不是把所有接口交给模型,再期待它一直做出正确选择。

第一步应该是明确:

哪些业务能力经过主动评审后,才允许进入当前 Agent 的视野。

这就是显式 opt-in 的价值。它很小,却决定了 Agent 的行动边界从哪里开始。

延伸阅读

  • ACC 规范与示例:https://agentcapability.org/docs/
  • ACC GitHub:https://github.com/agent-capability/agent-capability-contract
  • BailingHub:https://github.com/bailinghub/bailinghub

BailingHub 是一个实现 ACC 的开源控制面示例;ACC 本身保持实现中立,其他运行时、网关和工具平台也可以独立实现相同的声明语义。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐