跳到内容

上下文

上下文工程(Context engineering)是构建动态系统的实践,它以正确的格式提供正确的信息和工具,以便 AI 应用程序能够完成任务。上下文可以从两个关键维度进行描述:

  1. 可变性
    • 静态上下文:在执行期间不会改变的不可变数据(例如,用户元数据、数据库连接、工具)。
    • 动态上下文:随着应用程序运行而演变的可变数据(例如,对话历史、中间结果、工具调用观察)。
  2. 生命周期
    • 运行时上下文:作用域限定于单次运行或调用的数据。
    • 跨对话上下文:跨多个对话或会话持久化的数据。

运行时上下文 vs LLM 上下文

运行时上下文指的是本地上下文:您的代码运行所需的数据和依赖项。它指:

  • LLM 上下文,即传递给 LLM 提示的数据。
  • “上下文窗口”,即可以传递给 LLM 的最大令牌数。

运行时上下文可用于优化 LLM 上下文。例如,您可以使用运行时上下文中的用户元数据来获取用户偏好,并将其输入到上下文窗口中。

LangGraph 提供了三种管理上下文的方式,结合了可变性和生命周期两个维度:

上下文类型 描述 可变性 生命周期 访问方法
静态运行时上下文 启动时传递的用户元数据、工具、数据库连接 静态 单次运行 invoke/streamcontext 参数
动态运行时上下文(状态) 在单次运行期间演变的可变数据 动态 单次运行 LangGraph 状态对象
动态跨对话上下文(存储) 跨对话共享的持久数据 动态 跨对话 LangGraph 存储

静态运行时上下文

静态运行时上下文表示不可变的数据,如用户元数据、工具和数据库连接,这些数据在运行开始时通过 invoke/streamcontext 参数传递给应用程序。这些数据在执行期间不会改变。

LangGraph v0.6 新特性:context 取代 config['configurable']

运行时上下文现在通过 invoke/streamcontext 参数传递,这取代了之前将应用程序配置传递给 config['configurable'] 的模式。

@dataclass
class ContextSchema:
    user_name: str

graph.invoke( # (1)!
    {"messages": [{"role": "user", "content": "hi!"}]}, # (2)!
    context={"user_name": "John Smith"} # (3)!
)
  1. 这是对 Agent 或图的调用。invoke 方法使用提供的输入来运行底层的图。
  2. 此示例使用消息作为输入,这很常见,但您的应用程序可能会使用不同的输入结构。
  3. 这里是您传递运行时数据的地方。context 参数允许您提供 Agent 在执行期间可以使用的额外依赖项。
from langchain_core.messages import AnyMessage
from langgraph.runtime import get_runtime
from langgraph.prebuilt.chat_agent_executor import AgentState
from langgraph.prebuilt import create_react_agent

def prompt(state: AgentState) -> list[AnyMessage]:
    runtime = get_runtime(ContextSchema)
    system_msg = f"You are a helpful assistant. Address the user as {runtime.context.user_name}."
    return [{"role": "system", "content": system_msg}] + state["messages"]

agent = create_react_agent(
    model="anthropic:claude-3-7-sonnet-latest",
    tools=[get_weather],
    prompt=prompt,
    context_schema=ContextSchema
)

agent.invoke(
    {"messages": [{"role": "user", "content": "what is the weather in sf"}]},
    context={"user_name": "John Smith"}
)
from langgraph.runtime import Runtime

def node(state: State, config: Runtime[ContextSchema]):
    user_name = runtime.context.user_name
    ...
from langgraph.runtime import get_runtime

@tool
def get_user_email() -> str:
    """Retrieve user information based on user ID."""
    # simulate fetching user info from a database
    runtime = get_runtime(ContextSchema)
    email = get_user_email_from_db(runtime.context.user_name)
    return email

详情请见工具调用指南

提示

Runtime 对象可用于访问静态上下文以及其他实用程序,如活动存储和流写入器。详情请见 Runtime 文档。

动态运行时上下文(状态)

动态运行时上下文表示在单次运行期间可以演变的可变数据,并通过 LangGraph 状态对象进行管理。这包括对话历史、中间结果以及从工具或 LLM 输出中派生的值。在 LangGraph 中,状态对象在运行期间充当短期记忆

示例展示了如何将状态整合到 Agent 的提示中。

状态也可以被 Agent 的工具访问,这些工具可以根据需要读取或更新状态。详情请见工具调用指南

from langchain_core.messages import AnyMessage
from langchain_core.runnables import RunnableConfig
from langgraph.prebuilt import create_react_agent
from langgraph.prebuilt.chat_agent_executor import AgentState

class CustomState(AgentState): # (1)!
    user_name: str

def prompt(
    state: CustomState
) -> list[AnyMessage]:
    user_name = state["user_name"]
    system_msg = f"You are a helpful assistant. User's name is {user_name}"
    return [{"role": "system", "content": system_msg}] + state["messages"]

agent = create_react_agent(
    model="anthropic:claude-3-7-sonnet-latest",
    tools=[...],
    state_schema=CustomState, # (2)!
    prompt=prompt
)

agent.invoke({
    "messages": "hi!",
    "user_name": "John Smith"
})
  1. 定义一个扩展了 AgentStateMessagesState 的自定义状态模式。
  2. 将自定义状态模式传递给 Agent。这允许 Agent 在执行期间访问和修改状态。
from typing_extensions import TypedDict
from langchain_core.messages import AnyMessage
from langgraph.graph import StateGraph

class CustomState(TypedDict): # (1)!
    messages: list[AnyMessage]
    extra_field: int

def node(state: CustomState): # (2)!
    messages = state["messages"]
    ...
    return { # (3)!
        "extra_field": state["extra_field"] + 1
    }

builder = StateGraph(State)
builder.add_node(node)
builder.set_entry_point("node")
graph = builder.compile()
  1. 定义自定义状态
  2. 在任何节点或工具中访问状态
  3. 图 API 的设计旨在尽可能轻松地处理状态。节点的返回值表示对状态的请求更新。

开启记忆

关于如何启用记忆的更多细节,请参阅记忆指南。这是一个强大的功能,允许您在多次调用之间持久化 Agent 的状态。否则,状态的作用域仅限于单次运行。

动态跨对话上下文(存储)

动态跨对话上下文表示跨多个对话或会话持久存在的、可变的数据,并通过 LangGraph 存储进行管理。这包括用户个人资料、偏好和历史交互。LangGraph 存储在多次运行中充当长期记忆。这可用于读取或更新持久化的事实(例如,用户个人资料、偏好、先前的交互)。

更多信息,请参阅记忆指南