Skip to content

Middleware 中间件

在每个执行步骤中控制和定制 Agent 的行为

Middleware(中间件)是 LangChain Agent 的核心扩展机制,让你可以在 Agent 执行的每个环节插入自定义逻辑:日志记录、提示词变换、工具选择、重试、限流、PII 检测等。

为什么需要 Middleware

Agent 的核心循环是:模型调用 → 工具执行 → 模型调用 → ... → 完成

Middleware 在这个循环的各个阶段提供钩子(hook),让你可以:

  • 追踪行为:日志、分析、调试
  • 转换数据:修改提示词、格式化输出、过滤工具选择
  • 增加可靠性:重试机制、模型回退、提前终止
  • 保障安全:限流、护栏、PII 检测

使用内置 Middleware

LangChain 提供了一系列内置 middleware,通过 create_agent()middleware 参数传入:

python
from langchain.agents import create_agent
from langchain.agents.middleware import (
    SummarizationMiddleware,
    HumanInTheLoopMiddleware,
    ToolRetryMiddleware,
    ModelFallbackMiddleware,
)

agent = create_agent(
    model="openai:gpt-5.5",
    tools=[...],
    middleware=[
        SummarizationMiddleware(max_tokens=4096),
        HumanInTheLoopMiddleware(interrupt_on={"send_email": True}),
        ToolRetryMiddleware(max_retries=3),
    ],
)

内置 Middleware 列表

Middleware用途
SummarizationMiddleware当对话历史过长时自动总结压缩
HumanInTheLoopMiddleware在指定工具调用时暂停,等待人工审批
ToolRetryMiddleware工具调用失败时自动重试
ModelFallbackMiddleware主模型失败时切换到备用模型
ModelCallLimitMiddleware限制单次 Agent 运行中的模型调用次数
PIIMiddleware检测并屏蔽敏感信息(邮箱、电话、身份证等)
LLMToolSelectorMiddleware动态限制 Agent 可以使用的工具子集

Middleware 执行流程

Middleware 在 Agent 循环的每个步骤前后触发钩子:

Agent 执行循环
═════════════════

用户输入


┌─────────────────────────────┐
│  Middleware: 输入处理阶段     │  ← 在此修改/过滤输入
│  ・PII 检测                  │
│  ・输入验证                  │
└─────────────┬───────────────┘


┌─────────────────────────────┐
│  LLM 模型调用                │
└─────────────┬───────────────┘


┌─────────────────────────────┐
│  Middleware: 输出处理阶段     │  ← 在此处理模型输出
│  ・总结压缩                  │
│  ・格式转换                  │
└─────────────┬───────────────┘


┌─────────────────────────────┐
│  工具调用 (如有)             │
└─────────────┬───────────────┘


┌─────────────────────────────┐
│  Middleware: 工具后处理       │  ← 在此处理工具结果
│  ・重试逻辑                  │
│  ・结果转换                  │
└─────────────┬───────────────┘

      ┌───────┴───────┐
      │               │
    继续循环         完成


                  用户输出

在 LangGraph 工作流中使用 Middleware

Middleware 不是独立的运行时——钩子运行在 create_agent() 返回的编译后的 LangGraph 中。你可以将整个 Agent(包括 middleware)作为节点嵌入更大的 StateGraph

python
from langchain.agents import AgentState, create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.graph import START, StateGraph

# 创建带 middleware 的 agent
email_agent = create_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[read_email, send_email],
    middleware=[HumanInTheLoopMiddleware(interrupt_on={"send_email": True})],
)

# 嵌入更大的工作流
graph = (
    StateGraph(AgentState)
    .add_node("classify", classify_node)
    .add_node("email_agent", email_agent)
    .add_edge(START, "classify")
    .add_conditional_edges("classify", route)
    .compile()
)

这样,HITL 中断、总结、PII 脱敏、重试等所有 middleware 逻辑都会随 Agent 节点一起工作。

