别把 tool.completed 当成业务成功:AI 工具权限审计的四层事件链

tool.completed 不等于业务动作已完成。本文用一个需要确认的写工具说明事件、权限和业务回执的最小接线。

在 AI 助手里,tool.completed 不是"业务动作已完成"的同义词。要让一次创建工单、提交采购申请或发送通知可追溯,应用需要把四种事件串起来:工具提议、权限决定、工具生命周期和业务系统回执。下面用一个需要用户确认的写工具说明最小接线边界。

先定义审计链的四个锚点

  1. tool.proposed:记录工具名、toolCallId 和经过筛选的参数摘要,回答模型准备做什么。
  2. tool.permission.decided:记录 allow、deny 或 ask,以及 decisionSource;它回答为什么放行或拒绝。
  3. tool.started、tool.completed、tool.failed:记录是否真正进入 handler、耗时和错误类型。
  4. 业务回执:由 handler 调用的业务服务返回 businessRequestId、状态和查询入口,回答外部系统到底发生了什么。

第一到第三项来自运行链,第四项必须由业务服务提供。不要用模型最后一句话代替第四项。

让权限决定进入自己的审计出口

下面是接线示意,省略模型客户端、真实业务服务和 UI;它展示责任边界,不是复制即上线的完整教程:

ts 复制代码
const createTicket = defineTool({
  name: 'create_ticket',
  description: '创建当前用户有权提交的工单',
  readOnly: false,
  parameters: {
    title: { type: 'string' },
    priority: { type: 'string' }
  },
  handler: async (args) => ticketService.create({
    tenantId: auth.tenantId,
    userId: auth.userId,
    idempotencyKey: requestContext.idempotencyKey,
    ...args
  })
});

const session = await createSession({
  client,
  tools: { custom: [createTicket] },
  permission: {
    rules: { ask: ['create_ticket'] },
    askUser: async (call) => ui.confirm(call.name)
  },
  onDecision: (record) => audit.write({
    ...record,
    userId: auth.userId,
    tenantId: auth.tenantId
  })
});

这里的 onDecision 只接住权限决定;它不能替代业务回执。审计表还应在 handler 开始、结束或失败时补运行状态,并在业务服务返回后写入 businessRequestId 和权威状态。参数是否完整落盘由应用按敏感级别决定,不能把令牌、客户资料或完整请求体无条件写进审计日志。

权限决定的三种结果不能混成一个布尔值

allow 表示这次调用通过权限判断,deny 表示被拒绝,ask 表示需要确认或进入询问面。没有接入 askUser 时,涉及确认的调用可能按 fail-closed 被拒绝;应用应把这个结果显示为"需要确认/策略拒绝",而不是空数据。decisionSource 能帮助排查是用户、规则、模式、策略还是钩子做出的决定;matchedRule 若存在,也可以用于管理者复盘。

createSessionView 适合把这些会话事件投影成工具卡、确认提示和错误状态,但它不替应用保存审计数据库。页面要同时显示工具状态和业务状态:工具完成后仍要查询业务请求号,才能决定显示"已受理""处理中"还是"结果未知"。

超时后先查回执,再决定重试

业务写工具至少需要一个稳定请求号。调用超时可分成三类:尚未提交、已受理但未返回、已经有明确结果。应用先按请求号查询业务系统;只有确认未受理且业务接口允许重试时,才重新提交。SDK 的会话事件可以帮助你标记运行阶段,去重和补偿仍属于业务服务。

什么时候采用这条链

它适合 Node.js 或 Electron 应用中同时存在多轮任务、需要用户确认的工具和可查询的业务回执。Tansr 可以组织工具、权限和会话事件,把决定通过 onDecision 暴露给应用;应用仍负责身份、租户、幂等、审计存储和数据脱敏。一次固定查询或已经具备完整审计链的运行框架,不需要为了增加一条事件而迁移。

最小验收包括:允许、拒绝、等待确认各跑一次;确认工具开始和完成事件可见;超时后能按业务请求号查到最终状态;审计记录不会泄露参数中的敏感字段。完成这些检查后,再决定是否扩大写工具范围。

接口依据见 Tansr 的PermissionOptions、PermissionRules、会话与事件流和createSession。

示意代码省略真实模型和业务服务;上线前必须在自己的 Node.js 或 Electron 宿主中验证。

相关推荐
Henry-SAP几秒前
SAP PP中的核心业务流程——离散制造、重复制造、流程制造三大模式解析
前端·数据库·人工智能·制造
徐小夕6 分钟前
下载量超 30 万的开源智能体 Prime Agent:它把自己从 TypeScript 重写成了 Rust
前端·vue.js·github
Zhao-Jichao11 分钟前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
Moment36 分钟前
为什么这么多 Agent Harness 都选择 TypeScript
前端·后端·面试
toooooop843 分钟前
CRMEB 故障排查笔记:安全网关只放行 GET/POST 怎么办
前端·javascript·vue.js·thinkphp6·crmeb
涛涛ing1 小时前
我现在最怕的不是 AI 写不出代码,是它写得太快,快到我不好意思说“等一下”
前端
AllData公司负责人1 小时前
【产品便捷使用一】AIIData 数据中台:企业基础版核心能力支持,一站式全链路数据处理实操指南
大数据·前端·数据治理·数据可视化·数据开发·数据服务·数据接入
vipxieliang1 小时前
JavaScript 模板字符串与标签模板:不只是拼接
前端·javascript
恋猫de小郭1 小时前
Flutter 开始支持 Jetpack Compose Platform View
android·前端·flutter
IT_陈寒2 小时前
React实战技巧总结
前端·人工智能·后端