当前位置: 首页 > news >正文

季逸超:Manus的上下文工程启示

模型或许正变得更强大、快速、廉价,但任何原始能力都无法替代记忆、环境与反馈。塑造上下文的方式,最终决定了智能体的行为模式:它的执行速度、容错能力与扩展边界。 

——Manus首席科学家 季逸超

图片

项目启动之初,团队面临关键抉择:是基于开源模型训练一个端到端的智能体模型,还是在尖端模型能力之上构建智能体?

回溯我从事NLP的第一个十年(是的,那已是七年前),我们根本没有这样的选择余地。在BERT时代(2018年),模型必须经过微调和评估才能迁移到新任务。每次迭代常耗时数周——尽管当时的模型比如今的大语言模型(LLM)小巧得多。对于快速迭代的应用(尤其是未达成产品市场契合的阶段),如此缓慢的反馈循环是致命伤。这来自我上段创业经历的惨痛教训:当时我为语义搜索从头训练模型,而GPT-3和Claude的横空出世让自研模型一夜过时。颇具讽刺的是,正是这些模型开启了上下文学习的新纪元。

这份教训让选择变得清晰:Manus将押注上下文工程。这使我们能在数小时内(而非数周)实现改进,并让产品与底层模型解耦——若将模型进步比作涨潮,我们要做随潮涨落的船,而非扎根海底的桩柱。

然而上下文工程远非坦途。作为一门实验科学,我们已四次重构智能体框架,每次皆因发现更优的上下文塑造方法。我们戏称这种架构搜索、提示词调试与经验猜测的手动过程为"随机研究生下降法"(Stochastic Graduate Descent)。虽不优雅,但切实有效。本文分享了我们通过这套"SGD"获得的局部最优解。若您正在构建AI智能体,望这些原则助您更快收敛。

围绕KV缓存设计

若智能选择一个指标,KV缓存命中率堪称生产级AI智能体的核心指标,它直接影响延迟与成本。以Manus运行为例:

用户输入后,智能体通过工具链执行任务。每轮迭代中,模型基于当前上下文从预设动作空间选择一个动作,在环境(如Manus虚拟机沙盒)执行后生成观察结果。动作与观察结果追加至上下文,构成下一轮输入,循环直至任务完成。

可想而知,上下文持续增长而输出(通常是结构化函数调用)保持简短,导致智能体的输入输出token比率远高于聊天机器人。Manus的输入/输出token比约为100:1。幸运的是,相同前缀的上下文可利用KV缓存——无论使用自托管模型或调用推理API,都能显著降低首token延迟(TTFT)与推理成本。节省绝非微量:以Claude Sonnet为例,缓存输入成本0.30美元/百万token,未缓存则需3美元,相差十倍。

从上下文工程角度,提升KV缓存命中率需遵循:

  • 保持提示前缀稳定:因LLM的自回归特性,单token差异即可使后续缓存失效。常见错误是在系统提示开头添加时间戳(尤其是精确至秒级),虽可让模型返回当前时间,却会摧毁缓存命中率。

  • 上下文仅追加不修改:避免改动历史动作或观察结果,确保序列化具有确定性。多数编程语言和库在序列化JSON时无法保证键的顺序稳定,可能悄无声息的破坏缓存。

  • 显式标记缓存断点:部分模型服务商或推理框架不支持自动增量前缀缓存,需手动插入缓存断点。设置时需考虑缓存过期风险,至少确保断点包含系统提示结尾。

  • 启用缓存功能:若使用vLLM等框架自托管模型,请启用增量缓存,并采用会话ID等技术在分布式节点间保持请求一致。

屏蔽而非移除

随着智能体能力扩展,其动作空间必然复杂化——工具数量将爆发式增长。OpenAI函数调用的流行更助长此势。若允许用户配置工具,总有人将数百个神秘工具接入您精心设计的动作空间,导致模型误选操作或采取低效路径。简言之:全副武装的智能体反而变笨了。

