tool.completed 不等于业务动作已完成。本文用一个需要确认的写工具说明事件、权限和业务回执的最小接线。
在 AI 助手里,tool.completed 不是"业务动作已完成"的同义词。要让一次创建工单、提交采购申请或发送通知可追溯,应用需要把四种事件串起来:工具提议、权限决定、工具生命周期和业务系统回执。下面用一个需要用户确认的写工具说明最小接线边界。
先定义审计链的四个锚点
tool.proposed:记录工具名、toolCallId和经过筛选的参数摘要,回答模型准备做什么。tool.permission.decided:记录allow、deny或ask,以及decisionSource;它回答为什么放行或拒绝。tool.started、tool.completed、tool.failed:记录是否真正进入 handler、耗时和错误类型。- 业务回执:由 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 宿主中验证。