Skip to main content
上下文工程是指以正确的格式提供正确的信息和工具,使您的深度代理能够可靠地完成任务。 深度代理可以访问多种类型的上下文。 有些来源在启动时提供给代理;其他来源在运行时变得可用,例如用户输入。 深度代理包含用于在长时间运行的会话中管理上下文的内置机制。 本页概述了您的深度代理可以访问和管理的不同类型的上下文。
刚接触上下文工程?请参阅概念概述,了解不同类型的上下文及其使用时机。

上下文类型

上下文类型您控制的内容范围
输入上下文启动时代理提示词中包含的内容(系统提示词、记忆、技能)静态,每次运行时应用
运行时上下文调用时传递的静态配置(用户元数据、API 密钥、连接)每次运行,传播到子代理
上下文压缩内置的卸载和摘要功能,以保持上下文在窗口限制内自动,当接近限制时
上下文隔离使用子代理隔离繁重的工作,仅将结果返回给主代理每个子代理,当委派任务时
长期记忆使用虚拟文件系统跨线程持久存储跨对话持久化

输入上下文

输入上下文是在启动时提供给您的深度代理的信息,它成为其系统提示词的一部分。最终的提示词由几个来源组成:

系统提示词

您提供的自定义指令加上内置的代理指导。

记忆

配置后始终加载的持久化 AGENTS.md 文件。

技能

相关时按需加载的功能(渐进式披露)。

工具提示词

使用内置工具或自定义工具的说明。

系统提示词

您的自定义系统提示词会前置到内置系统提示词之前,后者包含用于规划、文件系统工具和子代理的指导。使用它来定义代理的角色、行为和知识:
import { createDeepAgent } from "deepagents";

const agent = await createDeepAgent({
  model: "google_genai:gemini-3.1-pro-preview",
  systemPrompt: `You are a research assistant specializing in scientific literature.
  Always cite sources. Use subagents for parallel research on different topics.`,
});
systemPrompt 参数是静态的,这意味着它不会随每次调用而改变。 对于某些用例,您可能需要动态提示词:例如,告诉模型“您拥有管理员权限”与“您拥有只读权限”,或者从长期记忆中注入用户偏好,如“用户偏好简洁回复”。 如果您的提示词依赖于上下文或 runtime.store,请使用 dynamicSystemPromptMiddleware 来构建上下文感知的指令。 您的中间件可以读取 request.runtime.contextrequest.runtime.store。 有关添加自定义中间件的详细信息,请参阅自定义,有关示例,请参阅 LangChain 上下文工程指南。 当仅工具使用上下文或 runtime.store 时,您不需要中间件;工具直接接收 runtime 对象(包括 runtime.contextruntime.store)。仅当系统提示词本身必须随请求变化时才添加中间件。
要为特定提供商或模型调整组装后的系统提示词,请使用测试配置文件base_system_prompt 完全替换基础提示词,system_prompt_suffix 则追加到其后。

记忆

记忆文件(AGENTS.md)提供始终加载到系统提示词中的持久化上下文。将记忆用于项目约定、用户偏好和应适用于每次对话的关键准则:
const agent = await createDeepAgent({
  model: "google_genai:gemini-3.1-pro-preview",
  memory: ["/project/AGENTS.md", "~/.deepagents/preferences.md"],
});
与技能不同,记忆总是被注入——没有渐进式披露。保持记忆最小化以避免上下文过载;使用技能来处理详细的工作流程和特定领域的内容。有关配置详情,请参阅记忆

技能

技能提供按需功能。代理在启动时读取每个 SKILL.md 的 frontmatter,然后仅在确定技能相关时才加载完整的技能内容。这减少了令牌使用量,同时仍然提供专门的工作流程:
const agent = await createDeepAgent({
  model: "google_genai:gemini-3.1-pro-preview",
  skills: ["/skills/research/", "/skills/web-search/"],
});
保持每个技能专注于单一工作流程或领域;广泛或重叠的技能会稀释相关性,并在加载时使上下文膨胀。在技能内部,保持主要内容简洁,并将详细的参考资料移至单独的文件中,并在技能文件中引用。将始终相关的约定放在记忆中。有关创作和配置,请参阅技能

