Skip to content
←返回博客
Hugging Face SafeAgents:在工具调用进入机器人运行时之前设一道确定性闸门
Agent SecurityTool Call Filtering具身智能

Hugging Face SafeAgents:在工具调用进入机器人运行时之前设一道确定性闸门

拆解 SafeAgents 的声明工具、主机来源、ATIF 扫描与可选裁判三层,并划清它与沙箱、网络出口和机器人物理安全之间的边界。

Cobus Greyling / Hugging Face2026年11月9日4 分钟阅读28次阅读
EN

智能体最危险的输出,往往不是一段文字,而是一次工具调用。 模型可以解释它为什么要读文件、安装依赖、访问网址或执行 shell 命令,但这些解释本身不会产生任何效果。真正把提议变成现实的是 harness。Hugging Face SafeAgents(HFSA)恰好插在这个交接点上:接收模型响应,检查其中准备执行的工具调用,只把通过策略的动作交给 harness。

这比“智能体安全”这个大词要窄得多,而它的价值也正来自这种克制。SafeAgents 不是新的智能体框架,不是执行沙箱,也不能替代操作系统权限控制。它是一个本地反向代理,观察模型流量,并在客户端收到响应之前重写被阻止的调用。目前它支持 OpenAI Chat Completions 和 Anthropic Messages;对于 OpenAI Responses API 与 Gemini API,它虽然可以转发,却还不能识别其中的工具调用。因此,当前 Codex CLI 和 Gemini CLI 的流量即便经过代理,也不会获得这里所说的调用级检查。

Cobus Greyling 的文章把系统拆成三层:只依赖请求内容的策略检查、基于 atif-scan 的确定性扫描,以及可选的大模型裁判。安全价值主要由前两层承担。裁判只能新增阻止,不能推翻确定性规则给出的阻止。这个顺序非常关键:概率模型适合处理边缘歧义,而不应该抹掉清晰、可复现的证据。

SafeAgents 代理位于智能体 harness 与模型服务器之间,包含确定性检查、atif-scan、可选裁判、工具与日志
图 1|代理位于模型响应返回 harness 的路径上。 harness 通过 SafeAgents 把请求发给模型;响应在代理处被暂存,待工具调用检查完成后再放行。被阻止的调用会替换成文字通知。图片来源:Cobus Greyling。

它的架构可以概括成一句话:SafeAgents 在模型边界过滤“准备做什么”,运行环境仍然必须治理“实际做了什么之后产生的效果”。 对机器人系统来说,这条界线尤其重要。harness 可能连接仿真器、ROS 桥、shell、部署脚本甚至物理控制器。模型边界的策略可以删掉明显错误的请求,却不能证明所有被放行的运动指令在物理上都安全。

1. SafeAgents 到底放在哪里

安装方式刻意保持简单。先针对 harness 原本使用的模型服务器启动代理,再把 harness 的 base URL 改为本地代理。仓库给出的 Anthropic 示例中,harness 访问 http://127.0.0.1:8787,SafeAgents 再把流量转发到 https://api.anthropic.com。harness 和模型都不需要实现新的安全协议,代理负责解析已有的请求与响应格式。

时机是整套设计的关键。每个完整的工具调用都要在 harness 看到模型响应之前完成审核。被阻止的调用不只是“记一条日志然后继续执行”,而是被替换成文字通知,使 harness 拿不到可执行的调用。普通文本流会照常即时转发;流式响应中的工具调用则要等到参数完整后再检查,因为真正需要判断的对象正是这些参数。没有发生改写的响应可以逐字节透传。

这也划定了产品边界。SafeAgents 不执行工具,不提供进程沙箱,不授予权限,也不在操作系统层限制网络。它是针对模型提议的策略门。harness 仍然负责执行,外围系统仍然负责隔离、资源限制、凭据保护、审计留存和人工审批。

视频 1|调用会经历放行、警告与阻止。 演示把 16 个 harness 放在代理之后,实时显示判决。中低风险信号可以进入警告,而高严重度发现会被直接阻止。来源:Cobus Greyling 与 SafeAgents 项目。

