资料馆/上下文工程
LangChain阅读档案 · 非官方中文译文

在多 Agent 运行框架中组织上下文Organizing Context in a Multi-Agent Harness

本站收录 本站更新
完整译文与原文逐段对应。图片、图注、表格和代码保留原文。A complete reading edition. Figures, captions, tables and code are preserved from the source.
中文译文ENGLISH ORIGINAL

摘要

TL;DR

大多数运行框架都支持子 Agent 功能,让主管 Agent 能够派生新任务。子 Agent 提供并行推理和上下文隔离能力,使主管 Agent 可以委派工作,同时避免污染自己的上下文窗口。

Most harnesses support a subagents feature to spawn new tasks from a supervisor agent. Subagents enable parallel reasoning and context isolation, allowing a supervisor agent to delegate work without polluting the context window.

主管 Agent 指定任务,而子 Agent 通常在一个全新的上下文窗口中完成任务。这可能造成浪费:子 Agent 可能重复执行主管 Agent 已经做过的上下文收集操作,例如读取文件。

Supervisor agents specify the task, and subagents typically complete the task in a fresh context window. This can lead to waste: subagents may redo context-gathering operations, like file reads, already done by the supervisor.

对于能够从主管 Agent 的上下文中受益的子 Agent,我们构建了分叉子 Agent。它们会继承主管 Agent 的完整对话,而不是从头开始。由于复用主管 Agent 的对话可以利用提示词缓存,并减少重复工作,分叉模式可能比隔离子 Agent 更快、成本更低。

For cases where subagents can benefit from the supervisor agent’s context, we built forked subagents. Forked subagents inherit the supervisor’s full conversation instead of starting fresh. Forking can be faster and cheaper than isolated subagents, since reusing the supervisor’s conversation takes advantage of prompt caching and reduces repeated work.

支持子 Agent 的运行框架

Harnesses with subagents

将任务委派给子 Agent,是 Agent 管理自身上下文的一种有效方式。子 Agent 提供上下文隔离,让各项任务的细节可以不进入主管 Agent 的上下文窗口。如果你想了解更多,我们已经详细撰文介绍过不同的多 Agent 架构!

Delegating tasks to subagents is one effective way that an agent can manage its own context. Subagents provide context isolation, so that the details of individual tasks can be withheld from a supervisor agent’s context window. If you’re curious to learn more, we’ve written at length about different multi-agent architectures!

主管模式是适用范围最广的模式之一,大多数编程运行框架都采用了它。在这种模式下,主管 Agent 维护计划,并将工作委派给专门的子 Agent。例如:

The supervisor is one of the most generalizable patterns, and most coding harnesses have adopted it. Here, a supervisor maintains a plan and delegates work to specialized subagents. For example,

  • 执行者:完成某项范围明确的实现工作。
  • 审查者:对已完成的工作作出独立判断。
  • Workers: addressing some well-scoped implementation.
  • Reviewers: independent judgment on work already done.

主管 Agent 通常只接收子 Agent 返回的任务结果;子 Agent 的中间推理过程不会进入主管 Agent 的上下文窗口。然而,子 Agent 应从主管 Agent 那里接收哪些上下文,取决于子 Agent 的用途。

The supervisor agent typically receives just the outcome of a task from the subagents; their intermediate reasoning is withheld from its context window. However, what context subagents should receive from the supervisor is dependent on what the subagent is used for.

子 Agent 的上下文模式

Context modes for subagents

为便于明确指定这一点,我们在最新版 deepagents 中引入了上下文模式。上下文模式指定子 Agent 可以从主管 Agent 那里接收哪些上下文。支持的取值为 "isolated" 和 "fork"。

To help specify this, we introduced context modes in the latest version of deepagents. Context modes specify what context subagents can receive from the supervisor. Supported values are "isolated" and "fork".

隔离子 Agent

Isolated subagents

这是 Deep Agents 中子 Agent 原有的默认行为。子 Agent 启动时拥有一个全新的上下文窗口,只接收主管 Agent 指定的任务描述。

This is the default and pre-existing behavior for subagents in Deep Agents. Subagents spawn with a fresh context window, receiving only the task description specified by the supervisor.

分叉子 Agent

Forked subagents

设置 "mode": "fork" 后,主管 Agent 的当前状态会传递给子 Agent,而不是让子 Agent 从空状态启动。这实际上是当前对话线程的一条分叉延续,并附加一条由主管 Agent 编写的指令;最终,分叉中的工作会收束为一个工具结果,供主管 Agent 读取。

