§06 中间件是 DeepAgents 的灵魂
先给结论:中间件拦截每一次 LLM 请求。它能改提示词、筛工具、跨轮追踪、注入上下文。
普通工具是"被调用的函数"。中间件是"包裹整个流程的层"。 这是两回事。
我用一个类比级联说清:
- 工具 = 员工的双手,干具体活。
- 中间件 = 主管,在员工动手前定规矩、动手后做检查。
默认中间件栈(从底层到高层)
FilesystemMiddleware 文件工具 + 大结果驱逐(>20k token)
SubAgentMiddleware task 工具 + 子代理管理
SummarizationMiddleware 上下文压缩(85% 阈值触发)
MemoryMiddleware AGENTS.md 注入(每轮)
SkillsMiddleware SKILL.md 渐进式披露
TodoListMiddleware 任务追踪
AnthropicPromptCachingMiddleware 省 token
PatchToolCallsMiddleware 修中断的工具调用
设了 interrupt_on,还会加 HumanInTheLoopMiddleware。
自己写一个中间件
日志需求,别用 callback。用 @wrap_tool_call:
from langchain.agents.middleware import wrap_tool_call
@wrap_tool_call
def log_tool_calls(request, handler):
print(f"调用工具: {request.name}") # 动手前
result = handler(request) # 真正执行
return result # 动手后
agent = create_deep_agent(model="...", middleware=[log_tool_calls])
每个中间件能挂四个钩子:
before_agent 整体预处理
before_model LLM 调用前
after_model LLM 调用后
after_agent 整体后处理
标叔的结论:要改提示词、跨轮追踪、动态注入——用中间件。无状态、自包含的函数——用普通工具。这个分水岭要清楚。
注意:别把日志挂模型
callbacks上。会和默认中间件冲突。这是 §19 里一个真实踩坑。
下一章,讲数据存在哪:后端系统。