banner
约 5,700 字
19 分钟

Context Engineering for AI Agents: Lessons from Building Manus 技术阅读

摘要

完整拆解 Manus 的六项上下文设计:稳定 KV 缓存、状态约束动作、可恢复文件记忆、任务清单复述、错误保留与轨迹多样性,并用一个报告任务解释执行过程和迁移边界。

长任务 Agent 的一次请求,常常携带大量历史内容,只生成很短的工具调用。随着浏览、文件处理和命令执行不断发生,系统必须同时控制输入成本、行动范围、记忆恢复和目标漂移。Manus 这篇文章给出了六项相互关联的设计:稳定缓存前缀、按状态约束动作、把文件系统作为外部记忆、反复更新任务清单、保留失败反馈,以及避免历史轨迹诱发机械模仿。

作者 Yichao “Peak” Ji 将这些方法定位为 Manus 在多轮框架重建中得到的工程经验。文章没有给出完整的受控消融实验,也没有公开整个生产系统。阅读时需要学清每项设计怎样改变 Agent 的输入和下一步决策,同时保留其测量与披露边界。

信息

内容

原文

Context Engineering for AI Agents: Lessons from Building Manus

作者与日期

Yichao “Peak” Ji,Manus,2025-07-18

材料类型

官方工程文章,采用技术阅读方式

阅读对象

英文全文,项目归档 PDF 共 10 页;本文页码指该归档版本

主要任务

多轮工具执行中的上下文组织、成本控制和错误恢复

先修概念

自回归生成、KV cache、工具调用、Agent 的动作—观察循环

证据范围

作者报告的运行特征与设计经验,配有六张机制示意图;没有各项改动的统一成功率对照表

原文入口

Manus 原文

先理解 Agent 每一轮究竟在处理什么

设用户要求 Agent 调研一个主题并生成报告。Agent 可以先搜索,读页面,把关键材料写入文件,再补查冲突信息,最后汇总。一轮的输入由系统指令、工具定义、用户目标和历史轨迹组成。模型输出动作,运行环境执行动作并返回观察,系统把这两个新记录加入下一轮输入。

可以把这个过程写成教学形式:

纯文本
上下文 C_t = 固定指令 + 工具定义 + 用户目标 + 历史动作与观察
动作 a_t = 模型基于 C_t 选择的下一步
观察 o_t = 环境执行 a_t 后返回的结果
上下文 C_(t+1) = C_t + a_t + o_t

这里的加号表示按顺序追加消息。观察可能是一段网页、PDF 的提取结果、命令错误或文件内容,长度远大于动作。模型下次做选择时还要访问这些内容,输入处理因此成为重要开销。作者报告 Manus 平均输入与输出 token 比约为 100:1,典型任务平均需要约 50 次工具调用。两项数据描述该团队当时的工作负载,不能直接代入任何 Agent 的成本预测。

这条循环也是六项设计的共同骨架。缓存关心历史输入能否复用;动作约束关心下一步允许执行什么;文件系统决定哪些材料继续留在短期上下文;任务清单把目标带回输入尾部;错误反馈与轨迹多样性影响模型怎样理解此前发生的事情。将它们割裂成六条提示词技巧,会丢失系统层面的相互约束。

一、围绕 KV 缓存组织请求

Prefill、decode 与前缀复用

自回归模型先处理输入,再逐 token 生成输出。处理输入的阶段通常称为 prefill,生成阶段称为 decode。Transformer 会为输入位置形成 key 和 value,后续注意力可以读取这些缓存。相邻 Agent 请求拥有大量相同历史,服务端若支持前缀复用,就能减少重复处理相同 token 的工作。

下图比较了上下文不断变化与稳定追加两种组织方式。观察图中的共享前缀,再看每轮新增内容从哪里开始。

原文缓存设计示意图
原文缓存设计示意图

来源:Manus 原文,Design Around the KV-Cache;归档 PDF 第 3 页。图为原文机制示意。

