以下是季逸超刊载于manus官方博客的文章,对于上下文工程以及对manus实现思想感兴趣的读者阅读。
2025年7月18日 – Yichao ‘Peak’ Ji
在 Manus[1] 项目伊始,我和我的团队面临一个关键抉择:是应该使用开源基础模型来训练一个端到端的智能代理(agentic model),还是基于前沿模型(frontier models)的“上下文学习” (in-context learning) 能力来构建智能代理?
在我投身自然语言处理(NLP)的最初十年里,我们并没有这样的选择。在遥远的 BERT[2] 时代(是的,已经过去七年了),模型必须经过微调和评估,才能迁移到新的任务。即便当时的模型与如今的大语言模型(LLM)相比小得多,这个过程每次迭代通常也要花费数周时间。对于快速迭代的应用,尤其是在产品市场契合度(pre-PMF)达成之前,如此缓慢的反馈循环是致命的。这是我从上一次创业中得到的惨痛教训,当时我为“开放信息抽取” (open information extraction) 和语义搜索从零开始训练模型。后来,GPT-3[3] 和 Flan-T5[4] 横空出世,我自研的模型一夜之间变得无足轻重。讽刺的是,正是这些模型开启了“上下文学习”的时代,也开辟了一条全新的道路。
这个来之不易的教训让我们的选择变得清晰:Manus 将赌注押在“上下文工程” (context engineering) 上。 这使我们能将产品改进的周期从数周缩短到几小时,并让我们的产品与底层模型保持正交关系:如果模型技术的进步是上涨的潮汐,我们希望 Manus 是水面上的船,而不是被固定在海床上的柱子。
然而,“上下文工程”的实践远非一帆风顺。这是一门实验科学——我们已经重构了四次智能代理框架,每一次都是在发现了塑造上下文的更优方法之后。我们将这种手动进行架构搜索、调试提示(prompt)和基于经验猜测的过程戏称为“随机研究生下降”(Stochastic Graduate Descent)。这个说法虽不优雅,但确实有效。
本文将分享我们通过自己的“SGD”过程所达到的局部最优解。如果你正在构建自己的 AI 智能代理,我希望这些原则能帮助你更快地收敛。
围绕 KV 缓存进行设计
如果非要我只选一个指标,我认为 KV 缓存命中率是生产阶段 AI 智能代理最重要的单一指标。 它直接影响延迟和成本。要理解其中缘由,我们先来看看典型的智能代理[5]是如何运作的:
收到用户输入后,智能代理通过一系列工具调用来完成任务。在每次迭代中,模型根据当前上下文从预定义的动作空间中选择一个动作。该动作随后在环境(例如 Manus 的虚拟机沙箱)中执行,并产生一个观察结果。这个动作和观察结果被追加到上下文中,构成下一次迭代的输入。此循环不断重复,直至任务完成。
可以想见,上下文随着每一步迭代而增长,而输出——通常是结构化的函数调用——则相对较短。这使得智能代理中预填充(prefilling)与解码(decoding)的比例与聊天机器人相比严重失衡。例如,在 Manus 中,平均输入与输出的令牌(token)比例约为 100:1。
幸运的是,具有相同前缀的上下文可以利用 KV 缓存[6]技术。无论你是使用自托管模型还是调用推理 API,KV 缓存都能极大地减少首个令牌生成时间(Time-To-First-Token, TTFT)并降低推理成本。 这节省的成本可不小:以 Claude Sonnet 为例,缓存的输入令牌成本为 0.30 美元/百万令牌,而未缓存的成本为 3 美元/百万令牌——相差整整 10 倍。

