Agent 工具调用的权限分级:不是所有工具都该对模型敞开

一、Agent 的工具调用权限问题比大多数人想的更严重

Agent 工作流的核心能力是让模型自主决定调用哪些工具来完成任务。这种自主性是效率的来源,也是风险的来源。一个生活助手Agent如果有权限调用"发送消息""创建日程""修改设置"等工具,模型可能在误判用户意图时执行不该执行的操作。

实际案例:用户说"帮我把明天的会议推迟一下",Agent调用日程修改工具把会议推迟了。但用户其实只是想讨论一下推迟的可能性,还没有决定。工具调用的不可逆性——一旦执行就很难自动撤回——让误操作的代价远高于误回复。

工具调用权限应该分级管理。只读工具(查询日程、搜索信息)对所有场景开放,修改工具(创建日程、发送消息)需要用户确认,删除工具(删除记录、取消会议)需要双重确认。

二、工具权限的三级分级模型

工具权限分为三级:自动执行、确认执行和禁止自动执行。

flowchart TD
  A[Agent决定调用工具] --> B{工具权限等级}
  B -->|一级:只读查询| C[自动执行:无需用户介入]
  B -->|二级:创建与修改| D[确认执行:展示操作详情等用户确认]
  B -->|三级:删除与危险操作| E[禁止自动执行:必须人工触发]
  C --> F[返回结果给Agent]
  D --> G{用户确认?}
  G -->|确认| F
  G -->|拒绝| H[Agent调整策略重新规划]
  E --> I[提示用户手动操作]

一级工具的结果直接返回给Agent继续推理。二级工具的操作详情展示给用户确认后才执行。三级工具Agent只能提示用户手动操作,不能代替执行。这个分级模型让Agent在效率和安全之间有明确的操作边界。

三、工具权限分级的实现

type ToolPermission = "auto" | "confirm" | "manual_only";

type AgentTool = {
  name: string;
  description: string;
  permission: ToolPermission;
  parameters: Record<string, unknown>;
};

// 工具权限分级注册表
const toolRegistry: Record<string, AgentTool> = {
  // 一级:只读查询,自动执行
  querySchedule: {
    name: "querySchedule",
    description: "查询日程安排",
    permission: "auto",
    parameters: { date: "string" },
  },
  searchInfo: {
    name: "searchInfo",
    description: "搜索生活信息",
    permission: "auto",
    parameters: { query: "string" },
  },
  // 二级:创建与修改,需要确认
  createEvent: {
    name: "createEvent",
    description: "创建日程事件",
    permission: "confirm",
    parameters: { title: "string", date: "string", time: "string" },
  },
  sendMessage: {
    name: "sendMessage",
    description: "发送消息给联系人",
    permission: "confirm",
    parameters: { contact: "string", content: "string" },
  },
  // 三级:删除与危险操作,禁止自动执行
  deleteEvent: {
    name: "deleteEvent",
    description: "删除日程事件",
    permission: "manual_only",
    parameters: { eventId: "string" },
  },
  deleteDiary: {
    name: "deleteDiary",
    description: "删除日记记录",
    permission: "manual_only",
    parameters: { diaryId: "string" },
  },
};

export function executeToolWithPermission(
  toolName: string,
  params: Record<string, unknown>
): ToolExecutionResult {
  const tool = toolRegistry[toolName];
  if (!tool) throw new Error(`工具未注册: ${toolName}`);

  switch (tool.permission) {
    case "auto":
      // 一级工具直接执行
      return { status: "executed", result: callTool(toolName, params) };

    case "confirm":
      // 二级工具返回确认请求,等待用户介入
      return {
        status: "pending_confirm",
        toolName,
        description: tool.description,
        params,
      };

    case "manual_only":
      // 三级工具禁止Agent自动执行,返回提示
      return {
        status: "manual_required",
        message: `${tool.description}需要你手动操作,Agent无法代替执行`,
      };
  }
}

type ToolExecutionResult = {
  status: "executed" | "pending_confirm" | "manual_required";
  result?: unknown;
  toolName?: string;
  description?: string;
  params?: Record<string, unknown>;
  message?: string;
};

pending_confirm 状态不是失败,而是等待。Agent收到这个状态后暂停当前推理步骤,把确认请求展示给用户。用户确认后Agent继续推理,用户拒绝后Agent调整策略寻找替代方案。

四、权限分级会增加交互轮次

权限分级的副作用是增加交互轮次。用户原本一句话就能让Agent完成的事情,现在可能需要两步:第一步Agent规划出操作方案,第二步用户确认后执行。对于创建日程这种常见操作,每次都要确认可能会让用户觉得繁琐。

缓解方式是给确认步骤设计快捷操作。确认界面只需要一个"确认"按钮和一个"取消"按钮,不需要让用户重新填写所有参数。参数已经由Agent生成好了,用户只需要看一眼操作描述然后点击确认。3秒内完成的确认不会打断用户的流畅感。

另一个优化是"信任累积"。用户连续5次确认同一类操作后,系统可以提示是否将这个工具从二级提升为一级。但这需要谨慎——信任累积不应该自动提升权限,只是提示用户可以手动调整。自动提升权限可能导致误操作概率在用户不注意时悄悄增加。

五、总结

Agent工具调用权限应分三级管理:只读工具自动执行、创建修改工具需要用户确认、删除和危险操作禁止自动执行只提供提示。二级工具的确认界面应简洁快捷,3秒内可完成。信任累积可以提示权限升级但不应自动执行。权限分级增加交互轮次,但安全收益值得这个代价。

更多推荐