模型的某个位置依赖它前面的 token。前缀中间发生变化时,从变化位置开始,后续状态就不能直接按旧前缀复用。假设系统指令开头含有精确到秒的时间,每一轮时间都不同,理论上可共享的长历史也会被这个早期差异切断。原文据此要求保持前缀稳定,将需要变化的状态放在合适的追加位置。

缓存命中还依赖提供方的具体实现。相同输入不保证永远命中,缓存可能过期、按块组织、分布在不同 worker 上,或需要显式标记断点。文章提出,在需要手动断点的接口里,应考虑缓存有效期,并至少让断点覆盖系统指令结束位置。自部署时还要确认前缀缓存已启用,分布式请求路由能够访问对应缓存。具体开关与接口格式应查所用服务当前文档,不能把文章中的历史写法直接当成通用 API。

追加历史与确定性序列化

保持追加式上下文意味着旧动作与旧观察的表示尽量稳定。若同一个 JSON 每次重新序列化都改变键顺序、空白或模板,语义可能相同,token 序列却不同。缓存比较的是实际表示,语义等价不能替代字节和 token 前缀的一致性。

一个教学例子是工具观察包含 status、path 和 count。第一次写成 status,path,count,下次把全部历史重建成 path,count,status,就可能制造无意义的缓存失配。解决方向是在写入轨迹时确定规范,之后复用已保存的表示。作者强调确定性序列化,但没有规定统一 JSON 格式;排序键、保存原始消息或使用固定模板都是需要结合实现验证的选择。

追加式历史也存在容量限制。持续追加无法无限延伸到上下文窗口外,因此必须与后面的可恢复压缩配合。两个目标的顺序需要分清:正常轮次保持稳定;确实需要缩短上下文时,执行可审计的整理,并接受该次操作可能造成缓存重新建立。为追求缓存而让输入超过窗口,同样会使任务失败。

文章中的价格如何阅读

原文以当时 Claude Sonnet 的缓存输入与非缓存输入价格举例,分别为每百万 token 0.30 美元和 3 美元,用于说明相差一个数量级的可能性。这是 2025 年文章中的历史例子,本文不把它当作当前报价。更可靠的迁移方法是记录自己的缓存读写量、未缓存输入量、输出量和实际账单。

缓存命中率、首 token 延迟和任务总成本应同时观察。高命中率可以来自反复处理无价值历史,如果总输入过大、重试过多,整体任务仍可能昂贵。文章将缓存命中率视为 Manus 的重点指标,工程上还需要结合任务完成率和每个成功任务的成本判断收益。

二、保留工具定义,按状态约束动作

工具数量为什么会改变决策质量

Agent 接入越来越多工具后,模型面对的动作空间会变大。相近名称、不同参数和不适用的操作都可能干扰选择。直观做法是按需加载一小组工具,但文章指出,频繁增删定义会带来两个具体问题:定义通常位于上下文前部,改变定义容易破坏后续缓存;历史动作仍可能引用已移除工具,使当前定义与过去轨迹之间产生不一致。

原文提出的状态机保留工具定义,根据当前状态限制解码时可选的动作。状态包含当前交互阶段与上下文条件,约束决定哪些输出形式或工具名称允许出现。

原文动作约束示意图
原文动作约束示意图

来源:原文 Mask, Don't Remove;归档 PDF 第 5 页。图解释保持定义稳定并约束当前可选动作的思路。

这种约束发生在生成过程中。模型看到完整定义,生成时却只能进入允许的分支。它需要推理服务或格式机制提供支持,单纯写一句“请不要调用某工具”不能被视为相同强度的约束。

Auto、Required 与 Specified

作者用 Hermes 格式解释三种选择模式。Auto 允许模型调用工具,也允许普通回复;Required 预填充到工具调用开始位置,使模型进入工具调用格式;Specified 将预填充推进到函数名的特定前缀,进一步缩小候选集合。文章示例中的 browser_ 和 shell_ 前缀用于组织不同工具类别。

