求助:LangChain结合Agent与Memory功能失败(基于AWS Bedrock Claude)
问题:LangChain Agent结合DynamoDB Memory未生效
尝试在LangChain中整合Agent的联网搜索功能(DuckDuckGo、Wikipedia)与基于AWS DynamoDB的对话历史记忆功能,使用Bedrock上的Claude模型作为交互模型,但将Memory传入AgentExecutor后未生效,无法保留对话历史。
问题根源分析
- Prompt模板未包含对话历史变量:自定义的PromptTemplate没有加入
chat_history输入变量,导致Agent无法获取对话历史。 - 手动调用memory.save_context导致重复存储:在
send_message函数中手动调用memory.save_context,但AgentExecutor本身会自动处理记忆存储,重复操作会导致数据混乱。 - invoke时传入冗余参数:AgentExecutor.invoke只需要传入
input参数即可,无需手动传入tools、tool_names、agent_scratchpad和chat_history,这些参数会由Agent和Memory自动处理。 - Memory未指定输出键:ConversationBufferMemory需要指定
memory_key="chat_history",确保与Prompt中的变量名匹配。
修正后的完整代码
import boto3 import json import os from langchain import hub from langchain.agents import create_react_agent from langchain_community.agent_toolkits.load_tools import load_tools from langchain_community.chat_message_histories import DynamoDBChatMessageHistory from langchain.memory import ConversationBufferMemory from langchain_aws import ChatBedrock from langchain.prompts import PromptTemplate from langchain_core.exceptions import OutputParserException from langchain.agents import AgentExecutor # AWS客户端配置 session = boto3.Session(region_name='ap-northeast-1') secrets_client = session.client('secretsmanager') bedrock_client = session.client( service_name='bedrock-runtime', region_name='ap-northeast-1', endpoint_url='https://bedrock-runtime.ap-northeast-1.amazonaws.com' ) # 获取LangChain API密钥 def get_langchain_api_key(secret_name): response = secrets_client.get_secret_value(SecretId=secret_name) secret_string = response['SecretString'] secret_dict = json.loads(secret_string) return secret_dict['LANGCHAIN_API_KEY'] api_key = get_langchain_api_key('LANGCHAIN_API_KEY') os.environ["LANGCHAIN_API_KEY"] = api_key # 会话ID设置 session_id = 'unique_session_id_20240827' # DynamoDB对话历史存储配置 history = DynamoDBChatMessageHistory(table_name="chat-history-dynamodb", session_id=session_id) # Bedrock Claude模型配置 chat_model = ChatBedrock(model_id='anthropic.claude-3-5-sonnet-20240620-v1:0', client=bedrock_client) # 修正后的Prompt模板:加入chat_history变量 prompt = PromptTemplate( input_variables=["input", "tools", "tool_names", "agent_scratchpad", "chat_history"], template=( "你是一个乐于助人的助手,请结合以下对话历史和提供的工具回答用户问题:\n" "对话历史:{chat_history}\n" "可用工具:{tools}\n" "工具名称列表:{tool_names}\n" "思考记录:{agent_scratchpad}\n" "用户当前输入:{input}\n" "请按照以下格式输出:\n" "如果需要使用工具,输出:\n" "Action: <工具名称>\n" "Action Input: <工具输入内容>\n" "如果不需要工具直接回答,输出:\n" "Response: <回答内容>" ) ) # 修正后的Memory配置:指定memory_key与Prompt变量匹配 memory = ConversationBufferMemory(chat_memory=history, memory_key="chat_history", return_messages=False) # 加载联网搜索工具 tools = load_tools(["ddg-search", "wikipedia"], llm=chat_model) # 创建REACT Agent agent = create_react_agent( llm=chat_model, tools=tools, prompt=prompt ) # 初始化AgentExecutor:传入memory agent_executor = AgentExecutor(agent=agent, tools=tools, memory=memory, verbose=True) # 对话处理函数 def send_message(user_message): try: # 仅传入input参数,其余由AgentExecutor自动处理 response = agent_executor.invoke({"input": user_message}) output_text = response.get("output", str(response)) return output_text except OutputParserException as e: print(f"输出解析错误:{e}") except AttributeError: print("错误:Agent对象不可调用,请检查Agent创建逻辑") except Exception as e: print(f"发生未知错误:{e}") return None # 测试对话流程 # 第一步:告知名字 # user_message = '你好,我叫张三' # response = send_message(user_message) # print(response) # 第二步:测试记忆 user_message = '你还记得我叫什么名字吗?' response = send_message(user_message) if response: print(response) else: print("未能获取Agent响应")
关键修改说明
- Prompt模板新增
chat_history变量:让Agent能读取对话历史内容 - Memory指定
memory_key="chat_history":确保Memory输出的键与Prompt中的变量名一致 - 移除手动调用
memory.save_context:AgentExecutor会自动处理对话历史的存储 - 简化
agent_executor.invoke参数:仅传入input即可,无需手动传递其他参数 - 优化输出格式提示:让Claude更清晰地理解需要遵循的输出规则
内容的提问来源于stack exchange,提问作者Ryou T
相关产品推荐
相关产品推荐

