Skip to content

React + AI 应用开发

AI Tool Calling 的确认、审批和执行状态如何设计?

工具调用 UI 不是展示一个“执行中”,而是要把提议、审批、执行、结果和失败拆成可审计状态。

适合阶段:资深前端 / Agent 应用面试核心能力:状态机 · 人在回路 · 幂等

面试官想考什么

  • 模型提出 tool call 后能否自动执行? 考察权限与风险边界。
  • 确认弹窗展示哪些信息? 考察用户可理解性。
  • 工具执行失败如何重试? 考察幂等和状态恢复。
  • 结果如何回填对话? 考察事件建模和可追踪性。

一句话回答

text
Tool call 应经历 proposed、awaiting_approval、approved、running、succeeded/failed/cancelled 状态,前端展示经过校验的参数和影响范围,服务端在执行前再次鉴权并用 toolCallId 做幂等,结果以独立事件回填消息。

面试回答详解

1. 状态机

text
proposed -> awaiting_approval -> approved -> running -> succeeded
       |             |                         |-> failed
       |             |                         |-> cancelled
       `-> rejected  `-> expired

前端状态只是投影,权威审批和执行状态必须在服务端。刷新页面后可以根据 toolCallId 查询恢复。

2. 确认界面

确认前展示工具名称、目标资源、关键参数、影响范围、预计副作用和有效期。对删除、发送、付款、发布等高风险工具,默认人工确认;只读搜索或低风险格式化可以按策略自动执行。

模型生成的参数不能直接原样展示为“即将执行”。服务端先做 schema 校验、权限计算和敏感字段脱敏。用户确认的是规范化后的 command,而不是一段可能被模型篡改的文字。

3. 执行一致性

  • toolCallId 唯一,重复确认返回同一执行结果。
  • 服务端执行前再次检查用户、租户、资源和策略。
  • 长任务使用 job 状态和轮询/事件,不让页面一直阻塞。
  • 失败区分可重试、需要用户修正和不可重试。
  • 结果带来源、时间、版本和错误码,避免模型把旧结果当新事实。

4. React 实现

消息中把 tool call 作为独立 block,避免混入纯文本。按钮动作调用 approve(toolCallId),提交后进入 approving,服务端事件再驱动 running 和最终结果。按钮要防重复点击,但不能只靠 disabled;幂等必须在服务端。

5. 审计与安全

记录谁在什么时候批准了什么规范化参数、使用了哪个策略和工具版本。审批 UI 不能泄露超出当前用户权限的数据。MCP 或第三方工具返回内容同样是不可信输入,结果展示和后续模型上下文要分离处理。

可直接背诵的 30 秒回答

text
我会把工具调用建成独立状态机,从 proposed 到审批、执行和结果,而不是一个 loading。确认界面展示经过服务端校验的工具、参数和副作用,高风险动作必须人工确认。执行前后都做权限复核,toolCallId 保证幂等,结果用独立事件回填并记录审计。前端刷新后通过 toolCallId 恢复状态。

扩展知识

高风险动作策略

可用风险等级、资源范围、金额阈值、审批人角色和过期时间组成策略,而不是在组件里写死一个 if (dangerous)

面试官追问链

追问一:前端把按钮禁用后还需要幂等吗?

  • 考察点:分布式重复请求。
  • 回答方向:必须需要。刷新、重放、多个标签页和网络重试都可能重复调用,服务端幂等才是最终保证。

追问二:审批后参数被修改怎么办?

  • 考察点:授权对象绑定。
  • 回答方向:审批绑定规范化参数摘要或版本,执行时校验 hash;变化后必须重新审批。

追问三:工具结果要不要直接给模型?

  • 考察点:不可信工具输出。
  • 回答方向:可以作为带来源和边界的 tool message 进入模型,但要过滤指令性内容、限制权限影响,并避免把结果当作系统指令。

推荐阅读

基于 MIT 协议开源