跳到主要内容

Mobile-Agent-E 与 PC-Agent:自进化长期记忆与分层编排

30 秒导读: v2 已经把感知/决策/反思/记忆拆成多个 agent 协作; Mobile-Agent-E(下称 E)再往前走一步——让 agent 做完一个任务后反思出可复用的经验 (Tips 与 Shortcuts),存进跨任务的长期记忆,下次遇到新任务先检索这些经验再动手,越用越熟练。 PC-Agent 则把这套"分层多智能体 + 反思"搬到桌面,用指令 → 子任务 → 动作三级分解, 扛住 PC 上那种横跨 Chrome/Word/微信的长指令。

本章要讲清楚的一句话:E 的真正新意,是"跨任务演化"的经验记忆,而不是"单任务内"的进度记忆。 后者 v2 早就有了;前者才是 E 名字里那个 "E"(Evolution,进化)的来源。


1. 这是什么(零基础也能懂)

  • 一句话定义: E 是一个能操作安卓手机的多智能体系统,它会在每次完成任务后 总结经验、把经验攒进一个会长期保留的知识库,让后续任务做得更快更稳。

  • 解决什么问题: 传统 GUI agent 每次都"从零开始"——哪怕它昨天已经在美团点过一次外卖, 今天再点还是一步步试错。E 想解决的是:做过的事,下次能不能更利索?

  • 两类被沉淀的经验:

    经验类型是什么类比
    Tips(贴士)一句句自然语言的操作忠告(如"打开 App 后先关弹窗")老手写在便利贴上的注意事项
    Shortcut(快捷方式)一段可复用的原子动作序列(如"点输入框→输入→回车")录制好的一键宏
  • 用起来什么样: 你连续给它几个任务,它会在 logs/.../tips.txtshortcuts.json 里 不断改写这两份记忆;跑下一个任务前,它先从这份记忆里挑出和新任务相关的贴士与快捷方式塞进 prompt。

  • 一句话直觉: 把 Tips & Shortcuts 想成 agent 的肌肉记忆——练得越多,遇到相似动作越不用重新思考。

本节不碰代码。记住:E = v2 的多智能体骨架 + 一层会随任务积累、会被检索的长期经验记忆


2. 顶层全景(它大概怎么转)

E 的所有 agent 不直接互相说话,而是读写同一块共享数据——一个叫 InfoPool 的数据类 (黑板模式:大家往同一块黑板上写、从同一块黑板上读)。运行期有四个"干活"的角色,外加两对 "攒经验/取经验"的角色。

怎么读下面这张图: 上半是一次任务内部的循环(每一步都跑一遍),下半是横跨任务的经验记忆 读写。中间的 InfoPool 是所有人共享的黑板。

┌───────────────────────── InfoPool(共享黑板) ─────────────────────────┐
│ instruction · plan · progress · important_notes · tips · shortcuts … │
└───────────────────────────────────────────────────────────────────────┘
任务内循环(每步) ▲ 读 ▲ 读/写 ▲ 读 ▲ 写
┌──────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌──────────┐
│ 感知 │──▶│ Manager │──▶│ Operator │──▶│ Action │──▶│ Notetaker│
│ Perceptor│ │ 高层规划 │ │ 执行原子动作 │ │ Reflector│ │ 记要点 │
└──────────┘ │ +定子目标 │ │ /快捷方式 │ │ 判断成败 │ └──────────┘
└──────────┘ └────────────┘ └──────────┘
─────────────────────────────────────────────────────────────────────────────
跨任务经验记忆 任务开始前 任务结束时("Finished")
┌───────────────────┐ ┌──────────────────────┐
│ ExperienceRetriever│ ◀── 检索历史 │ ExperienceReflector │ ──▶ 反思出
│ ShortCut / Tips │ │ ShortCut / Tips │ 新经验
└───────────────────┘ └──────────────────────┘
│ │
└────────── tips.txt / shortcuts.json ─┘(落盘,跨任务持久)

各角色一句话职责:

角色干什么定义位置
InfoPool所有 agent 共享的黑板数据类,字段涵盖感知/工作记忆/规划/未来任务MobileAgentE/agents.py:129
BaseAgent抽象基类,规定每个 agent 三件套:init_chat / get_prompt / parse_responseMobileAgentE/agents.py:173
Manager读黑板做高层规划、拆子目标、判断任务是否"Finished"MobileAgentE/agents.py:185
Operator把模型选的动作真正执行到手机上(原子动作或快捷方式)MobileAgentE/agents.py:326
ActionReflector对比动作前后两张截图,判定成功(A)/走错页(B)/无变化(C)MobileAgentE/agents.py:570
Notetaker把与任务相关的重要信息记进 important_notesMobileAgentE/agents.py:660
ExperienceReflectorShortCut/Tips任务后反思出新的 Shortcut / TipsMobileAgentE/agents.py:737 / :825
ExperienceRetrieverShortCut/Tips任务前从历史经验里检索相关的 Shortcut / TipsMobileAgentE/agents.py:887 / :923

主线走一遍(高层): 总编排在 inference_agent_E.py:run_single_task(:393)。 一次任务大致是:检索历史经验 → 进入循环(感知 → Manager 规划 → Operator 执行 → 再感知 → ActionReflector 判成败 → 成功则 Notetaker 记要点)→ Manager 判为 "Finished" → 反思出新经验并落盘。


3. 核心机制之一:InfoPool —— 所有 agent 共享的黑板

它要解决的小问题

多个 agent 要协作,就得有个统一的地方交换"现在计划是什么、进度到哪、上一步成没成、 攒了哪些经验"。E 的做法不是让 agent 互相传消息,而是共享一个数据结构

思路/直觉

用一个 @dataclass所有跨 agent 的状态集中起来。每个 agent 的 get_prompt 都只是 从这个 pool 里读字段、拼成自己的 prompt;它们的解析结果再写回这个 pool。黑板即接口。

真实实现

InfoPool 的字段按用途分区,一眼能看出这套系统关心什么(agents.py:129):

@dataclass
class InfoPool:
# 用户输入 / 累积知识(← 跨任务长期记忆就住在这里)
instruction: str = ""
tips: str = ""
shortcuts: dict = field(default_factory=dict)
# 感知:动作前/后的可点击元素 + 键盘状态
perception_infos_pre: list = field(default_factory=list)
perception_infos_post: list = field(default_factory=list)
# 工作记忆:动作历史、成败、错误描述、要点
action_history: list = field(default_factory=list)
action_outcomes: list = field(default_factory=list)
important_notes: str = ""
# 规划:计划、进度、当前子目标
plan: str = ""
progress_status: str = ""
current_subgoal: str = ""
# 未来任务(供经验反思时"面向未来"提炼)
future_tasks: list = field(default_factory=list)

关键要分清两种记忆(这是本章的核心论点):

  • important_notes / action_history / progress_status单任务内的工作记忆—— 任务一结束就没用了。v2 就有类似东西。
  • tips / shortcuts跨任务的长期记忆——它们被写到 tips.txt / shortcuts.json, 下个任务还在(见 §5)。这才是 E 相对 v2 的新增维度。

BaseAgent:统一的三件套

每个 agent 都实现同样的抽象接口(agents.py:173),这让编排循环可以用完全一致的方式驱动它们:

方法职责
init_chat()初始化对话,塞入该角色的 system prompt(如 Manager 的"track progress and devise high-level plans")
get_prompt(info_pool)从黑板读字段,拼出这一步的 user prompt
parse_response(response)从模型回复里用 ### 小节名 ### 切割,抽出结构化字段

4. 核心机制之二:任务内的四角色循环

这一层与 v2 精神一致,但角色更清晰。挑两个最能说明设计的角色细看。

4.1 Manager —— 高层规划 + 判定完成

Manager 有两套 prompt 分支(agents.py:193get_prompt):

  • 首次规划(plan == ""):让模型把指令拆成带编号的子目标列表。
  • 续规划:把当前计划、上一个子目标、进度、重要笔记、以及**"是否卡住"的错误日志**都喂回去, 让模型决定"继续、改计划、还是标记 Finished"。

一个巧妙的容错设计: 当连续若干步都失败,编排循环会置 info_pool.error_flag_plan = True (inference_agent_E.py:706 附近),Manager 的 prompt 里就会多出一段 "### Potentially Stuck! ###", 把最近 err_to_manager_thresh 次失败的动作/描述/反馈上报给高层重新规划(agents.py:232)。 这是"执行层解决不了就升级到规划层"的分层容错。

4.2 Operator —— 把话精确落到手机上

Operator 是"手脚"。它先在 prompt 里把原子动作可用快捷方式都列给模型 (agents.py:336),模型回一段 JSON 指定动作名和参数,再由 execute 落地。