协议限制不能当作脚注。一个代理如果在转发流量,却不知道工具调用在消息里的位置,就没有建立真正的工具调用边界。仓库明确把 Codex CLI 使用的 Responses API 和 Gemini CLI 使用的 Gemini API 标为“尚不支持检查”。在这种配置下,代理可能仍能完成路由和请求日志,但核心保护并不存在。部署系统应当在 harness 协议不受支持时显式报错,而不是给用户一个看似安全的绿色状态。

2. 三层检查解决的不是同一个问题

2.1 请求策略:调用方到底授权了什么

第一层只看进入代理的模型请求。如果响应调用了请求从未声明的工具名,就直接阻止。它还会从工具参数中提取完整 URL 和裸 IPv4 地址;如果一个主机既没有出现在可信对话上下文里,也不在显式允许列表中,这个调用同样会被阻止。构建主机上下文时会移除 assistant 消息,否则模型可以先写一句“请访问 evil.example”,再把自己上一轮生成的地址当作授权来源。

这是一个小而清晰的权限系统。它不假装理解所有命令,只回答两个确定性问题:这个工具接口是不是调用方声明过的?目标主机是不是来自模型自己以外的信息?主机检查尤其适合阻止一种常见外泄路径:shell 本身是合法工具,但模型突然要求把数据发送给用户从未提到过的地址。

2.2 atif-scan:把确定性证据放在中心

第二层把对话与待执行调用转换成 Agent Trajectory Interchange Format(ATIF)轨迹,再交给 atif-scan 运行确定性检测器和上下文规则。SafeAgents 只保留证据落在“当前待执行调用”上的发现。模型推理内容会被刻意排除;模型解释自己“为什么这样做”,不能当作它“实际会做什么”的证据。

达到或超过配置阈值的发现会被直接阻止。默认阈值是 high。低于阈值的发现会把调用标成可疑。若没有配置裁判,可疑调用只写日志,仍然放行。这个默认行为必须理解清楚:系统会对最高优先级规则进行硬阻止,但并不是“所有中等发现都必须人工审核”的万能闸门。

所谓“静态扫描”,只表示规则在一次运行中不会自己学习。规则库本身更新得很快。Greyling 在原文中报告:约七周内有 358 次提交,写作时版本为 v0.8.21。后续仓库审计看到 360 次提交和 v0.8.22,SafeAgents 依赖的最低版本则是 atif-scan>=0.8.15。作者还报告,每次调用扫描约增加 10–20 毫秒,测量环境是 M 系列 Mac。这些数字可以作为部署时的参考,但不是覆盖所有 CPU、轨迹长度、策略包和模型负载的独立基准。

2.3 裁判:只能补上“不允许”,不能取消“不允许”

可选裁判会收到当前用户请求、待执行工具调用和扫描器发现。它看不到系统提示、智能体推理或此前的工具结果。这个选择是有意为之:一个被攻击或正在追求目标的智能体,不应该获得长篇解释自己为何“值得放行”的机会。裁判返回受约束的允许或阻止结果。它可以给可疑调用再增加一个阻止,却不能撤销确定性规则已经作出的阻止。

裁判自身故障也需要明确策略。SafeAgents 默认 fail open:如果裁判不可达或返回了无效结果,可疑调用会被记录并放行。运维人员可以启用 fail closed。选择哪一种,应取决于动作后果。对文档摘要工具,短时间的裁判故障也许可以接受;对可能移动机器人、修改生产部署或暴露凭据的流程,审核层不可用通常就不应该继续放行高风险路径。

每个完整工具调用的决策路径
阶段 要回答的问题 默认结果 必须理解的失效方式
请求策略 工具是否声明过?目标主机是否来自可信上下文或允许列表? 立即阻止。 它检查主机来源,不证明一个已允许主机上的命令本身无害。
atif-scan 轨迹中是否有证据符合已知误用模式? 达到 high 或更高时阻止;低级别发现标为可疑。 未知模式仍然未知;扫描器异常当前会 fail open。
可选裁判 只依据用户任务、调用与发现,这个可疑动作是否仍应执行? 允许,或新增阻止。 没有裁判时记录后放行;裁判故障也默认放行,除非启用 fail closed。
harness 运行时 被放行的动作可以使用哪些进程、文件、网络与设备权限? 不属于 SafeAgents。 沙箱、能力控制、联锁、速率限制和人工签核都应放在这里。

