跳到正文
Elaine Blog
返回

工具什么时候可以执行:授权、审批与可恢复工作流

更新于:
Tool Calling 与 MCP

用户允许助手处理售后,不等于已经批准任意金额的退款。账号有退款权限,也不等于同意这次具体操作。工具执行需要同时回答“能不能做”和“是否同意做这件事”。

本篇用教学退款草稿解释这两个边界。实际金额、审批策略和身份验证由业务系统负责,示例只模拟状态变化,不连接支付服务。

先把动作变成可审阅的草稿

模型可以根据对话提出草稿:A1042、10000 分、CNY、退回原支付渠道。应用读取订单归属、剩余额度和适用规则后,再给用户展示待执行动作。

审批界面不能只显示“允许 Agent 继续”。至少要让用户知道操作、对象、金额、目标与关键影响。对于文件修改,可以展示具体差异;对于退款,展示业务参数及其依据。

参数标准化应发生在批准之前。若批准后才把“100”解释为另一种币种或单位,用户批准的内容和实际执行内容就不一致。

批准需要绑定哪份动作

一条批准记录可以包含审批 ID、主体、操作 ID、草稿版本、参数指纹、决定、创建时间和到期时间。指纹方便识别变更,真正的访问权限与审批来源仍需可信系统保证。

{
  "approval_id": "approval-9",
  "operation_id": "refund-op-9",
  "draft_revision": 2,
  "decision": true,
  "expires_at": "2026-09-11T12:10:00+08:00"
}

这是教学数据结构,不是协议通用格式。若金额从 100 元改成 200 元,草稿版本或参数指纹改变,旧批准必须失效。不能只根据“这个用户之前点过同意”放行。

同样,用户批准某个订单的退款,不应被复用到另一张订单。业务操作身份与参数绑定,使重复点击能关联同一意图,又能阻止扩大范围。

一个容易忽略的布尔值错误

Python 的 bool("false") 是 True,因为非空字符串被视为真。若审批来自 JSON,应用应要求真正的布尔类型,而不是任意值都转一次 bool。

def parse_decision(payload: dict) -> bool:
    """仅接受 JSON 布尔值,缺失或字符串都明确拒绝。"""
    if set(payload) != {"approved"}:
        raise ValueError("审批字段不完整或包含未知字段")
    if type(payload["approved"]) is not bool:
        # type 的严格检查避免把字符串、数字误当成合法批准。
        raise ValueError("approved 必须是 true 或 false")
    return payload["approved"]

即便类型正确,也不能接受模型自己生成的 approved=true 作为人类批准。请求必须来自经过认证和授权的审批通道,并绑定当前操作。类型检查解决数据格式,审批来源解决信任。

暂停与恢复之间发生什么

工作流在审批节点暂停,保存任务状态和待确认参数。用户回应后,服务端验证审批身份,再恢复对应任务。拒绝进入明确拒绝分支,过期需要重新审阅,取消不等于批准。

LangGraph 的 interrupt() 可以表达这种暂停,恢复节点时会从节点开头重新执行,因此它之前不应放不能重复的副作用。相关机制见 Interrupts 文档

例如在 interrupt 前发送邮件,恢复时可能再发一次。更合适的安排是前面准备无副作用的审批数据,批准后由独立执行节点完成,并与业务幂等结合。

现有 safe_tool_graph.py下载 改为使用同目录的审批运行时,展示严格解析与参数绑定。它仍然使用内存 Checkpointer 和模拟账本,不承诺进程重启后的恢复或真实退款 exactly-once。

批准之后为什么还要检查

用户等待五分钟后点批准,但订单可能已经由另一个客服处理,剩余额度减少,或用户权限被撤销。执行前应重新检查影响合法性的状态。

不是每个变化都需要重新审批。无关备注改变可能不影响操作;金额、目标、受款对象和关键业务条件改变则可能使原意图不再成立。策略应列明哪些参数与版本参与批准绑定。

审批服务记录“用户同意”,业务服务记录“实际执行”,两者分开保存。如果操作结果未知,不能通过让用户再点一次批准来解决通信问题,应该先查询操作记录。

不同动作需要不同确认方式

读取当前用户订单通常在已有任务授权范围内执行。可逆草稿写入可按产品规则自动完成并展示结果。外部通信、退款或删除是否需要额外确认,应结合用户已有授权、对象和影响判断,而不是所有工具一律弹窗。

反复要求无意义确认会使用户习惯性点击,真正高影响的决定反而不容易注意。审批应围绕具体需要人判断的变化展开,并保持参数清楚、范围有限。

生产中还可能需要职责分离,例如申请人与批准人不同。这属于业务审批策略,不能仅靠 Prompt 写“需要主管同意”实现。

审批、幂等和补偿怎样配合

审批决定是否允许某个意图执行;幂等减少同一意图重复造成的效果;补偿处理已经发生的部分结果。三者解决不同阶段的问题。

配套 approval_runtime.py下载 把 Draft、Approval 和 Ledger 分开。调用方必须带匹配批准,参数改变会失败,相同操作再次提交返回已有结果。它只是顺序内存模型,正式系统需补认证、原子持久化及下游回执。

把这些边界先设计好,后面将工具放进 MCP Server 时,才能保留同样的业务规则,而不是以为换了协议就获得可靠审批。

继续阅读

上一篇:工具调用失败以后:超时、重试、幂等与取消

下一篇:为什么需要 MCP:从本地工具到跨应用能力连接

下载文件、依赖与运行边界见配套指南下载


分享这篇文章:

上一篇
工具调用失败以后:超时、重试、幂等与取消
下一篇
为什么需要 MCP:从本地工具到跨应用能力连接