深度拆解 Manus 上下文工程

在 AI Agent 赛道上,Manus 作为通用 Agent,能以惊人的速度处理长程任务(Long-horizon Tasks),得益于其精妙的上下文工程设计。

很多开发者在使用 Agent 时都有两个痛点:越用越慢(首字生成延迟变高)和越用越笨(上下文过长导致指令遵循能力下降)。通常的解决方案是 RAG 或者精简 Prompt。

但 Manus 走了一条完全不同的路。

在深入使用Manus并研究了 Manus 的官方技术博客、核心团队访谈后,我发现 Manus 的核心理念可以用一个计算机系统隐喻来概括:

Context Window(上下文窗口)是极其昂贵且高速的 RAM(内存),而 Linux 沙箱的文件系统是 HDD(硬盘)。

许多开发者犯的根本错误,是试图把所有的上下文(海量文档、代码库、网页全文)都塞进 RAM 里。这不仅会导致系统崩溃(Context Overflow),更会让 CPU 过热降频(注意力分散、推理变慢)。

Manus 的做法极其克制:RAM 里只放当前正在运行的“程序指令”,所有的数据都在硬盘里。

本文将从工程架构角度,拆解 Manus 如何通过上下文工程实现这一目标。

速度魔法——极致的 KV-Cache 亲和架构

Manus 之所以快,不是因为它用的模型比 Claude 快,而是因为它极致地利用了推理缓存。在 Manus 的工程哲学里,“缓存命中率”是第一优先级

1. 黄金法则:Stable Prefixes(稳定前缀)

要理解 Manus 的速度,必须先理解大模型推理的底层机制——KV-Cache(全称 Key-Value Cache,键值缓存)

在 Transformer 架构中,模型生成每一个 Token 时,都需要计算这个 Token 与之前所有 Token 的“注意力关系”。如果不做优化,生成第 100 个词时需要重新计算前 99 个。KV-Cache 就像是**“计算结果的存档”**,它缓存了之前的 Key 和 Value 向量,让模型只需计算最新的那一个,避免重复计算,从而显著加速文本生成过程,同时用额外内存换取计算效率。

但 KV-Cache 有一个致命弱点:牵一发而动全身。

注意力机制是因果相关的。只要 Prompt 的开头变了一个字,后面所有内容的语义环境就变了,导致后续所有的 KV-Cache 全部失效。

因此,Manus 严格遵守**“静态与动态分离”**原则:

  • 静态区:System Prompt、工具定义(Tool Definitions)被“锁死”在 Prompt 最顶端,字节级不变。
  • 动态区:用户 Query、当前时间、状态更新,被严格放置在 Prompt 的末尾

反面教材: 一些开发者习惯在 System Prompt 第一行写 Current Time: 2024-12-17 10:00:01。这一秒的变动,会导致显存里存好的几千个 Token 的工具定义缓存瞬间作废,模型必须重新计算所有 Token 的Q K V,响应延迟直接增加数秒。

2. Soft Masking(软屏蔽)—— 从 API 层面干预“大脑”

一个通用 Agent 可能拥有 50+ 个工具。为了节省 Token,传统做法是删除看似不用的工具定义。但这会破坏 Cache。

Manus 采用的是 Soft Masking(软屏蔽) 技术。这并不是修改 Prompt,而是利用了 LLM 推理 API 的底层特性。

  • 原理: LLM 在生成下一个 Token 之前,会计算词表中每一个词的 Logits(未归一化的概率值),然后通过 Softmax 层转化为概率。 目前主流的推理 API(如 OpenAI, Anthropic)都提供了一个参数(通常叫 logit_bias),允许用户在 Softmax 之前,人为地给特定 Token 的 Logits 加上一个数值。
  • Manus 的做法: 它始终保留所有 50+ 个工具的定义(保住 Cache)。但在推理时,如果当前任务不需要 stock_price 工具,系统会在 API 调用中,将触发该工具名称的 Token 的 Logit Bias 设为 -100(负无穷)。
  • 效果: 虽然模型脑子里知道有这个工具(Context 里有),但它在物理上无法输出调用该工具的 Token。

这是一种高阶的 Trade-off:宁愿浪费一点 Token(保留长 Prompt),也要换取极致的 Cache 命中率和零延迟的工具切换能力。

容量魔法 —— 分层动作空间

如果上下文只能追加不能修改,Token 不会很快爆满吗?Manus 的解决方案是分层动作空间(Layered Action Space),并将“记忆”卸载到 Linux 环境中。

1. 为什么 Linux 文件系统是更好的“数据库”?

传统 RAG 使用向量数据库。它将文本切片(Chunks),通过语义相似度进行检索。这在问答场景很有效,但在 Agent 编写复杂项目时,Linux 文件系统(File System)表现得远比 RAG 优越。

A. 层级结构 vs. 扁平切片