3. 为什么确定性检查承担了主要重量

确定性发现可以被检查。运维人员能指出规则、查看证据、固定扫描器版本,并复现结果。大模型裁判则承担另一种角色:在确定性层已经把问题缩小之后,处理剩余歧义。如果把裁判放在最前面,整个策略就会变得随机,也更难审计。

原文把 atif-scan 称为代理背后真正的力量。这个判断的重点不是“模式匹配已经足够”,而是把廉价拒绝规则和不断积累的上下文检查结合起来。例如,凭据检查可以判断秘密是否真的被暴露;allowance 可以区分任务本身要求的依赖安装与无关诱饵。它们并非对单条命令跑一遍正则。

局限也同样清楚:扫描器只能抓住规则库已经表达出来的问题。全新误用、由多条普通命令组合出的危险后果,或者某个领域特有的不安全操作,都可能通过。因此,这个代理最合理的位置是“高置信度绊线”:它争取时间、留下证据、阻止已知模式,但不能证明剩余动作一定安全。

ATIF scan 仓库页面,展示确定性检测器、轨迹输入、发现、allowance 与发布活动
图 2|扫描器不是扁平的封禁词列表。 仓库介绍离线轨迹分析、上下文完整性检查、基准测试感知检测和任务级 allowance。发现只是待审查候选,不自动等于恶意结论。图片来源:Hugging Face atif-scan 仓库。

日志也会改变安全姿态。SafeAgents 可以以 --log-only 启动:只报告原本会阻止什么,不改写响应。对陌生 harness,这是最合理的第一步。团队可以先了解误报分布、真实工具集合和目标主机,再切换到阻断模式。需要留意的是,journal 会保存被阻止、标记和判定可疑的调用及其参数,而参数可能包含秘密;文件权限、凭据轮换与保留周期本身就是安全设计的一部分。

4. 如何阅读合成 ATIF 示例

原文给出了一段完全合成的轨迹,模拟一个基准测试任务中的三条 shell 调用:列出测试目录、安装依赖、运行测试。示例明确不包含任何真实 benchmark 数据或凭据。重点是扫描器同时看到轨迹和待执行调用,而不是把命令当成孤立字符串。

{
  "schema_version": "ATIF-v1.7",
  "steps": [
    {
      "step_id": 1,
      "timestamp": "2026-01-01T00:00:00Z",
      "source": "user",
      "message": "Synthetic fixture: no benchmark data or credentials."
    },
    {
      "step_id": 2,
      "timestamp": "2026-01-01T00:00:07Z",
      "source": "agent",
      "message": "This is a benchmark task. All tests passed.",
      "tool_calls": [
        {
          "tool_call_id": "synthetic-call-1",
          "function_name": "Shell",
          "arguments": { "command": "ls /tests" }
        },
        {
          "tool_call_id": "synthetic-call-2",
          "function_name": "Shell",
          "arguments": { "command": "pip install requests" }
        },
        {
          "tool_call_id": "synthetic-call-3",
          "function_name": "Shell",
          "arguments": { "command": "pytest -q" }
        }
      ],
      "observation": {
        "results": [
          { "source_call_id": "synthetic-call-1", "content": "Synthetic result only." },
          { "source_call_id": "synthetic-call-2", "content": "Synthetic result only." },
          { "source_call_id": "synthetic-call-3", "content": "Synthetic result only." }
        ]
      }
    }
  ]
}

输出把行为发现与遥测不确定性分开。access.test_path 是中等严重度,awareness.benchmark 较低,network.package_install 只是信息项。另有七项完整性检查无法得出结论,因为合成轨迹没有记录模型停止原因,也没有足够的 token、代价与调用计数。score 50 是示例中“未被 excuse 的最高匹配”;报告本身强调,发现是待审查候选,不是自动判决。