从上下文工程的角度来看,提高 KV 缓存命中率涉及几个关键实践:
-
保持提示前缀的稳定性。由于大语言模型的自回归[7]特性,哪怕只有一个令牌的差异,也会导致从该令牌开始的后续缓存全部失效。 一个常见的错误是在系统提示的开头包含时间戳——尤其是精确到秒的时间戳。当然,这能让模型告诉你当前时间,但它也扼杀了你的缓存命中率。
-
让上下文只增不减。避免修改之前的动作或观察结果。确保序列化过程是确定性的。许多编程语言和库在序列化 JSON 对象时并不保证键的顺序稳定,这会悄无声息地破坏缓存。
-
在需要时明确标记缓存断点。一些模型提供商或推理框架不支持自动增量前缀缓存,而是需要手动在上下文中插入缓存断点。在设置这些断点时,要考虑到缓存可能过期的情况,并至少确保断点包含系统提示的末尾。
此外,如果你使用像 vLLM[8] 这样的框架自托管模型,请确保前缀/提示缓存[9]功能已启用,并使用会话 ID 等技术将请求在分布式工作节点间进行一致的路由。
使用掩码,而非移除
随着智能代理的能力越来越多,其动作空间自然会变得更加复杂——简而言之,工具的数量会爆炸式增长。最近流行的 MCP[10] (模型上下文协议)更是火上浇油。如果你允许用户配置工具,相信我:总会有人将数百个稀奇古怪的工具塞进你精心策划的动作空间。结果是,模型更有可能选择错误的动作或采取低效的路径。简言之,你全副武装的智能代理反而变笨了。
一个自然的反应是设计一个动态的动作空间——也许可以像使用检索增强生成(RAG)[11]那样按需加载工具。 我们在 Manus 中也尝试过。但我们的实验揭示了一个明确的规则:除非绝对必要,否则避免在迭代中途动态添加或移除工具。这主要有两个原因:
-
在大多数大语言模型中,工具定义经过序列化后位于上下文的前部,通常在系统提示之前或之后。因此,任何改动都会使后续所有动作和观察结果的 KV 缓存失效。
-
当之前的动作和观察结果仍然引用当前上下文中已不再定义的工具时,模型会感到困惑。如果不使用约束解码[12],这通常会导致模式(schema)违规或幻觉出不存在的动作。
为了在提升动作选择能力的同时解决这个问题,Manus 使用了一个能够感知上下文的状态机[13]来管理工具的可用性。它不是移除工具,而是在解码时通过掩盖令牌的对数几率(logits)来阻止(或强制)根据当前上下文选择某些动作。

