LangChain1.0智能体开发:中间件(Middleware)

阅读本文您将获得:

  • 智能体中间件的作用
  • 智能体中间件的使用方法
  • LangChain内置的中间件
  • 如何自定义中间件
  • 中间件的执行顺序
  • 最佳实践经验

1、智能体中间件

中间件能够控制和定制化智能体每一步的执行过程 中间件提供了一种更严格地控制智能体内部运作的方式。 核心的智能体循环包括调用模型、让模型选择要执行的工具,以及当模型不再调用工具时结束循环:


中间件会在上述每个步骤的前后暴露钩子函数(hooks)。

2、中间件能做什么

  • 运行监控
    通过日志记录、数据分析和调试来跟踪智能体行为
  • 任务适配
    提示词转换、工具选择和输出格式化
  • 流程控制
    添加重试、备用方案和提前终止逻辑
  • 强制规范
    应用速率限制、安全防护和个人身份信息(PII)检测

3、基本用法

在创建Agent时,将中间件列表传递给create_agent接口的middleware参数:

python 复制代码
from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware, HumanInTheLoopMiddleware

agent = create_agent(
    model="gpt-4o",
    tools=[...],
    middleware=[SummarizationMiddleware(), HumanInTheLoopMiddleware()],
)

4、内置中间件

  • 任务适配
    4.1 SummarizationMiddleware(摘要中间件)
    4.2 AnthropicPromptCachingMiddleware(Anthropic提示词缓存中间件)
    4.3 LLMToolSelectorMiddleware(LLM工具选择中间件)
    4.4 ContextEditingMiddleware(上下文编辑中间件)
  • 流程控制
    4.2 HumanInTheLoopMiddleware(人工介入中间件)
    4.6 ModelFallbackMiddleware(模型回退中间件)
    4.8 TodoListMiddleware(待办事项中间件)
    4.10 ToolRetryMiddleware(工具重试中间件)
    4.11 LLMToolEmulator(LLM工具模拟器)
  • 强制规范
    4.4 ModelCallLimitMiddleware(模型调用限制中间件)
    4.5 ToolCallLimitMiddleware(工具调用限制中间件)
    4.7 PIIMiddleware(PII检测中间件)

5、自定义中间件

有两种方式创建中间件:

  • 基于装饰器(Decorator-based)------ 适用于单钩子中间件,快捷且简单
  • 基于类(Class-based)------ 适用于包含多个钩子的复杂中间件,功能更强大

5.1 基于装饰器创建中间件

对于仅需单个钩子函数(hook)的简单中间件而言,装饰器(decorator)是添加功能的最快方式。

python 复制代码
from langchain.agents.middleware import before_model, after_model, wrap_model_call
from langchain.agents.middleware import AgentState, ModelRequest, ModelResponse, dynamic_prompt
from langchain.messages import AIMessage
from langchain.agents import create_agent
from langgraph.runtime import Runtime
from typing import Any, Callable


