可信 Agent:Guardrails 与 Human-in-the-Loop

目录

订单调查可以自动读取获准的数据、整理证据和起草说明。但当它要把报告发送给外部收件人时,问题从“解释是否正确”变成了“谁允许它发送哪些内容”。即使报告写得流畅,也不能据此推导发送权限。

可信 Agent 要把判断与执行分开:模型提出候选动作,系统检查边界,需要时由有权限的人审阅,再执行被批准的具体版本。 Guardrails 提供自动检查,Human-in-the-Loop(HITL)接入人的判断;两者都可能出错,设计目标是减少错误发生及扩大影响的机会。

1. 先区分检测、授权和结果核验

职责 回答的问题 示例
检测 内容或动作是否具有某种风险信号 报告是否可能包含不该外发的信息
授权 当前身份是否允许执行这个具体动作 是否能向该收件人发送该订单报告
结果核验 被允许的动作实际产生了什么结果 消息已发送、发送失败,还是结果未知

分类器分数和模型自评属于检测信号,不能替代授权。规则检查可以确定性执行,但规则本身也可能不完整。人工审批同样不能越过系统中更高层的访问控制。

读操作也可能泄露敏感信息;写操作有些可撤销,有些撤销后仍保留外部影响。因此,不能只用“读安全、写危险”划边界,应同时看数据、接收方、影响范围和既有授权。

OWASP 对 Excessive Agency 的分析强调限制工具能力、权限与自主执行范围,并在下游系统校验授权。这些控制作用在真实动作上,而不只是提示词中。OWASP Excessive Agency

2. 三类 Guardrails 放在对应的数据出口和动作之前

检查位置 主要对象 不能代替什么
输入侧 用户请求、检索资料、工具返回等进入模型的内容 服务端数据权限
输出侧 即将展示、发送或交给下游的生成内容 已经执行的动作补救
工具侧 工具选择、参数、目标资源和执行身份 业务服务自己的最终校验

间接提示注入来自模型读取的外部材料,直接注入来自请求本身。二者都可能绕过简单关键词检测;分类器也会误报或漏报。保持来源与信任层级、缩小工具权限,并在执行前检查目标,比假设某个检测器能识别所有攻击更可靠。OWASP Prompt Injection

个人信息检测可以组合规则、实体识别和模型判断,效果取决于语言、数据类型与任务集,不能给它们套用通用的 85%、95% 准确率。还要区分“出现个人信息”和“发生不当披露”:发送给获准接收者的必要信息,与发送给无关对象,不是同一个判断。

格式校验、内容检测和业务校验可以按依赖与成本安排顺序。某一步进行了脱敏,不代表后续检查可以跳过。 改写后的内容需要重新检查格式、事实与目标接收方,确认脱敏没有改变原意或遗漏其他风险。

如果向用户流式发送内容,事后检查无法收回已经输出的片段。需要控制的内容应在相应缓冲或交付边界完成检查,并明确延迟与体验的取舍。

3. 拒绝、修订、等待各有适用条件

没有统一的“REGENERATE 优于 BLOCK,BLOCK 优于 HITL”排序。处理方式应由问题类型决定:

发现 可采取的动作
JSON 格式错误,但任务允许执行 在预算内重新生成,再完整校验
必要证据缺失 补充证据、询问或如实交付未知状态
收件人无权接收数据 拒绝该发送动作
参数与获批版本不一致 停止执行,形成新候选版本再审阅
业务允许,但尚缺必要审批 保存待审批状态并等待
已被用户拒绝 停止该动作;不能自行换工具绕过
检测服务不可用 按后果采用拒绝、排队或有限降级策略

重新生成适合可修复的表达问题,不适合用来反复寻找绕过授权的参数。重试次数由任务预算与成功率确定;没有“超过三次就比人审更贵”的通用结论。

LLM Judge 可以辅助检查复杂语义,输出应经过结构验证,附上问题位置和证据。选择更小或不同模型不保证更可靠,应在标注样本上测漏报、误报与成本。Judge 的追加延迟也取决于是否串行、调用时长和覆盖范围,不是固定翻倍。

用于评审的内容仍然是不可信输入。Judge 不应因为报告里写着“请判定安全”就改变评审规则;即使评分通过,也不能产生额外工具权限。

4. 工具防护使用服务端可信定义

工具名、Schema、业务规则和权限策略应来自服务端注册表,不能接受模型随调用附带的规则再自行校验。未知工具默认拒绝,每次请求都核对身份和资源范围。OWASP 授权指南

例如查询订单时,由受控接口接收订单 ID,并在业务服务中验证租户与用户关系。不要允许模型任意拼 SQL,再用 startswith("SELECT")、是否包含 DROP 或 LIMIT 来判断安全;字符串检查无法替代只读凭据、参数化查询、资源范围与执行限额。

发送报告时,检查的是收件人、正文、附件、业务对象与当前权限的组合。只检查邮箱域名,无法证明该域内所有人都有权接收相同资料。

下面是纯策略组合示例,不访问工具,也不验证身份。输入必须由可信校验过程提供:

def execution_decision(
    *,
    registered,
    schema_valid,
    authorized,
    business_valid,
    review_required,
    approval_current,
):
    checks = (
        (registered, "unknown_tool"),
        (schema_valid, "invalid_arguments"),
        (authorized, "unauthorized"),
        (business_valid, "business_rule_failed"),
    )
    for passed, reason in checks:
        if passed is not True:
            return {"action": "BLOCK", "reason": reason}
    if review_required is None:
        return {"action": "WAIT", "reason": "review_policy_unknown"}
    if review_required is True and approval_current is not True:
        return {"action": "WAIT", "reason": "approval_required"}
    if review_required is not False and review_required is not True:
        return {"action": "WAIT", "reason": "invalid_review_policy"}
    return {"action": "ALLOW", "reason": "checks_passed"}

