1821 字
5 分钟
LangChainlangchain
LangChain 进阶:Middleware

把 LangChain 的 Middleware 放回 Agent Loop 里理解:它到底拦在哪、能做什么,以及哪些 built-in middleware 最值得先掌握。

这篇更像 Agents 的后续拆解。前面已经把模型、消息、工具、记忆、流式和结构化输出串起来了,这里再回头看 middleware,就更容易理解它到底是"插在循环的哪一层"。

1. 介绍#

中间件提供了一种更精细地控制智能体内部运行逻辑的方式。中间件适用于以下场景:

  • 通过日志、分析和调试跟踪智能体行为。
  • 转换提示词、工具选择及输出格式。
  • 添加重试、降级方案和提前终止逻辑。
  • 应用速率限制、防护机制及个人身份信息检测

只要在create_agent的时候传入中间件即可,代码示例如下:

Python3 点击展开代码
11 lines 展开代码

我们知道,agent被invoke之后会进入一个loop,而中间件,就是在其中各个节点添加中间件。前面的学习中,其实我们已经多次用到中间件了。我们将普通的Agent Loop和带中间件的Agent Loop总结如下: alt text alt text

2. Prebuilt middleware#

LangChain 和 Deep Agents 为常见应用场景提供预构建中间件。每种中间件均可直接用于生产环境,并可根据你的具体需求进行配置。

总结如下。为了方便查阅,我把表格和下面的示例代码做成了跳转关系:

  • 点击 "Middleware" 列:跳到本文档下方对应示例
  • 点击 "官方文档" 列:跳到 LangChain 官方 built-in middleware 页面对应章节
Middleware中文解释作用典型用法适用场景官方文档
Summarization对话摘要当上下文快接近 token 上限时,自动压缩历史对话,保留关键信息把早期多轮聊天总结成一段摘要,替换冗长历史消息长对话、客服、持续多轮 agent链接
Human-in-the-loop人类介入审批在执行高风险动作前暂停,让人工确认是否继续调用删除文件、发邮件、转账、外部 API 写操作前先审批高风险工具调用、生产环境链接
Model call limit模型调用次数限制限制一次任务中调用 LLM 的次数,防止死循环或费用失控设置最多调用模型 5 次,超出后直接终止成本控制、调试 agent 循环链接
Tool call limit工具调用次数限制限制 agent 调用工具的次数,避免无限试错限制搜索工具最多调 3 次、数据库查询最多调 5 次工具容易死循环、外部调用昂贵链接
Model fallback模型降级/回退主模型失败时,自动切换到备用模型继续执行先用 gpt-4o,失败后回退到 gpt-4o-mini稳定性要求高、生产兜底链接
PII detection敏感信息检测检测输入/输出中是否包含个人敏感信息,并执行脱敏、拦截或告警识别手机号、身份证号、邮箱后自动打码隐私合规、企业内部系统链接
To-do list待办列表给 agent 增加任务分解、任务跟踪和完成状态记录能力把"大任务"拆成多个步骤,逐步完成并更新状态长流程任务、研究型 agent链接
LLM tool selector工具预筛选器先用一个小模型判断哪些工具相关,再交给主模型决策先选出最可能需要的 3 个工具,减少主模型负担工具很多、路由复杂链接
Tool retry工具重试工具调用失败时自动重试,并通常使用指数退避网络超时后 1 秒、2 秒、4 秒后再试外部 API 不稳定、偶发失败链接
Model retry模型重试模型请求失败时自动重试,减少临时错误影响遇到超时、429、临时连接失败时自动再调一次模型 API 不稳定、网络波动链接
LLM tool emulator工具模拟器用 LLM 模拟工具执行结果,便于测试 agent 流程不连真实数据库,而让模型假装返回查询结果本地调试、测试、演示链接
Context editing上下文编辑动态裁剪、清理或重写上下文内容,避免上下文污染删掉无用 tool message,只保留关键结论长流程、多工具混杂场景链接
Shell toolShell 工具给 agent 一个可持续的终端会话,让它执行命令运行 lspythongit status 等命令编码 agent、自动化运维链接
File search文件搜索提供文件级搜索能力,如 Glob、Grep、全文检索按文件名查找 *.md,或全文搜索某个函数名代码库问答、文档检索链接
Filesystem文件系统给 agent 提供读写文件能力,用于保存上下文、缓存或长期记忆把中间结果写入文件,下次继续读取持久化记忆、任务缓存链接
Subagent子代理允许 agent 派生多个子 agent 分工处理任务一个 agent 查资料,一个 agent 写总结,一个 agent 校验结果复杂任务拆分、并行处理链接

接下来,看看大概是怎么用的:

Summarization#

Python3 点击展开代码
14 lines 展开代码

Human-in-the-loop#

Python3 点击展开代码
28 lines 展开代码

Model call limit#

Python3 点击展开代码
16 lines 展开代码

Tool call limit#

Python3 点击展开代码
17 lines 展开代码

Model fallback#

Python3 点击展开代码
13 lines 展开代码

PII detection#

Python3 点击展开代码
11 lines 展开代码
Python3 点击展开代码
63 lines 展开代码

3. Custom middleware#

自定义的中间件,就是前面说的几个钩子自定义函数,大概有这几类:

Node-style:

  • @before_agent - 智能体启动前执行(每次调用仅运行一次)
  • @before_model - 每次调用模型前执行
  • @after_model - 每次模型返回结果后执行
  • @after_agent - 智能体执行完成后执行(每次调用仅运行一次)

Wrap-style:

  • @wrap_model_call - 用自定义逻辑包装每次模型调用
  • @wrap_tool_call - 用自定义逻辑包装每次工具调用 Convenience:
  • @dynamic_prompt - 生成动态系统提示词

关于这几个的调用,假设我们传入了三个中间件,执行流大概是这样的:

Before hooks run in order:
middleware1.before_agent()
middleware2.before_agent()
middleware3.before_agent()
Agent loop starts
middleware1.before_model()
middleware2.before_model()
middleware3.before_model()
Wrap hooks nest like function calls:
middleware1.wrap_model_call() → middleware2.wrap_model_call() → middleware3.wrap_model_call() → model
After hooks run in reverse order:
middleware3.after_model()
middleware2.after_model()
middleware1.after_model()
Agent loop ends
middleware3.after_agent()
middleware2.after_agent()
middleware1.after_agent()

4. Agent jumps#

我们可以使用jump_to命令,提前退出中间件,有几个条跳转对象:

  • 'end':跳转到智能体执行结束(或首个after_agent钩子)
  • 'tools':跳转到工具节点
  • 'model':跳转到模型节点(或首个before_model钩子)

例子如下:

Python3 点击展开代码
16 lines 展开代码

5. 最好的用法#

  • 保持中间件职责专一 —— 每个中间件只做好一件事
  • 优雅处理错误 —— 避免中间件异常导致智能体崩溃

使用合适的钩子类型:

  • 节点式钩子用于顺序逻辑(日志记录、数据校验)
  • 包装式钩子用于控制流(重试、降级、缓存)
  • 清晰文档化所有自定义状态属性
  • 集成前对中间件进行独立单元测试
  • 考虑执行顺序 —— 关键中间件放在列表首位
  • 尽可能使用内置中间件

专题阅读

LangChain

这篇文章属于同一条阅读链。你可以直接在这里切换,不用再回到列表页重新找。

当前进度11 / 11

留言区

留言

欢迎纠错、补充、交流。昵称和评论内容必填;如果你愿意,也可以留下联系方式,仅站主可见。

0

正在加载评论...

0 / 2000

阅读导航

文章目录

当前阅读位置将在这里显示

0 节