Skip to content

Latest commit

 

History

History
163 lines (112 loc) · 5.35 KB

File metadata and controls

163 lines (112 loc) · 5.35 KB

17. 运行时(Runtime)

原文链接: https://docs.langchain.com/oss/python/langchain/runtime

概述(Overview)

create_agent 在底层运行在 LangGraph 的 runtime 之上。LangGraph 暴露了一个 Runtime 对象,包含以下信息:

  1. Context(上下文):一次智能体调用的静态信息,例如用户 ID、数据库连接或其他依赖
  2. Store(存储):用于长期记忆的 BaseStore 实例
  3. Stream writer(流写入器):用于通过 "custom" 流模式发送自定义流式信息的对象

运行时上下文为你的工具和中间件提供了一种 依赖注入(dependency injection) 的机制。

相比在代码中写死配置或使用全局变量,你可以在调用智能体时注入依赖(例如数据库连接、用户 ID 或配置),这让工具更易于测试、复用和扩展。

你可以在 工具中间件 中访问运行时信息。


访问方式(Access)

使用 create_agent 创建智能体时,可以通过 context_schema 定义运行时 context 的结构。当调用智能体时,通过 context 参数传入本次运行的配置:

from dataclasses import dataclass

from langchain.agents import create_agent


@dataclass
class Context:
    user_name: str


agent = create_agent(
    model="gpt-5-nano",
    tools=[...],
    context_schema=Context,  # 定义运行时上下文结构
)

agent.invoke(
    {"messages": [{"role": "user", "content": "What's my name?"}]},
    context=Context(user_name="John Smith"),  # 为本次调用注入上下文
)

Context 的结构是你自定义的,可以根据业务需要添加更多字段(如 user_id、权限信息、区域设置等)。


在工具中访问运行时(Inside tools)

你可以在工具内部访问运行时信息,以便:

  • 读取上下文(如 user_iduser_name
  • 读写长期记忆(store)
  • 通过自定义流模式写入进度或状态更新

在工具签名中使用 ToolRuntime 参数即可访问 Runtime 对象:

from dataclasses import dataclass
from langchain.tools import tool, ToolRuntime


@dataclass
class Context:
    user_id: str


@tool
def fetch_user_email_preferences(runtime: ToolRuntime[Context]) -> str:
    """从存储中获取用户的邮件偏好。"""
    # 从上下文中读取用户 ID
    user_id = runtime.context.user_id

    # 默认偏好
    preferences: str = "The user prefers you to write a brief and polite email."

    # 如果配置了 store,则尝试从长期记忆中读取
    if runtime.store:
        if memory := runtime.store.get(("users",), user_id):
            preferences = memory.value["preferences"]

    return preferences

这里:

  • runtime.context 提供运行时上下文(由 context_schema 定义);
  • runtime.store 提供长期存储接口,可以按 key 读写数据;
  • 若你在工具中需要流式输出(如进度条信息),可以通过 runtime.stream_writer 写入。

在中间件中访问运行时(Inside middleware)

你也可以在中间件中访问运行时信息,以便:

  • 创建动态系统提示(dynamic prompt)
  • 根据用户上下文修改消息
  • 按用户、环境或业务逻辑控制智能体行为

在中间件装饰器中,通过 request.runtime 访问 Runtime 对象。Runtime 内嵌在传入中间件函数的 ModelRequest 参数中。

from dataclasses import dataclass

from langchain.messages import AnyMessage
from langchain.agents import create_agent, AgentState
from langchain.agents.middleware import dynamic_prompt, ModelRequest, before_model, after_model
from langgraph.runtime import Runtime


@dataclass
class Context:
    user_name: str


# 动态系统提示
@dynamic_prompt
def dynamic_system_prompt(request: ModelRequest) -> str:
    """根据运行时上下文动态生成系统提示。"""
    user_name = request.runtime.context.user_name  # 从运行时上下文读取用户名
    system_prompt = f"You are a helpful assistant. Address the user as {user_name}."
    return system_prompt


# 模型调用前的钩子
@before_model
def log_before_model(state: AgentState, runtime: Runtime[Context]) -> dict | None:
    """在模型调用前打印当前用户信息。"""
    print(f"Processing request for user: {runtime.context.user_name}")
    return None


# 模型调用后的钩子
@after_model
def log_after_model(state: AgentState, runtime: Runtime[Context]) -> dict | None:
    """在模型调用后打印当前用户信息。"""
    print(f"Completed request for user: {runtime.context.user_name}")
    return None


agent = create_agent(
    model="gpt-5-nano",
    tools=[...],
    middleware=[dynamic_system_prompt, log_before_model, log_after_model],  # 注册中间件
    context_schema=Context,  # 声明上下文结构
)

agent.invoke(
    {"messages": [{"role": "user", "content": "What's my name?"}]},
    context=Context(user_name="John Smith"),  # 为本次请求注入上下文
)

在这个示例中:

  • dynamic_system_prompt 使用 request.runtime.context 构造个性化的 system prompt;
  • log_before_model / log_after_model 通过 runtime.context 访问用户信息,用于日志或审计;
  • 所有这些逻辑都不依赖全局变量,而是依赖于运行时注入的上下文和 store,使得中间件在测试和复用时更加方便。

本文档由 LangChain 官方文档翻译而来