原子动作签名表(ATOMIC_ACTION_SIGNITURES,agents.py:272)是所有能力的底座:

动作参数说明
Open_Appapp_name靠 OCR 在屏幕上找到 App 名并点击
Tap / Swipe坐标点/滑
Type / Entertext / 无打字 / 回车
Back / Home / Switch_App / Wait系统级操作

快捷方式如何执行(关键): execute 里,若动作名命中 info_pool.shortcuts,就按它的 atomic_action_sequence 逐个展开成原子动作执行,并用 arguments_map 把快捷方式的参数 映射到每个原子动作(agents.py:509 起的 execute,展开逻辑在 :530)。这意味着一个 Shortcut 本质上是原子动作的可复用组合——这正是"经验"能被结构化沉淀的原因。

内置的初始快捷方式只有一个 Tap_Type_and_Enter(INIT_SHORTCUTS,agents.py:311), 其余都是 agent 自己在任务后反思出来的(见 §5)。

4.3 ActionReflector 与 Notetaker

  • ActionReflector(agents.py:570)拿动作前后两张截图对比,输出三选一的 outcome: A 成功 / B 走到错页 / C 无变化,并更新进度。编排层据此把结果写进 action_outcomes (inference_agent_E.py:947 起)。
  • Notetaker(agents.py:660)只在动作成功(A)后触发,把"与用户请求相关的重要文本/视觉信息" 累积进 important_notes(解析在 :717)——注意它被明确要求不要记低层动作,只记有价值的内容。

5. 核心机制之三(本章重点):自进化的长期经验记忆

这是 E 的灵魂。前面 §3/§4 讲的都是"单任务内"的事;这一节讲的是跨任务——经验如何在 一个任务结束时被"反思"出来、如何在下一个任务开始前被"检索"回来。

5.1 一句话总览:两个动作、两种经验

任务 N 结束 任务 N+1 开始
┌──────────────────────┐ ┌───────────────────────┐
│ ExperienceReflector │ ── 写 ──▶ 持久化 │ ExperienceRetriever │
│ · ShortCut(新宏) │ shortcuts.json │ · ShortCut(挑相关宏) │
│ · Tips(新贴士) │ tips.txt │ · Tips(挑相关贴士) │
└──────────────────────┘ │ └───────────────────────┘
反思 │ 读 检索

(下一个任务的 InfoPool.tips / shortcuts)

5.2 反思:任务后长出新经验

触发时机(重要): 反思不是每步都做,而是等 Manager 把 current_subgoal 标为 "Finished" 时才做一次(inference_agent_E.py:751):

# inference_agent_E.py:751 —— 只有任务收尾时才反思出经验
if len(info_pool.action_outcomes) > 0:
if "Finished" in info_pool.current_subgoal.strip():
# 1) 反思 Shortcut:能否把一串成功动作固化成新宏
prompt = exp_reflector_shortcuts.get_prompt(info_pool)
...
exp_reflector_shortcuts.add_new_shortcut(new_shortcut_str, info_pool)
# 2) 反思 Tips:有没有能防止常见错误的通用忠告
...
info_pool.tips = updated_tips
  • ExperienceReflectorShortCut(agents.py:737):把完整动作历史(含成败与进度)喂给模型, 问它"有没有哪段连续成功的动作可以固化成一个新 Shortcut"。它甚至会把 future_tasks 一并给模型参考(agents.py:785),让反思面向未来可能的任务而非只回顾过去。 产出的 JSON 经 add_new_shortcut(agents.py:806)校验后写进 info_pool.shortcuts ——去重:同名 Shortcut 不重复添加(:814)。
  • ExperienceReflectorTips(agents.py:825):同样喂完整历史,但产出的是自然语言贴士, 与已有 Tips 合并(agents.py:882 解析 updated_tips)。

落盘 = 跨任务的关键。 任务结束时 finish() 把两份记忆写到磁盘(inference_agent_E.py:354, 持久化分支在 :366-:373)。run_single_taskpersistent_tips_path / persistent_shortcuts_path 两个参数(inference_agent_E.py:401)就是"跨任务"开关——指向同一对文件,经验就在任务之间累积。

5.3 检索:任务前挑出相关经验