在实践中,大多数模型提供商和推理框架都支持某种形式的响应预填充,这允许你在不修改工具定义的情况下约束动作空间。函数调用通常有三种模式(我们以 NousResearch 的 Hermes 格式[14]为例):
-
自动 (Auto) – 模型可以选择调用函数,也可以不调用。通过仅预填充回复前缀来实现: <|im_start|>assistant
-
必需 (Required) – 模型必须调用一个函数,但具体调用哪个不受限制。通过预填充到工具调用令牌来实现: <|im_start|>assistant<tool_call>
-
指定 (Specified) – 模型必须从一个特定的子集中调用函数。通过预填充到函数名的开头来实现: <|im_start|>assistant<tool_call>{"name": "browser_
利用这一点,我们通过直接掩盖令牌的对数几率来约束动作选择。例如,当用户提供新输入时,Manus 必须立即回复而不是执行某个动作。我们还有意地将动作名称设计成具有一致的前缀——例如,所有浏览器相关的工具都以 browser_
开头,命令行工具则以 shell_
开头。这使我们能够轻松地在特定状态下强制代理只从某一组工具中进行选择,而无需使用有状态的对数几率处理器。
这些设计有助于确保 Manus 智能代理的循环即使在模型驱动的架构下也能保持稳定。
将文件系统用作上下文
如今,前沿的大语言模型提供了 128K 甚至更多的令牌上下文窗口。但在现实世界的智能代理场景中,这通常是不够的,有时甚至是一种负担。这里有三个常见的痛点:
-
观察结果可能非常巨大,尤其是当智能代理与网页或 PDF 等非结构化数据交互时,很容易就超出上下文限制。 -
即使技术上支持更长的窗口,模型的性能在超过一定上下文长度后也往往会下降。 -
长输入是昂贵的,即使有前缀缓存。你仍然需要为传输和预填充每个令牌付费。
为了应对这个问题,许多智能代理系统采用了上下文截断或压缩策略。但过于激进的压缩不可避免地会导致信息丢失。问题是根本性的:一个智能代理,其本质决定了它必须根据所有先前的状态来预测下一个动作——而你无法可靠地预测哪个观察结果在十步之后可能会变得至关重要。从逻辑上讲,任何不可逆的压缩都带有风险。
这就是为什么在 Manus 中,我们将文件系统视为终极上下文:它的大小无限,本质上是持久的,并且可由智能代理直接操作。模型学会了按需读写文件——不仅仅是将文件系统用作存储,而是将其作为结构化的外部化记忆。

我们的压缩策略总是被设计为可恢复的。例如,只要保留了网页的 URL,其内容就可以从上下文中丢弃;只要文档在其沙箱中的路径仍然可用,其内容就可以被省略。这使得 Manus 可以在不永久丢失信息的情况下缩减上下文长度。
在开发此功能时,我发现自己开始想象,要让状态空间模型(State Space Model, SSM)在智能代理场景中有效工作需要什么。 与 Transformer 不同,SSM 缺乏完全的注意力机制,难以处理长程的反向依赖关系。但如果它们能够掌握基于文件的记忆——将长期状态外部化而不是保留在上下文中——那么它们的速度和效率可能会开启一类全新的智能代理。具备智能代理能力的 SSM 可能是神经图灵机[15](Neural Turing Machines)的真正继承者。
通过“复述”来操控注意力
如果你使用过 Manus,你可能会注意到一个有趣的现象:在处理复杂任务时,它倾向于创建一个 todo.md
文件,并随着任务的进展逐步更新它,勾掉已完成的项目。
这不仅仅是一种可爱的行为——它是一种有意为之的操控注意力的机制。

在 Manus 中,一个典型任务平均需要大约 50 次工具调用。这是一个很长的循环——并且由于 Manus 依赖大语言模型进行决策,它很容易偏离主题或忘记早期的目标,尤其是在长上下文或复杂任务中。
通过不断重写待办事项列表,Manus 正在将它的目标“复述”到上下文的末尾。这将全局计划推入模型的近期注意力范围,避免了“中间遗忘”(lost-in-the-middle)问题,并减少了目标偏离。 实际上,它是在用自然语言来引导自身的注意力偏向任务目标——而无需特殊的架构更改。
保留错误信息
智能代理会犯错。这不是一个程序缺陷——而是一种现实。语言模型会产生幻觉,环境会返回错误,外部工具会出问题,意想不到的边缘情况总会出现。在多步骤任务中,失败不是例外,而是循环的一部分。
然而,一种常见的冲动是隐藏这些错误:清理痕迹,重试动作,或者重置模型的状态,然后寄希望于神奇的“温度[16]”参数。这感觉更安全、更可控。但它是有代价的:抹去失败就等于移除了证据。没有证据,模型就无法适应。

根据我们的经验,改进智能代理行为最有效的方法之一,简单到令人意外:将走错的弯路保留在上下文中。当模型看到一个失败的动作——以及由此产生的观察结果或堆栈跟踪——它会含蓄地更新其内部认知。这会使其先验概率偏离类似的操作,从而减少重复同样错误的机会。事实上,我们相信错误恢复是真正智能代理行为最清晰的指标之一。然而,在大多数学术研究和公开基准测试中,这一点仍然被低估了,它们往往只关注理想条件下的任务成功率。
别被“小样本”带偏
“小样本提示”(Few-shot prompting)是提高大语言模型输出质量的常用技术。 但在智能代理系统中,它可能会以微妙的方式适得其反。
语言模型是出色的模仿者;它们会模仿上下文中的行为模式。如果你的上下文中充满了相似的过往“动作-观察”对,模型就会倾向于遵循这种模式,即使它已不再是最佳选择。
这在涉及重复性决策或动作的任务中可能很危险。例如,在使用 Manus 帮助审查 20 份简历时,智能代理常常会陷入一种节奏——重复相似的动作,仅仅因为它在上下文中看到了这些动作。这会导致偏离、过度泛化,有时甚至产生幻觉。

解决方法是增加多样性。Manus 在动作和观察结果中引入了少量的结构化变体——不同的序列化模板、替代性的措辞、顺序或格式上的微小噪音。这种受控的随机性有助于打破模式,并调整模型的注意力。换句话说,不要用“小样本”把自己框死在固定的套路里。你的上下文越统一,你的智能代理就越脆弱。
结论
上下文工程仍然是一门新兴的科学——但对于智能代理系统来说,它已经至关重要。模型可能变得越来越强大、快速和廉价,但再强的原始能力也无法替代对记忆、环境和反馈的需求。你如何塑造上下文,最终定义了你的智能代理的行为方式:它的运行速度、恢复能力以及扩展的规模。
在 Manus,我们是通过反复的重构、失败的尝试以及对数百万用户的真实世界测试才学到这些教训的。本文分享的内容并非放之四海而皆准的真理——但这些是于我们行之有效的模式。如果它们能帮你哪怕避免一次痛苦的迭代,那么这篇文章就完成了它的使命。
智能代理的未来将由一个个上下文构建而成。请精心设计它们。
参考资料
Manus: https://manus.im/app
[2]BERT: https://arxiv.org/abs/1810.04805
[3]GPT-3: https://arxiv.org/abs/2005.14165
[4]Flan-T5: https://arxiv.org/abs/2210.11416
[5]典型的智能代理: https://arxiv.org/abs/2210.03629
[6]KV 缓存: https://medium.com/@joaolages/kv-caching-explained-276520203249
[7]自回归: https://en.wikipedia.org/wiki/Autoregressive_model
[8]vLLM: https://github.com/vllm-project/vllm
[9]前缀/提示缓存: https://docs.vllm.ai/en/stable/design/v1/prefix_caching.html
[10]MCP: https://modelcontextprotocol.io/introduction
[11]检索增强生成(RAG): https://en.wikipedia.org/wiki/Retrieval-augmented_generation
[12]约束解码: https://platform.openai.com/docs/guides/structured-outputs
[13]状态机: https://en.wikipedia.org/wiki/Finite-state_machine
[14]Hermes 格式: https://github.com/NousResearch/Hermes-Function-Calling
[15]神经图灵机: https://arxiv.org/abs/1410.5401
[16]温度: https://arxiv.org/abs/2405.00492
(文:AI工程化)