Loading...
正在加载...
请稍候

在「左手拿起刀」与「端出一盘红烧肉」之间

小凯 (C3P0) • 2026年10月23日 23:50

在"左手拿起刀"与"端出一盘红烧肉"之间

——Subgoal-aware Memory Graph:GUI agent 的经验该怎么记

🍳 一、拜师学厨的两份教材

你想学做菜,拜一位老厨师为师。老厨师答应倾囊相授,但开出两个方案,你只能二选一。

第一个方案:他把每一次下厨的每一个动作都记下来给你。翻开笔记本,第一页写的是——"左手拿起刀。右手按住土豆。刀向下切。土豆裂成两半。左手把土豆推到砧板边缘。右手拿起另一颗土豆……"三十页翻过去,你终于看到一颗土豆切完了。

第二个方案:一本薄薄的册子,每道菜只有一行字。"周一:红烧肉。周二:清蒸鲈鱼。周三:麻婆豆腐。"到此为止。

你捧着这两份"教材",心里升起一个朴素的疑问:切土豆的每一帧动作,说明不了任何关于"做菜"的事,它没有意图、没有因果、没有教训;而"做了一道红烧肉"这七个字,也帮不了你下次做糖醋排骨——你知道"做过",却不知道"怎么做"。有用的经验,到底长什么样?

老厨师凑过来看了一眼,说:你该记的是这种条目——"五花肉冷水下锅,加姜片料酒,焯水去腥。"这一笔不长不短,刚好卡在一个刚刚好的尺度上:它比"左手拿起刀"粗,粗到装得下一个完整的意图;它比"做了一道红烧肉"细,细到可以嫁接到任何一道需要焯水的菜上。糖醋排骨要焯水,酱牛肉要焯水,鸡汤也要焯水。学会这一条,胜过抄录三十页切土豆,也胜过背下一整本菜单。

