LangChain带Memory的Agent出现上下文丢失与超时问题求助
问题描述
我编写了一个初始化Agent并调用生成回复的函数,该函数通过工具将用户输入转换为结构化输出。不使用Memory时,能在约4秒内返回预期格式的响应。根据LangChain文档,我使用的chat-conversational-react-description Agent默认采用BufferMemory,因此创建BufferMemory实例并分配给Agent执行器,但这导致响应超时(耗时超1分钟)。LangChain默认日志显示终端已生成正确输出,但未返回,之后Agent丢失问题上下文,最终输出错误格式的结果,仅移除后端超时限制才会返回。
代码示例
const activityTextParser = StructuredOutputParser.fromNamesAndDescriptions({ name: "name of user's activity", duration: "time duration in seconds of user's activity", }); const activityFormatInstructions = activityTextParser.getFormatInstructions(); const activityPrompt = new PromptTemplate({ template: "Structure the output based on user's input.\n{format_instructions}\n{instruction}", inputVariables: ['instruction'], partialVariables: { format_instructions: activityFormatInstructions }, }); const model = new ChatOpenAI({ openAIApiKey: process.env.OPENAI_API_KEY, temperature: 0, }); const activityTool = new DynamicTool({ name: 'Create activity tool', description: 'Uses user input to create activity JSON object', func: async (text: string) => { const input = await activityPrompt.format({ instruction: text, }); return input; }, }); const tools = [activityTool]; const executor = await initializeAgentExecutorWithOptions(tools, model, { agentType: 'chat-conversational-react-description', verbose: true, }); const chatHistory = [ new AIChatMessage( 'Hi there! I am your productivity assistant, how can I help you today?', ), ]; const memory = new BufferMemory({ chatHistory: new ChatMessageHistory(chatHistory), memoryKey: 'chat_history', returnMessages: true, }); executor.memory = memory; const res = await executor.call({ input: 'Create an activity named Reading that lasts for 10 minutes', }); console.log({ res }); return res;
输出情况
- 注释掉
executor.memory = memory后,输出恢复正常。 - 预期输出格式:
"output": { "name": "Reading", "duration": "600" }
- Agent丢失上下文后的输出格式:
{ "output": "The activity named Reading lasts for 10 minutes." }
解决建议
- 避免手动赋值Memory,初始化时传入:不要直接给
executor.memory赋值,应该在调用initializeAgentExecutorWithOptions时直接传入memory参数。手动赋值可能破坏Agent内部的记忆绑定逻辑,引发循环调用或上下文处理异常。修改后的初始化代码如下:
const memory = new BufferMemory({ chatHistory: new ChatMessageHistory(chatHistory), memoryKey: 'chat_history', returnMessages: true, }); // 初始化时直接传入memory const executor = await initializeAgentExecutorWithOptions(tools, model, { agentType: 'chat-conversational-react-description', verbose: true, memory: memory });
- 优化工具逻辑,直接返回结构化结果:当前工具仅返回格式化后的prompt文本,Agent需要额外处理才能得到结构化数据。加入Memory后上下文变长,容易导致Agent混淆历史消息与工具输出。可以在工具内部直接调用模型并解析结果:
const activityTool = new DynamicTool({ name: 'Create activity tool', description: 'Uses user input to create activity JSON object', func: async (text: string) => { const input = await activityPrompt.format({ instruction: text, }); const response = await model.call(new HumanChatMessage(input)); // 直接解析并返回结构化数据 return activityTextParser.parse(response.text); }, });
自定义Agent Prompt,明确输出要求:
chat-conversational-react-description的默认prompt可能未明确要求保留结构化输出规则。可以自定义prompt,明确告知Agent必须返回工具生成的结构化JSON,同时正确引用对话历史。排查循环调用问题:超时可能是因为Agent陷入了循环调用工具的逻辑。开启verbose日志后,检查Agent的思考步骤,确认是否存在重复调用工具但未处理结果的情况。
内容的提问来源于stack exchange,提问作者DeonV
相关产品推荐
相关产品推荐

