智能体如何使用上下文工程




内容概要

本视频探讨了 AI Agent (人工智能代理) 的上下文工程 (Context Engineering) 的核心原则,以及这些原则如何在 Claude Code、Manus 和 LangChain 的 DeepAgents 等流行框架中实现。随着 AI Agent 处理日益复杂的任务,管理上下文窗口 (context windows) 变得至关重要。本视频分解了三个关键原则——卸载 (offload)、精简 (reduce) 和隔离 (isolate)——并展示了领先的 Agent 框架如何实现它们,以高效处理更长的任务。


目录

  • 上下文工程 (Context Engineering) 简介

  • Agent 的基本要素 (Primitives) 与工具链 (Harnesses)

  • 上下文工程的原则

  • 卸载上下文:文件系统

  • 卸载操作:使用脚本

  • 操作的渐进式披露 (Progressive Disclosure)

  • DeepAgents 工具概览

  • 精简上下文:压缩 (Compaction)

  • 精简上下文:摘要 (Summarization)

  • 精简上下文:过滤 (Filtering)

  • 隔离上下文:子代理 (Subagents)

  • 总结与比较

  • 结语


上下文工程 (Context Engineering) 简介

大家好,我是来自 LangChain 的 Lance。我想谈谈几个通用的上下文工程 (Context Engineering) 原则,以及它们如何体现在 Manis、Cloud Code 以及我们最近发布的 Deep Agents 包和 CLI (命令行工具) 中。

首先,一个 Agent (代理) 可以被简单地理解为一个在循环中调用工具的 LLM (大语言模型)。LLM 进行一次工具调用,工具被执行,工具的观测结果 (observation) 返回给 LM,这个过程不断重复,直到满足某个终止条件。

现在,AI Agent (人工智能代理) 能够执行的任务长度越来越长。来自 Meter 的一份出色报告显示,任务长度大约每 7 个月就会翻一番。

这样带来的挑战是,随着 Agent 承担更长的任务,你会积累越来越多的工具结果。例如,Manis 提到,一个平均的 Manis 任务会涉及超过 50 次的工具调用。同样,Anthropic 也提到,生产环境中的 Agent 运行轮次 (turns) 往往可能达到数百次。

问题在于,当你用所有这些不同工具调用的结果填充上下文窗口时,你实际上在每一轮都把所有先前的工具结果传回给模型。


Agent 的基本要素 (Primitives) 与工具链 (Harnesses)

因此,运行 Agent 相关的成本和延迟可能会急剧增加,不仅如此,性能也可能下降。

Chrome 有一份关于“上下文腐烂” (context rot) 的精彩报告,讨论了性能如何随着上下文长度而下降。因此,我们看到 Agent 的设计正越来越多地采用一些不同的原则来解决这个问题。

Agent 通常有几个通用的基本要素 (primitives):一个模型、提示 (prompting)、工具,以及通常还有钩子 (hooks)。

以 Cloud Code 为例。它使用的是 Cloud 系列模型,其系统提示 (system prompt) 实际上是公开的,你可以在这个链接中查看。我会确保把这个文档链接放在视频描述中。它有大约十几个原生工具,并且它允许使用钩子 (hooks),这些钩子基本上是在 Agent 生命周期 (life cycle) 的不同节点以编程方式运行的脚本,例如,在每次工具调用之前或之后。

我们的 Deep Agents 包和 Deep Agent CLI 也是围绕这些基本要素建立的。这个包允许使用任何模型提供商 (model provider);CLI 目前使用的是 Anthropic。你可以查看提示,它们都是开源的。它在包和 CLI 中分别使用了 8 个和 11 个原生工具,我稍后会详细展示。我们也在 Agent 生命周期的不同节点支持钩子。

了解了这些构成我们所谓的 Agent 工具链 (agent harness) 的基本要素后,我们需要思考:在管理上下文腐烂和由多轮工具调用积累的 token (令牌) 问题上,我们在不同 Agent 中看到了哪些通用技术?


上下文工程的原则

上下文工程 (Context Engineering) 是一个涵盖了许多这些原则的广义术语。Karpathy 在这里对此有非常好的概述。它是“在下一步中用恰到好处的信息填充上下文的精妙艺术和科学”,这非常适用于 Agent。你试图引导 Agent 在一系列动作轨迹中做出正确的下一步工具调用。

我提炼出的三个常见原则是:卸载 (offload)、精简 (reduce) 和隔离 (isolate)。

卸载 (Offloading) 是指将上下文从 LLM 的上下文窗口转移到外部,比如文件系统,以便稍后在需要时有选择地检索。

精简 (Reducing) 就是简单地减少在每一轮传递的上下文大小,实现这一点可以有很多不同的技术。

