AI agent四层记忆架构实践,治疗大模型"金鱼脑"
源码已跑通,本文不讲虚的概念,只讲我们在半导体 Fab(晶圆厂)场景落地 Agent 记忆时,怎么避免把 Prompt 撑爆。 github:https://github.com/BumbleBee-ZDS/fab_memory_agent
一、背景:Fab 工程师不需要"聊天",需要"查档"
在半导体工厂,工艺工程师(PE)最常问的问题是这类:
“EQP-01 又报警了,上次是怎么处理的?” “这批 Lot 的刻蚀参数,跟标准值差多少?”
传统的做法是:翻 EES 系统、查维修工单、翻 PDF 标准配方。
我也试过直接上 RAG:把几百份 SOP、几万条工单扔进向量库,每次全量召回塞给大模型。结果有两个问题:
痛定思痛,我重构了一套分层记忆系统,做了一个最小可运行 Demo(Streamlit + DeepSeek)。核心思想只有一句:
Context Window 是寄存器,不是硬盘。
二、架构总览:四层记忆,各司其职
我把记忆拆成四层,每一层都有明确的"存什么、活多久、怎么取"。
| 感知层 | Streamlit Input | 工程师的原始自然语言 | 毫秒 |
| 工作记忆 | st.session_state | 最近 5 轮对话(CoT 中间结果) | 单次会话 |
| 短期记忆 | Dict + TTL(模拟 Redis) | 当前正在查的 EQP-ID、Lot-ID | 30 分钟 |
| 长期记忆 | KV 热库 + ChromaDB 冷库 | 机台标准参数 / 历史维修工单 | 永久 |
关键区别:
- 机台的标准气压(500mTorr)是精确事实,放 KV,直接读,绝不向量化。
- 维修工单的描述(“valve 堵塞、工程师 A 更换”)是非结构化经验,放向量库,语义搜。
三、大脑:Memory Manager 调度逻辑
很多 Demo 里,记忆是个被动数据库。我的设计里,MemoryManager 是主动调度器,它干了三件最核心的事。
1. 路由:用规则,不用大模型
在 Fab 场景,用户说话很直接,没必要上 BERT 甚至 GPT-4o 做意图识别。
# router.py(简化版)
def route(self, query: str):
if "上次" in query or "历史" in query or "报警" in query:
return {"action": "retrieve"}
if query.startswith("/"):
return {"action": "system_cmd"}
return {"action": "direct_chat"}
为什么这么粗暴? 因为工程师不会跟机台谈哲学。看到"上次"“报警”,100% 是要查历史。规则延迟 0ms,比调 API 省下的钱够买两杯咖啡。
2. 短期记忆自动追踪
用户输入 EQP-01 又报警了,系统自动提取机台号:
# short_term.py
def update_state(self, query):
import re
match = re.search(r'(EQP-\\d+|CVD-\\d+)', query)
if match:
self.store['current_eqp'] = match.group(1)
这样,后续不管用户说"把参数调回去"还是"看看压力",系统都知道指的是哪台机台——这就是短期记忆维持"当前语境"的能力。
3. 冷热双路召回
长期记忆模块同时查两个地方:
# long_term.py
def search(self, eqp_id, query):
hot = self.kv.get(eqp_id) # 毫秒级,标准参数
cold = self.vector.query(query) # 语义,历史工单
return f"{hot}\\n{cold}"
热数据在前,冷数据在后。Prompt 里永远是"精确事实 + 相关经验",模型不再乱猜。
四、工作记忆:为什么只留 5 轮?
我在 main.py 里硬性限制工作记忆长度:
MAX_HISTORY = 5
working_memory.append(msg)
if len(working_memory) > MAX_HISTORY:
working_memory.pop(0)
原因很现实: 工程师查问题时,对话通常是"发散-收敛"的。前两轮可能是闲扯,第三轮锁定机台,后面才是调参。超过 5 轮前的上下文,90% 是噪音。砍掉它们,不仅省 Token,还能强迫模型依赖外部记忆,而不是靠自己"硬背"上文。
五、降级设计:LLM 不是唯一依赖
工业现场最怕断网或 API 挂。我在 utils/mock_llm.py 里做了一层兜底:
- 优先:调用 DeepSeek API,把检索结果组织成自然语言。
- 降级:如果 API Key 没配或超时,直接拼接检索结果返回。
[来源: 长期记忆]
机台 EQP-01 标准气压 500mTorr。
历史工单:Lot1234 气压异常,调整 valve 后恢复。
虽然生硬,但信息是对的。在 Fab,准确性永远大于文采。
六、跑起来的样子
Streamlit 左侧 Sidebar 实时展示"记忆快照":
- 🟢 短期记忆:EQP-01(剩余 28min)
- 📚 长期记忆:KV(12条) + 工单(10条)
- 💬 工作记忆:3/5 轮
用户问完,回复下方会打标签:
- [来源: 长期记忆] → 说明走了检索
- [来源: 直接回复] → 纯闲聊
- [来源: 系统] → 执行了 reset
点 /reset,短期记忆清零,相当于工程师下班交班,下一班从零开始。 
七、踩过的坑(重点)
1. 别把结构化参数向量化
最早我把"500mTorr"也嵌成向量,检索回来变成了"大约 400-600"。现在一律 KV 直读。
2. 工单数据要带时间戳
这次 MVP 还没加,但下个版本每条工单必须带时间,用来解决"新 SOP 覆盖旧工单"的冲突。
3. TTL 比手动删重要
工程师查完一个机台,半小时后大概率切到别的。TTL 自动过期,避免"上个案子的记忆串到下一个案子"。
八、总结:给工业 AI 开发者的建议
做 To C 的 Agent,可以靠模型"猜";做 Fab 这种工业场景,确定性比聪明更重要。
好的记忆系统不是拼 Prompt 有多长,而是:
- 短期记住"你在查哪台机台"
- 长期存好"这台机台到底该怎么修"
- 中间用规则和小模块,低成本地把两者连起来
网硕互联帮助中心
评论前必须登录!
注册