GoEX:给 AI 装上"撤销键"——当 Agent 真动手,我们靠什么兜底?
做一个思想实验。
你给你的 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)"。当它从答题者变成决策者,风险的性质就彻底变了。
更麻烦的是反馈延迟。AI 删错了一行配置,可能十分钟后服务才崩;它发错一封邮件,可能几天后客户才回复。等你发现问题、想去补救,破坏早就扩散开了。
所以问题的核心从来不是"AI 会不会犯错"——它一定会犯错,跟人一样。真正的问题是:当它犯错时,错误能不能被收回、被框住?
想通这一点,你就明白 GoEX 为什么不去卷模型能力,而是去卷"执行环节的安全网"了。这是两个完全不同的战场。
二、为什么"先审后做"根本扛不住?
面对"AI 会动手"这件事,业界的第一反应都是同一个:那就让人先审一遍。
你用过的所有 AI 编程工具都是这个套路:Copilot 给你补全代码,你回车确认;Claude Code 要执行命令,弹个框问你"允许吗";Agent 要调工具,先把参数摊给你看。这种"执行前先让人看一眼"的做法,论文给了个名字:pre-facto validation(事前验证)。
听起来天经地义。但它有个致命伤——太累,而且扛不住量。
你想想这个画面:AI Agent 干活的速度是每秒几十个动作,而你审一个 SQL 语句要盯三十秒。让一个人去事前审核一个 Agent 的每一步,就像让你站在高速公路上,用肉眼一辆一辆检查飞驰而过的车。要么你成为瓶颈,把 Agent 拖成蜗牛;要么你看烦了开始无脑点"同意"——那审核就形同虚设。
GoEX 的洞察,是反过来想:很多时候,"事后看结果"比"事前看代码"容易得多。
这就是论文的核心范式——post-facto validation(事后验证)。打个比方你立刻就懂:
事后验证,像是菜端上来,你尝一口——好吃就留下,不对味就退掉(前提是能退)。判断一盘菜好不好吃,永远比预判炒菜过程容易。
这背后是一个很深的认知规律:验证一个结果,通常比生成或预审这个结果简单。你看不懂 AI 写的那段复杂 SQL 到底会动哪些数据,但你一眼能看出"卧槽,用户表怎么少了一万行"。
但这里有个巨大的前提——事后验证之所以敢成立,是因为你假设"不对的时候,能撤回来"。
菜难吃可以退,但邮件发出去了能撤吗?数据删了能恢复吗?这才是真正的难题。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() # 你摇头 → 当无事发生
关键就在 commit 和 rollback 这两行:把"执行"和"认账"硬生生掰成了两步。AI 负责执行,你负责认账。
3. RESTful API:最难啃的硬骨头
真正的麻烦来了。API 调用没有统一的"回滚"按钮。怎么办?
GoEX 的做法是——让大模型在生成"正向调用"的同时,顺手生成一个"反向调用"。创建了一个日历事件(POST /events),那撤销动作就是删掉它(DELETE /events/{id});加了一个标签,撤销就是移除这个标签。一正一反配对出现,需要反悔时,执行反向那一条就行。
是不是有点像下棋时,每走一步都先想好"如果走错了怎么悔棋"?AI 在动手的同时,已经把退路准备好了。
但你肯定立刻想到一个反例:有些 API 根本没有反向操作啊。发出去的邮件没有 DELETE /email,转出去的钱没有 POST /refund(至少不由你说了算)。这种"覆水难收"的动作,撤销键失效了,怎么办?
这正是 GoEX 第二个抽象登场的时刻。
四、撤销不了怎么办?——损害隔离
承认一个现实:不是所有动作都能撤销。这是物理世界的硬约束,再聪明的工程也绕不过去。
GoEX 的态度很务实:撤不了的,那就别让它能造成大破坏。这就是第二个抽象——damage confinement(损害隔离)。论文里有个特别形象的词,叫"blast radius"(爆炸半径)。
这个比喻一下子就讲透了。你拆弹时不一定能保证不出事,但你可以把弹放进防爆罐里——就算炸了,破坏也只在罐子那么大。损害隔离干的就是这件事:让开发者和用户提前定义自己的风险容忍度,把任何意外的破坏,框死在一个可接受的范围内。
具体怎么框?靠的是限制权限和资源:
- 权限分级:允许 AI 读邮件,但发邮件需要额外授权;允许它查数据库,但删表必须人工二次确认。
- 额度上限:给 AI 的 token 限定 scope,转账类操作设个金额天花板。就算它疯了,单次能造成的损失也有上限。
- 范围隔离:让 AI 在沙盒、测试库、专用账户里活动,碰不到生产环境的核心数据。
所以"撤销"和"损害隔离"是一对黄金搭档,分工特别清晰:能撤的,大胆让 AI 去做,错了就回滚;不能撤的,就把爆炸半径缩到你赔得起的程度。一个管"事后补救",一个管"事前兜底",两条防线一前一后,事后验证这才真正敢落地。
说到这,你可能注意到一个细节被我跳过了:AI 要调你的邮箱、你的数据库,它得拿到密码和密钥吧?把这些东西交给一个会"即兴发挥"的模型,本身不就是最大的风险吗?
五、凭证为什么不能给模型看?
这是 GoEX 里一个容易被忽略、但我觉得特别关键的设计:大模型,自始至终碰不到你的凭证。
想想就后怕。如果你把数据库密码、OAuth token 直接塞进 prompt 给模型,会发生什么?这些敏感信息可能被写进日志、被模型在某次输出里复述出来、甚至顺着对话泄露给第三方。让一个概率性的黑盒拿着你家钥匙,这觉睡得着吗?
GoEX 的处理是职责分离:凭证存在本地的运行时里,模型只负责"决定要干什么",真正"拿着钥匙去开门"的是运行时,不是模型。论文里提到一个 DBManager 的角色就是干这个的——它把数据库的状态信息安全地喂给决策流程,但绝不把底层的连接凭证暴露出去。
这个设计点出了一个 Agent 安全里被严重低估的事实:风险不只来自模型"想错了",还来自模型"知道得太多了"。最小权限原则,对 AI 同样适用——它需要知道的,只是"现在的状态"和"能调哪些工具",而不是开门的钥匙本身。
六、GoEX 之后,这条路还缺什么?
聊到这,得把 GoEX 放回它的家谱里看,你才能体会它的分量。
Gorilla 这个团队的主线特别清晰。最早的 Gorilla 解决的是"AI 会不会调 API"——教大模型别瞎编函数名,把工具调对。而 GoEX 往前迈了一大步:解决"AI 调了 API 之后,我们敢不敢让它真的执行"。从"会调"到"敢执行",这中间隔着的,正是整个 Agent 从演示走向生产的鸿沟。
但论文作者自己也很坦诚:GoEX 是一篇"perspectives and designs(视角与设计)"的论文,它提出的是框架和一堆开放问题,而不是终极答案。坑还多着呢:
- 可逆性谁来判断?怎么自动、可靠地知道一个动作到底能不能撤?模型自己说能撤,但它判断错了呢?
- 多步连环怎么撤?AI 连着干了十步,第三步错了。回滚不只是退第三步,后面七步全得连带处理,这是个分布式事务级别的难题。
- AI 和 App 之间,缺一套协议。论文畅想了一个"LLM 与应用、应用与应用之间最小人类监督地交互"的未来——而这,差不多就是一年多后 MCP(模型上下文协议)爆火要解决的事。GoEX 在 2024 年初就把这个问题摆上桌了。
这个转向,我认为比论文里任何一个技术细节都重要。因为它承认了一个朴素的真相:AI 会犯错,人也会犯错,系统的可靠性从来不靠"永不犯错",而靠"犯错后能恢复"。
七、写在最后:先审还是后审?
把 GoEX 这一整套东西浓缩一下,其实就三句话:
- 换个验证时机:把人从"事前逐条审代码"的瓶颈,挪到"事后看结果当裁判"的位置——因为验证结果,远比预审代码容易。
- 撤销兜底:文件系统靠 Git 快照,数据库靠事务回滚,API 靠"正反配对"的反向调用,尽量让动作可逆。
- 隔离封顶:撤不了的,就用权限分级和爆炸半径把破坏框死;而凭证,永远不进模型。
但 GoEX 也戳中了一个没有标准答案的争论。关于"AI 能不能不经人审就直接动手",技术圈一直分成两派:
保守派说:人必须是最后一道关。AI 再聪明也只能建议,执行的扳机得攥在人手里——事前验证慢是慢,但稳。
激进派说:如果 AI 的出错率已经低于人类,硬塞一道人工审核,反而是拿一个更不可靠的瓶颈,去卡一个更可靠的执行者,纯属添乱。
我站激进派,但带 GoEX 给的那个前提条件:必须先有完善的撤销和隔离机制。我敢让 AI 直接动手,不是因为我信任它不犯错——而是因为我知道,它犯了错,我能在三秒内 Ctrl+Z,而且就算撤不了,损失也在我兜得起的范围内。
说到底,我们要的从来不是一个永不犯错的 AI。我们要的,是一个犯了错也能收场的系统。
那么问题留给你:在你自己的业务里,你会把那条"事前/事后"的线,划在哪儿?哪些动作你敢让 AI 直接执行,哪些你打死也要亲自点那个"确认"?
参考资料
- GoEX: Perspectives and Designs Towards a Runtime for Autonomous LLM Applications(arXiv:2404.06921,UC Berkeley,2024)
- Gorilla / GoEX 开源仓库 — ShishirPatil/gorilla(GitHub)
- UC Berkeley Introduce GoEX: A Runtime for LLMs with Undo and Damage Confinement(MarkTechPost)
- GoEX: Runtime for Autonomous LLM Applications(Emergent Mind 论文解读)