上下文工程

https://docs.langchain.com/oss/python/deepagents/context-engineering


上下文工程是指以正确的格式提供正确的信息和工具,以便您的深度智能体能够可靠地完成任务。

深度代理可以访问多种类型的上下文信息。有些上下文信息在启动时提供给代理;另一些则在运行时可用,例如用户输入。深度代理包含用于在长时间运行的会话中管理上下文的内置机制。

本页概述了您的深度代理可以访问和管理的各种上下文。

语境类型

上下文类型 你能掌控什么 范围
输入上下文 代理启动时提示信息包含哪些内容(系统提示、内存、技能) 静态,每次运行都应用
运行时上下文 调用时传递的静态配置(用户元数据、API密钥、连接) 每次运行,传播至子代理
上下文压缩 内置卸载和摘要功能,以将上下文信息保留在窗口限制内 当接近极限时,自动启动。
上下文隔离 使用子代理人隔离繁重的工作,只将结果返回给主代理人。 每个子代理人,在委托时
长期记忆 使用虚拟文件系统实现跨线程的持久存储 在对话中始终如一

输入上下文

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

系统提示

您的自定义系统提示符会添加到内置系统提示符之前,其中包含有关规划、文件系统工具和子代理的指导信息。您可以使用它来定义代理的角色、行为和知识:

from deepagents import create_deep_agent

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    system_prompt=(
        "You are a research assistant specializing in scientific literature. "
        "Always cite sources. Use subagents for parallel research on different topics."
    ),
)

system_prompt​参数是静态的,这意味着它不会在每次调用时都改变。在某些情况下,您可能需要动态提示:例如,告知模型“您拥有管理员权限”与“您拥有只读权限”,或者从长期记忆中注入用户偏好,例如“用户偏好简洁的回复” 。如果您的提示依赖于上下文runtime.store​,请使用@dynamic_prompt​ 来构建上下文感知指令。您的中间件可以读取request.runtime.context​和request.runtime.store​。有关添加自定义中间件的信息,请参阅“自定义”部分;有关示例,请参阅LangChain 上下文工程指南。

当工具单独使用上下文或直接接收ToolRuntime对象(包括 ToolRuntime​和 ToolRuntime​)时,不需要中间件。只有当需要将工具与系统提示符的更新一起打包时,才需要添加中间件

要针对特定提供商或型号调整组装的系统提示,请使用线束配置文件base_system_prompt​直接替换基本提示,并附system_prompt_suffix加到其上。

记忆

内存文件(AGENTS.md​)提供持久上下文,该上下文始终加载到系统提示符中。使用内存来存储项目约定、用户偏好以及适用于每次对话的关键准则:

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    memory=["/project/AGENTS.md", "~/.deepagents/preferences.md"],
)

与技能不同,内存始终是一次性注入的,没有逐步披露的过程。应尽量减少内存占用,避免上下文过载;对于详细的工作流程和特定领域的内容,请使用技能。有关配置详情,请参阅“内存”部分

技能

技能提供按需功能。代理SKILL.md在启动时读取每个技能的前置元数据,然后仅在确定技能相关时才加载完整的技能内容。这既减少了令牌的使用,又能提供专门的工作流程:

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    skills=["/skills/research/", "/skills/web-search/"],
)

每个技能都应专注于单一工作流程或领域;过于宽泛或重叠的技能会降低相关性,并在加载时造成上下文臃肿。在技能内部,保持主要内容简洁,并将详细的参考资料移至单独的文件中,这些文件在技能文件中引用。将始终相关的约定记入内存。有关编写和配置,请参阅“技能”部分

工具提示

工具提示是指导模型如何使用工具的指令。所有工具都会在其提示中公开模型可识别的元数据——通常是模式和描述。您通过tools​参数传递的工具会将这些工具元数据(模式和描述)传递给模型。深度代理的内置工具打包在中间件中,通常还会更新系统提示,提​​供更多关于这些工具的指导。​内置工具——中间件添加了框架功能(规划、文件系统、子代理),会自动将特定于工具的指令附加到系统提示符,从而创建工具提示,解释如何有效地使用这些工具:

  • 规划提示——write_todos维护结构化任务清单的说明
  • 文件系统提示符 – 文档ls​,,,,,(以及在使用沙盒后端时) read_filewrite_fileedit_fileglobgrep``execute
  • 子代理提示 – 使用该task工具委派工作的指南
  • 人机交互提示——用于在指定工具调用处暂停(当interrupt_on设置此选项时)
  • 本地上下文提示 – 当前目录和项目信息(仅限 CLI)

