AI Agent(学习五-长期记忆(向量库 + FAISS))
·
AI Agent(学习五-长期记忆(向量库 + FAISS))
上一篇加了Memory,但是由于是短期记忆,所以有很多限制,从这篇开始,我们学习长期记忆,长期记忆(向量库 + FAISS) 是 Agent 从「聊天玩具」➡「可成长系统」的分水岭
一、概念
长期记忆:把“重要信息”存成向量,需要时再自动找回来
比如:
你:我叫wp
(5天后)
你:我叫什么
Agent: 你好,wp
二、整体架构
用户输入
↓
短期 Memory(对话上下文)
↓
向量检索(FAISS,找相关历史)
↓
拼 Prompt
↓
LLM 决策 / Tool / 回复
三、安装依赖
pip install faiss-cpu langchain-community sentence-transformers
- faiss-cpu:本地向量库
- sentence-transformers:免费嵌入模型(不用 OpenAI)
四、长期记忆模块
将上一篇短期Memory的代码复制过来,创建一个新的文件main4.py,然后在上面进行修改
1、初始化向量库(程序启动一次)
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
# ===== 长期记忆(向量库) =====
embedding_model = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
vector_store = FAISS.from_texts(
texts=["系统初始化占位文本"],
embedding=embedding_model
)
这个逻辑的作用是:
用一个“文本 → 向量”的模型,创建一个“可以用语义搜索文本的长期记忆库(FAISS)”。
- 选择一个 免费的语义向量模型
- 把一句话变成一串数字(向量)
比如:
"我叫wp" -> [0.12,-0.33,0.88,..]
第二句:
vector_store = FAISS.from_texts(
texts=["系统初始化占位文本"],
embedding=embedding_model
)
注意:我开始写的是:texts=[],建立一个空的向量库,但是报错了,后面加了一个初始化占位文本
这句作用:
- 用FAISS创建一个向量数据库
- 每条文本会:
- 先用 embedding_model 变成向量
- 再存进 FAISS 里
整体架构:
文本
↓
Embedding 模型(理解语义)
↓
向量
↓
FAISS(存 + 查相似内容)
2、写入长期记忆
规则:不是所有的话都存,只存:事实性/用户信息
def save_long_term_memory(text: str):
vector_store.add_texts([text])
这个就是存储内容:
save_long_term_memory("用户叫wp")
save_long_term_memory("用户在北京从事 Java 后端开发")
3、检索长期记忆
这个就是给Agent用的
def search_long_term_memory(query: str, k: int = 3) -> str:
docs = vector_store.similarity_search(query, k=k)
if not docs:
return ""
result = "以下是你过往的重要信息:\n"
for doc in docs:
result += f"- {doc.page_content}\n"
return result
这段逻辑它会把当前用户输入转成向量,在 FAISS 向量库中检索语义最相近的历史事实,
再作为上下文的一部分注入到 Prompt 中,辅助大模型理解用户意图。
4、把长期记忆接入 Agent(核心)
修改原有的agent_run
def agent_run(user_input: str) -> str:
#取短期记忆(最近对话)
short_memory = render_memory()
#查长期记忆(历史事实)
long_memory = search_long_term_memory(user_input)
#构造 Prompt(关键设计)
prompt = (
long_memory
+ short_memory
+ ROUTER_PROMPT
+ "用户输入:\n"
+ user_input
)
#模型做「是否用 Tool」的决策-这是Agent和普通Chat的本质区别
decision_msg = llm.invoke(prompt)
decision_text = decision_msg.content.strip()
#JSON 解析失败 → 降级兜底
try:
decision = json.loads(decision_text)
except json.JSONDecodeError:
#立刻退化成普通聊天
reply_msg = llm.invoke(long_memory + short_memory + user_input)
reply = reply_msg.content
add_to_memory("用户", user_input)
add_to_memory("Agent", reply)
return reply
#解析 Tool 决策
tool_name = decision.get("tool")
tool_input = decision.get("input", "")
#执行 Tool(程序做事)
if tool_name in TOOLS:
result = TOOLS[tool_name](tool_input)
#更新短期记忆(无论哪种路径)
add_to_memory("用户", user_input)
add_to_memory("Agent", result)
return result
#普通对话路径(不用 Tool)
reply = tool_input
# ⭐ 判断是否值得写入长期记忆(简单规则)
if "我叫" in user_input or "我是" in user_input:
save_long_term_memory(user_input)
add_to_memory("用户", user_input)
add_to_memory("Agent", reply)
return reply
这个逻辑:把短期记忆、长期记忆和当前用户输入组合成 Prompt,让模型决定是否调用工具,并在每一步维护记忆。
顺序(你是谁、你记得什么、你能用什么、现在要干嘛):
- 长期记忆(背景事实)
- 短期记忆(对话上下文)
- 路由规则(工具选择约束)
- 当前输入(最新意图)
这段代码架构:
用户输入
↓
┌────────────────────┐
│ 长期记忆(FAISS) │
└────────────────────┘
↓
┌────────────────────┐
│ 短期记忆(上下文)│
└────────────────────┘
↓
┌────────────────────┐
│ LLM 决策(Router) │
└────────────────────┘
↓ ↓
Tool 执行 直接回答
↓ ↓
└──── 更新 Memory ────┘
五、运行与测试
运行:
python main4.py
测试
你:我叫wp
Agent: 你好,wp
你:你好啊
Agent: 你也好,wp
你:我的名字是啥来着
Agent: 你叫wp
你:我在北京从事JAVA后端开发
Agent: 很好,wp,你在北京从事JAVA端开发,很不错的职业选择。
不是关键词匹配,而是向量语义
更多推荐
所有评论(0)