最后是隔离 (Isolating) 上下文,即对单个任务使用独立的上下文窗口或独立的子代理 (sub-agents)。我在这里分享了一些参考资料。我在 Latent Space 播客上谈过这个话题。我与 Manis 共同举办了一次网络研讨会,我们讨论了这些原则以及 Manis 是如何使用它们的。我将在这里回顾它们,并讨论 Deep Agents 包和 CLI 是如何运用这些思想的。


卸载上下文:文件系统

首先是卸载上下文。我们反复看到的一个趋势是,赋予 Agent 访问文件系统的能力非常有用。这使得 Agent 可以在长时间运行的任务中保存和调用信息。

这一点非常直观。我在这里分享了一个来自 Anthropic 多代理研究员 (multi-agent researcher) 的链接,他们基本上是让研究员编写一个计划,将其写入文件,然后去做大量的工作,接着在许多子代理完成工作后,再检索该计划,以确保所有事项都已得到处理。

所以,你可以把计划写入文件,并在需要加强既定计划时将其读回上下文中。这对于确保你不会忘记计划中的特定步骤非常有用。通过将其外部化到文件,再读回上下文中,你可以确保它被持久化,并且 Agent 可以更容易地被引导,因为你是在需要时有选择地将其拉回上下文窗口,以帮助 Agent 保持在正轨上。

关于文件系统,另一个有趣的地方是它通常在不同的 Agent 调用 (invocations) 之间是持久化的。例如,如果你在本地笔记本电脑上使用 Cloud Code 运行你的 Agent,Cloud Code 总是可以引用这个 cloud.md 文件,这个文件可以存在于不同层级,比如项目级别,还有一个全局的 cloud.md。这个 cloud.md 可以存储你希望在与 Cloud Code 的所有不同交互中都持久化的信息。

Manis 当然也使用了同样的想法。Manis 在远程运行,所以它使用一个包含文件系统的沙盒环境 (sandbox environment),并给予 Agent 访问计算机的权限,同时它支持用户内存。

Deep Agents 包则允许使用不同的后端 (backends)。你可以使用 LangGraph 的状态对象 (state object),它只存在于内存中,或者你可以使用文件系统后端,例如你的本地机器。而 Deep Agent CLI 则很像在你的笔记本电脑上运行的 Cloud Code,它会直接使用你本地的文件系统作为后端。Deep Agent CLI 也支持通过一个 memories 目录和一个 agent.md 文件来实现内存功能。

我们反复看到的原则是:让 Agent 能够将上下文卸载到文件系统,这有很多好处。你可以在长时间运行的轨迹中持久化信息,也可以在 Agent 的不同调用之间持久化上下文,比如存储在 cloud.mdagent.md 文件中,或者在 Deep Agent CLI 的例子中,存储在一个 memories 目录里。


卸载操作:使用脚本

文件系统的另一个好处是,你实际上可以将操作 (actions) 从工具 (tools) 卸载到纯粹的脚本 (scripts) 上。这是什么意思呢?

我们希望 Agent 执行操作。假设我们想给一个 Agent 10 种不同的操作。通常你会想,好吧,对于每一种操作,我定义一个独特的工具。我把所有这些工具都绑定 (bind) 到 Agent 上,这样我就有了一个拥有 10 个不同工具的 Agent。

现在,该 Agent 中的 LLM 必须决定何时使用这 10 个工具中的哪一个,而且你还必须把所有这些工具的指令加载到系统提示 (system prompt) 中。这里有两个问题。一是 Agent 在使用哪个工具上会产生困惑,二是你的指令中充斥着大量的工具描述,导致提示“臃肿”。

看,如果有三、四个,甚至十个工具,问题不大,但如果我们谈论的是数百个工具,那么仅仅是所有的工具描述就会占用大量的 token。

所以,有一个原则,在与 Manis 的网络研讨会中我们深入探讨了这一点,那就是保持函数调用层 (function calling layer) 非常轻量级。只给 Agent 少数几个函数去调用,但要确保它们是通用的原子函数 (atomic functions),可以做很多事情,并把大量的具体操作推送到像文件系统中的脚本那样的东西上。

例如,Manis 给了 Agent 像 bash 工具和文件系统操作工具。有了这两样东西,它就可以使用各种工具来导航文件系统,搜索一个脚本目录,并使用 bash 工具执行其中的任何一个。

因此,通过三到四个用于文件操作和代码执行的简单工具,它就可以执行由你提供的脚本所指定的大量操作。这是一种在只给 Agent 少数工具的情况下,显著扩展其操作空间 (action space) 的方法。

我们反复看到这个原则。如果你看 Cloud Code,其工程和产品负责人 Boris Churnney 和 Cat Woo 最近上了一个很棒的播客,我把链接放在了这里,他们提到 Cloud Code 只使用了大约十几种工具。


