🏭导航收藏不迷路—>制造业数据与AI践行者老蒋的技术博客全系列文章汇总(持续更新)
文章摘要
与Agent对话时,用户分三次提供了意图、日期、产线名称,但Agent每次都重新询问缺失信息,仿佛患上“失忆症”。本文剖析Agent无状态(Stateless)的设计本质,揭示AgentExecutor默认不携带Memory的机制缺陷,并提供ConversationBufferMemory的接入方案。适用于所有基于LangChain构建对话Agent的开发者。

问题现象
兄弟们,前面五篇排坑笔记你们一路跟下来了。导入链污染、版本碎片化、中文括号、嵌套JSON、花括号战争——我们一个接一个地解决了。
我以为Agent终于可以好好干活了。
然后我做了一个测试——模拟真实用户的对话习惯,分三次输入信息:
🧑💻 你: oee
🤖 Agent: 您好,请告知我要查询哪条产线以及具体是哪个日期的数据?
🧑💻 你: 2026-07-18
🤖 Agent: 您想查询哪条生产线在2026-07-18的OEE呢?请提供具体的产线名称。
🧑💻 你: 交互屏组装A线
🤖 Agent: 请问您想查询哪一天的OEE数据?
我当时的第一反应又是:这不科学啊......😀
我跟它说了三次话:第一次说我要查OEE,第二次给了日期,第三次给了产线名称。正常人(或者说正常程序)应该能把这三条信息拼在一起,然后给我答案吧?
结果它倒好,我说OEE它问产线,我给产线它问日期,我给日期它又问产线——就像一条金鱼,记忆力只有3秒钟。
根因分析
说句实在话,这其实不是Agent的Bug,而是它的出厂设置就是这样。但问题是,LangChain的文档里没有把这个“特性”用大字标出来,导致我一开始以为是自己代码写错了。
第一层:Agent是无状态的(Stateless by Design)
LangChain的AgentExecutor在默认情况下,每次调用invoke()都是一次独立的对话。它不会记住上一次用户说了什么,也不会记住上一次它自己说了什么。
每次调用时,Agent接收到的信息只有:
-
当前这一次的用户输入(
input) -
当前这一次的工具调用历史(
intermediate_steps)
它看不到之前的对话记录。
这就意味着,当你分三次输入信息时,Agent的视角是这样的:
第1次调用:用户说"oee" → 我不知道产线和日期 → 我问他要
第2次调用:用户说"2026-07-18" → 我不知道这是日期还是别的什么 → 我问他产线
第3次调用:用户说"交互屏组装A线" → 我不知道日期 → 我问他日期
每一次都是全新的一轮对话,之前的上下文全部丢失。
第二层:为什么会这样设计?
LangChain的设计者可能认为,Agent应该是无状态的、可独立调用的函数——每次输入都独立处理,不依赖外部状态。这样的设计在微服务架构、批量处理等场景下是合理的。
但问题是,我们做的是对话Agent。
对话的本质是多轮交互,用户不会一次性把所有信息都告诉你,而是像跟人聊天一样,想到哪儿说到哪儿。一个没有记忆的对话Agent,就像一个每次见面都问你“你叫什么名字”的朋友——你会觉得他要么是记性太差,要么是根本不在乎你。
第三层:你可能会问——那我用ConversationBufferMemory不就行了吗?
是的,ConversationBufferMemory就是解决方案。但LangChain 0.3.x版本中,AgentExecutor对memory的支持方式发生了变化,不是简单传进去就能用的。如果只是把memory塞给AgentExecutor,你会发现它根本不搭理你。
这也是我花了点时间才搞明白的。
解决方案
说实话,ConversationBufferMemory这个方案本身不复杂,但LangChain的文档写得跟天书一样,东一榔头西一棒槌。我踩了一遍坑之后,整理出一套能直接跑的办法。
第一步:在common/base_agent_builder.py中注入Memory
修改BaseAgentBuilder的build方法,把memory挂到AgentExecutor上:
from langchain.memory import ConversationBufferMemory
class BaseAgentBuilder:
def __init__(self, temperature: float = 0.1, max_iterations: int = 5, with_memory: bool = True):
self.llm = get_llm(temperature=temperature)
self.max_iterations = max_iterations
self.with_memory = with_memory
self._tools = None
def build(self) -> AgentExecutor:
tools = self._register_tools()
prompt = PromptTemplate.from_template(self._get_prompt_template())
agent = create_react_agent(self.llm, tools, prompt)
# ---- 关键:注入Memory ----
memory = None
if self.with_memory:
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
executor = AgentExecutor(
agent=agent,
tools=tools,
memory=memory, # 这里传入memory
verbose=True,
max_iterations=self.max_iterations,
handle_parsing_errors=True
)
return executor
第二步:修改Prompt模板,让Agent知道“历史记录”的存在
这一步是很多人会漏掉的。你光给Agent塞了Memory,但如果不告诉它“你有历史记录可以用”,它还是会无视。
在_get_prompt_template中,增加chat_history的引用:
def _get_prompt_template(self) -> str:
return """
你是一个专业的制造业AI助手。
以下是对话历史记录:
{chat_history}
当前用户的问题是:{input}
你有权使用以下工具:{tools}
...
"""
这样Agent在每次推理时,都会把之前所有的对话记录都加载到Prompt里,实现“记忆”的效果。
第三步:验证——Agent终于“长记性”了
修改之后,重新运行测试:
🧑💻 你: oee
🤖 Agent: 请问您要查询哪条产线、哪一天的OEE呢?
🧑💻 你: 交互屏组装A线
🤖 Agent: 好的,产线是交互屏组装A线,请问具体是哪一天呢?
🧑💻 你: 2026-07-12
🤖 Agent: 正在计算交互屏组装A线在2026-07-12的OEE...
🤖 Agent: 交互屏组装A线在2026-07-12的OEE为86.39%。
这才是对话该有的样子!
经验总结
怕你忘了,我再啰嗦一遍:Agent默认是金鱼记忆,想让它有长期记忆,你得主动给它装一个“记忆芯片”。
落到具体操作上就是四条:
-
AgentExecutor默认不携带memory。这是它的设计机制,不是Bug。想让Agent记住对话,必须主动注入ConversationBufferMemory或其它Memory类型。 -
注入Memory的同时,必须在Prompt模板里添加
{chat_history}占位符。如果你只注入不引用,Agent依然会无视历史记录——就像你给一个健忘症患者配了笔记本,但没告诉他要翻笔记本一样。 -
ConversationBufferMemory会随着对话变长而膨胀。如果对话轮次很多(超过20轮),建议换成ConversationSummaryMemory或ConversationBufferWindowMemory,避免Token超限。 -
Case02将完整实现带记忆的Agent。本文只介绍了核心原理和最小实现方案。在即将发布的Case02中,我们会做一个完整的、可直接复用的带记忆Agent,支持持久化存储和跨会话记忆。
系列导航
📚 排坑笔记系列汇总
至此,《数据与AI工程排坑笔记》系列6篇文章已全部交付:
| 编号 | 标题 | 状态 |
|---|---|---|
| 坑01 | __init__.py导入链污染 | ✅ 已发布 |
| 坑02 | LangChain版本碎片化 | ✅ 待发布 |
| 坑03 | Pydantic中文括号SyntaxError | ✅ 待发布 |
| 坑04 | Agent嵌套JSON套娃 | ✅ 待发布 |
| 坑05 | PromptTemplate花括号冲突 | ✅ 待发布 |
| 坑06 | Agent无记忆之痛 | ✅ 待发布 |
本文问题源自:智联工坊实战:制造知识库工具调用Agent从零搭建(OEE+手册+排班)-优快云博客 完整源码及深度教程见该文详细内容。
💡 建议收藏:下次遇到Agent“金鱼记忆”问题,可以快速对照本文排查。
互动与交流
你在使用LangChain Agent时,有没有被它“金鱼般的记忆”折磨过?欢迎在评论区吐槽,或者分享你配置Memory时遇到的奇葩问题——咱们互相支支招。
关于作者
制造业数据与AI践行者老蒋,23年IT老兵。聚焦制造业数据架构与AI融合落地。全流程实战,全源码开源。
标签:#排坑笔记 #LangChain #Agent #记忆系统
370



被折叠的 条评论
为什么被折叠?



