Skip to content
Wen's Blog

AI代理的上下文工程:构建Manus的经验教训

Mar 2, 2026 — AI, Agents, Thoughts

这篇 Manus 文章最值得记下来的,不是某一条 prompt 技巧,而是一个更基础的判断:在前沿模型迭代足够快的阶段,很多 Agent 团队的优势,已经不再来自自训模型,而来自你怎样组织上下文。

Manus 押注上下文工程,本质上是在换取三件事:更短的反馈周期、更低的模型锁定,以及更强的系统可替换性。下面这些经验并不都适合照搬,但它们确实构成了一套比较完整的工程取舍。

为什么押注上下文工程

在构建 Manus 的早期,团队面临一个关键决策:是训练端到端的智能体模型,还是基于前沿模型的上下文学习能力来构建代理?

作者回顾了自己在 BERT 时代的经验:那时模型迁移必须依赖微调,每次迭代往往要花数周。对 PMF 尚未稳定的产品来说,这种反馈速度太慢。到了 GPT-3 和 Flan-T5 时代,底模的进步让很多内部模型迅速失去优势,反过来也证明了一件事:如果底层能力迭代很快,产品更应该押注上下文与系统设计,而不是把自己锁死在一套模型方案上。

Manus 选择押注上下文工程,换来的是几小时级别的改进周期,以及与底层模型保持相对正交的产品形态。作者用的比喻很直白:如果模型进步是上涨的潮水,他们希望 Manus 是那条船,而不是固定在海床上的柱子。

上下文工程并不优雅。Manus 重建过四次代理框架,靠的也不是什么完美理论,而是持续试错、调整提示、重排结构。作者把这个过程叫做“随机研究生下降”。名字有点戏谑,但很符合真实工程现场。

先围绕 KV 缓存设计

**KV-cache命中率是生产阶段AI代理最重要的单一指标。**它直接影响延迟和成本。

代理的工作方式是

,通过一系列工具使用链完成任务。每次迭代中,模型根据当前上下文选择动作,执行后产生观察结果,动作和观察结果被附加到上下文中形成下一次迭代的输入。随着每一步推进,上下文不断增长,而输出(通常是结构化函数调用)保持相对简短。在Manus中,平均输入与输出的token比例约为100

具有相同前缀的上下文可以利用KV缓存,这大大减少了首个token的生成时间(TTFT)和推理成本。以Claude Sonnet为例,缓存的输入token成本为0.30美元/百万token,而未缓存的成本为3美元/百万token——相差10倍。

提高KV缓存命中率的实践

  1. 保持提示前缀稳定——LLM的自回归特性意味着即使单个标记的差异也会使该标记之后的缓存失效。常见错误是在系统提示开头包含精确到秒的时间戳。

  2. 使上下文只追加——避免修改之前的操作或观察,确保序列化是确定性的。许多编程语言在序列化JSON对象时不保证键顺序稳定,这可能悄无声息地破坏缓存。

  3. 明确标记缓存断点——某些模型提供商不支持自动增量前缀缓存,需要手动插入缓存断点。分配断点时要考虑潜在的缓存过期问题。

此外,使用vLLM等框架自托管模型时,确保启用前缀缓存,并使用会话ID等技术一致地路由请求。

不要频繁改工具集合

随着代理能力增强,行动空间自然变得更复杂,工具数量爆炸式增长。如果允许用户自定义工具,总会有人将数百个神秘工具插入到精心策划的行动空间中。结果,模型更可能选择错误的行动或采取低效的路径——武装过度的代理变得更加愚蠢。

自然的反应是设计动态行动空间,类似RAG方法按需加载工具。但实验表明了一条明确规则:除非绝对必要,避免在迭代过程中动态添加或移除工具

原因有两个:

  1. 工具定义在序列化后位于上下文前部,任何更改都会使后续所有动作和观察的KV缓存失效
  2. 当先前的动作和观察仍然引用当前上下文中不再定义的工具时,模型会感到困惑,导致模式违规或幻觉动作

Manus使用上下文感知的状态机来管理工具可用性。它不是移除工具,而是在解码过程中掩蔽token的logits,基于当前上下文阻止或强制选择某些动作。

大多数模型提供商支持响应预填充,允许在不修改工具定义的情况下约束动作空间。函数调用通常有三种模式:

通过这种方式,直接掩码token的logits来约束动作选择。例如,当用户提供新输入时,Manus必须立即回复而不是执行动作。团队还有意设计了具有一致前缀的动作名称——所有与浏览器相关的工具都以browser_开头,命令行工具以shell_开头。这使得代理在给定状态下只从特定工具组中选择,而无需使用有状态的logits处理器。