纯文本
Auto:允许普通回复或工具调用
Required:要求进入工具调用格式
Specified:把可选择的工具限制在指定名称或前缀范围内

这段是依据原文整理的模式说明,不是可跨模型运行的代码。特殊 token、预填充能力和约束解码接口都受模型与服务实现影响。迁移时应先确认具体服务能否控制工具选择、能否限制名称子集,以及限制是否覆盖了参数格式。

原文举出的状态之一是收到新的用户输入后先立即回复,再继续行动。其他状态可以限制到浏览器或命令行工具组。这体现了控制流在模型之外的作用:即使模型知道全部能力,当前运行状态仍决定可用动作。文章没有公开完整状态转移表,不能据此补造 Manus 的所有规则。

约束动作名称也不能保证调用正确。参数可能无效,环境可能变化,工具返回内容可能不可信。实际执行层仍需要检查输入和返回结果,并把失败作为后续观察。动作约束与错误恢复负责不同环节,后者决定一次合法但失败的调用怎样影响下一轮。

三、把文件系统当作可恢复的上下文

网页和文档可以远大于模型窗口。即使能装进去,长输入也可能提高成本,降低模型利用相关材料的效果。截断或摘要有助于减少输入,但压缩时很难预先判断哪条信息将在若干轮后变得关键。

Manus 的选择是把完整材料外部化,让上下文保留定位与恢复入口。网页内容可以从活动上下文中省去,只要保留原始 URL;文档内容可以移出上下文,只要沙箱中保留文件及路径。模型需要材料时再读取,文件系统同时承担持久记忆和工作空间。

原文文件系统记忆示意图
原文文件系统记忆示意图

来源:原文 Use the File System as Context;归档 PDF 第 7 页。图展示把长内容外部化并保留恢复入口的思路。

这项设计把“保存了什么”与“本轮给模型看什么”分开。完整材料可继续保存,本轮只读取完成当前动作所需的片段。外部容量增加后,读取、索引和定位本身会成为新问题。文章说明模型按需读写文件,但没有公开完整的文件索引、检索或压缩策略,不能将它解释成已经给出一种特定向量数据库算法。

所谓可恢复,依赖入口实际有效。仅保存 URL 时,页面可能发生变化或失效;仅保存路径时,文件可能被覆盖或沙箱被销毁。对你自己的项目,一个可验证的扩展是同时保存原始来源、下载时间、文件标识与内容快照,再检查恢复成功率。这是本文的工程建议,原文没有报告该扩展的实验结果。

文件记忆也不自动获得信任。材料中的操作指令仍然属于内容,不能直接升级为系统授权。把记忆写成文件可以提高恢复能力,但需要区分用户目标、执行状态、来源证据和外部文本,防止读取时把不相关命令混入行动规则。

作者还讨论了状态空间模型结合外部文件记忆的可能性。该部分属于设想:如果模型能把长期状态外部化,其计算效率可能更适合部分 Agent 任务。文章没有提供 Agentic SSM 的实现和评测,因此不能把这个方向写成已实现贡献。

四、通过更新任务清单维持目标

当任务经历几十次工具调用后,最初目标会远离上下文尾部。搜索结果、错误信息和局部细节不断出现,模型可能过度跟随最近观察,偏离整体目标。文章用更新 todo.md 的方式,让全局计划在后续输入中重新出现。

原文目标复述机制示意图
原文目标复述机制示意图

来源:原文 Manipulate Attention Through Recitation;归档 PDF 第 8 页。图说明更新任务清单如何重新呈现全局目标。

一次有效更新包含已完成项、待完成项和必要状态。计划进入近期上下文后,模型可以用它解释新观察:这条信息解决了哪个子问题,接下来还缺什么,是否已经到达交付条件。这里的效果发生在上下文条件下,模型权重没有因此更新。

