LangChain LangGraph
Module 1 Module 2 Module 3
Module 3 · 中间件与 HITL
1 3.2 Managing Msgs
2 3.3 HITL
3 3.4 Dyn Models
4 3.4 Dyn Prompts
5 3.4 Dyn Tools
6 3.5 Email Agent
SUM Module Summary
HomeLangChainModule 3 · 中间件与 HITL3.4 Dyn Models
📓 Notebook 📖 Explained
LANGCHAIN MODULE 3 · LESSON 3.4a

动态模型选择
wrap_model_call · request.override

本节用 middleware 在运行时选择模型:短对话使用标准模型,长对话切换到更大的模型。

1 为什么需要动态模型

同一个 Agent 不一定每次都要用同一个模型。短问题可以用便宜快速的标准模型,长上下文或复杂任务可以切到更强模型。

场景模型策略
短对话、简单问题标准模型,降低成本和延迟
长对话、上下文很多大模型或更长上下文模型
高风险推理更强模型或专用模型
核心 API

@wrap_model_call 可以拦截模型调用前的 request,并用 request.override(model=...) 替换本次调用的模型。

2 准备两个模型

Notebook 准备了两个 DeepSeek 模型对象:standard_modellarge_model

Python
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from typing import Callable

large_model = deepseek_model("deepseek-v4-pro")
standard_model = deepseek_model()
模型对象

这里两个变量都是 LangChain chat model。区别只在模型名称和能力配置。

3 按消息数量切换模型

Middleware 读取 request.messages,根据消息数量判断对话长短。超过 10 条消息就切换到大模型。

Python
@wrap_model_call
def state_based_model(
    request: ModelRequest,
    handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
    """Select model based on State conversation length."""
    message_count = len(request.messages)

    if message_count > 10:
        model = large_model
    else:
        model = standard_model

    request = request.override(model=model)
    return handler(request)
handler 必须调用

Middleware 修改 request 后仍然要调用 handler(request),否则模型调用不会继续执行。

4 把 middleware 挂到 Agent

Agent 创建时仍然传一个默认模型,但实际调用会被 middleware 改写。系统提示让 Agent 扮演办公室实习生。

Python
agent = create_agent(
    model=deepseek_model(),
    middleware=[state_based_model],
    system_prompt="You are roleplaying a real life helpful office intern.",
)
默认模型的作用

默认模型是兜底配置;middleware 可以在每次模型调用前按条件覆盖。

5 验证短对话和长对话

Notebook 分别运行一个短问题和一个超过 10 条消息的长对话,并打印响应 metadata 里的 model_name,确认模型是否按条件切换。

Python
response = agent.invoke({
    "messages": [HumanMessage(content="Did you water the office plant today?")]
})
print(response["messages"][-1].response_metadata["model_name"])

response = agent.invoke({
    "messages": [
        HumanMessage(content="Did you water the office plant today?"),
        AIMessage(content="Yes, I gave it a light watering this morning."),
        HumanMessage(content="Has it grown much this week?"),
        AIMessage(content="It's sprouted two new leaves since Monday."),
        HumanMessage(content="Are the leaves still turning yellow on the edges?"),
        AIMessage(content="A little, but it's looking healthier overall."),
        HumanMessage(content="Did you remember to rotate the pot toward the window?"),
        AIMessage(content="I rotated it a quarter turn so it gets more even light."),
        HumanMessage(content="How often should we be fertilizing this plant?"),
        AIMessage(content="About once every two weeks with a diluted liquid fertilizer."),
        HumanMessage(content="When should we expect to have to replace the pot?"),
    ]
})
print(response["messages"][-1].response_metadata["model_name"])
调试方式

不要只看回答文本。动态模型逻辑应该通过 metadata、日志或 tracing 明确验证。

6 本课 takeaway