LangChain v1.1.0 于 2025 年 11 月 25 日发布,中间件(Middleware)作为
create_agent的核心特性,为 Agent 开发带来了前所未有的灵活性和可扩展性。本文将深入解读中间件机制,并通过实战示例帮助你快速上手。
一、什么是中间件?
中间件(Middleware)是 LangChain v1 引入的核心抽象,它允许开发者在 Agent 执行流程的各个阶段插入自定义逻辑,实现上下文工程(Context Engineering)——在正确的时间将正确的信息传递给模型。
中间件的核心价值:
- 动态提示词管理:根据上下文动态调整系统提示
- 对话历史压缩:自动摘要过长的对话历史
- 工具访问控制:根据用户权限选择性暴露工具
- 状态管理:跨执行周期维护自定义状态
- 安全护栏:输入输出验证、PII 脱敏、内容审核
二、中间件钩子详解
LangChain 中间件提供6 个核心钩子,覆盖 Agent 执行的完整生命周期:
| 钩子 | 执行时机 | 典型用例 |
|---|---|---|
before_agent | Agent 调用前 | 加载记忆、验证输入 |
before_model | 每次 LLM 调用前 | 更新提示词、裁剪消息 |
wrap_model_call | 包裹 LLM 调用 | 拦截/修改请求和响应 |
wrap_tool_call | 包裹工具调用 | 拦截/修改工具执行 |
after_model | 每次 LLM 响应后 | 验证输出、应用护栏 |
after_agent | Agent 完成后 | 保存结果、清理资源 |
三、内置中间件一览
3.1 SummarizationMiddleware - 对话历史摘要
当对话历史接近 Token 上限时,自动使用 LLM 压缩旧消息,保留近期上下文。
fromlangchain.agentsimportcreate_agentfromlangchain.agents.middlewareimportSummarizationMiddleware agent=create_agent(model="gpt-4o",tools=[weather_tool,calculator_tool],middleware=[SummarizationMiddleware(model="gpt-4o-mini",# 用于生成摘要的模型trigger={"tokens":4000},# 触发摘要的 Token 阈值keep={"messages":20},# 保留最近 20 条消息),],)v1.1 增强:支持基于模型 Profile 的灵活触发点配置,实现上下文感知的摘要策略。
3.2 PIIMiddleware - PII 敏感信息处理
检测并处理个人身份信息(PII),支持脱敏(redact)、掩码(mask)、阻断(block)等策略。
fromlangchain.agents.middlewareimportPIIMiddleware agent=create_agent(model="claude-sonnet-4-5-20250929",tools=[read_email,send_email],middleware=[# 脱敏邮箱地址PIIMiddleware("email",strategy="redact",apply_to_input=True),# 使用正则检测并阻断电话号码PIIMiddleware("phone_number",detector=r"(?:\+?\d{1,3}[\s.-]?)?(?:\(?\d{2,4}\)?[\s.-]?)?\d{3,4}[\s.-]?\d{4}",strategy="block"),])3.3 HumanInTheLoopMiddleware - 人机协作审批
对敏感工具调用暂停执行,等待人工审批。
fromlangchain.agents.middlewareimportHumanInTheLoopMiddleware agent=create_agent(model="claude-sonnet-4-5-20250929",tools=[read_email,send_email],middleware=[HumanInTheLoopMiddleware(interrupt_on={"send_email":{"description":"请审核此邮件后再发送","allowed_decisions":["approve","edit","reject"]}})])3.4 TodoListMiddleware - 任务规划
为 Agent 提供任务规划和跟踪能力,自动注入write_todos工具和相关系统提示。
fromlangchain.agents.middlewareimportTodoListMiddleware agent=create_agent(model="gpt-4o",tools=[read_file,write_file,run_tests],middleware=[TodoListMiddleware()],)适用场景:
- 需要跨多个工具协调的复杂多步骤任务
- 需要进度可见性的长时间运行操作
3.5 ModelRetryMiddleware - 模型调用重试(v1.1 新增)
自动重试失败的模型调用,支持可配置的指数退避策略,提升 Agent 可靠性。
fromlangchain.agents.middlewareimportModelRetryMiddleware agent=create_agent(model="gpt-4o",tools=[...],middleware=[ModelRetryMiddleware(max_retries=3,backoff_factor=2.0,# 指数退避因子),],)3.6 OpenAI Content Moderation - 内容审核(v1.1 新增)
使用 OpenAI 的审核端点检测和处理不安全内容,支持检查用户输入、模型输出和工具结果。
fromlangchain.agents.middlewareimportOpenAIModerationMiddleware agent=create_agent(model="openai:gpt-4o",tools=[search_tool,database_tool],middleware=[OpenAIModerationMiddleware(model="openai:gpt-4o",moderation_model="omni-moderation-latest",check_input=True,# 检查用户输入check_output=True,# 检查模型输出exit_behavior="end",),],)四、自定义中间件实战
4.1 基础结构
自定义中间件需要继承AgentMiddleware类并实现所需的钩子方法:
fromlangchain.agentsimportcreate_agentfromlangchain.agents.middlewareimportAgentMiddleware,AgentStatefromtypingimportAnyclassMyCustomMiddleware(AgentMiddleware):defbefore_model(self,state:AgentState,runtime)->dict[str,Any]|None:"""在每次模型调用前执行"""print(f"即将调用模型,当前消息数:{len(state['messages'])}")returnNone# 返回 None 表示不修改状态defafter_model(self,state:AgentState,runtime)->dict[str,Any]|None:"""在每次模型响应后执行"""print("模型调用完成")returnNone4.2 实战案例:调用计数器中间件
实现一个跟踪模型调用次数并在超限时终止的中间件:
fromlangchain.agentsimportcreate_agentfromlangchain.messagesimportHumanMessagefromlangchain.agents.middlewareimportAgentState,AgentMiddlewarefromtyping_extensionsimportNotRequiredfromtypingimportAny# 扩展状态 SchemaclassCustomState(AgentState):model_call_count:NotRequired[int]user_id:NotRequired[str]classCallCounterMiddleware(AgentMiddleware[CustomState]):"""调用计数器中间件:限制模型调用次数"""state_schema=CustomStatedef__init__(self,max_calls:int=10):self.max_calls=max_callsdefbefore_model(self,state:CustomState,runtime)->dict[str,Any]|None:count=state.get("model_call_count",0)ifcount>=self.max_calls:print(f"已达到最大调用次数{self.max_calls},终止执行")return{"jump_to":"end"}# 跳转到结束节点returnNonedefafter_model(self,state:CustomState,runtime)->dict[str,Any]|None:current_count=state.get("model_call_count",0)return{"model_call_count":current_count+1}# 使用中间件agent=create_agent(model="gpt-4o",middleware=[CallCounterMiddleware(max_calls=5)],tools=[],)# 调用时传入自定义状态result=agent.invoke({"messages":[HumanMessage("你好,请介绍一下自己")],"model_call_count":0,"user_id":"user-123",})4.3 实战案例:基于用户等级的动态模型选择
根据用户专业等级动态切换模型和工具:
fromdataclassesimportdataclassfromtypingimportCallablefromlangchain_openaiimportChatOpenAIfromlangchain.agents.middlewareimportAgentMiddleware,ModelRequestfromlangchain.agents.middleware.typesimportModelResponse@dataclassclassUserContext:user_expertise:str="beginner"# beginner | expertclassExpertiseBasedMiddleware(AgentMiddleware):"""根据用户等级动态选择模型和工具"""defwrap_model_call(self,request:ModelRequest,handler:Callable[[ModelRequest],ModelResponse])->ModelResponse:user_level=request.runtime.context.user_expertiseifuser_level=="expert":# 专家用户:更强大的模型 + 高级工具model=ChatOpenAI(model="gpt-4o")tools=[advanced_search,data_analysis,code_execution]else:# 初学者:轻量模型 + 基础工具model=ChatOpenAI(model="gpt-4o-mini")tools=[simple_search,basic_calculator]returnhandler(request.override(model=model,tools=tools))agent=create_agent(model="gpt-4o",tools=[simple_search,advanced_search,basic_calculator,data_analysis,code_execution],middleware=[ExpertiseBasedMiddleware()],context_schema=UserContext)五、中间件组合与执行顺序
多个中间件按照列表顺序依次执行,形成洋葱模型:
agent=create_agent(model="gpt-4o",tools=[...],middleware=[PIIMiddleware("email",strategy="redact"),# 第 1 层SummarizationMiddleware(model="gpt-4o-mini"),# 第 2 层HumanInTheLoopMiddleware(interrupt_on={...}),# 第 3 层CallCounterMiddleware(max_calls=10),# 第 4 层],)执行流程:
- 进入阶段:按顺序执行
before_*钩子(1→2→3→4) - 核心执行:模型调用 / 工具调用
- 退出阶段:按逆序执行
after_*钩子(4→3→2→1)
六、最佳实践
- 从简单开始:先使用静态提示词和工具,仅在必要时添加动态特性
- 增量测试:每次只添加一个中间件,验证其行为
- 监控性能:跟踪模型调用次数、Token 使用量和延迟
- 善用内置中间件:优先使用
SummarizationMiddleware、PIIMiddleware等成熟方案 - 区分瞬态与持久化:
- 瞬态(Transient):
before_model中的消息裁剪仅影响当前调用 - 持久化(Persistent):
SummarizationMiddleware会永久更新状态
- 瞬态(Transient):
七、总结
LangChain 1.1 的中间件系统为 Agent 开发提供了强大的扩展能力:
| 特性 | 说明 |
|---|---|
| 可组合性 | 多个中间件可自由组合,各司其职 |
| 生命周期钩子 | 6 个钩子覆盖完整执行流程 |
| 状态扩展 | 自定义状态 Schema 支持跨调用数据传递 |
| 生产就绪 | 内置中间件经过充分测试,可直接用于生产环境 |
无论是实现对话历史压缩、敏感信息脱敏、人机协作审批,还是构建复杂的动态上下文工程策略,中间件都能帮助你以优雅、可维护的方式实现目标。
参考资料
- LangChain v1.1.0 Changelog
- LangChain Middleware Documentation
- Custom Middleware Guide
- What’s new in LangChain v1