Set "mode": "fork" and the supervisor’s current state propagates to the subagents instead of starting it empty. This is effectively a forked continuation of the current thread— with an added directive written by the supervisor— that is finally unwound into a single tool result read by the supervisor.

具体而言:

Specifically:

  • 主管 Agent 生成一次工具调用,携带任务描述来调用子 Agent。
  • 子 Agent 接收主管 Agent 的全部状态,包括对话历史。末尾的工具调用会被移除,其中的任务描述会与一段用于说明子 Agent 角色的固定前置说明一起,格式化为一条用户消息。
  • 子 Agent 完成后,主管 Agent 会收到它的最终消息,作为最初那次工具调用的响应。
  • Supervisor agents generate a tool call invoking the subagent with a task description.
  • The subagent receives the entire supervisor agent’s state, including conversation history. The trailing tool call is excised, and its task description is formatted into a user message alongside a fixed preamble clarifying its role.
  • When the subagent finishes, the supervisor receives its final message as a response to the originating tool call.

虽然分叉子 Agent 的初始上下文比隔离子 Agent 更多,但其设计保留了利用提示词缓存的能力。当子 Agent 需要详细上下文才能正确完成任务时,分叉可以省去重复的工具调用和上下文收集。

Although forked subagents are seeded with more context than isolated subagents, prompt caching is respected by design. In cases where subagents require detailed context to correctly perform their tasks, forking can save repeated tool calls and context-gathering.

选择上下文模式

Choosing a context mode

应当选择哪种上下文模式,取决于子 Agent 与这项工作的关系。可以借助两种常见模式来理解:执行者继续主管 Agent 的工作,而验证者则独立评估这项工作。

The right choice of context mode depends on the subagent’s relationship to the work. A useful way to think about them is with two common patterns: workers that continue the supervisor’s work, and verifiers that evaluate it independently.

执行 Agent:继续已经开展的工作

Worker Agent: continue work already in progress

主管 Agent 已经收集上下文或作出决策后,执行 Agent 会接手其中一部分工作。例如,主管 Agent 可能先检查一个错误,将其追踪到某个具体函数,再将修复的实现和测试委派出去。

如果让执行 Agent 在隔离模式下启动,它就不得不重新搜集相关证据。使用 fork 时,它会收到主管 Agent 的历史记录,可以从调查暂停的地方继续。主管 Agent 在有工作需要完成、但未必关心执行者得出结论的中间步骤时,会调用这类 Agent。

A worker carries out a piece of work after the supervisor has already gathered context or made a decision. For example, the supervisor might inspect an error, trace it to a particular function, and then delegate the implementation and testing of a fix.

Starting the worker in isolation would force it to rediscover its evidence. With fork, it receives the supervisor’s history and can pick up where the investigation left off. A supervisor calls this when some work needs to be done, but doesn’t necessarily care about the intermediate steps it takes to arrive to a conclusion.

const fixerSubagent: SubAgent = {
  mode: "fork",
  name: "fixer",
  description:
    "Use when a problem has already been diagnosed and the remaining work is to implement and test the fix",
  systemPrompt: "...",
}

主管 Agent 可能这样分配任务:

The supervisor might invoke it with a task like:

根据我们已发现的超时问题更新重试逻辑,然后添加一项回归测试。
Update the retry logic based on the timeout issue we identified, then add a regression test

验证 Agent:独立评估工作

Verifier agent: independently evaluate work

验证 Agent 根据某些标准审查另一个 Agent 的工作,例如检查代码差异的正确性、向后兼容性和测试覆盖情况。

A verifier reviews another agent’s work against some criteria- for example, checking a diff for correctness, backwards compatibility, and test coverage.

在这种情况下,继承主管 Agent 的推理可能适得其反。验证 Agent 应当评估工作本身,而不是受主管 Agent 的诊断或预期所锚定。isolated 模式只向它提供任务和相关审查材料,不包含此前的对话。

In this case, inheriting the supervisor’s reasoning can be counterproductive. The verifier should evaluate the work itself rather than being anchored by the supervisor’s diagnosis or expectations. isolated mode gives it the task and relevant review materials without the preceding conversation.

const reviewerSubagent: SubAgent = {
  mode: "isolated",
  name: "reviewer",
  description:
    "Use after an implementation is complete and needs an independent review",
  systemPrompt: "...",
}

主管 Agent 可能这样调用它:

The supervisor might invoke it with:

审查这份代码差异,检查其完整性、向后兼容性,以及测试覆盖是否充分。
Review this diff for completeness, backwards compatibility, and adequate test coverage.

我们此前介绍过 RubricMiddleware,这也是使用独立验证者的一个例子!

