前面四篇把 Chain、Tool、Agent、记忆都跑通了但代码还像是玩具模型调用失败就抛异常工具报错就崩溃敏感操作也没有审核。我开始想如果要把 Agent 放到生产环境里至少得有加重试、有 fallback、关键操作前让人确认。这些能力在 LangChain 里叫Middleware中间件是 Agent Harness 的一部分。这篇文章记录我第一次给 Agent 加中间件的经历。一、我当时想干什么我想让 Agent 具备三个能力容错模型或工具调用失败时自动重试人工审核Agent 写文件前必须停下来等我确认文件操作Agent 能把搜索结果写入文件我最初的代码来自文档fromlangchain.agentsimportcreate_agentfromlangchain.agents.middlewareimport(ModelRetryMiddleware,ToolRetryMiddleware,HumanInTheLoopMiddleware,)fromdeepagents.middlewareimportFilesystemMiddlewarefromdeepagents.backendsimportStateBackendfromlangchain_core.toolsimporttoolfromlangchain_openaiimportChatOpenAI backendStateBackend()tooldefsearch(query:str)-str:搜索工具returnf搜索结果{query}tooldefwrite_file(filename:str,content:str)-str:写入文件withopen(filename,w,encodingutf-8)asf:f.write(content)returnf已写入{filename}llmChatOpenAI(modeldeepseek-chat,temperature0,openai_api_key你的 api key,openai_api_basehttps://api.deepseek.com/v1,)agentcreate_agent(modelllm,tools[search,write_file],middleware[FilesystemMiddleware(backendbackend),ModelRetryMiddleware(max_retries3),ToolRetryMiddleware(max_retries2),HumanInTheLoopMiddleware(interrupt_on{write_file:True}),],)但第一次运行就报错了。二、我写的代码问题出在HumanInTheLoopMiddleware配置了一个不存在的工具。我最初写HumanInTheLoopMiddleware(interrupt_on{write_file:True})但tools里只有search没有write_file。修改后把两个工具都加进去agentcreate_agent(modelllm,tools[search,write_file],middleware[FilesystemMiddleware(backendbackend),ModelRetryMiddleware(max_retries3),ToolRetryMiddleware(max_retries2),HumanInTheLoopMiddleware(interrupt_on{write_file:True}),],)streamagent.stream_events({messages:[{role:user,content:搜索 AI 新闻并写入 report.txt}]},configconfig,versionv3,)forsnapshotinstream.values:latestsnapshot[messages][-1]iflatest.content:print(fAgent{latest.content})eliflatest.tool_calls:names[tc[name]fortcinlatest.tool_calls]print(f准备调用工具{names})现在 Agent 想写文件前会暂停等人确认后再继续。三、我遇到的坑坑 1deepagents没安装第一次运行时报ModuleNotFoundError: No module named deepagentsFilesystemMiddleware和StateBackend来自deepagents包不是 LangChain 核心。需要先安装pipinstalldeepagents如果只是想体验核心中间件可以先用langchain.agents.middleware里的不需要deepagents。坑 2interrupt_on里写了不存在的工具我一开始只有search工具但配了HumanInTheLoopMiddleware(interrupt_on{write_file:True})这个配置不会报错但永远也不会触发因为 Agent 根本不会调用write_file。interrupt_on里的工具名必须在tools列表里存在并且要写好 docstringAgent 才知道什么时候该调用。坑 3stream_events()调用不完整我一开始写resultagent.stream_events()结果报错提示缺少参数。stream_events至少需要两个参数streamagent.stream_events({messages:[{role:user,content:搜索 AI 新闻并总结}]},versionv3,configconfig,)坑 4中间件顺序没想清楚我把HumanInTheLoopMiddleware放在最前面把FilesystemMiddleware放在最后面试过一次。虽然没报错但逻辑上不舒服文件操作中间件应该先准备好执行环境重试中间件应该靠近实际调用人工审核应该放在最后把关后来我改成middleware[FilesystemMiddleware(backendbackend),# 1. 执行环境ModelRetryMiddleware(max_retries3),# 2. 模型容错ToolRetryMiddleware(max_retries2),# 3. 工具容错HumanInTheLoopMiddleware(...),# 4. 人工审核]这个顺序更符合先准备、再执行、再兜底、最后审核的直觉。四、搞清楚后的结论LangChain 新架构里的 Agent 可以表示为Agent Model Harnesscreate_agent是 Harness 的一种实现而 Middleware 是扩展 Harness 的方式。是否MiddlewareFilesystemMiddlewareModelRetryMiddlewareToolRetryMiddlewareHumanInTheLoopMiddleware用户输入Middleware 层Model 推理调用工具Tool 执行最终输出每个中间件只负责一件事中间件作用使用场景ModelRetryMiddleware模型调用失败重试API 超时、rate limitToolRetryMiddleware工具调用失败重试外部服务抖动HumanInTheLoopMiddleware关键操作前暂停确认写文件、删数据、发邮件FilesystemMiddleware给 Agent 文件系统能力读配置、写报告五、我的收获生产级的 Agent不是模型有多强而是失败时能不能优雅地活下来。写中间件之前我的 Agent 像是一个只能在 demo 环境里跑的玩具正常流程能走通一旦出错就挂。加了ModelRetryMiddleware和ToolRetryMiddleware后它能应对网络抖动和偶发失败。加了HumanInTheLoopMiddleware后它能在高风险操作前停下来等人确认。这些能力模型本身不会给你必须靠 Harness 来实现。理解了 Middleware才算是从会写 Agent进阶到敢把 Agent 放生产。到这里我学 LangChain Agent 的五篇笔记就写完了。接下来准备进入 LangGraph把循环、状态、持久化这些概念再往上拔一层。