自定义 Middleware

你可以通过实现 middleware 钩子来创建自定义中间件:

python
from langchain.agents.middleware import BaseMiddleware

class LoggingMiddleware(BaseMiddleware):
    """记录每次模型调用和工具执行的日志。"""
    
    async def on_model_start(self, state, messages):
        print(f"[模型调用] 消息数: {len(messages)}")
        return messages
    
    async def on_model_end(self, state, response):
        print(f"[模型响应] Token: {response.usage_metadata}")
        return response
    
    async def on_tool_start(self, state, tool_call):
        print(f"[工具调用] {tool_call.name}({tool_call.args})")
        return tool_call
    
    async def on_tool_end(self, state, result):
        print(f"[工具结果] {str(result)[:100]}")
        return result

# 使用自定义 middleware
agent = create_agent(
    model="openai:gpt-5.5",
    tools=[search, calculator],
    middleware=[LoggingMiddleware()],
)

Middleware 钩子

钩子触发时机用途
on_model_start模型调用前修改/过滤发送给模型的消息
on_model_end模型响应后处理/记录模型输出
on_tool_start工具执行前验证/修改工具参数
on_tool_end工具执行后处理/转换工具结果
on_agent_startAgent 循环开始初始化上下文
on_agent_endAgent 循环结束清理/汇总

常见场景

场景 1:对话历史总结

防止长对话超出上下文窗口:

python
from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware

agent = create_agent(
    model="openai:gpt-5.5",
    tools=tools,
    middleware=[
        SummarizationMiddleware(
            max_tokens=4096,  # 超过此 token 数时触发总结
            summary_model="openai:gpt-5.5",  # 用于总结的模型
        )
    ],
)

场景 2:模型故障回退

主模型不可用时自动使用备用模型:

python
from langchain.agents import create_agent
from langchain.agents.middleware import ModelFallbackMiddleware

agent = create_agent(
    model="openai:gpt-5.5",
    tools=tools,
    middleware=[
        ModelFallbackMiddleware(
            fallbacks=["anthropic:claude-sonnet-4-6", "google_genai:gemini-3.5-flash"],
            max_attempts=3,
        )
    ],
)

场景 3:PII 检测

自动检测并脱敏敏感信息:

python
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware

agent = create_agent(
    model="openai:gpt-5.5",
    tools=tools,
    middleware=[
        PIIMiddleware(
            detectors=["email", "phone", "ssn", "credit_card"],
            masking_strategy="redact",  # "redact" | "hash" | "replace"
        )
    ],
)

场景 4:限制模型调用次数

防止 Agent 陷入无限循环:

python
from langchain.agents import create_agent
from langchain.agents.middleware import ModelCallLimitMiddleware

agent = create_agent(
    model="openai:gpt-5.5",
    tools=tools,
    middleware=[
        ModelCallLimitMiddleware(max_calls=15),  # 最多 15 次模型调用
    ],
)

Middleware 与 LangSmith

所有 middleware 的执行都会被 LangSmith 自动追踪,你可以在 LangSmith 中看到每个 middleware 钩子的执行情况:

python
import os
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "your-api-key"

LangSmith 会展示:

  • 每个 middleware 的执行耗时
  • middleware 对消息的修改
  • 任何重试或回退事件

我们推荐同时设置 LangSmith Engine,它会监控你的 trace,检测问题并建议修复方案。

最佳实践

  1. 保持 middleware 轻量:每个 middleware 应只关注一个职责
  2. 注意顺序:middleware 按传入顺序执行,PII 检测应放在最前面
  3. 避免副作用:middleware 应尽量幂等,避免意外修改 Agent 状态
  4. 充分测试:在生产环境前用 LangSmith 验证 middleware 行为
  5. 监控性能:middleware 会增加延迟,注意总执行时间

下一步

本站为非官方中文学习站点,不代表 LangChain 官方。部分内容参考官方文档并重新整理为中文学习笔记。