操作的渐进式披露 (Progressive Disclosure)

当你使用它时,你可以看到它使用了 globgrep,它使用 bash,它使用 fetch 来抓取 URL,但它使用的工具并不多,只有大约十几种。Manis 使用的工具不到 20 个。对于 Deep Agents,我们实际上只有 8 个原生工具,而在 Deep Agent CLI 中,我们有 11 个原生工具。我稍后会展示它们。

一个相关的想法是操作的渐进式披露 (progressive disclosure of actions)。Anthropic 在其最近发布的“技能” (Skills) 中专门谈到了这一点。这里有一个很好的引用,来自我链接的一篇博文。

Claude 的“技能” (Skills) 非常简单,就是一个 skills 文件夹,里面有许多子文件夹,每个子文件夹都是一个特定的技能。每个子文件夹只有一个 skill.md 文件,这是一个带有头部的 Markdown 文件。这个头部 (header) 只是用非常简短的语言解释了该技能的作用。只有这个头部信息会最先被加载到 Cloud Code 中。你可以在这张图中看到,这正是他们所展示的。所以,这里有关于每个可用技能的简短片段。

在 Claude Skills 的例子中,如果 Claude 想要使用任何给定的技能,它就可以有选择地去读取完整的 skill.md 文件。再次强调,默认情况下,只有头部信息被读入系统提示。如果 Claude 想要实际执行一个技能,它会读取那个完整的 skill.md 文件。

那个 skill.md 文件可以引用该技能目录中的任何其他文件。所以,它可以包含脚本,也可以包含其他含有更多上下文的文件。非常棒的一点是,Claude 仅凭它的 bash 工具,就可以去读取完整的 skill.md 文件,然后在需要时,执行该技能目录中的任何其他脚本或读取任何其他文件。

所以,这是一种向 Claude 渐进式披露操作的非常简单的方法,而无需预先将所有内容加载到系统提示中,更重要的是,无需将所有这些不同的功能或技能作为工具进行绑定。记住,在最简单的情况下,你只使用了 bash 工具来读取 skill.md 文件,然后执行该技能文件夹中的任何脚本或读取该文件夹中的任何其他文件。

我认为这是一种非常简单的方式,可以让 Agent 访问不同的操作,同时节省 token,因为它们是渐进式披露的,仅在 Claude 需要该技能时才展示。而且它只使用了简单的内置工具,比如 bash 工具和一些文件操作工具。

Manis 也使用了非常相似的原则。Manis Agent 可以访问大量不同的脚本,它可以使用其原生的文件搜索和 bash 工具来发现这些脚本。

我们目前在 Deep Agent CLI 中还没有“技能”这个概念,但我目前正在努力添加它,因为我认为这是一种让 Agent 访问大量操作的好方法,既不会因为指令而使其上下文窗口臃肿,也不必绑定额外的工具。


DeepAgents 工具概览

我想简单地明确一下 Deep Agents 包中具体有哪些工具,以突显这样一个观点:我们经常看到 Agent 发布的版本只带有少量通用的原子工具。

Deep Agents 包只有用于文件操作的基本工具,一个用于创建带有子代理的子任务的 task 工具,以及一个用于生成待办事项的 to-dos 工具。

CLI 在此基础上稍作扩展,增加了一些搜索工具和一个 bash 工具。


精简上下文:压缩 (Compaction)

现在,我们来谈谈精简上下文。这里有三个有趣的想法:压缩 (compaction)、摘要 (summarization) 和过滤 (filtering)。

首先,我来谈谈 Manis 是怎么做的。Manis 采用了这种压缩 (compaction) 的思想。左边展示的是一个工具调用和工具结果的轨迹,显然,工具结果可能会占用大量 token。

他们的做法是,通过将旧的工具结果的完整内容保存到一个文件中,并仅在消息历史 (message history) 中引用该文件,从而压缩这些结果。

他们只对那些已经被处理过的、可以称为“陈旧” (stale) 的工具结果执行此操作。但这是减少消息历史中 token 数量的一种非常好的方法。

这是他们展示的一张简洁的图表。想象你的 Agent 正在运行,执行了很多轮。在若干轮之后,你非常接近 LM 的上下文窗口限制了,这时他们就会应用这种压缩。

他们把所有历史工具结果(它们都使得消息历史变得臃肿)压缩起来,将它们卸载到文件系统,这大大降低了总体的上下文利用率。然后 Agent 继续运行,上下文又开始逐渐饱和。


精简上下文:摘要 (Summarization)

接着他们会应用摘要 (summarization)。摘要会查看整个消息历史,包括完整的工具结果消息,并将它们全部概括为一个更紧凑、更精炼的摘要,然后 Agent 就可以使用这个摘要。你可以看到,这个过程会继续下去。

