把人工审批绑定到AI的具体执行动作
文章提出通过载荷哈希将审批令牌绑定到具体操作,并在状态变更前执行确定性检查。架构区分检索知识、实时API数据、业务规则与模型调优,避免用模型能力替代规则约束。
AI 深度解读
AI 提议调整额度、修改业务数据时,人点一次「同意」还不够:执行前请求可能被改,审批也可能被重复使用。这篇文章想解决的,是怎样把人的批准绑定到一笔具体操作,让执行服务能验证,让事后审计能还原。
作者给出的路线是:用确定性规则分配风险等级,对准确载荷审批,执行前校验,再留下不可变记录。思路值得借鉴,但示例代码存在签名校验不一致等问题,需要把架构主张和实现质量分开看。
人批准的究竟是哪一笔操作
作者把系统依赖的信息分成四类:上下文或检索组件保存已有知识,权威 API 提供请求当时的实时值,确定性代码执行业务规则,模型调优则在系统评估和标注之后进行。
这个划分解决的是职责问题。模型知道某条规定,不代表它每次都会遵守;检索找到了额度说明,也不代表账户此刻的额度仍然相同。涉及状态变更,实时查询和规则校验必须进入执行链路,不能只写在提示词里。
文章的完整流程是 Proposal → Risk-Policy Evaluation → Tier Assignment → Exact-Action Approval → Execution → Immutable Audit Record,即提案、风险评估、分级、针对具体操作审批、执行、不可变审计记录。
关键在「具体操作」。作者称,早期原型把审批结果存在一个可修改字段里,后续审计发现,下游服务可以在批准后修改请求。于是他们决定把准确载荷的密码学哈希写入审批令牌。
下面这个函数把载荷转换成固定格式的 JSON,再计算 SHA-256:
def payload_hash(payload: Payload) -> str:
"""
Returns a hex‑encoded SHA‑256 over the canonical JSON representation.
"""
canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"))
return hashlib.sha256(canonical.encode("utf-8")).hexdigest()
要看的是 sort_keys=True 和 separators=(",", ":"):它们固定了键顺序和分隔格式,减少序列化差异。若换成 Node 服务参与计算,还需要统一跨语言的序列化约定,不能默认两端得到相同字节。
载荷包含 action、entity_id、parameters 和 requested_by。批准后任何字段发生变化,执行端重新计算的哈希就会不同,需要重新审批。即使修改只是补充信息,也会增加一轮等待,这是作者明确承认的代价。
审批记录必须能证明,人同意的是执行端实际收到的那笔请求。
风险分级怎样减少人的等待
每笔操作都交给同一支合规团队,会让低风险事项挤占高风险事项的处理时间。作者提出三个确定性等级,用不同审核要求分配人力。
示例规则直接依据 value_change 和 irreversible 判断:
def risk_tier(payload: Payload) -> RiskTier:
"""
Simple deterministic rule set.
- Tier 1: value_change < 1 000 and reversible
- Tier 2: value_change < 10 000 and reversible
- Tier 3: otherwise (potentially irreversible)
"""
change = payload["parameters"].get("value_change", 0.0)
irreversible = payload["parameters"].get("irreversible", False)
if change < 1_000 and not irreversible:
return 1
if change < 10_000 and not irreversible:
return 2
return 3
要注意两个严格小于号:可逆操作变化值低于 1,000 进入 Tier 1,达到 1,000 但低于 10,000 进入 Tier 2;达到 10,000,或者被标记为不可逆,都进入 Tier 3。
Tier 1 走自动合理性检查,Tier 3 进入专门的双人审批队列。Tier 2 的具体审核要求,原文没有交代。对于 Tier 3,作者还要求单独记录「我理解此操作不可逆」的确认事件。
这些数值只是教学规则,原文没说明单位,也没有证明它们适合其他业务。代码同样没有覆盖所有输入风险:缺少 value_change 时默认取 0.0;较大的负值也可能进入低风险等级。如果减少额度同样会造成重大影响,这套比较方式就需要调整。
分级还必须带上策略版本。作者要求,每次决策记录 policy version;记录版本与预期版本不一致时拒绝决策。规则更新要递增版本,并用历史提案回测,再上线。
原文称模拟运行验证了相同载荷分级的一致性,但没有给出测试规模、样本或结果明细。同一策略下结果稳定,是确定性函数应有的性质;策略升级后等级是否合理,则需要另行验证。
我的判断
最有价值的是把规则、批准、执行和审计连成可验证的链路。与一个可修改的「已批准」字段相比,载荷哈希能发现审批后请求被改动;与只靠提示词限制模型相比,执行端的强制校验更适合作为业务边界。
不过,哈希绑定只能证明载荷没有变化,不能单独证明批准仍然有效。 示例令牌包含审核人 sub、签发时间 iat 和载荷 hash,却没有展示有效期、单次使用限制、审核人权限校验,以及 Tier 3 两名审核人的完整验证逻辑。相同请求能否拿同一个令牌再次执行,原文没解决。
代码还有一个更直接的问题:create_approval_token 用原始 header、body 字节计算 HMAC-SHA256,然后把它们转成十六进制放入令牌;verify_and_execute 却用十六进制文本计算预期签名。两端签名输入不同,正常签发的令牌也无法按预期通过校验。
作者称单元测试验证了修改载荷会触发 AssertionError,但没有展示测试。仅凭这个负向结果,无法证明合法请求可以成功执行。况且,生产入口不应依赖可能被禁用的 Python assert 来强制校验。示例末尾还截断在 ex,并不是完整可运行程序。
原文已注明固定密钥、类似 JWT 的令牌仅供教学,生产应换用成熟 JWT 实现并定期轮换密钥。但替换库仍然不能自动补全上述业务约束。
另外,文章没有提供审核积压、队列耗时或事故率的前后对照。风险分级能降低审核负担,目前属于有合理依据的架构经验,不能当作已经量化验证的收益。
能拿来做什么
- 在前端审批页展示最终执行的对象、动作和参数,并让服务端令牌绑定同一份载荷;批准后参数改变,就重新进入审批流程。
- 给 Node 执行接口补齐验证顺序:检查签名、有效期、审核权限、策略版本和载荷哈希,再执行幂等、原子的业务操作。AI 编程助手可以生成提案,执行入口负责守住规则。
- 把测试同时覆盖合法请求成功、批准后篡改失败、重复执行受控,以及策略版本不匹配被拒绝。不要只验证异常分支。
- 审计时保存载荷哈希、审批令牌、风险等级、策略版本、审核人标识和时间戳,并定期重算哈希、观察各等级平均排队时间。密钥轮换期间,还要处理当前密钥与上一把密钥的重叠验证。