若攒的经验越来越多,全塞进 prompt 既贵又干扰。所以任务开始前有一个可选的检索步 (enable_experience_retriever,inference_agent_E.py:461):

  • ExperienceRetrieverShortCut(agents.py:887):把所有历史 Shortcut 的名字+描述给模型, 让它挑出与当前指令相关的,输出一个名字列表(解析在 :912);没有相关的就退回只用初始宏。
  • ExperienceRetrieverTips(agents.py:923):同理,从整段 Tips 里筛出与当前任务相关的条目。

检索完,选中的 Tips/Shortcuts 才被塞进 InfoPool,供本任务的 Manager/Operator 使用。

5.4 为什么说"这才是新意"

再强调本章论点:进度记忆(progress_statusimportant_notes)是单任务内的,v2 已有; 真正让 E "自进化"的,是这套在任务边界上反思→持久化→检索的 Tips & Shortcuts 长期记忆。 它把"经验"从一次性的对话上下文,变成了可累积、可检索、可执行(Shortcut 能直接跑)的资产


6. PC-Agent:同一套分层多智能体迁到桌面

PC-Agent 把 E 的"分层多智能体 + 反思"思路搬到 PC。README 自述是 "A Hierarchical Multi-Agent Collaboration Framework"。它和 E 是同源不同域:域从手机换成了 横跨 Chrome/Word/微信的桌面长任务。

6.1 新增的一层:指令 → 子任务 → 动作

PC 上的指令往往横跨多个应用、还要在应用间传数据(如"把微信里 John 问的问题拿去 Chrome 搜, 答案写进 Word")。PC-Agent 因此在动作循环之上加了一个子任务分解层:

用户长指令
│ get_subtask_prompt(prompt_qwen.py:44)

子任务 1 ─▶ 子任务 2 ─▶ 子任务 3 ... (可用 {key} 在子任务间传参)
│ │
▼ ▼
动作循环 动作循环 ← 每个子任务内部:感知→决策→反思→记忆(与 E 同构)
  • 子任务分解(PCAgent/prompt_qwen.py:44get_subtask_prompt):把复合指令拆成带编号的子任务, 并支持四种类型——普通串、输出字典的串、引用前序子任务 {key} 的串、以及两者兼有的串。 这套"字典传参"让子任务间能显式交换结果。
  • 参数回填:run.py 里遍历子任务,遇到需要 {key} 的子任务就从前序结果 answer_dict 里取值填充(PC-Agent/run.py:614 起的子任务循环)。

6.2 子任务内部:与 E 同构的四步

每个子任务内部的循环,角色和 E 几乎一一对应,只是 prompt 换成了桌面版 (全在 PCAgent/prompt_qwen.py):

PC-Agent 函数对应 E 的角色职责
get_action_prompt(:135)Operator决定下一个动作
get_reflect_prompt(:248)ActionReflector对比前后截图判成败
get_process_prompt(:326)Manager跟踪进度、判定子任务完成
get_memory_prompt(:307)Notetaker记录与指令相关的重要内容

6.3 桌面特有的难点:密集元素的感知

PC 屏幕上可交互元素又密又杂,PC-Agent 因此在感知侧做了不少融合工程 (PCAgent/merge_strategy.py):

  • merge_boxes_and_texts(:58)按 IoU(交并比)把重叠的文本框合并,减少碎片。
  • merge_all_icon_boxes(:147)处理图标框的包含/重叠关系,同一图标只留一个合适的框。
  • OCR 走的是阿里云 OCR API(PCAgent/text_localization.py:56),remove_punctuation(:43) 还会清洗识别噪声。

这一支是把 E 的感知层针对"桌面密集 UI"重做,论点上不改变分层多智能体的骨架。


7. 巧妙之处(可借鉴的技术)

  • 黑板即接口。 用一个 InfoPool dataclass 承载全部跨 agent 状态,agent 之间零直接耦合, 加/换 agent 只需读写字段(agents.py:129)。
  • 经验分两态:陈述性 vs 程序性。 Tips 是自然语言忠告(陈述性),Shortcut 是可执行的原子动作序列 (程序性)。后者能被 execute 直接展开跑(agents.py:530),让"经验"真正省下推理步数。
  • 反思面向未来。 经验反思时把 future_tasks 一起给模型(agents.py:785),提炼的经验 是"为将来准备"的,而非单纯复盘。
  • 分层容错。 执行层连错到阈值,就把失败日志上报给 Manager 重规划(error_flag_plan, inference_agent_E.py:706agents.py:232),而不是死磕。
  • 检索控预算。 经验多了先按相关性筛(ExperienceRetriever*,agents.py:887/:923), 避免长期记忆无限膨胀污染 prompt。
  • 子任务字典传参。 PC-Agent 用 {key} 在子任务间显式传数据(prompt_qwen.py:44), 把"跨应用长任务"降解成一串可独立执行的短任务。