工具提示词

工具提示词是指导模型如何使用工具的说明。所有工具都暴露模型在其提示词中看到的元数据——通常是一个模式和一个描述。您通过 tools 参数传递的工具会将该工具元数据(模式和描述)呈现给模型。深度代理的内置工具打包在中间件中,通常也会更新系统提示词,为这些工具提供更多指导。 内置工具 – 添加测试功能(规划、文件系统、子代理)的中间件会自动将特定于工具的说明追加到系统提示词中,创建解释如何有效使用这些工具的工具提示词:
  • 规划提示词 – 用于 write_todos 以维护结构化任务列表的说明
  • 文件系统提示词 – lsread_filewrite_fileedit_fileglobgrep(以及使用沙箱后端时的 execute)的文档
  • 子代理提示词 – 使用 task 工具委派工作的指导
  • 人在回路提示词 – 在指定工具调用处暂停的用法(当设置了 interrupt_on 时)
  • 本地上下文提示词 – 当前目录和项目信息(仅限 CLI)
您提供的工具 – 通过 tools 参数传递的工具,其描述(来自工具模式)会发送给模型。您还可以添加自定义中间件,该中间件添加工具并追加其自己的系统提示词说明。 对于您提供的工具,请确保提供清晰的名称、描述和参数描述。这些指导模型关于何时以及如何使用该工具的推理。在描述中包含何时使用该工具,并描述每个参数的作用。
const searchOrders = tool(
  async ({ userId, status, limit }) => { /* ... */ },
  {
    name: "search_orders",
    description: `Search for user orders by status.

Use this when the user asks about order history or wants to check
order status. Always filter by the provided status.`,
    schema: z.object({
      userId: z.string().describe("Unique identifier for the user"),
      status: z.enum(["pending", "shipped", "delivered"]).describe("Order status to filter by"),
      limit: z.number().default(10).describe("Maximum number of results to return"),
    }),
  }
);
要为特定提供商或模型覆盖内置或用户提供的工具的描述,请使用测试配置文件tool_description_overrides,按工具名称键控。excluded_tools 会将工具完全从可见工具集中移除。
有关内置功能,请参阅测试,有关直接传递工具,请参阅自定义

完整的系统提示词

深度代理的系统消息——模型在运行开始时接收的组装系统提示词——由以下部分组成:
  1. 自定义 system_prompt(如果提供)
  2. 基础代理提示词
  3. 待办事项列表提示词:如何使用待办事项列表进行规划的说明
  4. 记忆提示词:AGENTS.md + 记忆使用指南(仅在提供 memory 时)
  5. 技能提示词:技能位置 + 带有 frontmatter 信息的技能列表 + 用法(仅在提供技能时)
  6. 虚拟文件系统提示词(文件系统 + 执行工具文档,如果适用)
  7. 子代理提示词:任务工具用法
  8. 用户提供的中间件提示词(如果提供自定义中间件)
  9. 人在回路提示词(当设置了 interrupt_on 时)

运行时上下文

运行时上下文是您在调用代理时传递的每次运行配置。它不会自动包含在模型提示词中;模型只有在工具、中间件或其他逻辑读取它并将其添加到消息或系统提示词中时才会看到它。将运行时上下文用于用户元数据(ID、偏好、角色)、API 密钥、数据库连接、功能标志或您的工具和测试所需的其他值。 使用 contextSchema 定义该数据的形状,通常是一个 Zod 对象模式(例如 z.object({ ... }))。在传递给 invoke / ainvoke 的选项对象的 context 字段中传递运行时值。有关完整详情,请参阅运行时LangGraph 运行时上下文 在工具内部,从作为工具处理程序的 runtime 参数提供的 ToolRuntime 实例中读取 runtime.context
import { createDeepAgent } from "deepagents";
import { tool } from "langchain";
import type { ToolRuntime } from "@langchain/core/tools";
import { z } from "zod";

const contextSchema = z.object({
  userId: z.string(),
  apiKey: z.string(),
});

