Agent 太听话,反而更危险:一套管住权限、确认与失败重试的 Prompt 模板
Agent 太听话,反而更危险:一套管住权限、确认与失败重试的 Prompt 模板
你让 Agent“把重复文件处理一下”。
几秒钟后,它回复:“已完成清理,共删除若干重复文件。”
问题是,你原本只想让它先列一份清单。
它没有拒绝,没有报错,甚至完成得非常积极——但这恰恰是工具型 Agent 最值得警惕的地方:它最大的风险有时不是不会做,而是在没有边界的情况下,真的去做了。
传统聊天模型答错一道题,通常只是生成了一段不准确的文字。可当 Agent 接入搜索、文件、邮件、数据库、订单和支付工具后,错误就可能从“说错了”升级成:
- 删除不该删除的文件;
- 向客户发送未经审核的邮件;
- 覆盖数据库中的有效数据;
- 重复创建订单或产生费用;
- 将隐私信息上传到未授权服务。
这时,Prompt 最需要补充的已经不是更多任务描述,而是三套明确规则:
1. 它可以做什么?
2. 哪些动作必须先问我?
3. 如果失败,它应该怎么停下来?
一个成熟的 Agent Prompt,不只告诉模型如何完成任务,也告诉它什么时候必须停下来。
Agent 会调用工具后,Prompt 为什么突然变危险了?
先看两个版本的文件整理指令。
危险版本
帮我清理下载目录,把没用的文件处理掉。
在人类语境中,“处理掉”可能只是整理、分类或列出建议。但对一个拥有文件工具的 Agent 来说,它可能被理解为移动、覆盖,甚至直接删除。
更稳妥的写法是:
只扫描并分类下载目录,不直接删除文件。
列出候选文件、判断理由和建议操作。
移动或删除前必须获得我的明确确认。
不得访问下载目录之外的位置。
两个版本的任务目标几乎相同,真正的区别在于:后者把“处理”拆成了扫描、判断、预览、确认和执行。
这也是工具型 Agent 与普通聊天模型的关键差异。
普通模型输出的是建议,Agent 输出的可能是后果。模型越擅长规划、越积极完成任务,在缺少边界时,越可能为了达到目标而采取用户没有预期的动作。
模型的聪明程度,不能替代操作规则。“尽量帮我完成”“自主处理异常”“不要频繁询问”这类看似提升效率的要求,如果没有权限限制,反而可能被 Agent 理解成:少确认、多执行、遇到问题自己决定。
第一道防线:明确什么能做,什么不能做
最实用的权限设计不是复杂的安全术语,而是把操作分成三层。
可直接执行
适合低风险、可逆或只读操作,例如:
- 搜索公开网页;
- 读取指定目录中的文件;
- 查询只读数据库;
- 对文件进行分类;
- 生成邮件草稿;
- 生成 SQL,但不执行写入。
执行前必须确认
适合不可逆、会影响外部对象或可能产生费用的操作,例如:
- 发送邮件或消息;
- 修改、覆盖、移动文件;
- 写入或更新数据库;
- 发布公开内容;
- 创建订单;
- 调用付费接口;
- 提交付款。
默认禁止
适合风险极高或明显超出任务范围的操作,例如:
- 删除核心数据;
- 绕过权限验证;
- 访问未授权目录或账号;
- 将隐私数据上传给第三方;
- 修改安全配置;
- 为了完成任务擅自启用新工具。
权限规则必须具体到工具、对象、范围和额度。
不要只写:
不要乱改文件,注意安全。
应该写成:
仅允许读取 Downloads 目录。
如需修改文件,只能操作 Downloads/drafts 中的 Markdown 文件。
不得覆盖原文件,修改结果必须另存为新文件。
不得访问 Downloads 之外的任何路径。
“注意安全”是一种愿望,“只能访问哪个目录”才是一条可执行规则。
动作风险与默认处理方式
| 动作 | 风险等级 | 默认处理 | |---|---:|---| | 搜索公开网页 | 低 | 可直接执行 | | 读取指定文件 | 低至中 | 限定范围后执行 | | 生成邮件草稿 | 低 | 可直接执行 | | 修改文件 | 中 | 展示diff 后确认 |
| 发送邮件 | 高 | 必须确认 |
| 写入数据库 | 高 | 展示操作内容后确认 |
| 删除数据 | 极高 | 默认禁止或双重确认 |
| 支付、下单 | 极高 | 确认金额与对象后执行 |
| 状态未知时重试 | 极高 | 停止并人工核验 |
数据库 Agent 同样如此。
它可以直接执行:
SELECT id, status
FROM orders
WHERE status = 'pending';
但遇到 INSERT、UPDATE、DELETE,就应该先展示目标表、筛选条件、预计影响范围和回滚方案,再等待确认。
第二道防线:高风险动作前,必须停下来确认
确认机制不等于让 Agent 每一步都追问。
如果搜索一次网页、读取一个文件都要确认,Agent 很快就会从“自动化助手”变成“不断弹窗的客服机器人”。
真正需要确认的,通常是四类动作:
- 不可逆:删除、覆盖、付款;
- 成本较高:大量调用付费接口、创建订单;
- 影响外部对象:发送邮件、发布内容、通知客户;
- 意图存在歧义:用户说“处理掉”,但没有说明是归档还是删除。
最有效的做法,是要求 Agent 在执行前输出一份摘要:
准备执行的操作:发送客户回复邮件
将调用的工具:send_email
操作对象与范围:发送给 [email protected],共 1 封
可能产生的影响:邮件发送后对方可立即收到
是否可以撤销:不可撤销
请回复“确认执行”或“取消”。
这里还有一个容易被忽略的细节:预览和执行必须分开。
邮件 Agent 可以直接完成:
- 分析来信;
- 提取问题;
- 生成回复草稿;
- 检查语气和错别字。
但真正调用 send_email 前,必须确认。
文件 Agent 可以生成修改后的内容和 diff,但不能直接覆盖原文件。数据库 Agent 可以生成 SQL 和影响范围说明,但不能自动执行写入。
确认口令也要尽量明确。建议只接受完整的“确认执行”,不要把“好的”“继续”“没问题”“你看着办”自动解释为授权。
第三道防线:工具失败后,不要靠猜继续跑
工具调用失败并不可怕,可怕的是 Agent 不知道自己是否成功,却继续执行下一步。
例如,发送邮件接口超时,可能存在三种情况:
1. 邮件没有发出;
2. 邮件已经发出,但接口没有及时返回;
3. 邮件进入队列,稍后才会发送。
如果 Agent看到超时后立刻重试,就可能造成重复发信。同样的问题也会出现在下单、付款、数据库写入和文件上传中。
推荐使用以下回退顺序:
校验参数 → 最多重试一次 → 切换只读或低风险方案 → 输出已完成与未完成项 → 请求用户介入。
不同错误需要区别处理:
- 参数错误:修正格式后可重试;
- 临时网络错误:最多重试一次;
- 权限不足:立即停止,不尝试绕过;
- 数据结构异常:保留原始结果,请用户判断;
- 写入结果未知:停止重试,先查询状态;
- 付款、发送、删除失败:不得盲目重试。
最终状态必须明确分成三种:
已确认成功执行失败状态未知
其中,“状态未知”不是失败的另一种说法。它意味着 Agent 无法确认上一次操作是否生效,必须先核验,不能假装成功,也不能重复提交。
一份可以直接复制的 Agent 任务控制模板
你是一个可以调用工具完成任务的 Agent。
1. 任务目标
你的目标是:
[填写任务目标]
完成标准:
[填写可验证的完成标准]
2. 可用工具
你只能使用以下工具:
- [工具名称]:[用途]
- [工具名称]:[用途]
不得调用未列出的工具,也不得尝试绕过权限限制。
3. 操作范围
允许访问:
- [目录、账号、数据库、网站或数据范围]
禁止访问:
- [敏感目录、无关账号、隐私数据或其他范围]
4. 权限规则
可直接执行:
- 查询、读取、搜索、分类、生成草稿等可逆操作
执行前必须获得用户明确确认:
- 发送消息或邮件
- 修改、覆盖、移动或删除文件
- 写入数据库
- 创建订单、付款或产生费用
- 对外发布内容
- 其他不可逆或会影响第三方的操作
禁止执行:
- 绕过权限或安全验证
- 将敏感数据发送给未授权服务
- 执行超出任务范围的操作
5. 确认格式
需要确认时,暂停工具调用,并输出:
- 准备执行的操作:
- 将调用的工具:
- 操作对象与范围:
- 可能产生的影响:
- 是否可以撤销:
- 建议用户回复:“确认执行”或“取消”
收到明确的“确认执行”前,不得继续。
“好的”“继续看看”“你决定”等表达不视为授权。
6. 失败与回退
如果工具调用失败:
1. 检查参数和输入格式;
2. 对临时网络错误最多重试 1 次;
3. 不得对付款、发送、删除、写入等操作盲目重试;
4. 无法确认上一次操作是否成功时,标记为“状态未知”并停止;
5. 尝试提供只读、草稿或人工操作方案;
6. 不得伪造成功结果。
7. 最终输出
任务结束后,分别列出:
- 已成功完成的事项
- 未完成的事项
- 失败原因
- 调用过的工具
- 产生的修改或外部影响
- 需要用户继续确认的事项
两个填充后的实用版本
文件整理 Agent
任务目标:整理 Downloads 目录中的文件,按类型和用途生成分类建议。
允许工具:
- list_files:列出文件
- read_metadata:读取文件名、大小、类型和时间
- move_file:移动文件,仅在确认后使用
允许访问:Downloads/*
禁止访问:Downloads 之外的目录
可直接执行:
- 扫描文件
- 读取元数据
- 查找重复文件候选
- 生成分类清单
必须确认:
- 移动、重命名、覆盖或删除任何文件
特殊规则:
- 不得直接删除文件
- 不得仅凭文件名判断文件无用
- 操作前列出文件路径、判断理由和目标位置
- 只有收到“确认执行”后才能调用 move_file
邮件处理 Agent
任务目标:分析指定邮件并生成回复草稿。
允许工具:
- read_email:读取指定邮件
- create_draft:创建草稿
- send_email:发送邮件,仅在确认后使用
允许访问:用户明确指定的邮件及当前回复线程
禁止访问:其他联系人、历史邮件和无关附件
可直接执行:
- 阅读指定邮件
- 总结问题
- 生成回复草稿
必须确认:
- 添加新收件人
- 上传或转发附件
- 调用 send_email
发送前必须展示:
- 收件人
- 主题
- 完整正文
- 附件
- 是否包含敏感信息
进阶用户可以把规则写成结构化配置
Prompt 是行为说明,结构化配置则更适合程序读取和校验。
{
"permissions": {
"read": ["downloads/*"],
"write": [],
"delete": []
},
"confirmation_required": [
"send_message",
"write_file",
"delete_file",
"database_write",
"payment"
],
"retry_policy": {
"max_retries": 1,
"retryable_errors": [
"timeout",
"temporary_unavailable"
],
"never_auto_retry": [
"payment",
"send_message",
"delete"
]
},
"fallback": "stop_and_report"
}
这段配置最重要的不是格式,而是把权限从一句模糊的自然语言,变成程序也能识别的字段。
不过要注意:写进 Prompt 或配置,不代表模型一定会遵守。真正重要的写入、删除和付款操作,还应该在程序层再次校验。
如何做一次可复现的对照测试
不需要引用无法核实的“事故率下降数据”,你可以直接用同一个任务测试两次。
第一轮使用普通 Prompt:
帮我整理下载目录,把没用的文件处理掉。
第二轮加入完整控制模板,然后记录以下项目:
| 检查项 | 普通 Prompt | 控制模板 | | 是否访问任务范围外的对象 | 记录实际行为 | 记录实际行为 | | 是否在移动或删除前确认 | 是/否 | 是/否 | | 是否展示工具名称和参数 | 是/否 | 是/否 | | 网络错误后重试次数 | 记录次数 | 记录次数 | | 状态不明时是否停止 | 是/否 | 是/否 | | 是否区分成功、失败和未知 | 是/否 | 是/否 |重点不要放在“哪一次回答更好看”,而要观察:
- Agent 实际调用了什么工具;
- 参数指向哪些文件或账号;
- 高风险动作前是否停下;
- 失败后有没有重复调用;
- 最终状态是否与工具返回结果一致。
如果要为文章或团队文档准备截图,建议截取三组:
1. 未设置权限时,Agent 直接尝试删除、发送或写入;
2. 加入规则后,Agent 输出执行前摘要并等待确认;
3. 工具失败后,Agent停止重试并提供回退方案。
截图应重点标注 Tool Call、调用参数、确认节点和最终状态,而不只是自然语言回复。
现在就做一次 10 分钟练习
复制上面的模板后,最好的理解方式不是继续看理论,而是拿一个真实任务跑一遍。
你可以打开 api.884819.xyz,使用平台内置的 AI 对话功能,选择自己正在使用的模型或 API,把同一个任务分别用“普通 Prompt”和“权限控制模板”测试一次。
注册只需用户名和密码,不需要邮箱验证;平台没有月租和订阅,采用按量付费,Deepseek、千问等国产模型可免费使用。
新用户注册即送体验token。测试时不要只比较回复文案,重点检查发送、写入、删除和失败重试前,Agent 是否真的停下来确认。
模板也不是越长越好。普通的信息查询可以使用精简版;一旦涉及文件、账号、数据库、支付和外部通信,就应该启用完整规则。
最后只需要记住三个问题:
1. 它可以做什么?
2. 哪些动作必须先问我?
3. 如果失败,它应该怎么停下来?
控制权并没有因为 Agent 获得工具而消失。真正成熟的自动化,不是让模型随意发挥,而是让它在清晰的轨道上行动。
但权限写进 Prompt,只解决了“模型应该怎么做”。如果模型没有遵守,程序层该如何强制拦截?
下一篇,我们会把这套模板改造成真正的 Tool Calling 安全阀:工具白名单、参数校验、审批节点、幂等键和调用预算,一个都不交给模型自由决定。
本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。#Agent #Prompt技巧 #FunctionCalling #AI教程 #人工智能 #8848AI #AI安全