解密prompt系列56.Agent context Engineering - 单智能体代码剖析
近期关于智能体设计有诸多观点,一个关键点让我豁然开朗——无论智能体是1个还是多个,是编排驱动还是自主决策,是静态预定义还是动态生成,Context上下文的管理机制始终是设计的核心命脉。它决定了:每个节点使用哪些信息?分别更新或修改哪些信息?多步骤间如何传递?智能体间是否共享、如何共享?后续篇章我们将剖析多个热门开源项目,一探它们如何驾驭Context。本章聚焦单智能体设计,选取两个代表性框架:模仿OpenAI深度研究范式的Gemini-fullstack(编排式)与模仿Manus的OpenManus(自主式)。
框架对比
先来整体对比下两个框架,这样懒得看细节的盆友们就可以只看下表了~
特性 | Gemini Deep Search (编排式) | OpenManus Flow Mode (规划式自主) | OpenManus Manus Mode (纯自主) |
---|---|---|---|
智能体类型 | 单智能体,编排驱动 | 单智能体,全局规划 + 分步ReAct循环 | 单智能体,ReAct循环 |
任务分解 | 固定流程节点 | 全局Plan | 动态思考下一步(Think) |
Context 范围 | 节点级隔离 (每节点用特定输入) | Step级隔离 (每Step用Plan状态+当前任务) | 线性增长+窗口截断 (全历史) |
Context 传递 | 传递任务结果 (Query列表, 摘要文本) | 外层:传递Plan状态 + Step结果字符串;内层全部历史 | 传递完整ReAct历史 (截断后) |
状态管理 | 无显式状态,依赖数据流 | 显式Plan & Step状态管理 | 隐含在消息历史中 |
优势 | 流程清晰可控,模块化,引用处理优雅 | 步骤Context轻量,潜在减少迭代次数 | 灵活性高 |
挑战 | 灵活性较低,节点间“思考”不共享 | Plan质量依赖(或需要动态调整),Step间Context隔离可能导致信息断层/冲突 | Context膨胀,长程依赖易丢失,多轮消息会引入噪音 |
Gemini Deep Search- 编排智能体
Gemini Deep Search 是一个典型的编排式智能体。其执行流程预先定义,核心在于引入了反思节点,用于动态判断信息收集是否充分。流程清晰简洁:
图释:Gemini Deep Search的核心编排流程,包含查询生成、并行搜索、反思评估、路由决策和最终答案生成五个关键节点,通过反思节点实现循环控制。
1. 查询生成(Generate Query)
- 核心亮点:将“思考过程”工具化/结构化输出。
- 使用Pydantic模型强制输出包含查询列表(query)和推理依据(rationale)
class SearchQueryList(BaseModel):
query: List[str] = Field(
description="A list of search queries to be used for web research."
)
rationale: str = Field(
description="A brief explanation of why these queries are relevant to the research topic."
)
实际应用中会发现把 思考工具化(结构化) 有很多优点:
- 模型无关性: 不依赖模型的“思考”原生能力,任何支持结构化输出的模型皆可。
- 简洁可控: 结构化输出比模型自由生成的思考通常更简短、更聚焦,避免冗余和发散。。
2. 并行搜索+摘要(Web_research)
然后就是基于多个query的并行搜索模块这里直接使用了Langgraph自带的Send多线程并发模式,然后直接让大模型基于检索上文进行总结。这里可参考不多,因为引用生成等逻辑在Gemini的API中,用开源模型的盆友需要重新适配。
不过有意思的是现在如何给模型推理插入引用,原来多数都是在指令中加入要求,让模型一边推理一边生成引用序号[i]([citation:i])
,不过在新的模型能力下有了很多天马星空的方案。像Claude给出过先直接进行无引用推理,然后再让模型重新基于推理结果,在不修改原文的基础上,插入引用的markdown链接。
这里Google是直接推理API中集成了类似能力,哈哈我也没用过Gemini的API,不过看代码,应该是类似以下的结构, 会通过结构化推理(哈哈Google很爱用结构化推理,其实个人也觉得不论是工具还是Function Calling或者是Thinking,最底层的对接方案还是结构化推理),返回引用序号列表对应的文字段落的起止位置。
# Gemini API响应结构
response.candidates[0].grounding_metadata = {
"grounding_supports": [
{
"segment": {"start_index": 0, "end_index": 50},
"grounding_chunk_indices": [0, 1, 2]
}
],
"grounding_chunks": [
{
"web": {
"uri": "https://example.com/page1",
"title": "Example Page 1"
}
}
]
}
考虑到这里涉及两次模型推理,第一次就是每个query的搜索总结,第二次是最终基于所有总结段落的二次汇总推理。因此这里项目在本次推理(第一次)中把citation以markdown超链接的格式插回到了原文中,这样二次推理可以直接生成引用链接。(URL进行了缩写,降低推理token和copy出错的可能性)
3. 反思评估(Reflection)
- 评估当前收集的摘要信息是否足以回答用户问题。
- 同样采用结构化输出,个人实践的优化点: 可扩展Reflection模型,加入reasoning字段,让模型先分析“回答用户需要什么信息?”、“当前已有哪些信息?”,再做出判断和提出补充查询,使决策更透明、依据更充分。
class Reflection(BaseModel):
is_sufficient: bool = Field(
description="Whether the provided summaries are sufficient to answer the user's question."
)
knowledge_gap: str = Field(
description="A description of what information is missing or needs clarification."
)
follow_up_queries: List[str] = Field(
description="A list of follow-up queries to address the knowledge gap."
)
4. 决策路由(Router)
- 根据Reflection节点的输出 (is_sufficient) 和预设的最大循环次数,决定流程走向(继续搜索Generate Query或进入Finalize Answer)。
- Context管理:此节点本身不修改Context,仅基于Reflection的Context进行流程控制。
5. 生成最终答案(Finalize Answer)
- 汇总所有步骤收集到的摘要信息(已包含Markdown引用链接)
- 进行最终推理,生成回答,并保留摘要中已嵌入的引用信息。
Context管理
Gemini的Context管理
- 模块化隔离: 每个节点聚焦特定任务,使用特定的Context输入(如Generate Query只用原始Query,Web Research用特定Query列表,Reflection用所有摘要)。
- 无状态传递: 节点间不共享“推理状态”上下文(如之前的思考过程),主要传递任务结果(Query列表、摘要文本)。
OpenManus - 自主智能体
OpenManus 提供了两种模式:Manus Mode(基础ReAct)和Flow Mode(规划驱动)。虽然项目将Flow称为“多智能体”,但从Context管理角度看,更像是单智能体的两种任务分解策略:Manus是局部规划+即时执行,Flow是全局规划(Plan)+分步执行(Manus)。
Manus 模式:经典ReAct循环
Manus模式本质是ReAct循环:思考(Think)->行动(Act)->观察(Observe),循环执行直至任务完成。核心流程:
- Think: 基于当前Context(用户问题+历史消息+可用工具描述),模型决定下一步动作(调用哪个工具及其参数)。
- Act: 执行所选工具(如browser-use进行复杂网页交互操作、文本编辑器)。
- Observe: 将工具执行结果作为ToolMessage加入Context。
- 循环上述步骤,直到Think选择终止工具。
Manus的Context管理
线性增长: 整个任务由一个智能体完成,Context随执行步骤线性增长,每一步都使用前置的所有message信息。
Flow 模式
Flow的核心思想是引入全局Plan规划器。在当前模型能力下,先规划再执行有助于:
- 简化步骤Context: 每个Manus步骤只需关注当前Step和Plan状态,上下文更轻量。
- 减少迭代次数: 全局视野可能降低智能体陷入局部循环的概率。
- 潜在挑战: 步骤间Context隔离可能导致信息重复/冲突;全局规划器传递任务时可能丢失细节(Context Gap)。
Plan工具设计 (核心): Plan本身通过结构化工具实现管理:
- 两层结构: Plan -> Steps。
- 操作完备: 创建(Create)、更新(Update)、列表(List)、获取(Get)、激活(Set Active)、标记步骤状态(Mark Step)、删除(Delete)
- 状态跟踪: Step状态包括未开始(not_started)、进行中(in_progress)、完成(completed)、阻塞(blocked)。
- 核心参数示例如下
class PlanningTool(BaseTool):
"""
A planning tool that allows the agent to create and manage plans for solving complex tasks.
The tool provides functionality for creating plans, updating plan steps, and tracking progress.
"""
name: str = "planning"
description: str = _PLANNING_TOOL_DESCRIPTION
parameters: dict = {
"type": "object",
"properties": {
"command": {
"description": "The command to execute. Available commands: create, update, list, get, set_active, mark_step, delete.",
"enum": [
"create",
"update",
"list",
"get",
"set_active",
"mark_step",
"delete",
],
"type": "string",
},
"plan_id": {
"description": "Unique identifier for the plan. Required for create, update, set_active, and delete commands. Optional for get and mark_step (uses active plan if not specified).",
"type": "string",
},
"title": {
"description": "Title for the plan. Required for create command, optional for update command.",
"type": "string",
},
"steps": {
"description": "List of plan steps. Required for create command, optional for update command.",
"type": "array",
"items": {"type": "string"},
},
"step_index": {
"description": "Index of the step to update (0-based). Required for mark_step command.",
"type": "integer",
},
"step_status": {
"description": "Status to set for a step. Used with mark_step command.",
"enum": ["not_started", "in_progress", "completed", "blocked"],
"type": "string",
},
"step_notes": {
"description": "Additional notes for a step. Optional for mark_step command.",
"type": "string",
},
},
"required": ["command"],
"additionalProperties": False,
}
下面我们来看下Plan创建、遍历、更新的整个流程
- 创建初始Plan (create_initial_plan):
- 基于用户Query生成Plan (Steps)。
- Prompt设计的几个亮点关键词: 简洁有力,强调关键里程碑(Key Milestones)、可行动性(Actionable)、清晰度(Clarity)、效率(Efficiency)。
system_message = Message.system_message(
"You are a planning assistant. Create a concise, actionable plan with clear steps. "
"Focus on key milestones rather than detailed sub-steps. "
"Optimize for clarity and efficiency."
)
# Create a user message with the request
user_message = Message.user_message(
f"Create a reasonable plan with clear steps to accomplish the task: {request}"
)
- 效果评估: 生成的Plan结构(Plan-Step两层)清晰,但内容质量(步骤逻辑、并行性)较基础,有优化空间。
- 执行Plan (execute):
- 按顺序遍历Plan中的每个Step。
- 将当前Step标记为in_progress。
- 调用execute_step执行当前Step。
- 执行单个Step (execute_step):
- 为当前Step实例化一个Manus智能体。
- 关键Context注入:这里同时提供全部plan status能解决(一部分)有些步骤模型会发散把多个步骤一起做了导致重复或者冲突的问题。
- 当前任务: "You are now working on step {index}: '{step_text}'"
- 全局状态: "CURRENT PLAN STATUS: {plan_status}" (包含所有Steps的状态)
step_prompt = f"""
CURRENT PLAN STATUS:
{plan_status}
YOUR CURRENT TASK:
You are now working on step {self.current_step_index}: "{step_text}"
Please execute this step using the appropriate tools. When you're done, provide a summary of what you accomplished.
"""
- 所有Plan执行完成进入汇总阶段:会基于原始生成的所有Plan的执行状态,让模型给出一份汇总
Flow的Context管理
- 分层Context: 全局Plan状态 vs. 单个Step执行Context。
- 智能体隔离: 每个Step由独立的Manus智能体执行,其Context主要包含:Plan全局状态 + 当前Step描述 + 当前Step执行历史 (ReAct循环)。
- 状态共享: Plan Status(所有Step状态)作为只读Context传递给每个执行Step的Manus智能体,有助于缓解步骤间冲突。
- 信息传递: Step间不直接共享详细推理/操作Context,仅通过Plan Status的宏观状态(完成/阻塞)和最终结果字符串进行间接传递。
Reference
- how we build our multi-agent system: Claude给出的多智能体构建智能
- Don't build multi-agents:Devin创始人指出的多智能构建中的一些坑
解密prompt系列56.Agent context Engineering - 单智能体代码剖析的更多相关文章
- 解密Prompt系列6. lora指令微调扣细节-请冷静,1个小时真不够~
上一章介绍了如何基于APE+SELF自动化构建指令微调样本.这一章咱就把微调跑起来,主要介绍以Lora为首的低参数微调原理,环境配置,微调代码,以及大模型训练中显存和耗时优化的相关技术细节 标题这样写 ...
- 解密Prompt系列2. 冻结Prompt微调LM: T5 & PET & LM-BFF
这一章我们介绍固定prompt微调LM的相关模型,他们的特点都是针对不同的下游任务设计不同的prompt模板,在微调过程中固定模板对预训练模型进行微调.以下按时间顺序介绍,支持任意NLP任务的T5,针 ...
- 解密prompt系列5. APE+SELF=自动化指令集构建代码实现
上一章我们介绍了不同的指令微调方案, 这一章我们介绍如何降低指令数据集的人工标注成本!这样每个人都可以构建自己的专属指令集, 哈哈当然我也在造数据集进行时~ 介绍两种方案SELF Instruct和A ...
- 解密Prompt系列3. 冻结LM微调Prompt: Prefix-Tuning & Prompt-Tuning & P-Tuning
这一章我们介绍在下游任务微调中固定LM参数,只微调Prompt的相关模型.这类模型的优势很直观就是微调的参数量小,能大幅降低LLM的微调参数量,是轻量级的微调替代品.和前两章微调LM和全部冻结的pro ...
- 解密Prompt系列4. 升级Instruction Tuning:Flan/T0/InstructGPT/TKInstruct
这一章我们聊聊指令微调,指令微调和前3章介绍的prompt有什么关系呢?哈哈只要你细品,你就会发现大家对prompt和instruction的定义存在些出入,部分认为instruction是promp ...
- 9.Java 加解密技术系列之 RSA
Java 加解密技术系列之 RSA 序 概念 工作流程 RSA 代码实现 加解密结果 结束语 序 距 离上一次写博客感觉已经很长时间了,先吐槽一下,这个月以来,公司一直在加班,又是发版.上线,又是新项 ...
- 7.java 加解密技术系列之 AES
java 加解密技术系列之 AES 序 概念 原理 应用 代码实现 结束语 序 这篇文章继续介绍对称加密算法,至于今天的主角,不用说,也是个厉害的角色 — — AES.AES 的出现,就是为了来替代原 ...
- 6. Java 加解密技术系列之 3DES
Java 加解密技术系列之 3DES 序 背景 概念 原理 代码实现 结束语 序 上一篇文章讲的是对称加密算法 — — DES,这篇文章打算在 DES 的基础上,继续多讲一点,也就是 3 重 DES ...
- 5.Java 加解密技术系列之 DES
Java 加解密技术系列之 DES 序 背景 概念 基本原理 主要流程 分组模式 代码实现 结束语 序 前 几篇文章讲的都是单向加密算法,其中涉及到了 BASE64.MD5.SHA.HMAC 等几个比 ...
- 2.Java 加解密技术系列之 MD5
Java 加解密技术系列之 MD5 序 背景 正文 结束语 序 上一篇文章中,介绍了最基础的编码方式 — — BASE64,也简单的提了一下编码的原理.这篇文章继续加解密的系列,当然也是介绍比较基础的 ...
随机推荐
- 解密prompt系列52. 闲聊大模型还有什么值得探索的领域
在DeepSeek-R1的开源狂欢之后,感觉不少朋友都陷入了技术舒适区,但其实当前的大模型技术只是跨进了应用阶段,可以探索的领域还有不少,所以这一章咱不聊论文了,偶尔不脚踏实地,单纯仰望天空,聊聊还有 ...
- Python读取CSV文件并存储到MySQL
在项目中对后台进行测试时,经常会遇到要在数据库新增数据,那么如何快速新增数据来提高工作效率呢? 现整理如下: 代码内容(csv_to_mysql.py): # coding=utf-8import p ...
- 树状数组(Fenwick Tree)原理和优化全面解析
你正在开发一个交易系统,需要实时完成两种操作: 更新某个时间点的价格(单点修改) 快速计算某段时间段内的交易总量(区间查询) 当数据量较小时,我们可能会这样实现: vector<int> ...
- Model Context Protocol(MCP)在claude使用
定义 MCP通过统一的协议,使AI模型(如Claude.GPT等)能够动态调用外部工具(如数据库.API.本地文件等),并实现跨模型的上下文共享与协作 架构 客户端-服务器模型: MCP主机(Host ...
- 华为od机考2025A卷真题 -查找接口成功率最优时间段
题目描述与示例 题目描述 服务之间交换的接口成功率作为服务调用关键质量特性,某个时间段内的接口失败率使用一个数组表示,数组中每个元素都是单位时间内失败率数值,数组中的数值为 0~100 的整数,给定一 ...
- 暂时永久免费高配云服务可跑32b模型
谷歌IDX免费云主机,16核CPU,64G内存,300G硬盘! 需要谷歌账号一个,且能google,无需绑卡. 到手第一时间安装一个ollama+qwen2.5-coder:32b, 无限cursor ...
- 前端速成之路——html、css
项目一知识点 单表视图列表 标题标签 <h1>用户注册</h1> 分割线与换行 <hr> <br> 表单提交 get:通过浏览器地址栏传递值 post: ...
- <HarmonyOS第一课05>从简单的页面开始
ArkUI是HarmonyOS应用的UI开发框架,它提供了一套完整的基础设施,包括简洁的UI语法.丰富的UI功能(组件.布局.动画以及交互事件),以及实时界面预览工具等.ArkUI支持开发者进行可视化 ...
- 【HUST】网安|编译原理实验|实验四攻略
[实验代码及报告地址:Gitee传送门](已关闭传送大门,原因是抄袭过多,如需参考,请直接看博客,虽然下一届内容会变了) 不擅长写报告昂,很多地方能省全省了. 助力来年编译原理加大难度!(hhh) M ...
- 【工程应用十】 基于Hessian矩阵的Frangi滤波算法 == 血管图像增强 == Matlab中fibermetric函数的自我实现、加速和优化。
前几天在翻一翻matlab中的帮助文档,无意中发现一个叫fibermetric的图像处理函数,感觉有点意思,可以增强或者说突出一些类似于管状的对象,后面看了下算法的帮助文档,在百度上找了找,原来这也是 ...