8. 边界与局限(诚实)

  • 经验质量依赖 LLM 反思。 Shortcut/Tips 全靠模型自己总结,烂经验也会被写进库;去重只查名字 (agents.py:814),语义近似的重复宏挡不住。
  • Shortcut 用坐标,脆。 反思时被提醒"参数别太多、坐标必须当前屏幕可见"(agents.py:802), 但固化的坐标一旦换机型/换布局就可能失效——本质是绝对坐标的老问题。
  • 反思只在任务"Finished"时做。 若任务因 max_itr/连续失败而中止(inference_agent_E.py:583:599), 这次的经验不会被沉淀。
  • 感知是外挂的、慢。 E 仍靠 OCR + GroundingDINO + caption VLM 拼感知(inference_agent_E.py:229load_perception_models);这条外挂路线正是 v3/GUI-Owl 要用 原生基座模型内化掉的。
  • PC-Agent 的 OCR 绑定云 API。 text_localization.py 依赖阿里云 OCR 密钥(:15),离线跑不了。

9. 横向对比(在 Mobile-Agent 家族里的位置)

版本关键跃迁记忆维度
v1单智能体 ReAct + 外挂感知仅对话上下文
v2感知/决策/反思/记忆-规划 多智能体单任务内工作记忆
Mobile-Agent-E(本章)任务后反思 + 任务前检索+ 跨任务 Tips & Shortcuts 长期记忆
PC-Agent(本章)分层子任务分解迁到桌面子任务间字典传参
GUI-Owl / v3·v3.5把感知/定位/规划/反思内化进基座模型内化进模型权重

一句话:E 与 PC-Agent 是"把多智能体做深"的两支——E 深在时间维度(跨任务演化), PC-Agent 深在任务维度(层级分解)。它们的共同前提仍是"外挂感知 + 通用 VLM 编排"; 真正换赛道的是下一章的原生基座模型。


10. 代码地图(导航索引)

主题文件路径符号名
共享黑板数据类Mobile-Agent-E/MobileAgentE/agents.pyInfoPool
agent 抽象三件套Mobile-Agent-E/MobileAgentE/agents.pyBaseAgent (init_chat/get_prompt/parse_response)
高层规划 + 判完成Mobile-Agent-E/MobileAgentE/agents.pyManager
执行原子动作/快捷方式Mobile-Agent-E/MobileAgentE/agents.pyOperator.execute / Operator.execute_atomic_action
原子动作签名表Mobile-Agent-E/MobileAgentE/agents.pyATOMIC_ACTION_SIGNITURES
初始快捷方式Mobile-Agent-E/MobileAgentE/agents.pyINIT_SHORTCUTS
动作前后成败判定Mobile-Agent-E/MobileAgentE/agents.pyActionReflector
记录重要内容Mobile-Agent-E/MobileAgentE/agents.pyNotetaker
任务后反思出宏Mobile-Agent-E/MobileAgentE/agents.pyExperienceReflectorShortCut.add_new_shortcut
任务后反思出贴士Mobile-Agent-E/MobileAgentE/agents.pyExperienceReflectorTips
任务前检索经验Mobile-Agent-E/MobileAgentE/agents.pyExperienceRetrieverShortCut / ExperienceRetrieverTips
总编排循环Mobile-Agent-E/inference_agent_E.pyrun_single_task
经验持久化落盘Mobile-Agent-E/inference_agent_E.pyfinish(persistent_tips_path/persistent_shortcuts_path)
外挂感知模型装载Mobile-Agent-E/inference_agent_E.pyload_perception_models / Perceptor
PC 子任务分解PC-Agent/PCAgent/prompt_qwen.pyget_subtask_prompt
PC 动作/反思/进度/记忆 promptPC-Agent/PCAgent/prompt_qwen.pyget_action_prompt / get_reflect_prompt / get_process_prompt / get_memory_prompt
PC 感知框融合PC-Agent/PCAgent/merge_strategy.pymerge_boxes_and_texts / merge_all_icon_boxes
PC OCRPC-Agent/PCAgent/text_localization.pyocr / remove_punctuation
PC 子任务编排PC-Agent/run.py子任务循环(get_subtask_prompt → 逐子任务动作循环)