审批与人工接力
执行生命周期在 Agent 运行一个已声明动作之前,会到达一个确认决策。这个决策对应两种不同的人工参与方式。
审批回答 Agent 是否可以执行当前这次调用。Agent 仍是执行者。用户批准,页面已声明的处理函数运行;用户拒绝,调用结束,不进入该处理函数。
人工接力回答操作中的哪一部分必须由人完成。执行者发生变化。Agent 请求这一步,人在页面中操作,运行时等待后继续。Agent 不模拟人的工作。
本章所说的审批,指页面运行时对一次调用的交互确认。它不是企业审批记录、身份证明或后端授权的替代。这些是不同的机制。
执行流水线把这一步称为确认。本章用审批指代人在这一阶段作出的决定。
两个问题,不是同一条强度阶梯
订单页可能同时提供「批准退款」和「使用安全密钥签名」。两者风险都高,但需要不同的响应。
| 决策 | 回答的问题 | 执行者 | 运行时行为 |
|---|---|---|---|
| 审批 | Agent 是否可以执行这次调用? | Agent | 询问用户;得到肯定决定后才运行 |
| 人工接力 | 哪一部分必须由人完成? | 用户 | 不运行 Agent 的执行路径;等待用户,再验证结果 |
它们不是同一个控制的两种强度。更严格的审批提示仍然不能输入一次性验证码、选择本地文件或使用硬件密钥。人工接力也不表示 Agent 已获准准备、提交或完成周边操作。
一个操作可以同时需要两者。用户可能先批准一笔退款,再完成只有本人能做的银行确认。复合动作也可能在人工步骤前后都有 Agent 执行的步骤。审批和人工接力可以在同一次业务操作中相邻出现,但它们回答的问题不同。
审批针对一次具体调用
审批是执行路径中的闸门。Agent 已经选中动作并给出参数;运行时已经解析目标、校验输入。此时要决定的是,这次具体调用是否可以继续。
页面模型会标记需要确认的动作,模型因此可以预期这次中断并说明原因。这个标记不是授权。它只告诉 Agent 存在一道闸门;动作被调用时才执行检查。
判断的单位是业务后果,不是 DOM 元素种类或 HTTP 方法。更改列表筛选可以是只读操作;更新备注可能是可逆的;批量删除可能不可逆;导出客户记录在代码上是只读操作,却会把数据带离页面。
| 操作 | 可能的默认策略 | 理由 |
|---|---|---|
| 更改列表筛选 | 不询问 | 可逆的视图变化,没有业务写入 |
| 编辑备注 | 由应用决定 | 影响较低,但其他用户可能看到 |
| 批准退款 | 询问 | 改变资金状态,撤销成本可能很高 |
| 删除选中的订单 | 每次都询问 | 不可逆,且影响范围可能很大 |
| 导出全部客户记录 | 询问 | 只读,但数据离开了页面边界 |
read 不表示动作无害,write 也不能单独决定严重程度。声明必须说明操作改变什么、影响什么,以及结果能否撤销。
确认策略及其作用范围
能力描述把选择表达为不额外确认、ask 或 always。运行时将其解析为 none、ask 或 ask-always。多数应用只需要三种行为:
| 策略 | 行为 |
|---|---|
| 不额外确认 | 不询问,直接运行 |
| 询问 | 调用前询问;可向用户提供针对同一动作形状的会话内快捷授权 |
| 每次都询问 | 每次调用都询问;不提供「始终允许」 |
动作声明可以要求比默认更严格的策略。它也可以被显式设为不确认,但这应当由应用有意识地决定,不能成为绕开运行时的捷径。声明从不授予后端权限。
危险动作通常使用每次都询问的策略。如果用户在询问策略下选择「始终允许」,快捷授权覆盖当前运行时会话中的同一动作形状,不覆盖单条记录,也不覆盖所有动作。这对重复的行内操作有用,但不适合破坏性操作:对一条记录的批准不应自动覆盖另一条目标。
当前参考实现默认只对声明为危险的动作询问。应用可以选择更严格的模式,对写操作也询问。前一种模式打断更少;后一种在声明不完整时多一层保护。两种模式都不能替代准确的声明或后端授权。
一个动作一旦解析为询问或每次都询问,缺少确认通道时不能静默变成批准。调用会被拒绝。用户没有回答确认提示时,也按拒绝处理。清空待确认提示会拒绝这次请求,而不是让 Agent 循环一直等下去。
用户批准的是什么
审批决策应识别操作,而不只是控件。确认请求因此携带动作 id、业务说明、风险等级和将要使用的参数。确认界面必须让用户足以认出这项操作。至少应展示动作 id 和说明;某个参数会实质改变后果时,界面也应展示该参数。对于复合动作,按顺序执行的步骤应可查看。
参数中的引用可能在决策前已经还原,因此更完整的确认界面可以展示实际会运行的值。确认界面可以遮蔽敏感值,但不能在不展示变化的情况下替换成另一组值。对一个已展示操作的批准,不能授权另一个隐藏操作。
复合动作作为一次业务操作审批。运行时取当前能够从步骤中解析出的最高风险,并按这一档询问一次。如果后面的某一步比已批准范围更严格,执行到该步时会再次询问。续跑流程会沿用剩余步骤的已批准范围,不会因此取得新的、更宽的权限。
单次决策覆盖该次调用,不延伸到另一个目标、一项新操作或后续会话。询问策略的「始终允许」是显式例外:用户已经选择在当前运行时会话中记住同一动作形状的许可。
拒绝会结束本次调用。Agent 可以解释后果,或请用户重新作出决定,但不能把拒绝描述为批准,也不能静默改用更低层、产生相同效果的序列。
审批不能建立什么
运行时审批记录的是页面中的某个人对这次调用作出了决定。它不证明此人是谁、后端赋予了哪些角色,也不证明业务规则允许该操作。
| 审批可以建立 | 审批不能建立 |
|---|---|
| 某人允许这次调用继续 | 用户的身份或业务角色 |
| 决策针对已展示的参数和目标 | 后端对该资源的授权 |
| 被拒绝的调用没有进入页面处理函数 | 业务操作已经成功 |
| 当前运行时会话中收集到一次用户意愿 | 持久、可转让或覆盖整个组织的同意 |
对受监管或高价值操作,页面确认之后可能还需要后端审批,并绑定用户、Agent、会话、能力、目标、规整后的参数、有效期和请求 id。审批回执留在受信任的页面流程与审批后端之间,不进入 Agent 上下文。这些控制补充运行时审批,不替代它。
人工接力是一种执行方式
有些步骤即使整个任务可以委托,也不能交给 Agent。输入一次性验证码、完成图形挑战、选择本地文件、按下硬件密钥、使用个人证书签名或通过生物识别,都要求本人操作。
这类步骤声明为人工接力。动作仍可出现在页面模型中,因为 Agent 需要知道这项业务操作存在并应由它发起。调用时,运行时先校验动作及其目标,再请人完成这一步;它不会调用动作正常的页面处理函数。
接力请求带有原因,界面可以展示给用户。人通过页面自己的控件完成步骤。运行时等待三种结果之一:完成、取消或超时。默认等待五分钟,可以按步骤或由应用配置。
同一步不会再叠加审批提示。人正在执行这个动作,再问一次「Agent 是否可以做」是重复的。这不会移除同一操作中其他由 Agent 执行步骤所需的审批。
用户表示已完成时,运行时会检查声明的后置条件。条件成立,操作继续,回执记录该步骤由用户完成。条件不成立,结果是 HANDOFF_FAILED;用户点过完成按钮,不能被当作业务结果已经发生的证明。
每个接力都应尽量声明期望。没有期望时,运行时只能记录用户声称已完成;它仍可比较页面快照,但无法独立验证业务条件。
取消和超时并不证明页面没有变化。Agent 没有运行声明的处理函数,但用户可能已经在页面中操作过。安全的下一步是检查当前状态或询问用户,而不是自动重复人工接力。
分步人工接力
用户可能需要不止一句指引。分步接力按顺序展示操作说明,例如先选择文件,再确认文件名。每一步包含一句短说明,并可指定一个高亮目标。
高亮是视觉指引,不是能力。它可以指向一个已注册动作、一个只用于展示的指引目标,或者在未指定目标时指向发起接力的动作。只用于展示的目标不会成为工具,不会进入页面观察,也不会授予 Agent 操作底层控件的权限。
这一点对必须由人操作的输入框很重要。一次性验证码输入框可以被高亮,让用户知道在哪里输入,同时仍不注册为 Agent 动作。仅仅因为字段被高亮,运行时不会把用户输入的值读入模型上下文。
切换到上一步或下一步只改变界面正在讲解的位置,不执行业务动作,也不把步骤标成完成。内置界面在最后一步显示完成控件,运行时只使用声明的期望验证一次。
逐步骤验证被有意省略。有些步骤不会产生可独立观察的状态,为每条指令都加检查会制造精确性的假象。最终条件才是契约;步骤说明帮助用户到达那里。
复合动作中的人工步骤
复合动作可以同时包含 Agent 执行和人工执行的步骤。Agent 只调用一个工具;运行时先运行前面的步骤,在人工步骤停下,等待用户,然后继续执行剩余步骤。步骤账本会记录哪一步需要人工。
人工接力应写在特定步骤所属的动作上。把整条复合动作标成人工接力,会把整个操作交给用户,并跳过它的内部步骤。全手工流程可以这样声明,但不能用它表示其中一步需要人做。
外层调用仍可能因为前后有 Agent 执行的步骤而需要审批。审批覆盖该操作中由 Agent 执行的后果。人工步骤本身不会再审批一次。如果后面的步骤超出已批准风险,运行时会先询问再运行。
例如,发票导出可能先打开弹窗,再请用户输入一次性验证码,然后由页面生成文件。Agent 可以发起导出并打开弹窗;验证码输入是人工接力。最终期望确认文件已经存在,之后才把操作报告为完成。
失败结果
审批失败和接力失败的含义不同。错误码以及在失败时由谁控制执行,决定运行时知道什么。
| 情况 | 结果 | 已知事实 |
|---|---|---|
| 没有配置确认通道 | PERMISSION_DENIED | Agent 的执行路径没有运行 |
| 用户拒绝审批 | PERMISSION_DENIED | Agent 的执行路径没有运行 |
| 等待审批超时 | PERMISSION_DENIED | Agent 的执行路径没有运行 |
| 没有配置接力通道 | HANDOFF_FAILED | Agent 没有模拟人工步骤 |
| 用户取消接力 | HANDOFF_CANCELLED | Agent 的执行路径没有运行;用户自己的操作可能已经生效 |
| 接力等待超时 | HANDOFF_TIMEOUT | Agent 已停止等待;页面可能已经变化 |
| 用户报告完成,但期望不成立 | HANDOFF_FAILED | 没有观察到业务条件;页面可能只完成了一部分 |
这些结果是恢复的起点,不是自动重试指令。人工接力失败后,Agent 应检查页面,或询问用户流程停在哪里。没有这项检查就重复步骤,可能重复人工操作,或打断仍在完成的流程。
审批失败不授权另一条执行路径。用户拒绝一个已声明动作后,Agent 不应使用未声明的 DOM 操作或另一条低层序列完成相同结果。任何替代方案都必须是独立的业务动作,带有自己的后果说明和确认策略。
小结
审批与人工接力都涉及人,但它们改变执行生命周期的不同部分。审批保留 Agent 的执行者身份,决定当前调用是否可以继续。人工接力为一个步骤更换执行者,要求人完成 Agent 无法完成的工作。
审批必须把决定绑定到已展示的操作及其参数。它不能替代身份、后端授权或企业审批。人工接力必须跳过模拟执行,等待用户,并验证声明的结果。两条路径都按失败关闭处理;在页面给出所需证据之前,都不应报告成功。