const fetchUserData = tool(
  async (input, runtime: ToolRuntime<unknown, typeof contextSchema>) => {
    const userId = runtime.context?.userId;
    return `Data for user ${userId}: ${input.query}`;
  },
  {
    name: "fetch_user_data",
    description: "Fetch data for the current user",
    schema: z.object({ query: z.string() }),
  }
);

const agent = await createDeepAgent({
  model: "google_genai:gemini-3.1-pro-preview",
  tools: [fetchUserData],
  contextSchema,
});

const result = await agent.invoke(
  { messages: [{ role: "user", content: "Get my recent activity" }] },
  { context: { userId: "user-123", apiKey: "sk-..." } },
);
运行时上下文传播到所有子代理。当子代理运行时,它接收与父代理相同的运行时上下文。有关每个子代理的上下文(命名空间键),请参阅子代理

上下文压缩

长时间运行的任务会产生大量的工具输出和冗长的对话历史。 上下文压缩减少了代理工作记忆中的信息大小,同时保留与任务相关的细节。 以下技术是确保传递给 LLM 的上下文保持在其上下文窗口限制内的内置机制:

卸载

大型工具输入和结果存储在文件系统中,并用引用替换。

摘要

当接近限制时,旧消息被压缩为 LLM 生成的摘要。

卸载

深度代理使用内置文件系统工具自动卸载内容,并根据需要搜索和检索该卸载的内容。 当工具调用输入或结果超过令牌阈值(默认 20,000)时,会发生内容卸载:
  1. 工具调用输入超过 20,000 个令牌:文件写入和编辑操作会在代理的对话历史中留下包含完整文件内容的工具调用。 由于此内容已持久化到文件系统,因此通常是冗余的。 当会话上下文超过模型可用窗口的 85% 时,深度代理会截断较旧的工具调用,用指向磁盘上文件的指针替换它们,从而减少活动上下文的大小。 卸载示例,显示一个大输入被保存到磁盘,截断版本用于工具调用
  2. 工具调用结果超过 20,000 个令牌:当发生这种情况时,深度代理会将响应卸载到配置的后端,并用文件路径引用和前 10 行的预览替换它。然后代理可以根据需要重新读取或搜索内容。 卸载示例,显示一个大的工具响应被替换为关于卸载结果位置的消息以及结果的前 10 行

摘要

当前的摘要行为(通过 wrapModelCall 进行模型内摘要、准确的令牌计数和自动 ContextOverflowError 回退)需要 deepagents>=1.6.0
当上下文大小超过模型的上下文窗口限制(例如 max_input_tokens 的 85%),并且没有更多上下文有资格卸载时,深度代理会总结消息历史记录。 此过程有两个组成部分:
  • 上下文内摘要:LLM 生成对话的结构化摘要,包括会话意图、创建的工件和下一步操作——这将替换代理工作记忆中的完整对话历史。
  • 文件系统保留:完整的原始对话消息作为规范记录写入文件系统。
这种双重方法确保代理通过摘要保持对其目标和进度的感知,同时保留需要时恢复特定细节的能力(通过文件系统搜索)。 摘要示例,显示代理的对话历史,其中几个步骤被压缩 配置:
  • 在模型的 max_input_tokens 达到其模型配置文件的 85% 时触发
  • 保留 10% 的令牌作为最近的上下文
  • 如果模型配置文件不可用,则回退到 170,000 个令牌触发 / 保留 6 条消息
  • 如果任何模型调用引发标准 ContextOverflowError,深度代理会立即回退到摘要,并使用摘要 + 最近保留的消息重试
  • 较旧的消息由模型总结
来自代理的流式令牌通常包括摘要步骤生成的令牌。您可以使用其关联的元数据过滤这些令牌:
for await (const [namespace, chunk] of await agent.stream(
  { messages: [...] },
  { streamMode: "messages" },
)) {
  const [message, metadata] = chunk;
  if (metadata?.lcSource === "summarization") {
    continue;
  } else {
    ...
  }
}
摘要工具中间件需要 deepagents>=1.6.0
深度代理包含一个可选的工具用于摘要,使代理能够在适当时机(例如任务之间)触发摘要,而不是在固定的令牌间隔触发。 您可以通过将其追加到中间件列表来启用此工具:
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
from deepagents.middleware.summarization import (
    create_summarization_tool_middleware,
)