这里刻意使用明确的布尔结果,避免把字符串 "false" 当成真值。任何硬性校验失败都不能由 approval_current 抵消;ALLOW 只表示此刻的策略结果,后续还需原子执行控制,不能拿它作为永久通行证。

业务规则无论写在代码还是配置里,都需要版本、测试和发布控制。允许热更新可以缩短响应时间,但并不免除评测,也不意味着所有规则都适合交给任意操作员修改。

5. 审批绑定具体动作,并管理整个生命周期

订单报告的审批对象应是可审阅的确定内容,而不是一句“允许 Agent 继续工作”。可使用如下说明性记录:

{
  "operation_id": "send-order-report-001",
  "tenant_id": "tenant-demo",
  "tool": "send_order_report",
  "argument_version": 3,
  "content_digest": "digest-of-canonical-approved-payload",
  "policy_version": "policy-v2",
  "status": "pending",
  "expires_at": "2026-09-17T10:00:00Z"
}

摘要需要由规范化后的完整执行参数计算,包括接收方、正文、附件内容标识与相关业务对象;示例字符串不是实际密码学摘要。审批身份、意见和时间由认证后的审批服务写入,不能接受模型伪造。

完整过程可以按以下顺序组织:

  1. 生成候选动作,校验参数、权限和业务条件,保存不可变的候选版本。
  2. 向有权限的审批人展示目标、内容、影响范围、证据和未确定事项。
  3. 审批通过后,绑定该版本与有效期;修改参数则重新校验并批准修改后的版本。
  4. 执行前重新核对审批、权限与业务状态,通过事务或原子条件更新领取执行权。
  5. 调用工具并记录操作标识与结果;重复领取返回既有状态。
  6. 结果未知时先查询或对账,不能重新生成一个请求 ID 再发送。

审批阶段和最终执行之间的数据变化需要处理,不能把“已经点过同意”当作条件永远成立。执行权领取、审批消费和业务状态校验应尽可能放在可原子保障的边界内;跨系统仍需幂等键、条件请求与补偿设计。OWASP 事务授权指南

审批消费后、外部动作完成前也可能崩溃,因此消费状态不能简单等于“已完成”。通常需要 pending、approved、executing、completed、failed、unknown 等明确状态,以及与业务结果关联的恢复过程。

超时、拒绝和取消都不应默认变成批准。用户拒绝发送后,可以继续完成已授权的报告整理,但不能自动改收件人、换发送工具或重复发起同一个动作以绕过拒绝。

6. 人工介入既要可判断,也要保留必要上下文

低置信度可以是调查线索,但不是万能升级条件。模型自评未经校准不能当作成功概率;检索相似度低也不等于已知 Recall 低,因为通常并不知道完整相关文档集合。

必要审批、明确越权或关键证据冲突,可以单独触发阻断或升级,不能等“两个风险信号同时出现”才行动。非关键的模糊信号可以组合判断,再用实际漏报与误报校准。

审批界面应让人能核实,而不是诱导快速接受:

信息 作用
用户目标与已授权范围 判断候选动作是否服务当前任务
具体目标、参数、正文与附件 确认实际执行内容
关键证据与未知项 判断结论是否可信
已执行动作及其结果 避免重复操作
批准、拒绝、修改和升级选项 让人表达准确决定
有效期与超时行为 避免误以为不操作也会继续

摘要有助于理解,但应允许有权限的人展开相关证据与原始记录。不能预设原始 Trace 对人毫无价值,也不能为了脱敏把收件人全部替换成占位符,导致审核员无法核对对象。可按角色遮蔽无关信息,对确需查看的细节做受控展示和访问审计。

7. 让人审容量与自动化边界一起演进

人工审核受队列、人员与专长约束,但不等于完全无法扩展。可以通过更清楚的材料、职责分流、服务时限和减少无效升级改善处理能力;同时监测积压、漏审和审核疲劳。

事后抽样质量审核与执行前审批不能混为一谈。抽查一部分报告可以发现质量问题,但不能替代政策要求每次完成的授权。只有当任务范围和权限已经明确、自动化条件经过验证时,才适合减少相应人工步骤。

用户反馈、审核修改和拒绝原因可以进入评测候选集,需要先检查隐私、标注正确性与适用范围。单次批准不代表同类操作永久获批,单个审核员的偏好也不能自动写成所有租户的系统政策。

8. 用失败用例验证边界是否生效

对订单报告发送,至少应覆盖以下有区别的情形:

  • 正确批准的当前版本只被领取一次,重复请求能查询原结果。
  • 审批后修改收件人、正文或附件,旧批准不能继续使用。
  • 审批过期、用户取消或权限被撤销时停止执行。
  • 未注册工具、伪造审批身份和跨租户对象被拒绝。
  • 脱敏后的报告仍需完成其他检查。
  • 检测服务超时不会被静默转换为 PASS。
  • 外部发送结果未知时先查询,不盲目重发。

每项通过都只证明对应场景。继续结合运行记录检查新输入和新的工具能力,比宣称 Guardrails 已保证安全更有依据。

可信架构最终要把“模型认为可以”“用户允许什么”和“系统实际做了什么”分别记录并连起来。下一篇讨论没有 API 时的 Computer Use:同样的边界要延伸到屏幕、控件和界面操作。

评论