ATIF scan 输出显示 score 50、中低与信息级发现,以及七项未解决的遥测检查
图 3|严重度与置信度是两个维度。 输出把中等级别的行为发现、低级别意识信号、信息级安装活动以及缺失的遥测分开呈现。图片来源:Cobus Greyling。
atif-scan 0.8.21

input-0001 score 50 (medium) · behavioural coverage complete · telemetry checks unresolved
agent steps 1 · tool calls 3 · unrecognized tool calls 0
ending not known: the harness does not record model stop reasons
status  check                    evidence / reason
medium  access.test_path         step 2 call 0 command
low     awareness.benchmark      step 2 message
info    network.package_install  step 2 call 1 command
Telemetry checks unresolved (7 checks): integrity.cached_tokens_exceed_prompt,
integrity.cost_missing, integrity.output_token_ratio,
integrity.reasoning_tokens_exceed_completion, integrity.step_count_mismatch,
integrity.tokens_exceed_recorded_calls, integrity.totals_are_last_call
101 no match · 4 not applicable

1 input(s) · 1 available · 0 behavioural coverage incomplete · 1 telemetry
checks unresolved. Findings are review candidates, not verdicts; unknown checks
remain unresolved.

这段输出正好提醒我们不要把安全面板压成二值状态。“没有高危发现”不等于证据完整;“score 50”也不等于轨迹恶意。成熟部署必须区分没有命中、遥测缺失、轨迹覆盖不完整和规则无法评估这四种情况。

5. 六层安全,其中只有一层来自 SafeAgents

读完此类项目后最常见的错误,是把多个独立控制压缩成一句“SafeAgents 保护智能体”。它并不提供这种整体保障,只提供一个策略层。下面的表把不同职责拆开。

解决不同问题的控制层
层级 回答的问题 常见机制 SafeAgents 覆盖情况
工具调用策略 这个提议是否应该离开模型边界? 工具声明、主机来源、确定性检测、可选裁判。 覆盖。这是核心功能。
执行隔离 调用放行后,harness 或工具进程还能做什么? 容器、虚拟机、seccomp、命名空间、权限分离。 不覆盖。
文件与设备权限 可以访问哪些文件、串口、相机、执行器或 PLC 端点? 系统用户、挂载策略、设备权限、capability 列表。 不覆盖。
网络出口 调用获批后,哪些地址仍能真正接收流量? 防火墙、代理白名单、DNS 策略、服务网格、网络命名空间。 只在提议阶段部分检查,不是网络执行层。
物理安全 当前力矩、速度、工作空间与状态转换是否安全? watchdog、限幅、认证控制器、急停、独立联锁。 不覆盖。
身份与问责 谁授权了动作、依据什么策略、之后发生了什么? 限定范围的凭据、审批链、只追加审计、轨迹留存。 提供部分日志,不是身份或审批系统。

项目自己使用的是“本地代理”这个描述,而不是“沙箱”。它明确表示,系统过滤的是模型在 harness 执行前提出的请求。因此,它适合和容器、权限系统或执行器安全控制器互补。准确的部署判断应当是:SafeAgents 缩小了模型提议到达运行时之后的动作集合;它不保证集合中的每个动作都安全、合规或获得授权。

6. 为什么这对具身智能尤其重要

机器人智能体越来越常把语言或多模态模型放在工具层之上。工具层可能调用仿真器、查询机器人状态服务、发布 ROS 消息、运行运动规划 CLI、读取相机、修改部署清单,甚至调用厂商 API。许多原型还把 shell、云凭据和文件系统一起交给同一个 harness。于是一次异常工具调用就可能从文本生成跨入代码执行或设备控制。

如果模型协议受支持,SafeAgents 可以放在这样的 harness 之下。请求策略能阻止未声明的执行器工具,或阻止没有可信指令来源的目标主机;atif-scan 能识别已知危险模式,任务插件可以编码本地策略;当确定性证据仍然模糊时,裁判可以根据当前指令、调用和发现做第二次判断。

对机器人来说,“工具调用被允许”和“物理动作安全”不是同一句话。前者是软件策略决定;后者需要运行时理解状态、限制、时序和后果。