We’ve previously written about RubricMiddleware which is another instance of using an independent verifier!

让子 Agent 专门化

Specializing subagents

除了工具和中间件等手段,上下文模式也是让子 Agent 针对某项任务实现专门化的一种调节手段。以下是几种我们认为具有专门用途的子 Agent,以及它们与上下文模式的关系:

Alongside things like tools and middleware, context modes are one of the levers you can use to specialize subagents to a task. Here's a few subagents we consider specialized and their relationship to context modes:

研究 Agent:调查问题

Researcher agent: investigate a question

研究 Agent 调查一个问题,并向主管 Agent 返回精炼的答案。例如,主管 Agent 可能将关于某个陌生库、某个竞争对手,或某项技术决策历史的不同问题分别委派出去。

A researcher investigates a question and returns a condensed answer to the supervisor. For example, a supervisor might delegate separate questions about an unfamiliar library, a competitor, or the history of a technical decision.

当问题本身独立成立时,研究 Agent 不需要主管 Agent 的对话。使用 isolated 可以让它的上下文专注于当前问题。在多个研究 Agent 并行运行时,这尤其有用:如果让每个研究 Agent 都采用分叉模式,就会重复携带主管 Agent 的历史记录,但它们其实各自只需要被分配到的问题。

When the question can stand on its own, the researcher does not need the supervisor’s conversation. Using isolated keeps its context focused on the question at hand. This is especially useful when several researchers run in parallel: forking each one would duplicate the supervisor’s history even though each researcher only needs its assigned question.

const researcherSubagent: SubAgent = {
  mode: 'isolated',
  name: 'researcher',
  description:
    'Use to investigate a self-contained question and return a condensed, well-sourced answer',
  tools: [search_engine],
};

主管 Agent 可能这样调用它:

The supervisor might invoke it with:

确定 API 在 1.2 和 1.3 版本之间是否发生了变化,并提供相关发行说明的链接。
Determine whether the API changed between versions 1.2 and 1.3, and link to the relevant release notes.

我们可以为子 Agent 配置独立的能力(例如一个 search_engine 工具),帮助它完成任务。

We can give the subagent its own capabilities (like a search_engine tool) to help it complete its task.

记忆 Agent:保留对话中的信息

Memory agent: retain information from the conversation

记忆 Agent 从一次交互中识别出日后应该能够获取的信息,例如用户偏好、架构决策,或对话中确立的约束。

A memory agent identifies information from an interaction that should be available later- for example, a user preference, an architectural decision, or a constraint established during the conversation.

这里,对话本身就是 Agent 需要分析的材料。使用 fork 时,记忆 Agent 会收到完整交互,可以自行判断哪些内容值得保存,无需主管 Agent 在任务中重新叙述。

Here, the conversation is the material the agent needs to analyze. With fork, the memory agent receives the full interaction and can decide what is worth preserving without requiring the supervisor to restate it in the task.

const memorizerSubagent: SubAgent = {
  mode: "fork",
  name: "memorizer",
  description:
    "Use when the conversation contains durable decisions, facts, or preferences worth saving to memory",
  permissions: [
    {
      operations: ["write"],
      paths: ["/**"],
      mode: "deny",
    },
    {
      operations: ["read"],
      paths: ["/AGENTS.md", "/docs/**"],
      mode: "allow",
    },
  ],
};

主管 Agent 可能这样调用它:

The supervisor might invoke it with:

记住本次对话中确立的决策和偏好。
Memorize the decisions and preferences established in this conversation.

由于我们希望精确限制记忆 Agent 能够编辑的内容,可以通过限制它工作时可编辑的文件范围,让这个子 Agent 更适合其专门用途。

Because we want to limit exactly what the memorizer agent can edit, we can specialize the subagent by setting restrictions on what files it can edit while it works.

试用

Try It

deepagents 是我们正在构建的一个框架,凝聚了我们与数千个交付 Agent 的不同团队合作所得的经验。安装后,你就可以试用子 Agent 的上下文模式(文档见这里)以及更多功能:

deepagents is a framework we’re building that takes our lessons learned from working with thousands of different teams shipping agents. You can try subagent context modes (see the docs here), and much more by installing:

# Python
uv add deepagents
# Typescript
pnpm i deepagents

欢迎通过 GitHub issues、论坛,或 X / LinkedIn 告诉我们你的想法!

Let us know what you think via GitHub issues, the forum, or on X / LinkedIn!

— 全文完 —

原文来自 LangChain,中文为非官方学习译文。
查看原始出处 ↗

点击空白处或按 Esc 关闭