You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

LangGraph中使用@before_agent钩子覆写Agent状态时触发InvalidUpdateError错误求助

LangGraph中使用@before_agent钩子覆写Agent状态时触发InvalidUpdateError错误求助

哥们,我刚踩过LangGraph钩子同步异步混用的坑,一眼就看出你这问题出在哪了!

先看错误提示:说期望返回dict,但得到了协程对象——这明显是同步钩子和异步钩子搞混了导致的。

问题根源

LangGraph的Agent中间件钩子分两种:

  • 同步Agent用的:before_agent,必须用普通def定义,直接返回dict
  • 异步Agent用的:abefore_agent,必须用async def定义,返回的是可等待的dict(async函数自动包装成协程,LangGraph会自动await它)

看你的代码,你同时定义了before_agentabefore_agent,而且都是用普通def写的。如果你的Agent是异步模式(比如用了AsyncAgent),LangGraph会自动调用abefore_agent,但因为你用了同步def定义,它会被当成协程对象返回,而不是实际的dict,这就触发了InvalidUpdateError

另外,你代码里还有个小问题:直接修改原state里的message对象是不推荐的,LangGraph的state设计偏向不可变,直接修改可能会引发其他隐性问题,最好是创建新的消息对象来替换。

修复方案

分两种情况处理:

如果你用的是同步Agent

  1. 删掉冗余的abefore_agent方法,只保留before_agent
  2. _process_files里直接修改原message的逻辑改成创建新的消息对象(更安全):
def _process_files(self, state, runtime):
    messages = state.get("messages")
    extracted_files = []
    runtime.override()
    new_messages = []
    for message in messages:
        if isinstance(message, HumanMessage) and isinstance(message.content, list):
            non_file_content = []
            for item in message.content:
                if isinstance(item, dict) and item.get("type") == "file":
                    file_info = item.get("file", {})
                    if "file_data" in file_info:
                        extracted_files.append(file_info["file_data"])
                else:
                    non_file_content.append(item)
            # 创建新的HumanMessage,而不是修改原对象
            new_msg = HumanMessage(content=non_file_content, id=message.id)
            new_messages.append(new_msg)
        else:
            new_messages.append(message)
    return {"messages": new_messages}

def before_agent(self, state, runtime):
    return self._process_files(state, runtime)

如果你用的是异步Agent

  1. 删掉同步的before_agent方法,只保留abefore_agent,并且把它改成async def
  2. 同样建议修改_process_files的逻辑,创建新消息对象:
def _process_files(self, state, runtime):
    messages = state.get("messages")
    extracted_files = []
    runtime.override()
    new_messages = []
    for message in messages:
        if isinstance(message, HumanMessage) and isinstance(message.content, list):
            non_file_content = []
            for item in message.content:
                if isinstance(item, dict) and item.get("type") == "file":
                    file_info = item.get("file", {})
                    if "file_data" in file_info:
                        extracted_files.append(file_info["file_data"])
                else:
                    non_file_content.append(item)
            new_msg = HumanMessage(content=non_file_content, id=message.id)
            new_messages.append(new_msg)
        else:
            new_messages.append(message)
    return {"messages": new_messages}

# 改成async def的异步钩子
async def abefore_agent(self, state, runtime):
    return self._process_files(state, runtime)

额外注意点

  • 一定要确保钩子的定义和你的Agent运行模式完全匹配,同步用同步钩子,异步用异步钩子,别混用
  • 尽量不要直接修改原state里的对象,创建新对象替换更符合LangGraph的状态管理设计,能避免很多隐性bug
  • 调用runtime.override()是对的,这个方法会告诉LangGraph你要覆写state,而不是做增量更新

按这个改完,你那个InvalidUpdateError肯定就消失了!

火山引擎 最新活动