🏭导航收藏不迷路--->制造业数据与AI践行者老蒋的技术博客全系列文章汇总(持续更新)
文章摘要
兄弟们,你们的AI助手是不是也像条**"金鱼"**------刚说过的事转头就忘?本文带你给【智联工坊】的制造Agent装上三种"记忆芯片":Buffer、Window、SummaryBuffer。全程实战,附完整代码和3种模式对比测试数据。看完你就知道:记忆能解决什么、解决不了什么、为什么本地小模型在"刚才那个"这种指代上会翻车。全源码开源,可直接复用。

开篇:差点被Agent的"金鱼记忆"整破防
说实话,这事让我挺郁闷的。
上一篇文章我把智联工坊的制造Agent搭好了------能算OEE、能查手册、能问排班。班组长小刘试用了一下,反馈得很委婉,但我听懂了。
他说:"老蒋,这个能算OEE了,挺好的。就是......每次我都要把话重复好几遍。它记不住我。"
他的实际体验是这样的:
bash
小刘:"我想查OEE。"
Agent:"请提供产线名称和日期。"
小刘:"交互屏组装A线。"
Agent:"请提供日期。"
小刘:"2026-07-12。"
Agent:终于开始算了。
我当时的第一反应是:这不科学啊......😀😀😀 我都把对话传给Agent了,它怎么还是像个第一次见面的陌生人?
后来我才搞明白------这还真不是Bug,而是Agent的出厂设置就是"金鱼记忆"。每次对话都是独立的,它根本不记得你上一句说了什么。
本文要解决的痛点:给这个"金鱼记忆"的Agent装上记忆芯片,让它能记住用户之前说的话,实现跨轮次的信息关联。
适合谁读 :已经跑通基础Agent(比如看过我上一篇智联工坊实战:制造知识库工具调用Agent从零搭建(OEE+手册+排班)文章的兄弟),想进一步优化对话体验的制造企业IT工程师、AI架构师。
脱敏声明:本文基于虚拟工厂"智联工坊"场景,所有数据均已脱敏处理。
正文
一、方案设计:三种记忆模式,三种"记笔记"的方式
LangChain提供了三种记忆实现。我这人说话啰嗦,但为了让你好理解,我直接打个比方:
| 记忆类型 | 打个比方 | 优点 | 缺点 | 什么时候用 |
|---|---|---|---|---|
| BufferMemory | 把整本笔记从头抄到尾 | 一个字不丢 | 对话越长、Token越贵 | 短对话、调试 |
| WindowMemory | 只留着最近3页 | Token可控 | 超过3页的直接扔了 | 固定轮数对话 |
| SummaryBufferMemory | 前面的总结成一段摘要 | 近的详细、远的压缩 | 每次总结都要花钱(调LLM) | 正式上线首选 |
我的建议很实在:你在本地调试用BufferMemory就行,简单省事。真要上生产线给班组长用,最好用SummaryBufferMemory,长期看能省不少Token钱。
二、核心实现:这次我只改了3个地方
工程目录结构和Case01几乎一样,只动了3个地方:
bash
javy21_manufacturing_ai_practice/
├── common/
│ ├── base_agent_builder.py # ① 增加了memory注入
│ ├── memory_factory.py # ② 新建:记忆工厂类
│ └── ...
├── cases/
│ └── case02_memory_agent/ # ③ 新建案例,复用Case01的工具
│ ├── tools/ # 完全复制Case01的三个工具
│ ├── agent/
│ │ └── builder.py # 就5行代码,指定用哪种记忆
│ └── scripts/
│ └── 01_test_memory.py # 测试脚本
改动1 :common/memory_factory.py------新建一个记忆工厂,把三种记忆类型统一管理。
python
class MemoryFactory:
@staticmethod
def create_memory(memory_type: str = "buffer", llm=None, window_k: int = 5):
if memory_type == "buffer":
return ConversationBufferMemory(return_messages=True, memory_key="chat_history")
elif memory_type == "window":
return ConversationBufferWindowMemory(k=window_k, return_messages=True, memory_key="chat_history")
elif memory_type == "summary_buffer":
return ConversationSummaryBufferMemory(llm=llm, max_token_limit=2000, return_messages=True, memory_key="chat_history")
return None
改动2 :common/base_agent_builder.py------在build()方法里把记忆注入进去。
python
def build(self) -> AgentExecutor:
tools = self._register_tools()
self._memory = self._create_memory() # 创建记忆实例
prompt = PromptTemplate.from_template(self._get_prompt_template()) # 模板里要有{chat_history}
agent = create_react_agent(self.llm, tools, prompt)
executor = AgentExecutor(
agent=agent,
tools=tools,
memory=self._memory, # 关键:把记忆塞进去
verbose=True,
max_iterations=5
)
return executor
这里要留个心眼 :你的Prompt模板里必须 有{chat_history}占位符,不然记忆传进去了也不生效。这个坑我等下在排坑笔记里专门讲。
改动3 :case02_memory_agent/agent/builder.py------就5行代码,指定用哪种记忆。
python
class MemoryAgentBuilder(BaseAgentBuilder):
def __init__(self, memory_type: str = "buffer", **kwargs):
super().__init__(memory_type=memory_type, **kwargs)
def _register_tools(self) -> List[BaseTool]:
return [
CalculateOEETool(),
SearchManualTool(),
QueryShiftTool()
]
三、运行验证:实测三种记忆模式
我设计了一个5轮对话测试,模拟班组长小刘的真实使用场景:
| 轮次 | 用户说什么 | Agent应该怎么做 |
|---|---|---|
| 1 | 我想查OEE |
问产线和日期 |
| 2 | 交互屏组装A线 |
只问日期(记住前面说的是查OEE) |
| 3 | 2026-07-12 |
调用工具返回OEE数据 |
| 4 | 再查一下环境监测校准B线 |
问日期(记住要查的是B线) |
| 5 | 就刚才那个日期 |
理解"刚才"就是第3轮的日期 |
BufferMemory实测结果:
| 轮次 | Agent实际表现 | 我咋看 |
|---|---|---|
| 1 | 问产线和日期 | ✅ 没问题 |
| 2 | 只问日期 | ✅ 记住意图了! |
| 3 | 返回86.39% | ✅ 信息拼上了! |
| 4 | 问日期 | ✅ 知道要查B线 |
| 5 | 没懂"刚才那个日期" | ❌ 翻车了 |
看到第5轮我沉默了。
记忆确实传进去了,Agent也确实记住了我之前说过的话。但它理解不了"刚才那个"指的是哪一天 。这个事让我想明白了一个道理:保存不等于理解。模型能记住你说了什么,但不代表它真的"懂"你在说什么。
这不是代码的问题,是本地小模型的能力边界。 Qwen2.5-7B在指代消解任务上,确实还有差距。
WindowMemory和SummaryBufferMemory的实测结果:
跟BufferMemory几乎一样------前4轮都正常,第5轮都翻车。Window的窗口机制在这次测试里没触发(因为就5轮),SummaryBuffer倒是多加载了几个tokenizer文件,证明它确实在工作。
所以我的结论很实在:
| 记忆模式 | 基础记忆 | 跨轮关联 | 理解"刚才那个" | Token消耗 | 我推荐 |
|---|---|---|---|---|---|
| BufferMemory | ✅ | ✅ | ❌ | 最高 | 调试用 |
| WindowMemory | ✅ | ✅(窗口内) | ❌ | 中等 | 定长对话 |
| SummaryBufferMemory | ✅ | ✅ | ❌ | 最低 | 正式上线用 |
四、一点真心话:记忆不是银弹
这个实验让我接受了一个现实:再好的记忆系统,也无法弥补模型本身的理解缺陷。
如果用户的表达是模糊的(比如"刚才那个"、"上次那个"),本地小模型大概率会翻车。这不是你代码写得好不好的问题,是当前技术阶段下7B参数模型的能力天花板。
那怎么办? 我的建议很实际:
-
在工程上做补偿:设计对话流程时,尽量引导用户给出明确的、结构化的信息。
-
在预期上做管理:告诉用户"请尽量一次性提供产线名称和日期",而不是让用户误以为Agent什么都能听懂。
-
在选型上做取舍 :如果你的场景对模糊指代要求很高,可能需要考虑升级到更大参数量的模型,或者用
create_structured_chat_agent来更精确地控制工具调用。
说白了就是:技术要有敬畏心,别指望一个7B的模型能听懂"刚才那个"这种只有人才懂的模糊指代。
总结:怕你忘了,我再啰嗦一遍
本文解决了什么 :给Case01的制造Agent(点击链接看详情)装上了记忆芯片,让它能记住用户之前说过的话。
三个核心认知:
-
记忆能解决"忘记",但解决不了"不理解"。对话历史确实保存了,但模型能不能正确理解"刚才那个"是另一回事。这个区别是质的区别。
-
三种记忆模式各有各的坑。Buffer耗Token最多,Window会丢超出窗口的内容,SummaryBuffer每次都要调LLM做摘要,有成本。
-
Prompt设计比记忆类型更重要。我在调试过程中,走了一大段弯路------写了超长的Prompt、加了好多"绝对禁止"的规则,结果模型反而不知道该听哪条了。最后删掉一半规则,效果反而更好。
智能工厂对标 :本方案对应GB/T 39116-2020中**"数据资源"能力域(辅域)**------实现对话历史的结构化管理与复用,降低生产管理中的信息沟通成本。
系列导航
-
本文所属系列:【AI赋能数据开发工程手册】
-
下一篇:《多工具协同Agent实战》(Case03,即将发布)
互动与交流
你在用LangChain的Memory时,有没有遇到过"记忆传了但不生效"的尴尬?或者你的本地小模型有没有在"刚才那个"这种问题上翻过车?欢迎评论区吐槽,咱们互相安慰一下。说实话,我调试第5轮翻车的时候,是真的有点郁闷的。
关于作者
制造业数据与AI践行者老蒋,23年IT老兵。聚焦制造业数据架构与AI融合落地。全流程实战,全源码开源。
标签:#AI Agent #LangChain #制造业数据 #智能工厂 #记忆系统