Linux 文件系统是树状的(Root -> Directories -> Files)。

  • 这种结构本身就携带了巨大的信息量。例如,/src/utils/math.py/src/tests/test_math.py,路径本身就告诉了模型哪个是功能代码,哪个是测试代码。
  • RAG 将文档切碎后打平,丢失了这种“位置即语义”的层级上下文。

B. 精准匹配 vs. 模糊语义

当 Agent 想要找 def calculate_loss 函数时,grep 能 100% 找到它。

  • 原理grep 基于字符的精准匹配。代码是严谨的符号系统,容不得半点“模糊”。
  • RAG 的缺陷:向量检索基于“语义相似”。当你搜 calculate_loss,RAG 可能会返回 compute_cost 或者 gradient_descent 的解释文档,因为它们在语义上很像。但这对于编译器来说是错误的。在代码工程中,精准的 grep 远胜于向量检索。

C. 动态轨迹

RAG 索引通常是滞后的(索引需要时间)。而 Agent 需要的是实时记忆。

  • 当 Agent 刚运行完一个脚本报错了,错误日志写在了 ./error.log 里。
  • 文件系统能瞬间捕获这个“动态轨迹”。Agent 下一步立刻 cat ./error.log 就能看到最新的状态。而 RAG 此时根本来不及索引这个刚产生的文件。

2. 三层架构设计

  • Layer 1: Core (RAM):LLM 本体仅持有约 20 个原子工具(Read, Write, Search)。
  • Layer 2: Sandbox (HDD):利用云端 Linux 沙箱作为“无限外挂内存”。检索靠 grep,存储靠文件写入。
  • Layer 3: Sensors (Internet):浏览器抓取网页后,经过清洗转换为 Markdown(而非原始 HTML),不仅去噪,还能节省 50% 以上的 Token。

3. 核心技法:可逆压缩

这是 Manus 能够处理超长任务的关键技术。

当 Agent 编写代码时,如果将生成的 500 行代码直接留 Context 里,几轮对话后 Context 就会爆炸。Manus 采用了一种“偷梁换柱”的策略:

压缩过程:

  1. 模型执行 write_file(path="/src/main.py", content="...500 lines of code...")
  2. 文件被真实写入 Linux 沙箱。
  3. 关键步骤:在构建下一轮对话的 Prompt 时,系统会将历史记录中的 content 参数剥离,替换为一个占位符或路径引用。
    • 原始交互AI: call write_file(path="/src/main.py", content="import os...")
    • 压缩后的历史AI: call write_file(path="/src/main.py", content="<file_content_saved_to_disk>")

解压过程:

因为文件真实存在于沙箱里(HDD),数据并没有丢失,只是从 RAM(Context)移出去了。当模型后续需要修改代码时,它会主动调用 read_file(path=”/src/main.py”),此时系统再把内容从硬盘读进 RAM。

System Prompt 拆解

Manus 的 Syestem Prompt 并非只有一句 “You are a helpful assistant”,而是一个严密的状态机脚本

1. 强制思考

在 Prompt 中强调:

“You must always think before you act. Output your thoughts in <thought> tags.”

这不仅仅是为了 Chain-of-Thought(思维链)带来的准确率提升,更是一个工程伏笔。

在 Context 极度紧张时,系统可以通过正则表达式安全地删除历史记录中的 <thought>…</thought> 内容,只保留 Action。因为 <thought> 是过程,Action 是结果。过程可删,结果必须保留。

2. 失败恢复模式与多轮循环机制

在 Prompt 中写道:

“If a tool fails, analyze the error message in your <thought>, propose a fix, and try again.”

这个指令是如何生效的?

这并非要求 AI 在一次生成中完成“执行+报错+分析”。这是一个多轮交互(Multi-turn Interaction)的过程:

  1. Turn 1 (AI): 生成工具调用代码。
  2. Runtime (Engine): 执行代码 -> 失败 -> 捕获 stderr。
  3. Turn 2 (User/System): 将错误信息作为 Message 返回给 Context:“Tool execution failed: [Error Trace]”。
  4. Turn 2 (AI): 模型读取到最新的错误信息,同时回溯 System Prompt 中的指令(“If fails, analyze…”)。于是,模型遵守指令,在这一轮生成中,先在 <thought> 标签中分析、定义严格的 JSON Schema 枚举值、利用 Logit Bias 以及单步执行策略,人为地把概率性的 LLM 降维成确定性的“状态机”。让 Agent 的每一次思考都留下可被观测、可被截断、可被压缩的轨迹。

结语

未来的 Agent 开发,某种意义上是在开发一个新的操作系统:System Prompt 是内核,Tools 是驱动,而 Context 是被极致管理的内存(RAM)。

对于开发者而言,现在的方向很清晰:少做一点 Prompt 的玄学微调,多做一点 Context 的系统工程。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部