# Node-style: logging before model calls
@before_model
def log_before_model(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    print(f"About to call model with {len(state['messages'])} messages")
    return None

# Node-style: validation after model calls
@after_model(can_jump_to=["end"])
def validate_output(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    last_message = state["messages"][-1]
    if "BLOCKED" in last_message.content:
        return {
            "messages": [AIMessage("I cannot respond to that request.")],
            "jump_to": "end"
        }
    return None

# Wrap-style: retry logic
@wrap_model_call
def retry_model(
    request: ModelRequest,
    handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
    for attempt in range(3):
        try:
            return handler(request)
        except Exception as e:
            if attempt == 2:
                raise
            print(f"Retry {attempt + 1}/3 after error: {e}")

# Wrap-style: dynamic prompts
@dynamic_prompt
def personalized_prompt(request: ModelRequest) -> str:
    user_id = request.runtime.context.get("user_id", "guest")
    return f"You are a helpful assistant for user {user_id}. Be concise and friendly."

# Use decorators in agent
agent = create_agent(
    model="gpt-4o",
    middleware=[log_before_model, validate_output, retry_model, personalized_prompt],
    tools=[...],
)

可用的装饰器:

  • 节点式(在特定执行节点运行):
    @before_agent------ 智能体启动前(每次调用执行一次)
    @before_model------ 每次调用模型前
    @after_model------ 每次接收模型响应后
    @after_agent------ 智能体执行完成后(每次调用执行一次)
  • 封装式(拦截并控制执行流程):
    @wrap_model_call------ 围绕每次模型调用(全程拦截)
    @wrap_tool_call------ 围绕每次工具调用(全程拦截)
  • 便捷装饰器:
    @dynamic_prompt------ 生成动态系统提示词(等同于能修改提示词的@wrap_model_call装饰器)

5.2 基于类创建中间件

以下情况适合使用基于类创建中间件:

  • 需要多个钩子函数(hooks)
  • 复杂配置
  • 跨项目复用(初始化时配置)

两种类型的钩子:

  • 节点式钩子:在执行流程的特定节点运行。
    • before_agent------ 智能体启动前(每次调用执行一次)
    • before_model------ 每次调用模型前
    • after_model------ 每次接收模型响应后
    • after_agent------ 智能体执行完成后(每次调用最多执行一次)
  • 封装式钩子:当handler被调用时,拦截执行并控制。
    • wrap_model_call------ 围绕每次模型调用(全程拦截)
    • wrap_tool_call------ 围绕每次工具调用(全程拦截) 你可以决定handler的调用次数:零次(短路)、一次(正常流程)或多次(重试逻辑)。
python 复制代码
from langchain.agents.middleware import AgentMiddleware, AgentState
from langgraph.runtime import Runtime
from typing import Any

class LoggingMiddleware(AgentMiddleware):
    def before_model(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
        print(f"About to call model with {len(state['messages'])} messages")
        return None

    def after_model(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
        print(f"Model returned: {state['messages'][-1].content}")
        return None

6、中间件执行顺序

6.1 关键规则

  • before_* 钩子函数:按顺序执行(从第一个到最后一个)
  • after_* 钩子函数:按逆序执行(从最后一个到第一个)
  • wrap_* 钩子函数:嵌套执行(第一个中间件包裹所有其他中间件)

6.2 跳转功能

若要从中间件中提前退出,需返回一个包含jump_to的字典。

可用的跳转目标:

  • "end":跳转到智能体执行流程的末尾
  • "tools":跳转到工具节点
  • "model":跳转到模型节点(或第一个 before_model 钩子函数)

注意:当从before_model或after_model钩子函数中发起跳转时,跳转到"model"会导致所有before_model中间件重新运行。

若要启用跳转功能,需用 @hook_config(can_jump_to=[...]) 装饰你的钩子函数。

python 复制代码
from langchain.agents.middleware import AgentMiddleware, hook_config
from typing import Any

class ConditionalMiddleware(AgentMiddleware):
    @hook_config(can_jump_to=["end", "tools"])
    def after_model(self, state: AgentState, runtime) -> dict[str, Any] | None:
        if some_condition(state):
            return {"jump_to": "end"}
        return None

7、最佳实践经验总结

  • 保持中间件专注性 ------ 每个中间件应专注做好一件事
  • 优雅地处理错误 ------ 避免中间件错误导致智能体崩溃
  • 使用合适的钩子类型:
    • 节点式(Node-style)适用于顺序逻辑(如日志记录、验证)
    • 封装式(Wrap-style)适用于控制流(如重试、备用方案、缓存)
  • 清晰地文档化所有自定义状态属性
  • 集成前独立对中间件进行单元测试
  • 考虑执行顺序 ------ 将关键中间件放在列表首位
  • 尽可能使用内置中间件,避免重复造轮子。
相关推荐
陈天伟教授2 分钟前
人工智能应用-机器听觉:15. 声纹识别的应用
人工智能·神经网络·机器学习·语音识别
zhang133830890753 分钟前
CG-09H 超声波风速风向传感器 加热型 ABS材质 重量轻 没有机械部件
大数据·运维·网络·人工智能·自动化
板面华仔26 分钟前
机器学习入门(三)——决策树(Decision Tree)
人工智能·决策树·机器学习
GAOJ_K39 分钟前
滚珠花键的无预压、间隙调整与过盈配合“场景适配型”
人工智能·科技·机器人·自动化·制造
ai_xiaogui43 分钟前
【开源探索】Panelai:重新定义AI服务器管理面板,助力团队私有化算力部署与模型运维
人工智能·开源·私有化部署·docker容器化·panelai·ai服务器管理面板·comfyui集群管理
源于花海1 小时前
迁移学习的前沿知识(AI与人类经验结合、传递式、终身、在线、强化、可解释性等)
人工智能·机器学习·迁移学习·迁移学习前沿
king of code porter1 小时前
百宝箱企业版搭建智能体应用-平台概述
人工智能·大模型·智能体
愚公搬代码1 小时前
【愚公系列】《AI短视频创作一本通》004-AI短视频的准备工作(创作AI短视频的基本流程)
人工智能·音视频
物联网软硬件开发-轨物科技1 小时前
【轨物洞见】告别“被动维修”!预测性运维如何重塑老旧电站的资产价值?
运维·人工智能
电商API_180079052471 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