本能反应是设计动态动作空间(如通过插件机制按需加载工具)。Manus曾尝试此方案,但实验表明:非必要时应避免在迭代中动态增删工具。原因有二:

  • 多数LLM中,工具定义位于上下文前端(系统提示前后),任何改动将使后续动作与观察结果的KV缓存失效。

  • 当历史动作仍引用已移除工具时,若无JSON Schema校验,模型将产生模式冲突或幻觉操作。

为解决这一问题,Manus采用上下文感知的屏蔽机制管理工具可用性:我们不移除工具,而是通过解码时屏蔽token logits,基于当前上下文禁止或强制选择特定动作。

实践中,多数模型服务商和推理框架支持某种形式的响应预填充,可在不修改工具定义的情况下约束动作空间。以NousResearch的工具调用为例,通常有三种模式:

  • 自动模式:模型可自由选择是否调用函数。实现方式:仅预填充回复前缀 <|im_start|>assistant

  • 必须模式:模型必须调用函数但选择不受限制。实现方式:预填充至工具调用token <|im_start|>assistant<tool_call>

  • 指定模式:模型必须调用特定子集函数。实现方式:预填充至函数名开头<|im_start|>assistant<tool_call>{"name": "browser_

基于此,我们通过屏蔽token logits直接约束动作选择。例如用户输入新内容时,Manus必须立即回复而非执行操作。我们还刻意设计带一致前缀的动作名(如浏览器工具均以browser_开头,命令行工具以shell_开头),无需状态化logits处理器即可确保智能体在特定状态下仅选择某类工具。这些设计保障了Manus智能体循环在模型驱动架构下的稳定性。

将文件系统作为上下文

现代前沿LLM虽提供128K token的上下文窗口,但在真实智能体场景中仍显不足,甚至成为负担。痛点有三:

  • 观察结果可能巨大(尤其处理网页/PDF等非结构化数据),易突破上下文限制

  • 超出特定长度后模型性能衰减(即使技术支持该窗口)

  • 长输入成本高昂(即使有前缀缓存仍需为每个token的传输和预填充付费)

对此,许多系统采用上下文截断或压缩策略。但过度压缩必然导致信息丢失——智能体本质需基于完整历史状态预测下一动作,而无法预知哪项观察在十步后至关重要。从逻辑看,任何不可逆压缩皆具风险。

因此Manus将文件系统视为终极上下文:容量无限、天然持久化,且智能体可直接操作。模型学会按需读写文件,使文件系统不仅成为存储介质,更是结构化的外部记忆体。

我们的压缩策略始终设计为可恢复:只要保留URL即可移除网页内容;只要沙盒中存在路径即可省略文档内容。这让Manus能压缩上下文长度而不永久丢失信息。

开发此功能时,我常思考状态空间模型(SSM)在智能体场景的应用前景:与Transformer不同,SSM缺乏全局注意力且难处理长距离反向依赖。但若能掌握基于文件的记忆(将长期状态外部化而非存于上下文),其速度与效率或催生新一代智能体。智能体SSM可能成为Transformer的真正继任者。

通过复述操控注意力

使用过Manus的用户会发现:处理复杂任务时,它常创建todo.md文件,并随任务进展逐步勾选已完成项。这不仅是趣味行为,更是操控注意力的精心设计。

Manus的典型任务平均需50次工具调用。如此长的循环中,依赖LLM决策的智能体易偏离主题或遗忘早期目标(尤其在长上下文或复杂任务中)。

通过持续重写待办清单,Manus将目标复述至上下文末尾,使全局计划进入模型近期注意力范围,避免"迷失在中段"问题并减少目标偏差。本质上,它用自然语言将自身注意力导向任务目标,而无需特殊架构改造。

保留错误痕迹

智能体会犯错——这非缺陷,而是现实。语言模型会幻觉,环境会报错,外部工具会异常,边缘案例层出不穷。在多步任务中,失败非例外而是循环的组成部分。

人们常见做法是掩盖错误:清理轨迹、重试操作或重置模型状态后依赖神奇的"CoT"(思维链)。这看似安全可控,实则代价巨大:清除失败痕迹等于销毁证据。缺乏证据,模型无法自我调整。

我们发现,提升智能体行为最有效的方法之一出奇简单:将错误路径保留在上下文中。当模型看到失败操作及衍生的观察结果(或堆栈跟踪)时,其内部信念会隐式更新,降低重复同类错误的概率。

事实上,错误恢复能力是智能体行为的核心指标,但多数学术研究与公开基准仍聚焦理想条件下的任务成功率。

警惕少样本陷阱

少样本学习虽可改进LLM输出,但在智能体系统中可能引发微妙反效果。语言模型是卓越的模仿者,它们会复制上下文中的行为模式。若上下文充满相似的历史动作-观察对,即使该模式已非最优,模型仍倾向于遵循。

这在涉及重复决策的任务中尤为危险。例如用Manus审核20份简历时,智能体易陷入固定节奏——仅因上下文存在相似记录就重复操作,导致偏离、过度泛化甚至幻觉。

解决的办法是增加多样性。Manus在动作与观察中引入少量结构化变化:不同的序列化模板、替换措辞、顺序或格式的轻微噪声。这种受控随机性打破固有模式,调整模型注意力。简言之,勿因少样本提示陷入窠臼。上下文越单一,智能体越脆弱。

结语

上下文工程仍是一门新兴科学,但对智能体系统已不可或缺。模型或许正变得更强大、快速、廉价,但任何原始能力都无法替代记忆、环境与反馈的需求。塑造上下文的方式,最终决定了智能体的行为模式:它的执行速度、容错能力与扩展边界。

在Manus,这些认知源于数百万用户场景中的反复重写、试错与实战检验。本文所分享皆非普世真理,但它们的确是我们的有效路径。若这些经验能助您减少一次痛苦迭代,便达成了写作初衷。

智能体的未来,将由每个精心设计的上下文构筑。请务必雕琢好它们。

http://www.lryc.cn/news/598990.html

相关文章:

  • JMeter压测黑马点评优惠券秒杀的配置及请求爆红问题的解决(详细图解)
  • 基于20和28 nm FPGAs的实现多通道、低非线性时间到数字转换器
  • Android15或AndroidU广播的发送流程
  • Redis学习:持久化与事务(Transaction)
  • 如何查看docker实例是否挂载目录,以及挂载了哪些目录
  • 浏览器访问[http://www.taobao.com](http://www.taobao.com/),经历了怎样的过程。
  • NOTEPAD!NPCommand函数分析之comdlg32!GetSaveFileNameW--windows记事本源代码分析
  • Python 程序设计讲义(15):Python 的数据运算——位运算
  • 人形机器人_双足行走动力学:Maxwell模型及在拟合肌腱特性中的应用
  • 深入解析Java微服务架构请求流程:Nginx到Nacos的完整旅程
  • 进阶系统策略
  • 人形机器人双足行走动力学:K-V模型其肌腱特性拟合中的应用
  • 模拟退火算法 (Simulated Annealing, SA)简介
  • 【推荐100个unity插件】Animator 的替代品?—— Animancer Pro插件的使用介绍
  • AD一张原理图分成多张原理图
  • 深入思考【九九八十一难】的意义,试用歌曲能否解释
  • python教程系列1--python001
  • 学习设计模式《十九》——享元模式
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-17,(知识点:PCB布线,传输线阻抗影响因素)
  • ParFlow 模型
  • 【自用】JavaSE--阶段测试
  • vite+vue3 工程-SVG图标配置使用指南——vite-plugin-svg-icons 插件
  • Vitest 用法详解及 Coverage Web 工具介绍
  • 工具篇之开发IDEA插件的实战分享
  • Nvidia Isaac Sim机械臂实验
  • Linux命令基础完结篇
  • Mysql大数据架构设计:当表中数据超过800万时,对数据表进行分表操作,以及分页查询优化详解
  • C++STL系列之set和map系列
  • Node.js 中的内置模板path
  • 【时时三省】(C语言基础)怎样定义和使用指向函数的指针变量