pending_approval 判定时,该智能体的工具调用被挂起
而非派发——它现在在等待一名人工。本页面向审查者:如何从控制台批准智能体
工具调用挂起(或拒绝它们)、队列向你展示什么,以及 OrcaRouter 如何防止
两名审查者在同一个决策上相撞。
这是人工介入的解决那一半。关于一个调用为什么被挂起以及被挂起的智能体
之后如何重新提交,参见 判定 以及更深入的
审批参考。要从你自己的系统而非控制台解决,
参见 审批 webhook。
1. 从审查者视角看被挂起调用的生命周期
一个被挂起的调用是一个简短的带外循环。你的工作是中间那一步:该调用被挂起
一条规则解析为
pending_approval。中继返回 HTTP 400,带码
firewall_approval_pending 和一个审批 id;该调用从不到达工具。智能体
开始在那个 id 上轮询。解决一个挂起被门控到 Developer+——与防火墙 Events 信息流相同的门。更低
角色可以读取防火墙策略、设置和 discovered tools,但只有 Developer 及以上
角色才能列出审批队列或批准/拒绝一个被挂起的工具调用。参见
角色与范围。
2. 列出挂起队列
Approvals 标签读取GET /api/workspace/firewall/approvals。无过滤时它返回
pending 队列,最旧优先——所以等待最久的调用位于顶部,你按顺序处理
积压。
state 是那个重要的过滤器。这些值映射到审批的生命周期:
state | 返回的审批 |
|---|---|
pending (默认) | 已挂起,等待一个决策——你的工作队列。 |
approved | 已放行。 |
rejected | 已拦截。 |
3. 读懂该调用为什么被挂起
每一行携带审查者需要的决策输入——工具名(tool_name)、一个参数
指纹(args_hash,规范化调用参数的 SHA-256——原始参数值不存储在审批中)、
请求 id,以及一行点名触发的策略、规则和子句的朴素英文来源行:
policy_name —— 哪条策略挂起了它
policy_name —— 哪条策略挂起了它
匹配规则所属的命名策略,工作区限定地解析,这样一个陈旧的 id 永远无法
浮现另一个租户的策略名。
rule_label + matched_clause —— 人类可读的原因
rule_label + matched_clause —— 人类可读的原因
规则的标签和一行”为什么”描述符——例如
command contains rm -rf,或对
一条仅 glob 规则的 tool matches "http_fetch"。这渲染队列中的
“Held because…” 行。rule_changed —— 你可以信任的来源
rule_changed —— 你可以信任的来源
当匹配规则在这个审批创建之时或之后被编辑时为
true。此时实时标签和
子句被抑制(它们可能不再反映实际挂起该调用的东西),而队列显示一个
“rule since changed” 提示而非陈旧的来源。工具名和参数——真正的决策输入
——总是被显示。4. 批准或拒绝
解决发送PATCH /api/workspace/firewall/approvals/:id,带一个 approved
或 rejected 的 decision 和一个可选的 reason。当你点击按钮时控制台为你
做这件事;其形态是:
approved→ 被挂起的调用可以继续。智能体携带一次性审批头的下一次 重新提交被放行一次。rejected→ 该调用保持被拦截。智能体看到这次拒绝,能另选一条路径、 询问用户,或停止。
decision 对照封闭的 {approved, rejected} 集合验证——其他任何东西都被
拒绝。reason 与该决策一起被记录,并连同行动者、工具名和请求 id 一起写入
防火墙审计日志。
每一次解决都写入一个工作区审计行,点名谁决定、决策以及原因。控制台
解决记录人类行动者;webhook 解决
记录一个系统行动者。解决来源绝不会被静默丢弃。
5. 首个写入者生效:没有双重解决
一个挂起审批可能被竞争——控制台里两名审查者,或一次控制台点击和一个 webhook 回调 一起到达。OrcaRouter 用一条单一的首个写入者生效规则解决它:- 该决策是一个原子的条件更新,只在该审批仍是
pending时触发。第一个 写入者胜出并应用该决策。 - 每个更晚的写入者观察到”已解决”,并被当作一个幂等空操作——它得到 HTTP 200,带已解决的文档,而非一个错误。
resolved: true 意味着你的调用应用了该决策;already_resolved: true
意味着某人(或某个 webhook)先到了那里,而你看到的是他们的结果。无论哪种
方式,队列都对账到一个一致的状态。
6. 一次具体地处理队列
一个 balanced-autonomy 工作区挂起了一个智能体的shell.exec 调用,因为一条
规则匹配了 command contains rm -rf。作为审查者,你:
- 打开 Approvals——被挂起的
shell.exec位于最旧优先的pending列表 顶部。 - 读取该行:工具
shell.exec、args_hash指纹、请求 id,以及 “Held because…command contains rm -rf” 行(从匹配规则的子句渲染)。 没有rule_changed标志,所以来源是最新的。 - 目标是一个临时目录,所以你带一个原因批准。
- 你的
PATCH返回resolved: true;智能体的下一次轮询看到approved、 携带它的一次性头重新提交,而该命令恰好运行一次。
already_resolved: true——无害,无双重运行。
接下来去哪里
审批参考
完整的 HITL 循环:挂起、轮询、重新提交以及一次性头。
审批 webhook
用一个 HMAC 签名的回调从你自己的系统解决挂起。
判定
pending_approval 在六个防火墙判定中的位置。
事件日志
在信息流中确认一个已解决调用的下游结果。
