Z Talk 是真格分享认知的栏目至尊配资。
在《》中,Manus 联合创始人、首席科学家 Peak(季逸超)提到,每当团队在讨论某个功能的技术实现时,他会习惯性地思考:这个功能,能不能在产品里形成网络效应?
作为一个通用 Agent,Manus 每增加一项能力,团队就希望它能和已有功能之间产生意想不到的耦合效应。比如在加入图像读取功能后,他们发现 Manus 能自行调试生成的数据可视化代码,甚至能神奇地修复其他模块的问题。这正是他们所看重的复合效应。
昨天,Manus 官网发布了一篇新文章,Peak 分享了他们在搭建上下文工程过程中踩过的坑和总结出的经验。这是一篇真诚、深入、极具实战价值的记录。Peak 把团队在一次次试错中淬炼出的经验系统梳理,为正在构建 AI Agent 的开发者们提供了一套可借鉴的路径,也带我们重新走了一遍 Manus 从零到一的探索过程。
Manus 还在前行。正如 Peak 在文中所说:「如果模型进步是上涨的潮水,我们希望 Manus 是船,而不是钉在海床上的柱子。」
如果你也在打造自己的 Agent,希望这些总结能帮你更快找到方向。本文转自 Founder Park,基于 Kimi K2 翻译,以下为编译原文:
展开剩余91%在 Manus 项目伊始,我和团队就面临一个关键抉择:是利用开源基础模型训练一个端到端的智能体,还是依托前沿模型的上下文学习能力,在其之上构建智能体?
在我投身 NLP 的第一个十年里,我们并没有这种奢侈的选择。遥想当年 BERT 问世(没错,那已是七年前),模型必须先经过微调——还要评估——才能迁移到新任务。每次迭代往往耗时数周,尽管那时的模型体积与今日的 LLMs 相比微不足道。对于快速迭代的应用,尤其是 PMF 之前的阶段,如此缓慢的反馈循环几乎是致命的。这是我上一家初创公司留下的惨痛教训:当时我从零开始训练模型,用于开放信息抽取和语义搜索。随后 GPT-3 与 Flan-T5 横空出世,我那些自研模型一夜之间便失去了意义。颇具讽刺意味的是,正是这些新模型开启了上下文学习的大门,也为我们指明了一条全新的道路。
这个来之不易的教训让选择变得清晰:Manus 将押注于上下文工程。这让我们能在几小时内发布改进,而非几周,同时也让我们的产品与底层模型保持正交:如果模型进步是上涨的潮水,我们希望 Manus 是船,而不是钉在海床上的柱子。
然而,上下文工程远非一帆风顺。它是一门实验科学。我们已经四次重构了智能体框架,每一次都是在发现更好的上下文塑造方式之后。我们亲切地把这个手动进行架构搜索、提示微调和经验猜测的过程称为「随机梯度下降」(Stochastic Graduate Descent)。它并不优雅,但确实有效。
这篇文章分享了我们通过自身「SGD」抵达的局部最优解。如果你正在构建自己的 AI 智能体,希望这些原则能帮助你更快收敛。
围绕 KV-Cache 进行设计
如果只能选一个指标,我会说 KV 缓存命中率是生产级 AI 智能体最重要的单一指标,它直接影响延迟和成本。要理解原因,我们先看一个典型智能体的工作流程:
收到用户输入后,智能体通过一连串工具调用来完成任务。每一次迭代,模型都会根据当前上下文从预定义的动作空间中选择一个动作,然后在环境(如 Manus 的虚拟机沙箱)里执行该动作并产生观察结果。动作和观察结果被追加到上下文中,成为下一次迭代的输入。这个循环持续进行,直到任务完成。
可以想象,上下文在每一步都会增长,而输出——通常是一个结构化的函数调用——相对较短。这使得智能体的预填充与解码比例相比聊天机器人严重失衡。以 Manus 为例,平均输入与输出 token 的比例约为 100:1。
幸运的是,具有相同前缀的上下文可以利用 KV 缓存,从而显著降低首 token 延迟(TTFT)和推理成本,无论你是使用自托管模型还是调用推理 API。这可不是小打小闹的节省:以 Claude Sonnet 为例,缓存的输入 token 价格为 0.30 美元/百万 token,而未缓存的则高达 3 美元/百万 token,相差 10 倍。
从上下文工程的角度来看,提高 KV 缓存命中率需要遵循几个关键实践:
1. 保持提示前缀稳定。由于 LLMs 的自回归特性,即使只有一个 token 的差异,也可能从该 token 开始使整个缓存失效。一个常见错误是在系统提示开头加入时间戳——尤其是精确到秒的那种。虽然这让模型能告诉你当前时间,但也会让你的缓存命中率归零。
2. 让上下文保持追加式。避免修改之前的动作或观察结果。确保序列化是确定性的。许多编程语言和库在序列化 JSON 对象时并不保证键的顺序稳定,这会在无声无息中破坏缓存。
3. 在需要时明确标记缓存断点。某些模型提供方或推理框架不支持自动增量前缀缓存,而是要求手动在上下文中插入缓存断点。设置这些断点时,要考虑潜在的缓存过期,并至少确保断点包含系统提示的结尾。
此外,如果你使用 vLLM 等框架自行托管模型,请确保启用了前缀/提示缓存,并使用会话 ID 等技术在分布式工作节点间一致地路由请求。
通过掩码而非移除的方式约束行为选择
随着你的智能体承担更多能力,其行动空间自然会变得更加复杂。直白地说,工具数量会爆炸式增长。最近 MCP 的流行更是火上浇油。如果你允许用户自行配置工具,相信我:一定会有人把上百个神秘工具插进你精心策划的行动空间。结果,模型更容易选错动作,或走上低效的路线。简而言之至尊配资,全副武装的智能体反而变得更笨。
一种自然的想法是设计一个动态的动作空间——也许用类似 RAG 的方式按需加载工具。我们在 Manus 中也尝试过。但实验结果给出了一个明确的规则:除非绝对必要,否则避免在迭代过程中动态增删工具。主要原因有两点:
1. 在大多数 LLMs 中,工具定义在序列化后通常位于上下文的前部,一般在系统提示之前或之后。因此,任何变动都会使后续所有动作与观察的 KV-cache 失效。
2. 当之前的动作和观察仍引用当前上下文中已不存在的工具时,模型会陷入混乱。在没有约束解码的情况下,这往往导致模式违规或幻觉动作。
为了在提升动作选择的同时解决这一问题,Manus 使用了一个上下文感知的状态机来管理工具可用性。它并不真正移除工具,而是在解码阶段屏蔽相应 token 的 logits,从而根据当前上下文阻止(或强制)选择某些动作。
在实践中,大多数模型提供商和推理框架都支持某种形式的响应预填充,这让你无需修改工具定义即可约束动作空间。函数调用通常有三种模式(我们以 NousResearch 的 Hermes 格式为例):
Auto – 模型可以选择是否调用函数。实现方式:仅预填充回复前缀:<|im_start|>assistant
Required – 模型必须调用函数,但具体调用哪个函数不受限制。实现方式:预填充到工具调用标记:<|im_start|>assistant<tool_call>
Specified – 模型必须从特定子集中调用函数。实现方式:预填充到函数名开头:<|im_start|>assistant<tool_call>{"name":「browser\_
Auto – 模型可以选择是否调用函数。实现方式:仅预填充回复前缀:<|im_start|>assistant
Required – 模型必须调用函数,但具体调用哪个函数不受限制。实现方式:预填充到工具调用标记:<|im_start|>assistant<tool_call>
Specified – 模型必须从特定子集中调用函数。实现方式:预填充到函数名开头:<|im_start|>assistant<tool_call>{"name":「browser\_
我们利用这一点,直接在 token logits 上施加掩码来限制动作选择。例如,当用户提供新的输入时,Manus 必须立即回复,而不能执行任何动作。我们还特意为动作名称设计了统一的前缀——例如,所有与浏览器相关的工具都以 browser\_ 开头,命令行工具则以 shell\_ 开头。这样一来,我们就能轻松地在给定状态下限定智能体只能从某一组工具中选择,而无需依赖有状态的 logits 处理器。
这些设计有助于确保 Manus 智能体循环保持稳定,即使在以模型为驱动的架构下也是如此。
将文件系统作为上下文
现代前沿 LLMs 现已支持 128K 乃至更大的上下文窗口。但在真实的智能体场景中,这往往仍不够用,有时甚至反而成为负担。常见痛点有三:
1. 观测结果可能非常庞大,尤其是当智能体与网页或 PDF 这类非结构化数据交互时。很容易就会超出上下文限制。
2. 模型性能在超过某个上下文长度后往往会下降,即使窗口技术层面仍支持。
3. 长输入成本高昂,即使有前缀缓存,你仍需为传输和预填充每个 token 付费。
为了应对这一问题,许多智能体系统实现了上下文截断或压缩策略。但过度激进的压缩必然导致信息丢失。问题本质在于:智能体本质上必须基于所有先前状态来预测下一步行动。你无法可靠地预测哪条观测在十步之后会变得至关重要。从逻辑角度看,任何不可逆的压缩都伴随风险。
正因如此,我们在 Manus 中将文件系统视为终极上下文:容量无限、天然持久,并且代理可直接操作。模型学会按需读写文件,把文件系统不仅当作存储,更当作结构化、外化的记忆。
我们的压缩策略始终保证可还原。例如,只要保留 URL,网页内容即可从上下文中移除;只要路径仍在沙盒中可用,文档内容也可省略。这让 Manus 能在不永久丢失信息的前提下缩短上下文长度。
在开发这一功能的过程中,我开始设想要让状态空间模型(SSM)在代理环境中高效运作需要哪些条件。与 Transformer 不同,SSM 缺乏完整的注意力机制,难以处理长距离的反向依赖。然而,如果它们能够掌握基于文件的记忆——将长期状态外部化,而非保存在上下文里——那么它们的速度与效率或许就能催生一类全新的代理。代理化的 SSM 可能成为神经图灵机的真正继承者。
通过复述操控注意力
如果你用过 Manus,可能会注意到一个有趣的现象:在处理复杂任务时,它往往会创建一个 todo.md 文件,并在任务推进过程中逐步更新,把已完成的项逐一勾选。
这可不是卖萌的小动作,而是一种刻意设计的注意力操控机制。
在 Manus 中,一个典型任务平均需要约 50 次工具调用。这是一个很长的循环。由于 Manus 依赖 LLMs 做决策,它很容易在冗长上下文或复杂任务中偏离主题或遗忘早期目标。
通过不断重写待办清单,Manus 把目标「背诵」到上下文的末尾。这样一来,全局计划就被推入模型的近期注意力范围,避免「中间丢失」问题,减少目标错位。实际上,它是在用自然语言把自己的注意力偏向任务目标,无需任何特殊架构改动。
保留错误内容
智能体会犯错。这不是缺陷,而是现实。语言模型会产生幻觉,环境会返回错误,外部工具会出故障,意外的边缘情况也层出不穷。在多步骤任务中,失败并非例外,而是循环的一部分。
然而,一种常见的冲动是掩盖这些错误:清理追踪记录、重试操作,或重置模型状态,然后寄希望于神秘的「温度」参数。这看似更安全、更可控,却付出了代价:抹除失败就等于抹除证据。而没有证据,模型就无法适应。
根据我们的经验,提升智能体行为最有效的方法之一看似简单却极具欺骗性:把走错的路留在上下文中。
当模型看到一次失败的行动,以及随之而来的观察结果或堆栈跟踪,它会潜移默化地更新内部信念。这会把先验从类似行动上移开,降低重蹈覆辙的概率。事实上,我们认为错误恢复是真正具备智能体行为的最清晰指标之一。然而,在大多数学术研究和公开基准中,它仍然被低估,这些研究和基准往往聚焦于理想条件下的任务成功。
不要被 Few-Shot 反噬
少样本提示(Few-Shot Prompting)是一种提升 LLM 输出的常用技术,但在智能体系统中,它可能以微妙的方式适得其反。
语言模型是出色的模仿者;它们会模仿上下文中的行为模式。如果你的上下文里充斥着大量相似的动作-观察对,模型就会倾向于沿用这一模式,即便该模式已不再最优。
这在涉及重复性决策或任务的场景中可能很危险。例如,当使用 Manus 协助审阅一批 20 份简历时,代理往往会陷入一种节奏——仅仅因为上下文里出现了类似操作就不断重复。这会导致漂移、过度泛化,甚至有时产生幻觉。
解决方法是增加多样性。Manus 在动作和观察中引入少量结构化变化,像不同的序列化模板、替代表述方式、顺序或格式上的轻微扰动。这种受控的随机性有助于打破固定模式,微调模型的注意力。换句话说,不要把自己困死在少量示例里。上下文越单一,Agent 就越脆弱。
结论
上下文工程仍是一门新兴学科。但对智能体系统而言,它已是不可或缺。模型可能变得更强大、更快速、更便宜,但再强的原生能力也无法取代记忆、环境与反馈。你如何塑造上下文,最终决定了智能体的行为:运行速度、恢复能力,以及可扩展的极限。
在 Manus,我们通过一次次重写、走进死胡同,以及在数百万用户中的真实测试,才悟出这些经验。我们在此分享的内容并非放之四海而皆准的真理,但它们是我们验证有效的模式。如果它们能帮你少走哪怕一次痛苦的迭代,这篇帖子就值了。
智能体的未来至尊配资,将靠一个个上下文逐步构建。请把它们设计好。
发布于:北京市一鼎盈提示:文章来自网络,不代表本站观点。