Runtime

在实际应用中,我们经常会遇到这样的需求:同一个Graph,在不同的调用场景下,需要使用不同的配置参数 。

有时候我们希望Graph使用Claude模型,有时候希望使用GPT模型;有时候我们希望给模型设置不同的System Prompt,以适应不同的任务场景;这时候,Runtime Configuration(运行时配置) 就派上用场了

Runtime Configuration允许我们在调用Graph时 (而不是在定义Graph时)传入配置参数,让同一个Graph能够根据不同的配置表现出不同的行为。这样,我们就可以在不修改Graph定义的情况下,灵活地控制Graph的运行方式

基本设置方法

定义ContexSchema

from langgraph.graph import END, StateGraph, START  
from typing\_extensions import TypedDict  

# 1. Specify config schema  
class ContextSchema(TypedDict):  
    my_runtime_value: str  
    
# 2. Define a graph that accesses the config in a node  
class State(TypedDict):  
    my_state_value: str

它负责定义运行时配置的结构,告诉LangGraph,我们在调用Graph时可以传入哪些配置参数

在节点函数中配置runtime参数

rom langgraph.runtime import Runtime  
  
def node(state: State, runtime: Runtime[ContextSchema]):    
    if runtime.context["my_runtime_value"] == "a":    
        return {"my_state_value": 1}  
    elif runtime.context["my_runtime_value"] == "b":    
        return {"my_state_value": 2}  
    else:  
        raise ValueError("Unknown values.")

在节点函数的参数中添加runtime参数,将它的类型设定为Runtime[ContextSchema]。这样,节点函数就可以访问运行时配置了

接下来看函数体内部:

首先,我们通过runtime.context["my_runtime_value"]来访问配置值。这里runtime.context是一个字典,我们可以通过指定键名来获取对应的配置值。

然后,根据配置值的不同,节点会返回不同的state更新结果。如果传入的是"a",就返回{"my_state_value": 1};如果传入的是"b",就返回{"my_state_value": 2};如果传入其他值,则抛出异常.

根据上述代码,我们可以通过观察state值的变化,确定runtime信息是否被读取

向Graph传入contetx_schema

builder = StateGraph(State, context_schema=ContextSchema)    
builder.add_node(node)  
builder.add_edge(START, "node")  
builder.add_edge("node", END)  
  
graph = builder.compile()

这里的关键点在于StateGraph的初始化。除了传入State(这是我们之前就熟悉的),我们还需要传入context\_schema=ContextSchema参数.这个参数告诉LangGraph,这个Graph支持运行时配置,并且配置的格式由ContextSchema定义

Runtime Configuration的使用

# 3. Pass in configuration at runtime:  
print(graph.invoke({}, context={"my_runtime_value": "a"}))    
print(graph.invoke({}, context={"my_runtime_value": "b"}))

在调用graph.invoke()时,除了传入初始state(这里传入的是空字典{}),我们可以通过context参数传入运行时配置

context参数接收一个字典,字典的键必须与ContextSchema中定义的字段名一致。这里我们传入{"my_runtime_value": "a"}{"my_runtime_value": "b"},Graph会根据不同的配置值,按照我们在节点函数中的设定,执行不同的逻辑。

  • 第一次调用 graph.invoke({}, context={"my_runtime_value": "a"}) 时,节点会返回 {"my_state_value": 1}
  • 第二次调用 graph.invoke({}, context={"my_runtime_value": "b"}) 时,节点会返回 {"my_state_value": 2}

Runtime Configuration的实际应用

1.指定运行时使用的Model

from dotenv import load_dotenv  
from langchain.chat_models import init_chat_model  
from langgraph.graph import MessagesState, END, StateGraph, START  
from langgraph.runtime import Runtime  
from typing_extensions import TypedDict  


# 导入API Key  
load_dotenv()  
  
classContextSchema(TypedDict):  
    model_type: str  

MODELS = {  
    "chat": init_chat_model("deepseek-chat", model_provider="deepseek"),  
    "reasoner": init_chat_model("deepseek-reasoner", model_provider="deepseek"),  
}

定义一个MODELS字典作为模型库,存储不同提供商对应的模型实例(已通过init_chat_model完成初始化)。这样,我们就可以根据配置的提供商名称,快速获取对应的模型。

需要注意的是,这里可以看到我们没有定义state,那是因为我们引用了LangGraph的一个内置组件MessagesState

(2)模型切换的节点函数定义

def call_model(state: MessagesState, runtime: Runtime[ContextSchema]):  
    # 使用 get 方法提供默认值 "chat"  
    model_type = (runtime.context or {}).get("model_type", "chat")  
    model = MODELS[model_type]  
    response = model.invoke(state["messages"])   
    return {"messages": [response]}

使用(runtime.context or {}).get("model\_type", "chat")获取配置的模型类型。这里使用(runtime.context or {})是为了处理runtime.context可能为None的情况,如果为None则使用空字典{}。然后使用get方法的好处是,如果没有提供配置(即context={}contextNone),则会使用默认值"chat"

然后,根据获取到的model\_typeMODELS字典中选择对应的模型,调用模型的invoke方法处理消息,并将响应添加到消息列表中返回。

(3)搭建Graph传入context_schema

builder = StateGraph(MessagesState, context_schema=ContextSchema)  
builder.add_node("model", call_model)  
builder.add_edge(START, "model")  
builder.add_edge("model", END)  
  
graph = builder.compile()

(4)在graph.invok中指定contetx的参数

# Usage  
input_message = {"role": "user", "content": "hi"}  
# With no configuration, uses default ("chat")  
response_1 = graph.invoke({"messages": [input_message]}, context={})["messages"][-1]  
# Or, can set reasoner  
response_2 = graph.invoke({"messages": [input_message]}, context={"model_type": "reasoner"})["messages"][-1]  
  
print(response_1.response_metadata["model_name"])  
print(response_2.response_metadata["model_name"])
  1. 在节点函数中使用了 (runtime.context or {}).get("model\_type", "chat") ,当配置为空字典时,会使用默认值 "chat" ,所以这次调用会使用DeepSeek的chat模型
  2.  context={"model\_type": "reasoner"} 。我们显式地传入配置,指定使用DeepSeek的reasoner模型

最后的打印会显示两个不同的模型。

这样,我们就实现了同一个Graph,根据运行时配置使用不同的模型

 

posted @ 2026-05-26 16:10  幻影之舞  阅读(32)  评论(0)    收藏  举报