TECH ARTICLES
Agent LLM 安全 执行引擎

GoEX:给 AI 装上"撤销键"——当 Agent 真动手,我们靠什么兜底?

Jackie Zhan 2026-06-17
目录
一、我们到底在怕 AI 的什么? 二、为什么"先审后做"根本扛不住? 三、撤销键,怎么给 AI 装上? 四、撤销不了怎么办?——损害隔离 五、凭证为什么不能给模型看? 六、GoEX 之后,这条路还缺什么? 七、写在最后:先审还是后审?

做一个思想实验。

你给你的 AI 助手开了邮箱权限,让它帮你处理一封客户来信。它读完,"理解"了你的意图,然后——啪——把一封措辞激进、把价格报错了一位数的回信,发给了你最大的那个客户。

等你反应过来,邮件已经躺在对方收件箱里了。

这一秒,你心里冒出来的不是"AI 真聪明",而是一个特别朴素的念头:有没有 Ctrl+Z?

这就是整个 AI Agent 行业现在卡住的地方。我们已经能让大模型"想得很好"——它能规划、能调工具、能写出像模像样的 API 调用。但只要它真的动手,去发邮件、删数据、改文件、转账,麻烦就来了:现实世界,大多没有撤销键。

2024 年 4 月,UC Berkeley 的 Gorilla 团队(就是那个教大模型规规矩矩调 API 的团队)扔出了一篇论文,标题很学术——《GoEX: Perspectives and Designs Towards a Runtime for Autonomous LLM Applications》。但它干的事特别接地气:给 AI 的每一个动作,想办法装上一个撤销键;装不上的,就把它能造成的破坏圈在一个小盒子里。

这两个抽象,作者叫它"undo(撤销)"和"damage confinement(损害隔离)"。听起来平平无奇?但我跟你打赌,它触到了一个比"模型多聪明"更要命的问题。我们一层层拆开看。


一、我们到底在怕 AI 的什么?

先想清楚一件事:我们对 ChatGPT 聊天,为什么从来不害怕?

因为它说的话,是"可弃的"。它胡说八道,你不采纳就完事了,没有任何后果落到现实世界里。聊天机器人的输出停留在屏幕上,屏幕是个安全的沙盒。

但 Agent 不一样。Agent 的定义,就是"会动手的 AI"。它的输出不再是文字,而是动作——一条 DELETE 请求、一次数据库写入、一个 rm 命令。动作一旦执行,就改变了世界的状态。而世界,是不能"不采纳"的。

论文里有个观点我特别认同:我们应该把大模型当成"决策者(decision-maker)",而不是"数据压缩器(data compressor)"。当它从答题者变成决策者,风险的性质就彻底变了。

insider 视角
传统软件的 bug 你不怕,是因为它确定——同样的输入永远跑出同样的结果,你能写测试覆盖它。但大模型是概率性的:同一个 prompt,今天乖乖调对 API,明天可能就多删了一张表。论文管这叫"传统测试方法的失效"。你没法用单元测试去防一个会即兴发挥的执行者。

更麻烦的是反馈延迟。AI 删错了一行配置,可能十分钟后服务才崩;它发错一封邮件,可能几天后客户才回复。等你发现问题、想去补救,破坏早就扩散开了。

所以问题的核心从来不是"AI 会不会犯错"——它一定会犯错,跟人一样。真正的问题是:当它犯错时,错误能不能被收回、被框住?

想通这一点,你就明白 GoEX 为什么不去卷模型能力,而是去卷"执行环节的安全网"了。这是两个完全不同的战场。

二、为什么"先审后做"根本扛不住?

面对"AI 会动手"这件事,业界的第一反应都是同一个:那就让人先审一遍。

你用过的所有 AI 编程工具都是这个套路:Copilot 给你补全代码,你回车确认;Claude Code 要执行命令,弹个框问你"允许吗";Agent 要调工具,先把参数摊给你看。这种"执行前先让人看一眼"的做法,论文给了个名字:pre-facto validation(事前验证)

听起来天经地义。但它有个致命伤——太累,而且扛不住量。

你想想这个画面:AI Agent 干活的速度是每秒几十个动作,而你审一个 SQL 语句要盯三十秒。让一个人去事前审核一个 Agent 的每一步,就像让你站在高速公路上,用肉眼一辆一辆检查飞驰而过的车。要么你成为瓶颈,把 Agent 拖成蜗牛;要么你看烦了开始无脑点"同意"——那审核就形同虚设。

GoEX 的洞察,是反过来想:很多时候,"事后看结果"比"事前看代码"容易得多。

这就是论文的核心范式——post-facto validation(事后验证)。打个比方你立刻就懂:

关键区别
事前验证,像是你点外卖前,要求看厨师炒菜的每一个动作并逐一批准——你既不专业,又会把厨师逼疯。
事后验证,像是菜端上来,你尝一口——好吃就留下,不对味就退掉(前提是能退)。判断一盘菜好不好吃,永远比预判炒菜过程容易。

这背后是一个很深的认知规律:验证一个结果,通常比生成或预审这个结果简单。你看不懂 AI 写的那段复杂 SQL 到底会动哪些数据,但你一眼能看出"卧槽,用户表怎么少了一万行"。

事前验证(pre-facto) AI 生成动作 人逐条审代码 才能执行 瓶颈在人,看不懂也得看 VS 事后验证(post-facto) AI 生成动作 直接执行 看结果→不对就撤销 看结果比看代码容易
两种验证范式:GoEX 把人从"执行前的瓶颈"挪到了"执行后的裁判"

但这里有个巨大的前提——事后验证之所以敢成立,是因为你假设"不对的时候,能撤回来"。

菜难吃可以退,但邮件发出去了能撤吗?数据删了能恢复吗?这才是真正的难题。GoEX 的全部技术含量,都压在这个"撤"字上面。

三、撤销键,怎么给 AI 装上?

"撤销"这两个字,程序员一点都不陌生。数据库的事务回滚、Git 的版本回退、编辑器的 Ctrl+Z——本质都是同一件事:先记住"做之前"的状态,出了事就退回去。

GoEX 聪明的地方在于,它没有发明什么新魔法,而是把这套老智慧,针对 AI 会碰的三类东西,分别落地了。

1. 文件系统:交给 Git 来记账

AI 要改你的代码、改配置文件?好办。GoEX 借用版本控制的思路:动手之前先做一次快照(commit),AI 一通操作之后,如果你看着不对,一条命令就 revert 回去。

这是三类里最舒服的——因为文件系统天生就有成熟的"时光机"(Git),撤销几乎是免费的。

2. 数据库:用事务把"做"和"认账"分开

数据库更优雅。关系型数据库本来就有事务(transaction)这个神器:一组操作可以先执行、但不立即生效,等到你喊一声 COMMIT 才真正落地,喊 ROLLBACK 就当无事发生。

GoEX 正是踩着这个机制:AI 的数据库操作先跑在事务里,把结果给你看,你点头才提交,你摇头就回滚。这简直是为"事后验证"量身定做的。

# GoEX 处理数据库操作的核心思路(简化示意)
conn.begin()                    # 开启事务,进入"可反悔"区
execute(llm_generated_sql)      # 跑 AI 生成的 SQL,但还没真正生效
show_diff_to_user()             # 把改了哪些行摊给你看

if user_approves():
    conn.commit()               # 你认账 → 落地
else:
    conn.rollback()             # 你摇头 → 当无事发生

关键就在 commitrollback 这两行:把"执行"和"认账"硬生生掰成了两步。AI 负责执行,你负责认账。

3. RESTful API:最难啃的硬骨头

真正的麻烦来了。API 调用没有统一的"回滚"按钮。怎么办?

GoEX 的做法是——让大模型在生成"正向调用"的同时,顺手生成一个"反向调用"。创建了一个日历事件(POST /events),那撤销动作就是删掉它(DELETE /events/{id});加了一个标签,撤销就是移除这个标签。一正一反配对出现,需要反悔时,执行反向那一条就行。

用户意图 LLM 生成 正向 + 反向调用 正向:POST /events 真正执行 反向:DELETE /events/id 存着,要悔棋时才跑 撤销完成
REST API 的撤销:让模型把"反悔的那一步"提前写好,备而不用

是不是有点像下棋时,每走一步都先想好"如果走错了怎么悔棋"?AI 在动手的同时,已经把退路准备好了。

但你肯定立刻想到一个反例:有些 API 根本没有反向操作啊。发出去的邮件没有 DELETE /email,转出去的钱没有 POST /refund(至少不由你说了算)。这种"覆水难收"的动作,撤销键失效了,怎么办?

这正是 GoEX 第二个抽象登场的时刻。

四、撤销不了怎么办?——损害隔离

承认一个现实:不是所有动作都能撤销。这是物理世界的硬约束,再聪明的工程也绕不过去。

GoEX 的态度很务实:撤不了的,那就别让它能造成大破坏。这就是第二个抽象——damage confinement(损害隔离)。论文里有个特别形象的词,叫"blast radius"(爆炸半径)

这个比喻一下子就讲透了。你拆弹时不一定能保证不出事,但你可以把弹放进防爆罐里——就算炸了,破坏也只在罐子那么大。损害隔离干的就是这件事:让开发者和用户提前定义自己的风险容忍度,把任何意外的破坏,框死在一个可接受的范围内。

具体怎么框?靠的是限制权限和资源:

常见误解
很多人以为"安全"就等于"让 AI 啥都干不了"——把权限收到最紧,确实最安全,但也最没用,那不如不上 Agent。GoEX 的思路恰恰相反:安全不是一刀切的禁止,而是一个可以调的旋钮。你根据任务的可逆性和重要性,自己决定把"爆炸半径"调多大。低风险任务放开手脚,高风险任务收紧缰绳。

所以"撤销"和"损害隔离"是一对黄金搭档,分工特别清晰:能撤的,大胆让 AI 去做,错了就回滚;不能撤的,就把爆炸半径缩到你赔得起的程度。一个管"事后补救",一个管"事前兜底",两条防线一前一后,事后验证这才真正敢落地。

说到这,你可能注意到一个细节被我跳过了:AI 要调你的邮箱、你的数据库,它得拿到密码和密钥吧?把这些东西交给一个会"即兴发挥"的模型,本身不就是最大的风险吗?

五、凭证为什么不能给模型看?

这是 GoEX 里一个容易被忽略、但我觉得特别关键的设计:大模型,自始至终碰不到你的凭证。

想想就后怕。如果你把数据库密码、OAuth token 直接塞进 prompt 给模型,会发生什么?这些敏感信息可能被写进日志、被模型在某次输出里复述出来、甚至顺着对话泄露给第三方。让一个概率性的黑盒拿着你家钥匙,这觉睡得着吗?

GoEX 的处理是职责分离:凭证存在本地的运行时里,模型只负责"决定要干什么",真正"拿着钥匙去开门"的是运行时,不是模型。论文里提到一个 DBManager 的角色就是干这个的——它把数据库的状态信息安全地喂给决策流程,但绝不把底层的连接凭证暴露出去。

关键区别
打个比方:模型是下指令的指挥官,运行时是握着保险柜钥匙的管家。指挥官说"把 3 号文件取出来",管家去开柜子取——但钥匙永远在管家兜里,指挥官从头到尾没摸过。指挥官就算被策反(被恶意 prompt 注入),也偷不走钥匙。

这个设计点出了一个 Agent 安全里被严重低估的事实:风险不只来自模型"想错了",还来自模型"知道得太多了"。最小权限原则,对 AI 同样适用——它需要知道的,只是"现在的状态"和"能调哪些工具",而不是开门的钥匙本身。

六、GoEX 之后,这条路还缺什么?

聊到这,得把 GoEX 放回它的家谱里看,你才能体会它的分量。

Gorilla 这个团队的主线特别清晰。最早的 Gorilla 解决的是"AI 会不会调 API"——教大模型别瞎编函数名,把工具调对。而 GoEX 往前迈了一大步:解决"AI 调了 API 之后,我们敢不敢让它真的执行"。从"会调"到"敢执行",这中间隔着的,正是整个 Agent 从演示走向生产的鸿沟。

但论文作者自己也很坦诚:GoEX 是一篇"perspectives and designs(视角与设计)"的论文,它提出的是框架和一堆开放问题,而不是终极答案。坑还多着呢:

延伸思考
GoEX 最大的价值,可能不在于它的具体实现有多完美——它本来也还在演进。它真正的贡献是换了个提问方式:行业之前都在问"怎么让 AI 更聪明、更少犯错",GoEX 问的是"怎么让 AI 犯错的代价变得可承受"。前者是无止境的军备竞赛,后者是工程上立刻能动手的事。

这个转向,我认为比论文里任何一个技术细节都重要。因为它承认了一个朴素的真相:AI 会犯错,人也会犯错,系统的可靠性从来不靠"永不犯错",而靠"犯错后能恢复"。

七、写在最后:先审还是后审?

把 GoEX 这一整套东西浓缩一下,其实就三句话:

但 GoEX 也戳中了一个没有标准答案的争论。关于"AI 能不能不经人审就直接动手",技术圈一直分成两派:

保守派说:人必须是最后一道关。AI 再聪明也只能建议,执行的扳机得攥在人手里——事前验证慢是慢,但稳。

激进派说:如果 AI 的出错率已经低于人类,硬塞一道人工审核,反而是拿一个更不可靠的瓶颈,去卡一个更可靠的执行者,纯属添乱。

我站激进派,但带 GoEX 给的那个前提条件:必须先有完善的撤销和隔离机制。我敢让 AI 直接动手,不是因为我信任它不犯错——而是因为我知道,它犯了错,我能在三秒内 Ctrl+Z,而且就算撤不了,损失也在我兜得起的范围内。

说到底,我们要的从来不是一个永不犯错的 AI。我们要的,是一个犯了错也能收场的系统。

那么问题留给你:在你自己的业务里,你会把那条"事前/事后"的线,划在哪儿?哪些动作你敢让 AI 直接执行,哪些你打死也要亲自点那个"确认"?