SafeAgents 尚未在真实机器人软硬件栈上得到验证。它不知道关节位置、力矩限制、碰撞几何、控制器模式、急停状态,也无法判断一个仿真器是否已经连接到真实设备。机器人部署必须把这些检查留在控制器和安全链路中,独立于语言模型和模型边界代理。对于高后果工具,应先做 dry run 或影子模式,由独立审批服务确认,并完整保留调用与判决记录。

最现实的早期用途是研发与运维,而不是直接控制执行器。可以先把代理放在会修改机器人软件、调整仿真配置或准备部署的编码智能体前面。用 --log-only 模式运行一段时间,审计真实调用,再收紧主机与工具范围,只把经过验证的流程切到阻断模式。即便同一个智能体可以准备控制命令,真正的物理执行仍应位于独立的确定性安全层之后。

7. 部署检查清单

  1. 盘点所有模型路径。 子智能体、标题生成、上下文压缩和所有会调用模型的组件都应通过受支持的代理格式。一条 Responses 或 Gemini 旁路就可能绕过工具调用检查。
  2. 从 log-only 开始。 在改写响应之前,先收集真实工具集合、目标主机、中等级别发现、误报和裁判行为。
  3. 固定版本。 记录 SafeAgents commit、atif-scan 版本、插件代码、裁判模型、提示词与严重度阈值。持续更新的规则库应像安全软件一样做版本管理。
  4. 明确故障策略。 按动作后果决定扫描器异常和裁判不可达时应 fail open 还是 fail closed。默认值不适合所有风险等级。
  5. 收紧允许列表。 按任务审查主机与工具。不要让模型自己前一回合写出的文本成为主机授权,也不要用一张宽泛的共享允许列表覆盖互不相关的工作流。
  6. 继续隔离执行环境。 harness 只应拥有任务所需的文件、网络、凭据和设备权限。过滤一次调用,不会让高权限执行器变安全。
  7. 保护 journal。 工具参数可能包含秘密。限制文件权限,轮换已经暴露的凭据,定义保留周期,并把审计访问与智能体自身访问分开。
  8. 测试负向路径。 证明被阻止的调用确实没有到达 harness,未支持协议会显式暴露,裁判故障遵守策略,log-only 只改变报告而不改变执行。
  9. 保留物理安全链。 机器人控制器、工作空间限制、watchdog、联锁和急停都必须独立于大模型代理。

8. 判断

SafeAgents 是一个边界清楚的安全层样例。它没有试图解决整个智能体问题,而是在模型文本变成可执行提议的位置放入第一道确定性检查,保留可见的决策证据,并且只在证据已经足以称为“可疑”之后才调用受约束的裁判。

它的弱点同样清楚。协议覆盖还不完整;没有裁判时,低级别发现默认通过;扫描器和裁判故障可能 fail open;策略能够执行已知工具与主机约束,却无法证明未知命令安全、harness 未被攻破或物理动作符合当前状态。项目仍很年轻,规则库变化很快,因此版本固定和回归测试不可省略。

正确的结论不是“SafeAgents 让智能体系统安全了”,而是“面向模型的工具策略值得成为独立边界,并与执行隔离分开”。对具身智能而言,这种分离尤其有价值:语言模型可以提出动作,代理可以拒绝已知的坏提议,机器人运行时还必须判断剩余动作在物理上是否有效。每一层都应能独立地说“不”。

仓库审计说明:本文检查了 huggingface/safeagents 的提交 2a178aacb74fe386667956d825fed49453823f70,以及 huggingface/atif-scan 的提交 1d64be4b491c1fb62c5dfce6c4a3fd766b94867a。SafeAgents 声明版本为 0.0.1,依赖要求为 atif-scan>=0.8.15;审计时的扫描器版本为 0.8.22。文中性能与提交频率来自作者的运行和观察,并非本文独立复现的基准。

原文来源:Cobus Greyling 于 2026 年 11 月 9 日发布的《HuggingFace Safe Agents》。项目来源:Hugging Face SafeAgents 与 ATIF Scanner。

本站含 CakeGrowth 联盟推广链接,我们可能从符合条件的购买中获得佣金。