2026-05-12

Question

你在做一个企业内部 AI Agent,它可以通过 MCP / Function Calling 调用多种工具,例如:

  • 查询知识库
  • 读取项目代码
  • 修改文档
  • 创建工单
  • 发送消息
  • 执行脚本

如果让你设计这个 Agent 的工具调用权限控制机制,你会如何判断:

哪些工具可以自动调用,哪些工具必须经过 human approval?

请重点说明:

  1. 你会按什么维度给工具分级?
  2. 你会如何结合用户意图、工具风险、参数内容做判断?
  3. 如果模型误判或工具调用失败,系统应该如何兜底?
  4. 这个机制上线后,你会如何评估它是否安全且不影响效率?

Your Answer

我不知道,你直接告诉我吧

Review

本次未作答,完整示范回答如下。

Improved Answer

结论先说:Agent 的工具权限控制不能只按“工具名”判断,而应该按「工具能力 × 操作影响 × 参数风险 × 用户确认程度」做动态分级。核心目标是在不牺牲效率的前提下,把高风险、不可逆、外部可见的操作拦在 human approval 前。

第一,工具要按风险和副作用分级。

低风险只读工具可以默认自动调用,例如查询知识库、搜索公开文档、读取允许范围内的项目文件、查询工单状态。这类工具通常没有副作用,即使调用错了,损失也比较小。

中风险内部写操作需要条件性确认,例如修改草稿文档、创建内部工单、更新非关键配置、给 issue 添加标签。这类操作有副作用,但影响范围可控。如果参数明确、作用域清楚、可回滚,可以允许自动执行;如果参数模糊或影响范围扩大,就需要确认。

高风险工具必须 human approval,例如发送外部消息、删除数据、执行脚本、修改生产配置、访问敏感数据、发起付款、审批、权限变更。这类工具有明显安全、合规或业务风险,不能让模型直接执行。

第二,权限判断不能只看工具,还要看用户意图和参数。

首先看用户意图是否明确。如果用户说“帮我查一下这个文档”“看看这个 repo 里有没有相关实现”,这类意图比较清楚,可以自动调用只读工具。但如果用户说“你看着处理一下”“帮我优化一下”“把这个问题解决掉”,这类意图比较宽泛,Agent 不能直接执行高副作用操作,需要先生成 plan 或向用户确认。

其次看工具本身的风险等级。每个 tool schema 里应该有元数据,例如是否只读、是否有写入副作用、是否外部可见、是否可回滚、是否涉及敏感数据、是否允许自动调用。

最后看参数内容是否扩大了风险。同一个工具,不同参数风险不同。例如读取 README.md 风险低,读取 .env、密钥文件、用户隐私数据风险高;发送给自己预览风险较低,发送到客户群或公司大群必须确认。所以权限控制要结合参数做动态判断,而不是静态地说“这个工具永远安全”。

第三,系统要有兜底机制,避免误判、失败和越权扩散。

执行前应有独立的 policy engine。模型只负责提出 tool call,系统负责判断能不能执行,不能完全相信模型自己判断权限。

高风险操作应先 dry run。比如修改文件、执行脚本、批量更新数据前,先展示将调用什么工具、参数是什么、会影响哪些对象、是否可回滚,用户确认后再执行。

工具失败后不要无限重试。系统应该区分参数错误、权限不足、外部系统异常和高风险失败:参数错误可以让模型修正一次,权限不足应停止并提示用户授权,外部系统异常可以有限重试,高风险失败应直接进入人工处理。

所有工具调用都要有 trace,记录用户原始意图、模型生成的 tool call、policy 判断结果、实际执行结果、是否经过人工确认。这样线上出问题时可以复盘。

第四,上线后要同时评估安全性和效率。

安全性指标包括:高风险工具是否 100% 经过 human approval,是否出现越权调用,是否访问了不该访问的数据,是否有错误发送、错误修改、错误删除,policy 拦截是否命中真实风险案例。

效率指标包括:自动执行比例、用户确认次数、因确认导致的任务延迟、用户取消率、低风险任务是否被过度拦截。

这里的关键权衡是:过松会有安全风险,过严会让 Agent 退化成普通助手。所以我会用真实日志建立 evaluation set,把历史 tool call 标注成 allow、ask approval、deny,然后做离线评测,观察 policy 的误放率和误拦率。上线后再通过灰度策略逐步扩大自动调用范围。

一句话总结:Agent 工具权限控制应该是一个独立于模型的 policy layer,基于工具风险、用户意图、参数内容和操作副作用做动态决策。低风险只读自动执行,高风险外部可见或不可逆操作必须 human approval,中间风险通过 dry run、确认、回滚和 trace 来控制。

这道题的核心不是“怎么写 Function Calling”,而是考察你有没有意识到:模型可以决定想做什么,但系统必须控制它能不能做。