任务清单的位置和内容都需要设计。只创建文件但从不读取,不能保证目标回到活动上下文;每轮复制完整清单又可能增加成本。原文强调不断更新与复述,没有披露最优频率或统一清单格式。实现时可比较关键阶段更新、每次大动作后更新等策略,测量目标遗漏与输入开销。

清单还需要与环境结果一致。假设子任务是把报告写到指定文件,模型说已完成但文件不存在,清单就应继续保留未完成状态。否则后续轮次会把未经验证的计划当成事实。这个要求是根据机制提出的实践约束,应由程序或工具结果支持,不能只依赖模型自报。

五、让失败成为后续决策的依据

失败观察包括命令报错、工具参数不合法、页面不存在或执行结果不符合目标。隐藏失败、只保留最终成功动作,会让后续决策缺少曾经尝试过什么、为什么不能继续的证据。

原文错误保留示意图
原文错误保留示意图

来源:原文 Keep the Wrong Stuff In;归档 PDF 第 9 页。图展示失败动作与观察进入后续上下文的作用。

保留失败时,动作与返回结果应一起保存。只有一句“失败了”不足以解释原因。例如读取某个文件得到不存在错误,后续模型需要知道完整路径、错误种类和当前状态,才能决定列目录、改路径或停止。保留结果使它能针对失败改变行为,而不是在相同条件下重复同一调用。

原文用内部信念变化描述模型在看到错误后如何调整后续行动。这属于上下文内的行为变化,不能称为一次梯度更新,也不能视为模型已经长期学会该错误。任务结束后,若希望知识跨会话持续有效,还需要另外设计记忆写入、检索或训练数据流程。

保存全部大段错误也有成本。对自己的系统,可以保留错误类别、关键栈信息、必要参数和原始日志路径,让活动上下文携带足以改变决策的证据,完整日志仍可恢复。需要验证裁剪是否删除了关键原因,避免在降低长度时重新制造信息丢失。原文没有给出统一裁剪算法,这里是可测试的实现方向。

错误恢复评价应检查后续行为。任务成功率之外,还可以统计相同失败的重复次数、无效重试花费,以及环境变化后是否更换策略。文章批评一些评价过度关注理想条件下的成功,但没有发布对应新基准。不能将这些建议包装成 Manus 已测得的恢复分数。

六、避免轨迹把 Agent 带入重复模式

模型会从上下文中的动作—观察模式中学习局部规律。当历史轨迹过于相似时,重复本身可能诱发不合时宜的行动。作者举了批量审阅 20 份简历的例子:Agent 容易沿着已有节奏继续重复,忽略当前材料与前面样本的差异。

原文轨迹多样性示意图
原文轨迹多样性示意图

来源:原文 Don't Get Few-Shotted;归档 PDF 第 10 页。图是机制示意,不能读取成成功率统计。

文章采用少量结构化变化,例如替换序列化模板、调整措辞或局部格式,让轨迹不那么容易形成固定模仿模式。变化必须保留任务语义。随意改字段名、打乱参数关系或扰动执行约束,会损害工具接口正确性。

这里与缓存稳定性有一处真实的张力。前文要求过去消息表示稳定,此处允许新轨迹存在结构化差异。两者可以通过区分时间位置来理解:已有前缀继续保持稳定;新产生的观察可采用受控变化,一旦写入历史就不再反复改写。这个解释依据两项机制整理,原文没有给出完整联合优化方案,也没有测量变化强度的最佳值。

不要把这项经验直接扩展为取消所有 few-shot。少量准确示例仍可能帮助模型理解接口;文章关心长轨迹形成的过度模仿。适用性需要在自己的任务上测量,尤其检查模板多样性是否影响结构解析和前缀复用。

用一个报告任务走完六项设计

下面是依据原文机制设计的教学案例,不是 Manus 的真实轨迹或本文实测。任务是比较三种模型的部署条件,生成一份有来源的报告。

