Middleware:LangChain 里最容易被忽视的企业级能力
Agent 想上线,必须有 Middleware。它不是锦上添花,而是生产系统的安全带。 01 Middleware 是 Agent 的“拦截器” 裸 Agent 的逻辑很简单:模型思考,决定调工具,工具返回,模型继续。 这个链路能跑 De
Agent 想上线,必须有 Middleware。它不是锦上添花,而是生产系统的安全带。
01 Middleware 是 Agent 的“拦截器”
裸 Agent 的逻辑很简单:模型思考,决定调工具,工具返回,模型继续。
这个链路能跑 Demo。
但生产环境不够。
生产环境要回答这些问题:谁在调用?能不能调用?花了多少钱?失败怎么办?结果能不能出?敏感数据有没有泄露?
这些问题不应该散落在业务代码里。它们应该统一进入 Middleware。
一句话:Middleware 不负责让模型变聪明,它负责让模型变可控。
02 为什么它是企业级能力
真正的 Agent 不是“会聊天”。
真正的 Agent 是“会按规则执行任务”。
• 用户身份要校验。
• 工具权限要校验。
• 模型调用要限流。
• 失败要重试。
• 高风险动作要人工审批。
• 输出要检查。
• 每一步要能追踪。
这些都不是业务函数本身的职责。
业务函数只负责“做事”。Middleware 负责“管事”。
03 六个 Hook:看懂就掌握一半
LangChain Middleware 有两种风格。
一种是 Node-style。它像流程节点,按顺序执行。
另一种是 Wrap-style。它像包装器,包住模型调用或工具调用。
Node-style:适合顺序动作
• before_agent:整个 Agent 开始前执行一次。
• before_model:每次模型调用前执行。
• after_model:每次模型返回后执行。
• after_agent:整个 Agent 结束后执行一次。
这类 Hook 适合做日志、校验、计数、状态更新、提前终止。
Wrap-style:适合控制调用
• wrap_model_call:包住模型调用。
• wrap_tool_call:包住工具调用。
这类 Hook 适合做重试、缓存、模型降级、工具权限、超时兜底。
04 源码入口:AgentMiddleware
源码里,Middleware 的核心抽象就是 AgentMiddleware。
它不是一个神秘对象。它就是一个基类。
你继承它,然后选择实现某几个方法。
• 实现 before_model,就能在模型调用前插手。
• 实现 wrap_model_call,就能包住模型调用。
• 实现 wrap_tool_call,就能包住工具调用。
• 实现 after_agent,就能在 Agent 结束后统一落日志。
源码设计的关键点是:你不需要改 Agent 主循环。你只要写 Middleware。
05 ModelRequest:模型调用前的“请求包”
wrap_model_call 拿到的不是一串字符串。
它拿到的是 ModelRequest。
这个对象里放着模型调用需要的一切。
• model:当前要调用的模型。
• messages:当前上下文消息。
• system_message:系统指令。
• tools:当前可用工具。
• tool_choice:工具选择策略。
• response_format:结构化输出配置。
• state:Agent 当前状态。
• runtime:运行时上下文。
这就是为什么 Middleware 能做动态 Prompt、动态模型选择、动态工具裁剪。
因为它拿到的不是结果,而是“即将发给模型的完整请求”。
源码里的 request.override(...) 很关键:它不是直接改老请求,而是生成一个修改后的新请求。这样更安全,也更容易组合。
06 ModelResponse 与 Command:结果如何回写状态
模型返回后,源码会把结果包装成 ModelResponse。
里面通常有两类东西。
• result:模型返回的消息。
• structured_response:结构化输出结果。
如果 Middleware 不只想改返回结果,还想更新状态,就要用 ExtendedModelResponse。
它比普通响应多了一个 Command。
Command 的作用很直接:告诉图运行时,往 AgentState 里更新什么。
比如模型调用次数、token 用量、风险标记、审计标签,都可以这样写回去。
理解这个点:Middleware 不只是“看一眼”。它可以读请求、改请求、拦响应、改状态。
07 ToolCallRequest:工具调用也能被拦截
wrap_tool_call 拿到的是 ToolCallRequest。
它包含这次工具调用的工具名、参数、工具对象、state 和 runtime。
这给了企业系统非常重要的控制点。
• 调数据库前,先验权限。
• 发邮件前,先人工审批。
• 查用户隐私前,先脱敏。
• 工具超时后,返回标准兜底 ToolMessage。
模型可以提出工具调用。
但真正能不能执行,应该由 Middleware 决定。
08 多个 Middleware 如何组合
企业项目不会只有一个 Middleware。
通常是一串。
比如:PII 脱敏、Prompt 版本、调用限额、模型重试、工具审批、审计日志。
顺序很重要。
• before_*:按列表顺序,从前到后。
• wrap_*:像洋葱一样嵌套,第一个包住所有后面的。
• after_*:反过来,从后到前。
所以关键规则要放前面。
比如预算、权限、安全。
业务小修饰可以放后面。
09 Agent jumps:中间件可以改变流程
Middleware 还可以让 Agent 提前跳转。
源码里有 jump_to 这个状态字段。
• jump_to = end:直接结束。
• jump_to = tools:跳到工具节点。
• jump_to = model:回到模型节点。
这很适合做硬规则。
比如命中违规内容,直接结束。比如工具结果不完整,回模型重问。比如风险动作,先跳审批。
不要把所有判断都交给模型。规则明确的地方,用 Middleware 硬控。
10 内置 Middleware:常见能力不用从零写
LangChain 已经提供了一批内置 Middleware。
它们覆盖了生产 Agent 的高频问题。
如果只是做摘要、PII、人工审批、重试、降级、调用次数限制,优先用内置。
自定义 Middleware 留给企业自己的规则。
11 企业项目怎么设计 Middleware Stack
不要一个 Middleware 管所有事。
一个 Middleware 只做一件事。
这样好测试,好替换,好排查。
推荐分层
• RequestMiddleware:生成 requestId,记录用户身份和入口参数。
• PIIMiddleware:输入发给模型前先脱敏。
• PromptMiddleware:按场景选择 system prompt 和版本。
• BudgetMiddleware:限制模型调用次数、工具调用次数和 token 成本。
• FallbackMiddleware:模型失败时切换备用模型。
• ToolAuthMiddleware:工具执行前做权限和参数校验。
• AuditMiddleware:把模型输入、工具参数、工具结果、最终答案写入日志。
这套分层做完,Agent 才像一个后端服务。
12 源码级总结:把链路压缩成一条线
• create_agent 接收 middleware。
• 装配阶段识别 AgentMiddleware、state_schema、tools、transformers。
• Node-style hook 编进 LangGraph 的执行节点。
• Wrap-style hook 包住模型调用和工具调用。
• ModelRequest / ToolCallRequest 带着 state 和 runtime 进入 hook。
• handler 是真正执行模型或工具的入口。
• hook 可以调用 handler,也可以重试、短路、替换请求。
• 返回 ModelResponse、ToolMessage 或 Command。
• Command 通过 reducer 更新 AgentState。
• Agent 继续循环,直到没有 tool_calls 或被 jump_to=end 结束。
所以 Middleware 的本质不是“额外功能”。它是 Agent Runtime 的控制面。
13 常见坑
坑一:所有逻辑写进一个大 Middleware
最后会变成第二个业务系统。
拆。日志是日志,权限是权限,预算是预算。
坑二:把 after_model 当安全出口
after_model 已经在模型返回之后。
如果你要防止敏感数据发给模型,要在 before_model 或 wrap_model_call 做。
坑三:wrap 里忘记调用 handler
不调用 handler,就是短路。
这可以用于缓存和拦截,但不能误用。
坑四:工具权限只写在工具函数里
太晚。
权限应该在 wrap_tool_call 里统一做。工具函数只负责业务执行。
坑五:没有记录中间状态
Agent 出错时,你必须知道错在哪。
是 Prompt 错、模型错、工具参数错、工具返回错,还是 Middleware 拦截错。
14 总结
Middleware 是 LangChain 新版 Agent 里最像后端工程的部分。
它把横切能力从业务代码里抽出来。
它让 Agent 有规则。
它让模型调用可追踪。
它让工具调用可审计。
它让失败有兜底。
它让高风险动作能暂停。
最终结论:没有 Middleware 的 Agent,是会跑的 Demo;有 Middleware 的 Agent,才是能上线的系统。
要点速读
Agent 想上线,必须有 Middleware。它不是锦上添花,而是生产系统的安全带。 01 Middleware 是
- Agent 想上线,必须有 Middleware
- 它不是锦上添花,而是生产系统的安全带
- 01 Middleware 是