深度拆解 OpenManus 技术框架:与 Manus 的差距分析
从代码层拆解 OpenManus 的四层架构与 ReAct 骨架,用一次真实的旅游规划任务暴露它的僵尸 Agent 和内存污染缺陷,再对照官方 Manus 与 Anthropic,看清开源框架和商业产品之间那道叫上下文工程的鸿沟。
TL;DR
MetaGPT 团队开源的 OpenManus 提供了一套清晰的 Agent 骨架: 基础设施层、工具层、Agent 层、应用入口层,核心是 BaseAgent 到 ReActAgent 到 ToolCallAgent 的三层继承, 跑的是 think → act → observe 的循环。 我用一个「北京五日游规划」的复杂指令实测了它的多 Agent 模式, 结果非常有教学价值:Agent 在浏览器工具连续超时后会幻觉自己成功了, PlanningFlow 复用 Agent 实例却不重置状态,切换任务时不清空 memory 导致 API 400 报错, Agent 就此僵尸化,而 Planner 只是记录错误然后继续调度下一步。 对照官方 Manus 会发现,真正的护城河全在上下文工程上: 文件系统才是真正的上下文、遮蔽而非移除工具以保住 KV 缓存、多 Agent 的首要目标是上下文隔离而非模仿人类角色。
目录
MetaGPT 团队开源了 OpenManus,一个通用的 AI Agent 框架。它的目标是提供一套强大的架构,让 Agent 能够执行浏览器操作、代码执行、文件操作等复杂任务。
那么,这个框架是怎么搭建的?它和我们熟知的 Manus 有什么异同呢?
PM 视角:为什么要扒开源代码?
现在 AI 几乎可以秒懂任何代码库,程序员的技术黑盒在逐渐白盒化,看代码就像是看文档。产品经理可以,也应该,深入前沿技术,进行「黑客级竞品调研」。
它不是简单地罗列功能,而是建立一个交叉验证的闭环:
- 实测体验:从用户视角,感知竞品(如商业版 Manus)的效果。
- 技术解密:深入挖掘竞品的技术博客、论文、访谈,理解其技术原理。
- 开源复现:找到一个业界最接近的开源项目(如 OpenManus),在内部跑起来,观察其实现过程,哪怕这个开源项目只有商业 Manus 效果的 50%。
那为什么要复现一个可能落后的开源项目?因为没有对比,就没有分析。通过复现 OpenManus,我们是作为开发者的角度,能看到 Agent 所有的思考日志。这让我们能精准定位到它技术架构的优劣势,并看到它和真 Manus 的差距。
看到差的,才能真正理解好的牛在何处,才有要优化的方向。
整体技术架构概览
从代码和设计来看,OpenManus 采用了经典的分层设计,可以概括为四个核心层次:
- 基础设施层:最底层,提供 LLM 抽象、沙箱环境、配置管理和日志。
- 工具层:中间层,提供 Agent 动手的能力,如浏览器、代码执行、文件操作、搜索等。
- Agent 层:核心控制层,负责思考,决定何时调用什么工具。
- 应用入口层:最上层,负责接收用户指令,启动 Agent。
简化的流程是:用户指令 → Manus Agent(Agent 层)→ LLM(基础设施层)思考并决定调用工具 → 工具集合(工具层)↔ 沙箱 / 浏览器 / 外部系统。
1、统一的 LLM 抽象层(app/llm.py)
这是 Agent 的大脑中枢。框架没有锁定单一模型:
- 兼容多家模型:OpenAI、Azure、Ollama(本地模型)、AWS Bedrock 都可以通过
config.toml无缝切换。 - 统一 API:封装了统一的
ask和ask_tool接口。 - 内置健壮性:自带
tenacity重试策略,能处理常见的速率限制和 API 错误。 - 成本控制:内置 Token 统计,包括图片 Token 估算,能有效防止上下文超限。
2、强大的工具集合(app/tool/)
这是 Agent 的双手,内置了极为丰富的工具集:
- 环境控制:
BrowserUseTool(基于 Playwright 和 BrowserGym 的浏览器自动化)、ComputerUseTool(配合 Daytona Sandbox 实现 GUI 层面的电脑控制)。 - 代码与文件:
PythonExecute/Bash(在沙箱中安全执行代码和 Shell 命令)、FileOperators/StrReplaceEditor(文件读写、列举、编辑)。 - 信息获取:
WebSearch(封装 Google / Bing / Baidu)、Crawl4ai(结构化抓取网页内容)。 - 其他能力:
DataAnalysis+ChartVisualization(数据分析与图表可视化)、AskHuman(在关键节点引入人类确认)。
3、隔离的沙箱环境(app/sandbox/)
安全是 Agent 框架的重中之重。默认使用 DockerSandbox,将代码执行和 Shell 命令限制在隔离的 Docker 容器中,可以配置 CPU 和内存限制防止资源滥用,也支持连接 Daytona 远程开发环境实现更复杂的 GUI 控制。
4、独特的能力:环境感知与协议支持
浏览器环境感知:在 Agent 操作浏览器时,这个模块会自动将当前页面的 DOM 摘要、页面信息等上下文喂给 LLM,极大提升了模型对当前环境的感知力。
A2A / MCP 协议支持:MCPClientTool 支持模型上下文协议,允许 Agent 动态地从外部服务加载和调用工具;protocol/a2a 支持将 Manus Agent 整体封装成一个 A2A 服务,让其他系统远程调用它的能力。
核心工作流拆解:Agent 如何思考与行动
OpenManus 的核心是一套基于 ReAct 模式的 Agent 引擎。无论上层是哪种 Agent,它们几乎都共享同一套骨架。
1、通用骨架:BaseAgent → ReAct → ToolCall
BaseAgent 定义了 Agent 的通用生命周期:run(request) 是总入口,负责管理状态(IDLE → RUNNING)、初始化 memory、启动多步循环;step() 是循环中的核心,每一步都会调用一次,直到达到 max_steps 或状态变为 FINISHED;cleanup() 在任务结束时清理资源。
ReActAgent 继承 BaseAgent,注入 ReAct 思想,把 step() 拆分成了 think()(思考)和 act()(行动)两个方法。
ToolCallAgent 继承 ReActAgent,是最关键的实现层:
think()负责调用 LLM。它打包好memory中的历史消息和available_tools的工具列表,调用llm.ask_tool(...),等待 LLM 返回思考文本和工具调用计划。act()负责执行工具。它解析think()阶段拿到的tool_calls,通过execute_tool()真正去调用工具,并拿到执行结果。
总结成一个闭环就是:think → act → 把 ToolResult 写回 memory → 进入下一步循环。
2、单 Agent 流程:各司其职
基于上述骨架,OpenManus 派生出了多种专职 Agent,共享骨架但拥有不同的工具集:
- 通用 Manus Agent:默认的全能型 Agent,工具集包括浏览器、代码、文件、AskHuman、Terminate,以及动态加载的 MCP 工具。
create()时会根据配置初始化 MCP 客户端;think()之前会检查是否需要注入浏览器上下文。 - SandboxManus Agent:Computer Use 专家,专为 Daytona 等远程 GUI 沙箱设计,工具是沙箱特供版,能力更强。
create()时创建远程沙箱,cleanup()时销毁。 - DataAnalysis Agent:数据分析师,工具是跑分析脚本、生成图表配置、调用服务绘图。
- SWEAgent:程序员,工具集极简,只有
Bash和StrReplaceEditor,专注于「运行测试 → 发现错误 → 修改代码」的循环。
3、多 Agent 编排
当任务复杂需要多种 Agent 协作时,PlanningFlow 出场:
- 创建 Flow:注册多个 Agent,例如
{"manus": Manus(), "data_analysis": DataAnalysis()}。 - 生成计划:先用
PlanningTool(内部调用 LLM)根据用户输入生成一个包含多个步骤的任务计划。 - 分发执行:循环遍历步骤,检查
Step的type字段,调用get_executor(step_type)找到最合适的 Agent;没有匹配的就用默认的manus兜底。 - 执行并更新:把当前步骤的
step_prompt交给选定的 Agent 运行,完成后标记为 COMPLETED。 - 汇总:所有步骤完成后返回结果。
以旅游规划为例:一次真实的协作流
为了测试协作能力,我用 run_flow.py 的多 Agent 模式下达了一个典型的复杂指令:
我想要 11.15-11.20 去北京游玩,我和我妈妈两个人,请你帮我制定一下旅游规划,预算一万五左右
一、启动 PlanningFlow
Agent 接收到指令后,第一件事不是动手,而是启动规划流程。规划器调用 LLM,把模糊指令分解为一份清晰有序的行动计划,几秒钟后生成了 7 步:
Plan: 北京5日游规划(11.15-11.20,2人预算一万五左右)0. [ ] 前期准备:预订机票/高铁票、酒店、景点门票1. [ ] Day 1 (11.15):抵达北京,入住酒店,游览天安门广场、前门大街2. [ ] Day 2 (11.16):故宫博物院深度游,景山公园俯瞰全景3. [ ] Day 3 (11.17):八达岭长城一日游4. [ ] Day 4 (11.18):颐和园游览,圆明园遗址参观5. [ ] Day 5 (11.19):天坛公园,王府井购物,品尝北京烤鸭6. [ ] Day 6 (11.20):自由活动,整理行李,返程二、调度执行者:从在线预订到被迫放弃
计划制定后,PlanningFlow 开始调度默认的 Manus Agent 完成第 0 步「前期准备」,Agent 获得了 20 步的执行权限。接下来是一场教科书式的挣扎与妥协。
尝试 1(Web 搜索):调用 browser_use (action: "web_search"),报错 Cannot navigate to invalid URL。
尝试 2(访问携程):Agent 自救,改为 go_to_url 直接访问携程,报错 Timeout 30000ms exceeded。
关键缺陷(幻觉):下一步的思考日志写着「Great! I can see we’ve successfully navigated to Ctrip」。这是最致命的一点——尽管上一步明确超时失败,Agent 却幻觉自己成功了,并基于这个错误状态继续执行 extract_content、click_element,结果自然是连续失败。
最后的妥协:在连续 18 步失败后,Agent 似乎意识到浏览器工具不可靠,日志写着「The website seems to be having navigation issues. Let me try a different approach」,转而调用文件编辑工具,成功创建了《北京5日游预订规划.md》和《北京5日游预算计算器.py》。
最终 Agent 耗尽了 20 步,PlanningFlow 把第 0 步标记为完成。
三、关键缺陷:僵尸 Agent 与健忘的 Planner
前期准备完成后,PlanningFlow 指派同一个 Manus Agent 实例去执行第 1 步。Agent 重复了「挣扎—妥协」循环,最后用文件工具产出了《Day1详细行程.md》,并成功调用 terminate 结束任务。
但从第 2 步开始,系统暴露了严重的设计缺陷。
状态管理缺陷:调度第 2 步「Day 2 故宫」时,日志显示 Executing step 11/20。注意,这是一个新任务,但 Agent 的 current_step 计数器却从 11 开始——PlanningFlow 复用了 Agent 实例,却没有重置它的内部状态。
内存管理缺陷(致命):Agent 成功创建了《Day2故宫深度游.md》后,执行第二项操作时系统崩溃:
ERROR | app.llm:ask_tool - OpenAI API error: Error code: 400{'error': {'message': "Messages with role 'tool' must be a response toa preceding message with 'tool_calls'"}}这个 400 错误是 Agent 开发中最经典的错误:消息历史被污染了。上一个任务的最后一条消息是一条 tool 结果,而新任务没有正确清空历史,导致 think() 时发送了一个无效的消息序列。
错误处理缺陷:此时 Agent 实例已经僵尸化,think() 会永远 400 报错。而 PlanningFlow 捕获了错误之后……继续调度第 3 步。接下来的日志就是这个僵尸循环的不断重复:调度 Day 3 → Agent 成功写一个文件 → think() 时 400 报错 → Planner 捕获错误,继续调度 Day 4。
小结:
优点是规划能力清晰(成功把复杂任务分解成逻辑清晰的步骤)、实现了指挥家—执行者的调度模式、有一定弹性(浏览器工具连续失败时能妥协转向文件工具,曲线救国)。
缺陷是工具脆弱(browser_use 和 python_execute 高频超时)、状态管理有漏洞(复用实例不重置)、内存管理有漏洞(切任务不清空 memory)、错误处理缺乏健壮机制(不重试也不重新规划,只是记录后继续)。
与 Manus 的差距,以及 MCP 的演进
Manus 官方博客揭示了这套朴素流程在真实复杂任务(平均 50 次工具调用)中会遇到的核心瓶颈——上下文管理。这正是最大的差距所在,官方 Manus 的核心护城河就是上下文工程。
差距一:上下文管理
OpenManus 的做法非常朴素:把每一步的观察完整地、只增不减地追加到 memory 列表,累积到 Token 上限时 LLM 就报错,任务失败。
官方 Manus 的做法是把上下文当作成本最高昂的资源来管理,其策略不是存储,而是调度。核心理念是——文件系统才是真正的上下文:
- 上下文卸载:LLM 的上下文窗口只是一个短暂的暂存器,Manus 被训练成按需读写文件,将文件系统用作结构化的外部记忆。
- 上下文缩减:不存储完整结果,而是区分 Full 和 Compact。一个工具调用的原始结果(Full)可能非常长,Manus 会把它存入文件系统,只在
memory中保留一个文件路径(Compact)。
差距二:工具调用与 KV 缓存成本
OpenManus 的做法:think() 阶段每次都把 available_tools 里的所有工具都塞给 LLM。
官方 Manus 的做法围绕 KV 缓存命中率来设计:
- 问题:如果在循环中动态添加或删除工具,会导致 LLM 的 KV 缓存失效,推理成本和延迟飙升十倍。
- 方案:遮蔽,而非移除。Manus 的工具列表是固定的,它不会移除工具,而是在解码时通过遮蔽或预填充的方式,强制 LLM 只能从一个特定子集(比如
browser_*)中选择。 - 卸载到沙箱:Manus 只保留极少数(不到 20 个)原子工具,其他所有复杂功能都被卸载到沙箱中,通过
Bash以命令行方式调用。这极大简化了工具集,进一步保证了 KV 缓存的稳定。
差距三:多 Agent 编排
OpenManus 的做法:PlanningFlow 先让 LLM 生成计划,然后按步骤为每个步骤选择执行者,把 step_prompt 传过去。
官方 Manus 的做法:多 Agent 的首要目标是上下文隔离,而不是模仿人类角色,因为 LLM 没有人类的认知局限。它的情景式上下文共享比简单的 step_prompt 传递灵活得多:
- 简单任务:Planner 只传递指令,子 Agent 在干净的上下文中执行后返回结果。
- 复杂任务:例如子 Agent 需要读写 Planner 正在操作的文件,Planner 会把完整上下文加共享文件系统一起传过去,确保子 Agent 在需要时拥有完整记忆,同时又能在自己的隔离环境中思考。
小结一下:OpenManus 提供了一个功能完整、模块清晰的 Agent 骨架,让我们看清了 Agent 是如何基于 think → act → observe 循环工作的。但官方 Manus 展示了,从一个「能跑」的开源框架到一个「好用」的商业产品,中间隔着一条由上下文工程组成的深深护城河。
作为服务:Agent 能力的 API 化
OpenManus 提供了两种把能力暴露给外部的方式:A2A 协议把整个 Agent 封装成一个标准服务,让外部系统远程调用它作为黑盒执行者;MCP 服务器则把工具层打包成 MCP 服务器,实现 Tools-as-a-Service。
但用 Anthropic 提出的 Agent Skills 和 MCP Code Execution 来审视,会发现两者在设计哲学上的巨大差异。OpenManus 实现了「API 化」,而 Anthropic 正在构建一个「可扩展的能力生态」。
概念辨析:接口 vs 技能包
OpenManus 的 AgentSkill 在 A2A 协议中仅仅是一个可远程调用的能力接口。它告诉外部系统「我有一个叫 python_execute 的功能」,但并不包含如何用好这个功能的知识。
Anthropic 的 Agent Skill 则是一个「知识 + 代码」的经验包,是一个包含 SKILL.md 和辅助脚本的完整文件夹,核心是渐进式披露:启动时只加载元数据,Agent 认为相关时才主动读取 SKILL.md 学习怎么做,需要时再进一步读取其他脚本。
差距在于:OpenManus 的 Skill 是一个固定的功能点,而 Anthropic 的 Skill 是一个可被 Agent 学习和发现的知识包。
架构对比:直接调用 vs 代码执行
OpenManus 把自己的工具注册为 MCP 工具,任何客户端 Agent 都要在上下文中加载这些工具的完整定义,然后直接调用。
Anthropic 明确指出了直接调用的两个致命缺陷:定义过载(工具成百上千时,所有 schema 会塞爆上下文)和结果过载(工具的中间结果,比如一份两小时的会议转录稿,必须完整流入上下文再传给下一个工具)。
它的解决方案是把 MCP 工具作为代码 API 暴露在文件系统上,Agent 不再直接调用工具,而是编写代码来与 MCP 交互。这种模式的优势是压倒性的:
- 渐进式披露:Agent 通过
ls ./servers发现工具,只在需要时cat读取特定工具的代码。 - 上下文高效:Agent 可以在沙箱中用代码处理数据(过滤、聚合),只把最终的小结果返回给 LLM。
- 能力持久化:Agent 可以把自己写的好用代码保存为新文件,再加一个
SKILL.md,这就创造了一个全新的 Agent Skill。
最后
OpenManus 不仅仅是一个能运行的 Agent,它是一个设计清晰、高度模块化的 AI 代理框架。
但通过与官方 Manus 和 Anthropic 的深度对比,我们能更清醒地看到「能跑的开源框架」与「好用的商业产品」之间的真正鸿沟。
这正回应了开篇提到的黑客级竞品调研。拆解 OpenManus,看的不仅是它如何思考与如何行动,更是为了通过复现它的脆弱与缺陷,去反推那些商业产品到底解决了多少看不见的难题。
对于 PM 而言,这就是深入代码的价值。
核心结论
标注「判断」「假设」的是我的看法而非事实;标注「已推翻」的保留在这里,不删除。
程序员的技术黑盒正在白盒化,PM 可以也应该做「黑客级竞品调研」——实测体验、技术解密、开源复现三者交叉验证。看到差的,才能真正理解好的牛在何处。#
判断 · 把握较大
实测中最致命的一幕:浏览器导航明确超时失败后,Agent 在下一步思考里幻觉自己成功了,并基于这个错误状态继续操作。工具失败后的状态确认是 Agent 可靠性的关键缺口。#
把握较大
PlanningFlow 复用 Agent 实例时既不重置 current_step,也不清空 memory,导致新任务发出无效消息序列而 API 400 报错,Agent 从此僵尸化,而 Planner 只是记录错误继续调度下一步。#
把握较大
OpenManus 和官方 Manus 之间最大的差距是上下文管理。OpenManus 只增不减地往 memory 里追加观察,撑到 Token 上限就失败;Manus 把上下文当最昂贵的资源来调度,文件系统才是它真正的上下文。#
判断 · 把握较大
在循环中动态增删工具会让 KV 缓存失效,推理成本和延迟可能飙升十倍。正确做法是保持工具列表固定,在解码时通过遮蔽强制模型只从特定子集中选择。#
引用本文
晨旭,《深度拆解 OpenManus 技术框架:与 Manus 的差距分析》,晨光里的AI,2025-11-15
[晨旭:《深度拆解 OpenManus 技术框架:与 Manus 的差距分析》](https://chenxu.xin/writing/openmanus-teardown)带进你的 AI 继续追问
这篇文章有一份干净的 Markdown 原文,可以直接交给任何模型读,不用复制粘贴。