Agent 开始时获得固定系统指令与完整工具定义,把用户要求写入任务清单。第一个模型请求读入这些稳定前缀,选择搜索操作。搜索返回多个页面,系统追加动作和观察;下一轮仍复用此前表示,只有新增后缀需要处理。

当 Agent 进入页面阅读阶段,状态机将可用动作限制到浏览工具或相关读取操作,完整工具定义保持稳定。它读到一个较长模型卡后,把内容写入来源文件,活动上下文保留来源 URL、文件路径与当前提取结论。后续需要核对许可证时,重新读取对应片段。

如果第二份材料的链接失效,系统把请求地址和失败结果记录到轨迹。下一轮模型据此改查发布页,并在任务清单中保留该来源尚未核验的状态。找到原始资料后再更新状态,失败记录继续为来源选择提供上下文。

完成一个模型的资料卡时,更新任务清单,让尚未完成的两个模型以及最终输出要求重新进入近期上下文。整理多份相似资料时使用有控制的描述变化,维持字段语义与对比口径,检查每个模型的具体条件,避免直接沿用前一份结论。

最后由文件读取或其他环境结果确认报告实际存在,核查主要结论是否有来源,再结束任务。六项设计共同作用于一条循环:固定的内容便于复用,需要变化的状态进入新观察,长材料可恢复,失败能改变下一步,完成条件由外部结果支持。

怎样迁移到自己的 Agent 与模型训练

先记录一组代表性任务的基线轨迹。建议保留成功结果、调用次数、输入输出 token、缓存命中、首 token 延迟、错误种类与最终产物位置。然后一次改变一个相关环节,保持底座模型和任务条件尽量一致。否则模型升级、任务变化与上下文改造可能混在一起,难以判断是哪项改动生效。

改动

需要检查的行为

建议测量的结果

固定前缀与历史表示

相邻请求是否拥有相同的长前缀

缓存命中、TTFT、每个成功任务的输入成本

按状态约束动作

是否减少阶段不适用或无效工具选择

非法调用率、错误重试、最终成功率

外部化长材料

保存与恢复入口是否实际有效

输入长度、恢复成功、证据遗漏

更新任务清单

目标与状态是否随真实结果同步

子任务遗漏、错误标记完成、额外输入开销

保留失败

是否减少相同条件下重复失败

重复错误次数、恢复耗时与 token

受控轨迹变化

是否保持语义和格式兼容

批量任务差异识别、解析正确性、缓存变化

对于微调,首先需要区分问题来源。工具调用失败可能来自模型不知道接口,也可能来自定义缺失、轨迹截断或运行状态错误。后几种情况需要先修上下文和执行流程。把不一致轨迹直接用于 SFT,可能使模型学习错误接口或错误完成条件。

若准备构建 Agent 训练数据,可以保留稳定的工具定义、真实动作与观察、纠错后的决策和可验证结果,让模型学习如何利用环境反馈。不同阶段约束与记忆读写也可进入样本设计。但这部分属于本文对训练工作的迁移建议,原文没有提出具体 SFT 数据配方、奖励函数或训练实验。

这篇文章最适合用来检查 Agent 的运行输入:哪些信息需要稳定,哪些状态需要更新,哪些内容需要能够恢复。对每项改动,都应同时观察任务质量与成本,保留能够解释失败的轨迹,再决定是否进一步改变模型权重。

来源与对照阅读

  1. Manus 英文原文,2025-07-18。六项机制分别对应 Design Around the KV-Cache、Mask, Don't Remove、Use the File System as Context、Manipulate Attention Through Recitation、Keep the Wrong Stuff In、Don't Get Few-Shotted。

  2. 项目归档 PDF 第 2—3 页:输入输出比例、工具调用循环与缓存条件;第 4—5 页:动作约束及预填充模式;第 6—7 页:可恢复文件记忆;第 7—10 页:任务清单、错误保留与轨迹多样性。

  3. 本文的报告任务、测量表与训练迁移部分是依据机制整理的教学案例和建议,未进行作者系统复现,不构成生产效果验证。

END