Langchain为Gmail Agent添加内存失效问题排查请求
STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION Agent对话内存失效原因及解决
问题描述
我尝试通过以下代码为STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION类型的Gmail Agent添加对话内存:
from langchain.prompts import MessagesPlaceholder from langchain.memory import ConversationBufferMemory llm = OpenAI(temperature=0) agent_kwargs = { "extra_prompt_messages": [MessagesPlaceholder(variable_name="memory")], } memory = ConversationBufferMemory(memory_key="memory", return_messages=True) agent = initialize_agent( tools=tools, llm=llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, memory=memory, agent_kwargs=agent_kwargs, verbose=True )
但发送第二个请求时,Agent执行了完全不同的Gmail查询,未保留短期记忆。
原因分析
- 核心问题是记忆未被正确注入到Agent的Prompt关键位置。STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION类型的Agent有固定的Prompt结构,仅通过
extra_prompt_messages添加MessagesPlaceholder,会导致对话历史被放在Prompt的非优先读取区域(比如末尾),LLM生成思考逻辑时无法优先获取之前的对话上下文,自然不会复用历史信息。 - 另外,默认的
ConversationBufferMemory虽能存储对话,但如果Prompt未明确将历史对话置于当前用户查询之前,Agent无法关联前后请求的逻辑关联。
解决方法
需要自定义Agent的Prompt模板,将对话记忆的占位符放在系统提示与当前用户输入之间,确保LLM优先读取历史上下文。修改后的代码示例:
from langchain.prompts import MessagesPlaceholder, ChatPromptTemplate from langchain.memory import ConversationBufferMemory from langchain.agents import AgentType, initialize_agent from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(temperature=0) # 自定义STRUCTURED_CHAT类型的Prompt模板 prompt = ChatPromptTemplate.from_messages( [ ("system", """你是一个能操作Gmail的助手,按照以下格式思考和行动: 思考:我需要做什么? 行动:调用工具的名称,参数为JSON格式 行动输入:工具的具体参数 当你完成任务后,用Final Answer回复。"""), # 对话记忆放在系统提示之后、当前用户查询之前 MessagesPlaceholder(variable_name="memory"), ("user", "{input}"), # 必须保留agent_scratchpad,用于存储思考和工具调用记录 MessagesPlaceholder(variable_name="agent_scratchpad"), ] ) memory = ConversationBufferMemory(memory_key="memory", return_messages=True) agent = initialize_agent( tools=tools, llm=llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, memory=memory, agent_kwargs={"prompt": prompt}, verbose=True )
关键说明
- 建议使用
ChatOpenAI而非OpenAI,STRUCTURED_CHAT类型的Agent对聊天模型的适配性更好。 - 自定义Prompt时必须保留
agent_scratchpad占位符,这是Agent存储思考过程和工具调用记录的核心区域。 - 对话记忆的
MessagesPlaceholder必须置于用户当前输入之前,保证LLM处理新请求时先读取历史对话,再解析当前查询。
内容的提问来源于stack exchange,提问作者Miguel Ángel Hernández
相关产品推荐
相关产品推荐