把文件系统当外部记忆

现代前沿LLM提供128K令牌或更多的上下文窗口,但在真实世界的代理场景中,这往往不够,甚至可能是一种负担。三个常见痛点:

  1. 观察结果可能非常庞大,尤其是与网页或PDF等非结构化数据交互时
  2. 模型性能在超过一定上下文长度后会下降
  3. 长输入成本高昂,即使使用前缀缓存

许多代理系统实现了上下文截断或压缩策略,但过度激进的压缩不可避免地导致信息丢失。这个问题是根本性的

,而无法可靠预测哪个观察结果可能在十步之后变得至关重要。从逻辑角度看,任何不可逆的压缩都带有风险。

这就是为什么Manus将文件系统视为终极上下文

,天然持久化,代理可以直接操作。模型学会按需写入和读取文件——不仅将文件系统用作存储,还用作结构化的外部记忆。

Manus的压缩策略始终设计为可恢复的。例如,网页内容可以从上下文中移除,只要保留URL;如果沙盒中仍然保留文档路径,则可以省略文档内容。这使得Manus能够缩短上下文长度,而不会永久丢失信息。

用复述拉回注意力

如果你使用过Manus,可能注意到一个有趣现象

,它倾向于创建一个todo.md文件,并在任务进行过程中逐步更新,勾选已完成项目。

这不仅仅是可爱的行为——这是操控注意力的刻意机制

Manus中的典型任务平均需要约50次工具调用,这是一个很长的循环。由于Manus依赖LLM进行决策,它很容易偏离主题或忘记早期目标,尤其是在长上下文或复杂任务中。

通过不断重写待办事项列表,Manus将其目标复述到上下文的末尾。这将全局计划推入模型的近期注意力范围内,避免了”丢失在中间”的问题,并减少了目标不一致。实际上,它使用自然语言来使自己的注意力偏向任务目标,而不需要特殊的架构变更。

把失败留在上下文里

代理会犯错。这不是bug——这是现实。语言模型会产生幻觉,环境会返回错误,外部工具会出现异常行为,意外的边缘情况随时都会出现。在多步骤任务中,失败不是例外,它是循环的一部分。

一个常见的冲动是隐藏这些错误

,重试操作,或重置模型的状态并将其留给神奇的”温度”。这感觉更安全,更受控制,但代价是擦除失败会移除证据。没有证据,模型就无法适应。

改善代理行为最有效的方法之一出奇地简单:将错误的尝试保留在上下文中。当模型看到一个失败的行动,以及由此产生的观察结果或堆栈跟踪,它会隐式地更新其内部信念,改变其先验,降低重复相同错误的可能性。

作者认为错误恢复是真正代理行为的最明显指标之一,但大多数学术工作和公共基准测试仍然关注理想条件下的任务成功,这一点代表性不足。

别让重复示例绑架决策

少样本提示是提高LLM输出的常用技术,但在代理系统中,它可能以微妙的方式适得其反。

语言模型是优秀的模仿者,它们模仿上下文中的行为模式。如果你的上下文充满了类似的过去行动-观察对,模型将倾向于遵循该模式,即使这不再是最优的。

这在涉及重复决策或行动的任务中可能很危险。例如,当使用Manus帮助审查20份简历时,代理通常会陷入一种节奏——仅仅因为这是它在上下文中看到的,就重复类似的行动。这导致偏离、过度泛化,或有时产生幻觉。

解决方法是增加多样性。Manus在行动和观察中引入少量的结构化变化——不同的序列化模板、替代性措辞、顺序或格式上的微小噪音。这种受控的随机性有助于打破模式并调整模型的注意力。

不要让自己陷入少样本学习的窠臼。你的上下文越单一,你的智能体就变得越脆弱。

我的取舍

上下文工程还远没有定型,但对 Agent 系统来说,它已经是绕不过去的主战场。模型会继续变强、变快、变便宜,可这些进步并不会自动替你解决记忆、环境和反馈的问题。

我读完后留下的判断是:如果你的代理系统已经进入多步任务、长链路执行和高成本验证阶段,最值得投入的往往不是“再换一个更强模型”,而是把上下文设计做得更像工程系统。缓存、工具集合、外部记忆、注意力回拉和错误保留,这些看起来零散,其实都在回答同一个问题:怎样让模型在长任务里少走弯路。