您提供的工具​——通过tools​参数传递的工具会将其描述(来自工具架构)发送到模型。您还可以添加自定义中间件,该中间件会添加工具并附加其自身的系统提示说明。对于您提供的工具,请务必提供清晰的名称、描述和论证说明。这些信息将指导模型判断何时以及如何使用该工具。请在描述中说明何时使用该工具,并解释每个论证的作用。

@tool(parse_docstring=True)
def search_orders(
    user_id: str,
    status: str,
    limit: int = 10
) -> str:
    """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.

    Args:
        user_id: Unique identifier for the user
        status: Order status: 'pending', 'shipped', or 'delivered'
        limit: Maximum number of results to return
    """
    # Implementation here
    ...

要覆盖特定提供商或型号的内置工具或用户提供的工具的描述,请使用按工具名称键名的线束配置tool_description_overrides​文件。excluded_tools这会将工具从可见工具集中完全移除。

有关内置功能,请参阅Harness;有关直接传递工具,请参阅 Customization 。

完整的系统提示

深度代理的系统消息(即模型在运行开始时接收到的组装好的系统提示)由以下几个部分组成:

  1. 自定义system_prompt(如有提供)
  2. 基本代理提示
  3. 待办事项清单提示:如何使用待办事项清单进行规划的说明
  4. 内存提示:AGENTS.md​+ 内存使用指南(仅在memory提供时提供)
  5. 技能提示:技能位置 + 技能列表(含前置信息)+ 用法说明(仅当提供技能时)
  6. 虚拟文件系统提示符(如果适用,请提供文件系统 + 执行工具文档)
  7. 子代理提示:任务工具使用情况
  8. 用户提供的中间件提示(如果提供了自定义中间件)
  9. 人机交互提示(当interrupt_on设置时)

运行时上下文

运行时上下文是每次运行的配置,您在调用代理时传递该配置。它不会自动包含在模型提示中;只有当工具、中间件或其他逻辑读取它并将其添加到消息或系统提示中时,模型才能看到它。运行时上下文可用于用户元数据(ID、首选项、角色)、API 密钥、数据库连接、功能标志或您的工具和组件所需的其他值。

使用 context_schema​ 定义数据的形状:use a dataclasses.dataclass​ or typing.TypedDict​ class。将值作为context​的参数传递给invoke​/ainvoke​。有关完整详细信息,请参阅运行时LangGraph 运行时上下文。

在工具内部,从注入的ToolRuntime读取上下文:

from dataclasses import dataclass

from deepagents import create_deep_agent
from langchain.tools import tool, ToolRuntime

@dataclass
class Context:
    user_id: str
    api_key: str

@tool
def fetch_user_data(query: str, runtime: ToolRuntime[Context]) -> str:
    """Fetch data for the current user."""
    user_id = runtime.context.user_id
    return f"Data for user {user_id}: {query}"

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    tools=[fetch_user_data],
    context_schema=Context,
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "Get my recent activity"}]},
    context=Context(user_id="user-123", api_key="sk-..."),
)

运行时上下文​会传播到所有子代理​。当子代理运行时,它会接收到与父代理相同的运行时上下文。有关每个子代理的上下文(命名空间键),请参阅“子代理”部分。

上下文压缩

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

卸载

深度代理使用内置的文件系统工具自动卸载内容,并根据需要搜索和检索已卸载的内容。当工具调用输入或结果超过令牌阈值(默认为 20,000)时,就会发生内容卸载:

  1. 工具调用输入超过 20,000 个标记:文件写入和编辑操作会在代理的会话历史记录中留下包含完整文件内容的工具调用。由于这些内容已经持久化到文件系统中,因此通常是冗余的。当会话上下文超过模型可用窗口的 85% 时,深度代理会截断较旧的工具调用,将其替换为指向磁盘上文件的指针,从而减小活动上下文的大小。
    image

    <TRUNCATED>​ 的意思是“被截断/被裁剪了”。输入没有真正消失,而是被“偷梁换柱”了。 完整的 500 多行代码被系统从大模型的 Session 历史记录(内存上下文)中删掉了,替换成了类似 [内容已截断,请参考本地文件 /my-file] 的简短占位符。

  2. 工具调用结果超过 20,000 个令牌:发生这种情况时,深度代理会将响应卸载到配置的后端,并将其替换为文件路径引用和前 10 行的预览。然后,代理可以根据需要重新读取或搜索内容。

    image

