尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

OpenManus框架解析(一)完整 Prompt 组装架构与全链路流程

OpenManus框架解析(一)完整 Prompt 组装架构与全链路流程
📅 发布时间:2026/7/19 6:15:47

在 AI Agent 开发中,Prompt 组装是决定 Agent 推理能力、工具调用准确性、场景适配性的核心底层逻辑。很多 Agent 项目看似功能复杂,其核心底层均依靠一套分层、动态、可扩展的 Prompt 组装机制。

本文将基于完整的项目源码逻辑,层层拆解AI Agent 三段式 Prompt 组装架构,涵盖模板定义、动态注入、LLM 格式化全流程,附源码片段、执行时序、数据流图与核心设计思想,帮你彻底吃透 Agent Prompt 运行原理。

一、核心整体架构:三层分层设计

项目将 Prompt 组装拆分为三层独立职责,各层各司其职、解耦协作,兼顾静态模板统一性与动态场景灵活性:

Layer 1:模板定义层(app/prompt/*.py)

静态字符串模板,为每一类 Agent 独立配置专属的系统提示词(SYSTEM_PROMPT)和下一步思考提示词(NEXT_STEP_PROMPT),是所有 Prompt 的基础模板。

Layer 2:Agent 注入层(think() 方法)

核心动态逻辑层,负责读取静态模板、填充动态占位符、将下一步提示词注入对话记忆(memory),实现每轮推理的动态引导。

Layer 3:LLM 格式化层(ask_tool / format_messages)

API 适配层,将项目自定义的 Message 对象转为 OpenAI API 兼容字典格式,专门处理多模态图片、Token 计算、消息格式标准化。

架构极简总结:静态模板定义 → 动态内容注入 → 标准化 API 格式化

二、模板定义层:各类型 Agent 专属 Prompt 模板

项目中不同功能的 Agent 均拥有独立的 Prompt 模板文件,区分系统定位(SYSTEM_PROMPT)和迭代思考引导(NEXT_STEP_PROMPT),部分模板支持动态占位符。所有 Agent 模板配置汇总如下:

文件

Agent 类型

SYSTEM_PROMPT(系统定位)

NEXT_STEP_PROMPT(下一步引导)

toolcall.py

ToolCallAgent

"You are an agent that can execute tool calls"

"If you want to stop interaction, use terminate tool"

manus.py

Manus

"You are OpenManus, an all-capable AI assistant..." 含 {directory} 动态占位符

主动选择工具、拆解任务、解释执行结果

browser.py

BrowserAgent

详细浏览器自动化规则(JSON响应、元素交互、导航、错误处理)

含 {url_placeholder} 等5个动态占位符

mcp.py

MCPAgent

MCP协议说明、动态工具适配、异常错误处理规则

思考并选择最优 MCP 工具执行下一步操作

swe.py

SWEAgent

命令行编程环境专属定位,限制单次仅调用一个工具

空字符串(无需额外引导)

planning.py

PlanningAgent

结构化任务规划专家定位

校验计划完整性,执行规划的下一步任务

visualization.py

VisualizationAgent

数据分析与可视化专属定位,含 {directory} 占位符

单次仅选一个工具,遇到报错自动修复重试

三、Agent 注入层:think() 核心双路径逻辑

注入层是 Prompt 动态组装的核心,通过think()方法实现两条核心路径:系统提示词独立前置、下一步提示词入库迭代,两者逻辑完全隔离。

3.1 System Prompt:永久前置,不参与 Memory 截断

系统提示词用于定义 Agent 核心身份与能力,设计上不存入对话记忆 memory,每次调用 LLM 时单独前置拼接,永久不受max_messages=100截断规则影响,保证 Agent 身份定位全程不变。

核心源码(toolcall.py 47-55行):

response = await self.llm.ask_tool( messages=self.messages, # 对话历史(不含 system prompt) system_msgs=( [Message.system_message(self.system_prompt)] if self.system_prompt else None ), tools=self.available_tools.to_params(), tool_choice=self.tool_choices, )

LLM 内部拼接逻辑(llm.py 684-688行):

核心特性:System 消息永远位于消息列表最首位,全程保留,不会被对话历史截断。

3.2 Next Step Prompt:逐轮注入 Memory,引导迭代思考

下一步提示词是每轮推理的引导核心,会以伪用户消息的形式追加到 memory 末尾,强制引导 LLM 基于当前对话状态思考后续操作,实现任务迭代。

核心源码(toolcall.py 41-43行):

if self.next_step_prompt: user_msg = Message.user_message(self.next_step_prompt) self.messages += [user_msg] # 追加到 memory 对话历史末尾

执行效果:每一轮 Agent 推理,都会新增一条用户侧引导消息,让 LLM 持续对齐任务目标、推进流程。

四、LLM 格式化层:统一 API 消息格式

format_messages()是底层适配核心,负责将项目自定义的 Pydantic Message 对象,转为标准 OpenAI API 字典格式,同时专门处理多模态图片资源,兼容图文混合推理。

核心源码(llm.py 267-352行):

@staticmethod def format_messages(messages, supports_images=False) -> List[dict]: formatted_messages = [] for message in messages: # Pydantic 对象转为字典 if isinstance(message, Message): message = message.to_dict() # 处理 base64 图片,适配 OpenAI 多模态格式 if supports_images and message.get("base64_image"): message["content"] = [ {"type": "text", "text": message["content"]}, {"type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{message['base64_image']}" }} ] del message["base64_image"] # 过滤有效消息 if "content" in message or "tool_calls" in message: formatted_messages.append(message) return formatted_messages

核心能力:自动兼容纯文本/图文多模态场景,统一 API 入参格式,上层业务无需感知底层适配逻辑。

五、动态 Prompt 占位符机制:场景化实时适配

静态模板无法适配动态场景(如浏览器 URL、页面滚动位置、标签页数量),因此项目设计了动态占位符填充机制,以 BrowserAgent、Manus Agent 为典型代表。

5.1 BrowserAgent 动态 Prompt 逻辑

BrowserAgent 每次推理前,会实时获取浏览器状态,填充 5 个专属占位符,同时支持截图注入多模态消息。

think() 主流程源码(browser.py 120-125行):

async def think(self) -> bool: self.next_step_prompt = ( await self.browser_context_helper.format_next_step_prompt() ) return await super().think()

占位符填充核心逻辑(browser.py 47-79行):

async def format_next_step_prompt(self) -> str: # 1. 获取浏览器实时状态 browser_state = await self.get_browser_state() # 2. 提取状态信息,组装占位符内容 url_info = f"URL: {browser_state.url}, Title: {browser_state.title}" tabs_info = f"{len(tabs)} tab(s) available" content_above_info = f"({pixels_above} pixels)" if pixels_above else "" content_below_info = f"({pixels_below} pixels)" if pixels_below else "" # 3. 截图注入:将浏览器截图转为多模态用户消息 if self._current_base64_image: image_message = Message.user_message( content="Current browser screenshot:", base64_image=self._current_base64_image, ) self.agent.memory.add_message(image_message) # 4. 批量替换模板占位符 return NEXT_STEP_PROMPT.format( url_placeholder=url_info, tabs_placeholder=tabs_info, content_above_placeholder=content_above_info, content_below_placeholder=content_below_info, results_placeholder=results_info, )

5.2 Manus Agent 动态切换 Prompt

Manus 作为通用 Agent,支持场景自适应 Prompt 切换:检测到使用浏览器工具时,自动切换为浏览器专属动态 Prompt,执行完成后恢复默认模板。

核心源码(manus.py 140-165行):

async def think(self) -> bool: # 检测最近消息是否调用浏览器工具 browser_in_use = any( tc.function.name == BrowserUseTool().name for msg in recent_messages if msg.tool_calls for tc in msg.tool_calls ) # 浏览器场景动态替换Prompt if browser_in_use: self.next_step_prompt = ( await self.browser_context_helper.format_next_step_prompt() ) result = await super().think() # 执行后恢复默认Prompt self.next_step_prompt = original_prompt return result

六、完整 Prompt 组装时序案例

以Manus Agent 执行「搜索 Python 最新版本」任务为例,完整还原两轮推理的 Prompt 组装、消息入库、API 拼接全流程。

初始状态

Memory.messages = []

Step 1:第一轮推理

1、think() 注入下一步引导 Prompt,memory 新增伪用户消息:

Memory.messages = [ Message(role=user, content="Based on user needs, proactively select...") ]

2、ask_tool 完成最终消息拼接(系统消息前置):

# 前置系统消息 Message(role=system, content="You are OpenManus, an all-capable AI assistant...") # 后续对话历史 Message(role=user, content="Based on user needs..") # 附带全局工具列表 tools: [{name:"python_execute",...}, {name:"browser_use",...}, ...]

3、LLM 返回工具调用结果,memory 存入助手消息:

Message(role=assistant, content="我来搜索一下", tool_calls=[{name:"web_search", args:{query:"Python latest version"}}])

4、act() 执行工具,存入工具返回结果消息,第一轮结束:

Memory.messages = [ Message(role=user, content="Based on user needs..."), Message(role=assistant, content="我来搜索一下", tool_calls=[...]), Message(role=tool, content="Observed output of cmd `web_search`...", tool_call_id="call_1") ]

Step 2:第二轮推理

1、再次执行 think(),注入新的下一步 Prompt:

Memory.messages = [ # 上一轮历史消息 Message(role=user, content="Based on user needs..."), Message(role=assistant, content="我来搜索一下", tool_calls=[...]), Message(role=tool, content="Observed output..."), # 本轮新增引导消息 Message(role=user, content="Based on user needs...") ]

2、最终 API 消息结构:系统消息永久前置,完整拼接历史对话

七、全链路数据流总图

为方便整体理解,梳理从模板定义到 API 调用的全链路闭环流程:

①模板定义:app/prompt/ 下定义静态 SYSTEM、NEXT_STEP 模板,预留动态占位符

②Agent 初始化:实例化 Agent,填充固定占位符(如 workspace 目录),绑定 Prompt 模板

③每轮 think() 执行:动态替换场景占位符、注入下一步引导 Prompt、追加截图多模态消息

④LLM 格式化组装:系统消息前置、历史消息标准化、图片格式转换、Token 校验、挂载工具列表

⑤API 调用:组装完成的标准消息体、工具参数传入 OpenAI 接口,获取推理结果

八、核心设计决策与底层原理

这套 Prompt 架构的所有设计,均为解决 Agent 推理稳定性、场景适配性、可扩展性问题,核心设计决策汇总:

设计点

具体实现方式

核心设计原因

System Prompt 不入库 Memory

单独传递 system_msgs,调用时前置拼接

不受 max_messages 截断影响,永久保留 Agent 身份定位

Next Step Prompt 逐轮入库

每轮以伪 user 消息追加至对话历史

贴合 LLM 对话交互逻辑,精准引导迭代思考

原生 str.format() 占位符

自定义 {key} 占位符,代码动态填充

无需引入 Jinja2 等模板引擎,轻量化、低依赖、可读性强

截图独立多模态传递

base64 字段单独存储,格式化时转为标准图片格式

不污染文本对话历史,最大化利用多模态模型能力

工具列表动态生成

每次 think() 调用 to_params() 重新生成工具参数

适配 MCPAgent 动态增减工具的场景,保证工具列表实时准确

无复杂模板语法

纯字符串 + format 替换实现所有动态能力

降低项目复杂度,便于 Prompt 调试、修改、维护

九、Memory 最终消息形态(实战落地)

一次完整的 Manus 任务执行后,Memory 中真实存储的对话序列(无 System 消息,仅存交互历史):

索引

角色

内容说明

消息来源

0

user

帮我搜索 Python 最新版本

用户原始输入

1

user

Based on user needs, proactively...

第一轮 Next Step 注入

2

assistant

我来搜索 Python 最新版本 + 工具调用

第一轮 LLM 推理返回

3

tool

网页搜索结果数据

第一轮工具执行返回

4

user

Based on user needs, proactively...

第二轮 Next Step 注入

5

assistant

输出结果 + terminate 结束工具

第二轮 LLM 推理返回

6

tool

任务结束提示

第二轮工具执行返回

十、总结

这套三层 Prompt 组装架构,是 AI Agent 实现智能化、动态化、场景化推理的核心基石:

1、分层解耦:静态模板、动态注入、API 格式化三层分离,各司其职;

2、设计精巧:系统提示永久常驻、迭代提示逐轮更新,兼顾稳定性与灵活性;

3、场景适配:支持动态占位符、多模态图文、场景自适应 Prompt 切换;

4、轻量化可维护:无冗余模板依赖,逻辑清晰,便于迭代优化。

理解这套机制,就能彻底掌握 AI Agent 「如何思考、如何调用工具、如何迭代任务」的底层核心逻辑。

相关新闻

  • 单机直连网关可通PLC,但是加入局域网不通
  • 游戏模组开发全流程:从资源替换到脚本注入的技术实践
  • EUI-NEO跨平台框架:纯C++多平台编译开发实战指南

最新新闻

  • 如何用DeepBump实现AI驱动的纹理转换:从单张图片到专业3D材质的完整指南
  • 从P1265公路修建题解析Prim与Kruskal算法核心差异与选型策略
  • SeasonalInvite 电子贺卡钓鱼滥用 RMM 工具攻击机理与分层防御研究
  • React删除评论逻辑:1、客户端立即更新UI(乐观更新)2、后台调用删除评论API(乐观消息Optimistic Message)
  • Python爬取小红书笔记信息加图片(仅供学习参考)
  • 哔哩下载姬终极指南:如何快速免费下载B站8K高清视频

日新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号