一个有趣的点是,这个压缩步骤实际上是可逆的,因为你随时可以回去查看那些被保存到文件中的原始工具结果。这是使用文件系统的另一个好处。

然而,摘要 (Summarization) 并非如此。这是一个需要仔细考虑的步骤,因为当你进行摘要时,你必然会丢失信息。

你也会在 Anthropic 看到这些思想的应用。Anthropic 最近推出了上下文编辑 (context editing) 功能,它只是以一种可配置的方式修剪 (prunes) 消息历史中旧的工具结果。当达到上下文窗口的 95% 左右时,Cloud Code 会应用摘要功能。

Deep Agents 包则通过摘要中间件 (summarization middleware) 来应用摘要。这个功能会在达到某个阈值(例如 17 万 token)后自动启动,并保留一定数量的消息。当然,这一切都是开源且可配置的。


精简上下文:过滤 (Filtering)

Deep Agents 包和 CLI 中采用的另一项技术是,文件系统中间件 (file system middleware) 实际上会过滤掉大型的工具结果,这是防止将过大的工具结果直接传递给 LLM 的一种好方法。


隔离上下文:子代理 (Subagents)

最后,我们来谈谈上下文隔离 (context isolation)。这是我们反复看到的一种技术,而且这个想法非常简单。

Agent 执行的许多任务都可以分配给一个子代理 (sub-agent)。这个子代理有自己的上下文窗口,所以它可以从头开始处理一个特定的任务,特别是当这个任务是良好自包含 (self-contained) 的时候。它执行完该任务,然后把输出结果返回给父代理 (parent agent)。

这就是这里展示的第一种模式,Manis 也讨论过这种通信模式。你有一个父代理或主代理 (main agent),它想派生一个子代理来执行某个任务。它向该子代理传递一些指令。子代理自行运转,然后将结果传回给主代理。这是一种非常常见的模式。

当然,这里面还有一些细微差别。有时候你希望与子代理共享更多的上下文,实际上,Manis 允许与子代理共享父代理的完整消息历史。同样地,在 Deep Agents 和 Deep Agent CLI 中,子代理实际上有权访问与父代理相同的文件系统。


总结与比较

所以,它们之间存在一些共享的上下文。总结一下,Agent 工具链 (harnesses) 通常至少采用三种原则来管理上下文:卸载、精简和隔离。

在上下文卸载方面,一些最常见的想法包括使用文件系统。我们看到所有框架都在使用它。Cloud Code、Manis 和 Deep Agent CLI 都支持使用文件系统。

启用用户内存 (user memories)。这很直观,指的是在 Agent 的不同调用之间记住信息的能力。Cloud 通过 cloud.md 启用了它。Deep Agent CLI 有一个 memories 文件夹作为内存目录,以及 agents.md。Manis 也支持跨会话 (cross-session) 内存。

使用最少的工具。这可以在工具描述方面显著节省 token,并最大限度地减少 Agent 必须在不同工具之间做出的决策数量。Cloud Code 只使用了大约十几种工具,Manis 不到 20 种,DB Agent CLI 有 11 种。

给 Agent 一台“计算机”,即一个 bash 工具。所有这些 Agent 工具链都做到了这一点。


结语

操作的渐进式披露 (Progressive disclosure of actions)。Cloud Code 通过“技能” (Skills) 来实现这一点。Manis 的实现方式是,让 Agent 访问一个包含大量不同脚本的目录,并让它在需要时使用其现有的文件系统和 bash 工具来细读该目录。Deep Agent CLI 的“技能”功能还在开发中。

关于压缩 (compaction) 的想法,即修剪旧的工具消息。Manis 肯定做了。Cloud SDK 确实支持它,他们称之为上下文编辑 (context editing)。我猜 Cloud Code 也在这样做,但我不能完全确定。所以,我应该把这个标记为不确定,但我猜它正在被使用。

我们确切知道的是,一旦达到上下文窗口的 95% 左右,Cloud Code 就会进行摘要 (summarization)。Manis 做了,Deep Agent CLI 也做了,并且这三者都支持子代理 (sub-agents),用于将不同任务隔离到独立的上下文窗口。

Deep Agent CLI 是开源的。欢迎大家贡献代码,在一个可以与许多不同模型一起使用的开源工具链中尝试运用这些想法是很有趣的。

希望这个关于这些原则如何在不同流行的 Agent 工具链中运作,以及它们如何在 Deep Agent CLI 中被使用的概述对大家有所帮助。欢迎提出任何问题或贡献。谢谢。


AI 前线

Runway Gen-4.5 刷屏发布,把重量尘土和光影都做对了,网友:颠覆

2025-12-24 22:33:29

AI 前线

编程助手对软件供应链的威胁

2025-12-24 22:33:33

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索