backend = StateBackend  # if using default backend

model = "google_genai:gemini-3.1-pro-preview"
agent = create_deep_agent(
    model=model,
    middleware=[
        create_summarization_tool_middleware(model, backend),
    ],
)
启用此功能不会禁用在模型上下文限制达到 85% 时的默认摘要操作。 有关详情,请参阅 SummarizationToolMiddleware API 参考。

通过子代理进行上下文隔离

子代理解决了上下文膨胀问题。当主代理使用具有大输出的工具(网络搜索、文件读取、数据库查询)时,上下文窗口会很快填满。子代理隔离这项工作——主代理只接收最终结果,而不是产生它的数十个工具调用。您还可以为每个子代理单独配置(例如,模型、工具、系统提示词和技能)。 工作原理:
  • 主代理有一个 task 工具来委派工作
  • 子代理在自己的全新上下文中运行
  • 子代理自主执行直到完成
  • 子代理向主代理返回单个最终报告
  • 主代理的上下文保持干净
最佳实践:
  1. 委派复杂任务:使用子代理处理会扰乱主代理上下文的多步骤工作。
  2. 保持子代理响应简洁:指示子代理返回摘要,而不是原始数据:
    const researchSubagent = {
    name: "researcher",
    description: "Conducts research on a topic",
    systemPrompt: `You are a research assistant.
    IMPORTANT: Return only the essential summary (under 500 words).
    Do NOT include raw search results or detailed tool outputs.`,
    tools: [webSearch],
    };
    
  3. 对大数据使用文件系统:子代理可以将结果写入文件;主代理读取其所需的内容。
有关配置,请参阅子代理,有关运行时上下文传播和每个子代理的命名空间,请参阅上下文管理

长期记忆

使用默认文件系统时,您的深度代理将其工作记忆文件存储在代理状态中,该状态仅在单个线程内持久化。 长期记忆使您的深度代理能够跨不同线程和对话持久化信息。 深度代理可以使用长期记忆来存储用户偏好、积累的知识、研究进度或任何应超出单个会话持久化的信息。 要使用长期记忆,您必须使用 CompositeBackend,它将特定路径(通常是 /memories/)路由到 LangGraph Store,该存储提供持久的跨线程持久化。 CompositeBackend 是一个混合存储系统,其中一些文件无限期持久化,而其他文件则限定在单个线程范围内。
import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph-checkpoint";

const agent = await createDeepAgent({
  model: "google_genai:gemini-3.1-pro-preview",
  store: new InMemoryStore(),
  backend: new CompositeBackend(
    new StateBackend(),
    { "/memories/": new StoreBackend() },
  ),
  systemPrompt: `When users tell you their preferences, save them to /memories/user_preferences.txt so you remember them in future conversations.`,
});
您不需要预先填充 /memories/ 文件。 您提供后端配置、存储和系统提示词说明,告诉代理保存什么以及保存在哪里。 例如,您可以提示代理将偏好存储在 /memories/preferences.txt 中。 路径开始时为空,当用户分享值得记住的信息时,代理会按需使用其文件系统工具(write_fileedit_file)创建文件。 要在 LangSmith 上部署时预置记忆,请使用 Store API。 有关设置和用例,请参阅长期记忆

最佳实践

  1. 从正确的输入上下文开始 – 保持记忆最小化以包含始终相关的约定;使用专注于任务特定功能的技能。
  2. 利用子代理处理繁重工作 – 将多步骤、输出量大的任务委派出去,以保持主代理的上下文干净。
  3. 在配置中调整子代理输出 – 如果您在调试时注意到子代理生成了长输出,可以向子代理的 system_prompt 添加指导,以创建摘要和综合发现。
  4. 使用文件系统 – 将大输出持久化到文件中(例如子代理写入或自动卸载),以保持活动上下文较小;模型可以在需要细节时使用 read_filegrep 拉取片段。
  5. 记录长期记忆结构 – 告诉代理 /memories/ 中有什么以及如何使用它。
  6. 为工具传递运行时上下文 – 使用 context 传递用户元数据、API 密钥和其他工具所需的静态配置。

相关资源