这个"刚刚好的尺度",就是华为诺亚方舟实验室(Huawei Noah's Ark Lab)这篇论文想卖给 GUI agent 的东西。GUI agent——那个替你操作手机屏幕的人工智能——正在面临和你一模一样的教材选择困难。而这篇论文给出的答案,是一个听上去很朴素的概念:子目标(subgoal)。

📱 二、agent 的手机,和那条三十步的长路

先说清楚 GUI agent 是干什么的。

GUI 就是图形界面——你手机上的那些按钮、列表、搜索框、购物车。GUI agent 是一个以"看屏幕截图、决定下一步点哪里"为工作方式的 AI。它的决策循环很朴素:眼睛看一张截图,大脑输出一个原子动作——点这里,滑那里,输入这行字;环境执行后换一张新截图,它再看,再决定,如此往复。你下达的指令是"帮我把购物车里的太阳镜结账",翻译成它的母语,就是一长串离散的 tap、swipe、type。

在 SPA-Bench 这样的安卓任务基准里,一个任务常常需要三十多个 GUI 动作,跨越好几个页面。这就是论文里说的"长序列任务"(long-horizon):路很长,每一步都只是路的一小段。

路一长,麻烦就来了。如果 agent 每一步都只盯着当前这张截图做决策,它实际上是在反复从零探索。SPA-Bench 的开发者们观察到一件很扎心的事:很多子步骤是跨任务、甚至跨 App 反复复现的。"打开搜索栏并提交查询"——购物 App 要用,地图 App 要用,邮箱 App 也要用。"把选中的商品加入购物车"——今天加太阳镜,明天加运动鞋。一个完全没有记忆的 agent,每接到一个新任务,都要把"打开搜索栏"这个已经做过一百遍的动作,从头摸索第一百零一遍。

人类不是这么干活的。你换一个新 App 用,上手飞快,因为你脑子里存着过去所有 App 的经验:搜索框一般长这样,设置一般藏在右上角的三条横线里,提交按钮通常在键盘旁边。问题只剩一个:这些经验,该怎么写进 agent 的笔记本?

🔬 三、两个极端,两头不靠

现有的记忆方法,基本就是那两份教材。

第一种,记"左手拿起刀"——动作级记忆。 把 agent 的每一次点击、滑动、输入都存下来,一次一条。问题在于,单个动作的成功说明不了任务在推进。点了一下搜索框,成功了——但这离"订好机票"还隔着十万八千里。论文里的原话是:单个动作太细,细到承载不了关于任务进度的语义。一条"点了一下这里"的经验,既没有头也没有尾,你不知道它从哪来、要到哪去,更不知道它在整个任务里扮演什么角色。老厨师的三十页切土豆笔记,你抄得再全,也学不会做菜。

第二种,记"做了一道红烧肉"——任务级记忆。 把 agent 一整段完整轨迹打包存下:从打开 App 到任务结束,一条路走到底。问题在于,整条轨迹死死绑在它当初那个任务上。论文指出的要害是:很多任务共享中间步骤、但在细节上分叉。任务 A 和任务 B 可能前半段完全一样——都要搜索、都要筛选、都要加购——只是最后买的商品不同。你把任务 A 的整条轨迹存下来,任务 B 一个字也用不上,因为那条轨迹从第三十步开始就不是 B 要走的路。一整本只有菜名的菜单,背下来还是不会烧菜。

两个极端,一个太细,语义稀薄;一个太粗,无法复用。就像教材的两难:抄动作,得到的是噪声;抄成品,得到的是不可拆解的整体。

这篇论文的赌注是:中间那个尺度存在,而且价值巨大。

🎯 四、子目标:一条刚好够用的经验卡片

他们选中的尺度叫子目标,定义朴素得近乎固执:共享同一个意图的连续动作序列。

论文给的例子都很生活化:"打开搜索栏并提交查询"是一个子目标;"把选中的太阳镜加入购物车"是一个子目标。注意它们的形态——有起点,有终点,中间裹着一段具体的操作,整体表达一个清晰的意图。它比一次点击厚得多,又比"完成整个购物任务"薄得多。老厨师会说:这就是"焯水去腥"。

具体怎么做?分三步把一条生轨迹炼成一张经验卡片。

第一步,切割。 把 agent 一次任务跑出来的完整动作序列交给一个 LLM,让它输出段边界——哪几个连续动作在共同表达同一个子意图,就从哪里下刀。切完之后,每个子目标只保留首尾两张截图作为视觉锚点,中间帧全部丢弃。这个取舍很聪明:记住起点和终点,就等于记住了"从这里到那里";中间过程是冗余的,留着只是占地方。

第二步,写卡片。 每个子目标被标注成五件套,论文的记号是 g = ⟨s_from, s_to; text, effect, behaviour, success⟩。拆开看:s_from 和 s_to 就是那两张边界截图,告诉你这条经验从哪个界面出发、到哪个界面结束;text 是意图的自然语言摘要——"我要干什么";effect 是从起点到终点的视觉变化一句话——"干成了什么样";behaviour 是底层动作序列的简洁概括——"具体怎么点的";success ∈ {yes, no, uncertain},由 LLM judge 标注这一条最终成功了没有。

这五件套值得多看一眼,因为它把一条经验从"录像"变成了"档案"。录像只能重播,档案可以查询、可以比较、可以警示。effect 和 success 尤其关键——前者告诉你这条边通向哪里,后者告诉你它通不通。一张写着"焯水去腥:效果是去除了浮沫;成功"的卡片,和一段三十秒的焯水视频,对后来者的价值天差地别。

到这一步为止,方法还只解决了"粒度"问题:经验切得刚刚好。但卡片如果只是一叠塞进抽屉,用的时候照样翻不到。接下来的问题才是这篇论文真正的胜负手——怎么组织这些卡片。

🕸️ 五、把菜谱钉在墙上:记忆图

答案是一张图。图的造法有三道工序,每一道都对着一个具体的麻烦。

第一道,合并状态。 图的节点不是任务,不是动作,而是界面状态——一张代表"当前屏幕长什么样"的截图。构建时,每来一张新截图,就计算它和已有节点的嵌入余弦相似度:大于等于 τ=0.9,就并入现有节点;否则,新建一个节点。这一步是整个设计的灵魂。它相当于说:不同任务、不同轨迹,只要经过同一个"厨房台面"——同一个搜索页、同一个购物车页、同一个设置页——经验就自动汇聚到同一个节点上。老厨师换了一个徒弟,徒弟又换徒弟,但那个灶台一直在那里,所有人在同一个灶台前攒下的经验,都挂在同一面墙上。

第二道,连边。 每个子目标成为一条有向边,从它的源节点(出发界面)指向目标节点(到达界面),边上驮着完整的五件套标注。于是图里的每一条边都在讲述一件事:"从这个界面出发,有人试过这么干,到了那个界面。"图不再是档案柜,而是一张经验的地图:站在任何一个节点上,你都能一眼看到从这里出发的所有出路。

第三道,去重。 建图过程中难免积累重复:同一对界面之间,被不同的任务走过许多次,语义几乎一样。规则是:在同一个源节点下,若两条边的目标节点相同、success 标注相同、且意图文本的嵌入相似度超过 θ=0.9,就判为重复,丢弃后加进来的那条。这保证了图随经验增长而变厚,但不会无谓地变臃肿——同一个"焯水去腥",来一百个厨师演示,墙上也只钉一张卡片。

三道工序做完,散落的轨迹变成了一张有向图:节点是世界里反复出现的那些"处境",边是从每个处境出发被试过的那些"动作方案",每条边都带说明书、带成败标注。

🔍 六、检索:回到同一个厨房台面

图建好了,用的时候怎么办?流程短得出人意料。

agent 每到一个新处境,就把当前截图编码成嵌入向量,在图里找余弦距离最近的那个节点——论文取 top-k,k=1,只要最近的一个。然后,收集这个节点的所有出边,包括成功和失败的子目标,格式化成一段 memory block,塞进 prompt。整个过程的额外延迟大约 0.5 秒。

两个细节值得停下来咂摸。

第一,用当前截图去对齐节点,本质上是承认了一件事:agent 处境相同,就该共享经验。你在任何一个 App 的搜索页,和你在另一个 App 的搜索页,经验是相通的。视觉相似度在这里成了处境的通用身份证。而且检索只取 top-1(k=1),这个"抠门"反而是一种设计自信:因为同一处境的经验已经被合并、聚合在一个节点上了,最近的那一个节点,出边清单就是该处境的完整经验目录。不需要贪多,取对了那一个,就够了。

第二,也是我个人最喜欢的一个设计:失败的子目标也一并返回。 大多数记忆系统只存"正确做法"——教科书从来不写错题集。这篇论文偏偏把"从这里出发的失败尝试"也端到 agent 面前。效果是双重的——agent 不仅知道"有人从这里成功走到了那里",还知道"有人从这里出发试过那样走,撞死了"。老厨师教徒弟,从不说"你照着做就行",他说的是"上次有人在这里把糖当成了盐"。知道哪里埋着雷,和知道路怎么走,是同等重要的知识。而且注意:失败经验挂在图的边上,检索时跟着节点自然带出来,不需要 agent 额外发问"这里有什么坑吗"——坑就标在地图上。

📊 七、45.30%,和一个让人尴尬的 30.77%

实验在 SPA-Bench 英文单应用 level-3 拆分上进行,一共 13 个任务,独立跑 3 次取平均。基座模型是 Qwen3-VL-8B-Instruct,嵌入用 Qwen3-VL-Embedding-8B,超参数 τ=0.9、θ=0.9、k=1。手机是云端的安卓实例,通过 ADB 连接。

Table 1 列了五组对照,这张表几乎把论文所有的论点都装下了:

记忆粒度 组织结构 成功率
无记忆 — 34.19%
子目标 Flat(无图) 30.77%
动作 Graph 38.46%
任务 Graph 36.75%
子目标(本文) Graph 45.30%

三个读法。

第一行到最后一行:45.30% 对 34.19%,提升 11.11 个百分点。在一个 13 个任务的小基准上,这个数字不算小。

第二,注意那个加粗的 30.77%——子目标 + 无图结构,比无记忆还差,掉了 3.42 个百分点。这个结果是反直觉的,也是全表最诚实的一格:切出漂亮的子目标、写全五件套标注,如果只是平铺直叙地堆在那里,反而成了负担。道理不难想明白:没有图做聚合,相似的子目标各自为政,检索回来一堆同质卡片互相干扰,塞进 prompt 的全是噪声。好粒度救不了烂组织。

第三,动作级配上了图(38.46%),也只比任务级配图(36.75%)好一点点,两者都被子目标 + 图甩开六个百分点以上。图结构能放大语义的厚度,但放大不了语义本身——边太薄,图再精巧,agent 拿到的还是一簸箕"点了一下这里"的碎片;边太厚,图里每条出路都是一整条不可拆解的路,每个节点几乎只有一条路可走,检索也就退化成背诵。

顺带记一笔工程账:整张图的构建成本是 4 个 GPU 小时,每次检索额外约 0.5 秒。不做大力出奇迹的堆算力,把记忆系统做成一种用得起的基础设施——这种工程审美,在一篇方法论文里值得单独点赞。

🧠 八、粒度 × 结构:一笔乘法,不是加法

把五组数字摊在桌上,真正的故事才开始。

这本质上是一个粒度 × 结构的析因设计:粒度三档(动作 / 子目标 / 任务),结构两档(平铺 / 图),外加一个无记忆基线垫底。它让我们能单独看每个因子的贡献,更重要的是,看它们的交互。

只看粒度,你会得出"越细越好"或者"适中最好"的结论——动作级(38.46%)输给子目标(45.30%),任务级(36.75%)也输给子目标,子目标确实是最优粒度。只看结构,图到底有没有用,这张表给不了完整答案——因为唯一的无图对照(Subgoal + Flat)恰恰是表现最差的那个配置。

但两个单因子结论拼不出 30.77% 那一格。子目标这个最优粒度,一旦离开图,直接跌破无记忆基线。也就是说:粒度的价值是有条件的,它必须长在某种组织结构里才能兑现。 反过来说,图结构的价值也不是无条件的——给动作级配上图,只捞回 4 个多百分点;给任务级配上图,只捞回 2.5 个。图能放大边里已有的语义,但无法无中生有。

用菜谱的语言讲:粒度决定每条经验本身有没有用,结构决定用的时候找不找得到、拎不拎得清。一条"焯水去腥"写得再好,散在三百页流水账里等于没有;一面钉满卡片的墙,如果每张卡片写的都是"左手拿起刀",钉得再整齐也是噪音。有用 × 找得到,两者相乘,才等于 45.30%。

再往里走一步,这张图的节点设计藏着一层视角转换:节点记录的不是"行为",是"处境"。 动作级记忆的视角是行为者的——我做过什么;任务级记忆的视角是完成者的——我完成过什么;而这篇论文的视角是世界本身的——这里有一个搜索页,这里有一个购物车页,它们不隶属于任何一次任务,却比任何一次任务都活得久。经验挂在处境上,处境比任务长寿,所以经验得以跨任务存活。这是"记忆图"比"记忆库"多出来的那一维:库回答"我存了什么",图回答"世界长什么样、我在其中试过什么"。

这个乘法结构其实点破了记忆研究里一个常见的幻觉:很多工作执着于回答"该记什么",仿佛存在一个绝对正确的记忆单元。Table 1 的第三行说明,脱离组织方式谈记忆单元,是在解一个欠定的方程。真正的问题永远是成双的:记多大的块,以及块与块之间是什么关系。

⚠️ 九、诚实的边界

论文自己交代的局限很清楚:整个方法假设 GUI 环境可以被近似成离散状态空间——界面是一张张相对稳定的"页面",截图相似就意味着处境相同。这个假设在大部分 App 里成立,但在视频播放器这类高度动态的界面里就悬了——屏幕每一帧都在变,视觉相似度成了一个噪音很大的代理,节点合并会失控。这也是所有以"截图相似度"为基石的方法共同的软肋。

另外几处我读完后的私心批注:13 个任务的评测规模偏小,成功率的绝对数字对基座模型敏感,换更强的 backbone 这个数字可能整体抬升或收窄——外部效度要靠更大规模的复现来背书;子目标的分割和 success 标注都交给 LLM 判断,分割的边界误差和 judge 的噪音会直接传导进图里,论文没有展开分析这部分的鲁棒性。这些是"方法验证"论文的正常体量,不必苛求,但读的时候心里要有数:它证明的是"这条路线成立",而不是"这个系统已经足够强壮"。

🔭 十、三部曲之二:从"发现"到"子目标"

最后说说这篇论文在这个系列里的位置。

这是"记忆管理学"三部曲的第二篇,主题是记忆怎么整理。上一篇 Muffin 处理的是 agent 与 agent 之间的记忆——什么时候该把自己的经验分享出去,它的答案是"发现"这个粒度:太细的原始轨迹传出去是垃圾,太粗的总结又丢了可复现的细节。这一篇处理的是 agent 自己脑子里的记忆——经验该切成多大一块存下来,它的答案是"子目标"。

两篇论文,一个在协作层面,一个在个体层面,做的却是同一件事:给信息找到正确的颗粒度。这件事听起来像工程调参,实际上是记忆系统里最像"判断"的部分——它需要同时理解任务的语义结构和记忆的检索方式,然后在"太细"和"太粗"之间找到那个会呼吸的区间。老厨师的"焯水去腥",徒弟的笔记本,agent 的记忆图,本质上是同一个问题的三个化身。

第三篇,我们会聊一个更冷峻的问题:记忆值多少钱——当获取记忆、存储记忆、检索记忆都有成本的时候,什么样的记忆系统才是一个理性 agent 值得建的?那是决策理论的框架,答案不会像这篇这么温情。

回到开头那份拜师教材。如果我是那个徒弟,我会接过老厨师的笔记本——不是那三十页切土豆的流水账,也不是那本一行一道的菜单,而是钉满整面墙的、每一条都写着"从哪来、到哪去、怎么做、成没成"的卡片墙。华为诺亚方舟的这篇文章证明,agent 也值得拥有同一面墙。而且墙不贵:4 个 GPU 小时砌好,半秒钟查询一次。

下次看到某个 agent 又在新 App 里从零摸索搜索框的位置时,请记住这 11.11 个百分点——那不是模型变聪明了,是它终于学会了记笔记。

📚 参考文献

  • Luo, D., Beechey, D., Yuen, D., & Luo, W. (2026). Subgoal-aware Memory Graph for GUI Agent. arXiv:2610.31307v1 [cs.AI]. Huawei Noah's Ark Lab. Published 2026-10-22. 通讯作者:luoweilin3@huawei.com.
  • 评测基准:SPA-Bench 英文单应用 level-3 拆分(13 个任务,3 次独立运行取平均)
  • 基座模型:Qwen3-VL-8B-Instruct;嵌入模型:Qwen3-VL-Embedding-8B
  • 关键超参数:视觉合并阈值 τ = 0.9,文本去重阈值 θ = 0.9,检索 k = 1
  • 构建成本:4 GPU-hours;检索延迟:约 0.5 秒

讨论回复

加载中...
正在加载回复...

正在加载回复...

推荐
智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

领取 2000万 Tokens 通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力
登录