🧠 LangChain 中间件(Middleware)实战:实现“模型调用守卫”
在上一章我们已经实现了一个基础 Agent。
那么如果我们想实现类似前端路由守卫的能力,比如:
- 在模型调用前/后做处理
- 动态修改请求(如切换模型、调整参数)
- 做日志、监控、策略控制
👉 这时候就需要用到 Middleware(中间件)
⚙️ 一、如何定义一个中间件?
LangChain 提供了装饰器:
1 |
定义方式如下:
1 | def middleware(request, handler): ... |
👉 必须接收两个参数:
📦 参数1:request(ModelRequest 对象)
request 表示一次完整的模型调用请求,是一个对象(不是 dict):
1 | ModelRequest( |
🧠 messages(最关键字段)
1 | request.messages |
结构如下:
1 | [ |
👉 获取用户输入:
1 | request.messages[-1].content |
⚠️ 更推荐的写法(更严谨):
1 | from langchain_core.messages import HumanMessage |
🔁 参数2:handler(核心执行器)
handler 是一个函数,表示:
👉 “继续执行模型调用流程”
你可以理解为:
1 | handler(request) = 真正调用 LLM |
🚨 非常重要的规则
👉 在 middleware 中:
- ✅ 可以修改
request - ✅ 必须调用
handler(request) - ❌ 不要自己调用
llm.invoke()
🔄 二、Middleware 执行流程
当调用:
1 | agent.invoke(...) |
实际流程如下:
1 | 用户输入 |
👉 核心思想:
💡 Middleware = “模型调用前的拦截与改写”
🚀 三、完整 Demo:根据问题复杂度切换模型
1️⃣ 定义分类模型(判断问题复杂度)
1 | from pydantic import BaseModel, Field |
2️⃣ 定义中间件(核心逻辑)
1 |
|
3️⃣ 挂载中间件到 Agent
1 | agent = create_agent( |
🧠 四、总结
通过 Middleware,我们可以在不修改 Agent 主逻辑的情况下,实现:
- ✅ 动态模型路由(simple / complex)
- ✅ 请求改写(messages / params)
- ✅ 统一日志与监控
- ✅ 策略控制(限流 / 权限等)
💡 一句话理解
👉 Middleware = “模型调用前的可编程拦截层”
🤯 五、踩坑总结
request是对象,不是 dictmessages是 Message 对象列表,不是字符串- 不要直接调用
llm.invoke()(会绕过 pipeline) - 正确方式是:修改
request+ 调用handler(request)
🚀 下一步
- 多模型路由(更复杂策略)
- Tool Calling(Agent核心)
- Memory(上下文管理)
- LangGraph(流程编排)
By
GPT编写