2026-04-22 LangChain Agent 中间件 Bug 记录总结

今日核心场景:LangChain 最新版(含LangGraph)Agent 中间件配置与运行,目标实现「中间件日志监控+工具调用+system角色注入」,全程遇到6个核心Bug,均已解决,现将所有Bug及解决方案整理如下,方便后续复盘。

一、Bug1:Prompt格式不兼容报错

报错信息

ValueError: Unexpected message type: agent_scratchpad. Use one of 'human', 'user', 'ai', 'assistant', or 'system'.

报错原因

新版 LangChain Agent(create_agent)不支持旧版 ChatPromptTemplate + agent\_scratchpad 格式,两套体系不兼容;新版无需手动定义完整Prompt模板,仅需通过 system\_prompt 参数注入角色。

解决方案

  1. 删除 ChatPromptTemplatePromptTemplate 相关代码

  2. 改用纯字符串给 system\_prompt 赋值,用于设定Agent角色

二、Bug2:create_agent 参数错误

报错信息

TypeError: create_agent() got an unexpected keyword argument 'prompt'

报错原因

1. 混淆新版 create\_agent 与旧版 create\_react\_agent,新版 create\_agentprompt 参数;

2. 误将旧版参数写法(prompt=xxx)用于新版函数。

解决方案

  1. 删除 prompt 参数,改用 system\_prompt 参数注入角色描述(纯字符串);

  2. 新版 create\_agent 核心参数仅需 modeltools,可选 system\_promptmiddleware

三、Bug3:Pydantic 类型错误(字符串/字典类型不匹配)

报错信息

Input should be a valid string [type=string_type, input_value=('input_types', {}), input_type=tuple]
Input should be a valid dictionary [type=dict_type, input_value=('output_parser', None), input_type=tuple]

报错原因

误将 PromptTemplate 对象传入 system\_prompt 参数,新版 system\_prompt 仅接受纯字符串,不支持任何模板对象。

解决方案

system\_prompt 改为纯字符串,删除所有 PromptTemplateChatPromptTemplate 相关定义。

四、Bug4:中间件装饰器使用错误

报错信息

AttributeError: type object 'function' has no attribute 'wrap_tool_call'

报错原因

1. 新版 LangChain 中间件不支持「装饰器函数」直接传入 middleware 列表;

2. 误将 @before\_agent@wrap\_tool\_call 装饰的函数放进 middleware,系统会将其识别为工具中间件,查找 wrap\_tool\_call 属性失败。

解决方案

  1. 删除所有中间件装饰器(@before\_agent@wrap\_tool\_call 等);

  2. 改用「类中间件」,继承 AgentMiddleware,重写同步方法(before\_agentbefore\_model 等);

  3. 将类中间件实例传入 middleware 列表(如 middleware=\[LogMiddleware\(\)\])。

五、Bug5:异步中间件与同步调用不兼容

报错信息

NotImplementedError: Synchronous implementation of wrap_tool_call is not available. You are likely encountering this error because you defined only the async version...

报错原因

1. 定义了异步中间件(如 @wrap\_tool\_call 装饰的 async 函数);

2. 使用同步调用方式 agent\.invoke\(\),同步调用不支持异步中间件。

解决方案

  1. 初学/调试场景:删除所有异步中间件,仅保留类中间件中的同步方法(before\_agentbefore\_model 等);

  2. 需异步场景:将中间件改为异步方法(abefore\_agentabefore\_model 等),使用 await agent\.ainvoke\(\) 异步调用。

六、Bug6:AIMessage 对象无法用字典索引

报错信息

TypeError: 'AIMessage' object is not subscriptable

报错原因

新版 Agent 调用返回的 result\[\&\#34;messages\&\#34;\] 中,元素是 AIMessageHumanMessage 对象,不是字典,无法用 \[\&\#34;content\&\#34;\] 索引获取内容。

解决方案

通过对象属性获取内容,即 msg\.content(而非 msg\[\&\#34;content\&\#34;\]),可通过循环遍历 result\[\&\#34;messages\&\#34;\] 找到最终回答。

二、今日核心避坑要点

  1. 新版 create\_agentprompt 参数,仅用 system\_prompt(纯字符串)设定角色;

  2. 中间件必须用「类形式」(继承 AgentMiddleware),不能用装饰器函数;

  3. 同步调用(invoke\(\))对应类中间件的同步方法(无 async 修饰);

  4. 异步中间件(async 修饰)必须搭配异步调用(ainvoke\(\));

  5. 返回的 Message 对象用\.content 获取内容,不能用字典索引;

  6. middleware 参数必须配置,否则中间件不生效,需传入类中间件实例。

三、最终可运行核心逻辑(避坑版)

from langchain.agents import create_agent, AgentMiddleware
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain.tools import tool

# 1. 工具定义
@tool(description='查询天气')
def get_weather() -> str:
    return '晴天'

tools = [get_weather]

# 2. 类中间件(同步版,适配invoke())
class LogMiddleware(AgentMiddleware):
    def before_agent(self, state, runtime):
        print(f"[before_agent] 消息数: {len(state['messages'])}")
    def after_agent(self, state, runtime):
        print("[after_agent] 完成")
    def before_model(self, state, runtime):
        print("[before_model] 调用LLM")
    def after_model(self, state, runtime):
        print("[after_model] 调用完成")

# 3. 模型与系统提示词
llm = ChatTongyi(model_name='qwen3-max', temperature=0)
system_prompt = "你是专业天气助手,只回答天气相关问题,简洁准确。"

# 4. 创建Agent(必传middleware)
agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt=system_prompt,
    middleware=[LogMiddleware()]
)

# 5. 同步调用与结果获取
result = agent.invoke({
    "messages": [("user", "今天北京天气怎么样?")]
})

# 6. 正确获取最终回答
for msg in reversed(result["messages"]):
    if msg.content:
        print("最终回答:", msg.content)
        break
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