总结

当上下文大小超过模型的上下文窗口限制(例如 85% max_input_tokens),并且没有更多上下文可以卸载时,深度代理会总结消息历史记录。这个过程包含两个部分:

  • 上下文摘要:LLM 生成对话的结构化摘要,包括会话意图、创建的工件和后续步骤——该摘要取代了代理工作记忆中的完整对话历史记录。
  • 文件系统保存:完整的原始对话消息作为规范记录写入文件系统。

这种双重方法确保代理能够了解其目标和进度(通过摘要),同时保留在需要时恢复特定细节的能力(通过文件系统搜索)。

image

配置:

  • max_input_tokens​触发条件为模型特征的 85%。
  • 保留 10% 的代币作为近期上下文
  • 如果模型配置文件不可用,则回退到 170,000 个令牌触发器 / 保留 6 条消息。
  • 如果任何模型调用引发标准的ContextOverflowError异常,深度代理会立即回退到摘要模式,并使用摘要和最近保留的消息重试。
  • 模型会对较早的消息进行总结。
摘要工具

深度智能体包含一个可选的摘要工具,使智能体能够在合适的时机(例如任务之间)触发摘要,而不是在固定的标记间隔触发摘要。您可以通过将此工具添加到中间件列表来启用它:

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.5-flash"
agent = create_deep_agent(
    model=model,
    middleware=[
        create_summarization_tool_middleware(model, backend),
    ],
)

启用此功能不会禁用模型上下文限制达到 85% 时的默认摘要操作。SummarizationToolMiddleware详情请参阅API 参考文档。

利用子代理进行上下文隔离

子代理解决了​上下文膨胀问题。当主代理使用输出量大的工具(例如网页搜索、文件读取、数据库查询)时,上下文窗口会迅速被填满。子代理将这项工作隔离出来——主代理只接收最终结果,而不是生成该结果的数十个工具调用。您还可以将每个子代理与主代理分开配置(例如,模型、工具、系统提示和技能)。

工作原理:

  • 主代理人拥有task委派工作的工具
  • 子代理在其自身的全新上下文中运行
  • 子代理自主执行直至完成
  • 子代理人向总代理人提交一份最终报告。
  • 主代理人的背景信息保持清晰

最佳实践:

  1. 委派复杂任务:使用子代理处理多步骤工作,以免主代理的上下文变得混乱。

  2. 保持子代理响应简洁:指示子代理返回摘要,而不是原始数据:

    research_subagent = {
        "name": "researcher",
        "description": "Conducts research on a topic",
        "system_prompt": """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": [web_search],
    }
    
  3. 使用文件系统处理大数据:子代理可以将结果写入文件;主代理读取所需内容。

有关运行时上下文传播和每个子代理命名空间的配置和上下文管理,请参阅子代理。

长期记忆

使用默认文件系统时,深度代理会将工作内存文件存储在代理状态中,而代理状态仅在单个线程中有效。长期内存使深度代理能够跨线程和会话持久保存信息。深度代理可以使用长期内存来存储用户偏好、累积知识、研究进度或任何需要在单个会话之外持久保存的信息。

要使用长期内存,您必须使用一个CompositeBackend​将特定路径(通常是 /etc/local/bin​)路由/memories/​到 LangGraph 存储的路由机制,该机制提供持久的跨线程持久性。LangGraph 存储CompositeBackend是一种混合存储系统,其中一些文件会无限期地持久保存,而另一些文件则仅限于单个线程。

from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore

def make_backend(runtime):
    return CompositeBackend(
        default=StateBackend(runtime),
        routes={"/memories/": StoreBackend(runtime)},
    )

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    store=InMemoryStore(),
    backend=make_backend,
    system_prompt="""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_file​, edit_file​)按需创建文件。要在 LangSmith 上部署,请使用Store API预先配置内存。有关设置和使用案例,请参阅“长期内存”部分。

最佳实践

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

相关资源