极客时间:用 FAISS、LangChain 和 Google Colab 模拟 LLM 的短期与长期记忆

article/2025/7/5 15:34:17

  每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行! 订阅:https://rengongzhineng.io/

在一场技术实验中,我们在 Google Colab 上利用开源工具,演示了如何在不重新训练模型的前提下,为大型语言模型(LLM)添加“记忆”功能。通过集成 FAISS 向量检索、LangChain 工作流和 Sentence Transformers 嵌入模型,该系统实现了动态知识注入、模拟遗忘、处理记忆冲突以及时间偏好排序等行为。

🎯 实验目标

  • 注入模型从未学过的事实(如:“狗狗 YoYo 喜欢胡萝卜”)
  • 模拟“遗忘”机制
  • 处理前后矛盾的信息(如:“YoYo 现在讨厌胡萝卜”)
  • 实现“时间偏好”逻辑(更倾向于检索最近的信息)

🛠️ 技术配置:LangChain + FAISS + Sentence Transformers

系统构建过程如下:

pythonCopyEditfrom langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.documents import Document
import faiss
import numpy as np
import time# 加载嵌入模型
embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
print("Embedding model loaded.")# 创建 FAISS 索引
sample_embedding = embedding_model.embed_query("test")
dimension = np.array(sample_embedding).shape[0]
index = faiss.IndexFlatL2(dimension)
print("FAISS index initialized.")# 初始化 FAISS 向量存储
faiss_store = FAISS(embedding_model.embed_query, index, {}, {})
print("FAISS vector store initialized.")

🧠 添加记忆与查询记忆的函数

pythonCopyEdit# 添加记忆函数
def add_memory(text, reason):metadata = {'reason': reason, 'timestamp': time.time()}doc = Document(page_content=text, metadata=metadata)faiss_store.add_documents([doc])print(f"Added to memory: {text}")# 查询记忆函数
def retrieve_memory(query):retrieved_docs = faiss_store.similarity_search(query, k=1)if retrieved_docs:print(f"Retrieved: {retrieved_docs[0].page_content}")else:print("No relevant information found.")


🧪 实验部分:知识注入、遗忘、矛盾更新、时间偏好

1️⃣ 注入新知识

pythonCopyEditadd_memory("My dog's name is YoYo and he loves carrots.", "initial fact")
retrieve_memory("What does my dog love?")

输出结果:

vbnetCopyEditAdded to memory: My dog's name is YoYo and he loves carrots.
Retrieved: My dog's name is YoYo and he loves carrots.

📌 分析:系统成功存储并检索新事实,表明具备动态注入知识的能力。


2️⃣ 模拟遗忘机制

pythonCopyEdit# 清空 FAISS 索引
faiss_store.index.reset()
print("Memory cleared.")# 尝试再次检索
retrieve_memory("What does my dog love?")

输出结果:

pgsqlCopyEditMemory cleared.
No relevant information found.

📌 分析:通过清空向量索引,系统“遗忘”了原先的信息。


3️⃣ 处理前后矛盾的记忆更新

pythonCopyEditadd_memory("My dog's name is YoYo and he hates carrots.", "contradictory update")
retrieve_memory("What does my dog love?")

输出结果:

vbnetCopyEditAdded to memory: My dog's name is YoYo and he hates carrots.
Retrieved: My dog's name is YoYo and he hates carrots.

📌 分析:系统将新信息覆盖旧记忆,默认以“最近添加”为准,成功处理冲突。


4️⃣ 实现时间偏好(Recency Bias)

pythonCopyEditadd_memory("My dog's name is YoYo and he is indifferent to carrots.", "updated preference")
retrieve_memory("What does my dog feel about carrots?")

输出结果:

vbnetCopyEditAdded to memory: My dog's name is YoYo and he is indifferent to carrots.
Retrieved: My dog's name is YoYo and he is indifferent to carrots.

📌 分析:最新信息被成功检索,说明系统能根据时间排序优先返回更新内容。


📦 完整代码参考(含时间偏好查询与记忆清空)

pythonCopyEditimport time
from uuid import uuid4
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.docstore.in_memory import InMemoryDocstore
from langchain_core.documents import Document
import faiss
import numpy as np# 加载嵌入模型
embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
print("Loading embedding model...")# 初始化 FAISS 索引
dimension = np.array(embedding_model.embed_query("test")).shape[0]
index = faiss.IndexFlatL2(dimension)# 初始化文档存储
docstore = InMemoryDocstore()# 初始化索引到文档 ID 映射
index_to_docstore_id = {}# 创建 FAISS 向量存储
print("Initializing FAISS vector store...")
faiss_index = FAISS(embedding_function=embedding_model,index=index,docstore=docstore,index_to_docstore_id=index_to_docstore_id
)# 添加事实到记忆
def add_fact(fact_text, reason):print(f"\n Adding to memory: {fact_text}")metadata = {'reason': reason, 'timestamp': time.time()}doc = Document(page_content=fact_text, metadata=metadata)faiss_index.add_documents([doc])print(f"Fact added with metadata: {metadata}")# 查询记忆
def query_memory(query_text):print(f"\n Querying memory for: '{query_text}'")results = faiss_index.similarity_search(query_text, k=1)if results:top_result = results[0].page_contentprint(f" Retrieved: {top_result}")return top_resultelse:print("No relevant information found.")return None# 清除所有记忆
def clear_memory():print("\n Clearing memory...")faiss_index.index.reset()faiss_index.docstore = InMemoryDocstore()faiss_index.index_to_docstore_id = {}print("Memory cleared.")# 基于时间排序的查询
def query_with_recency(query_text):print(f"\n Querying with recency for: '{query_text}'")results = faiss_index.similarity_search(query_text, k=5)if not results:print("No relevant information found.")return Noneresults.sort(key=lambda x: x.metadata.get('timestamp', 0), reverse=True)top_result = results[0].page_contentprint(f"Retrieved (most recent): {top_result}")return top_result# 实验流程
add_fact("My dog's name is YoYo and he loves carrots.", reason="initial fact")
query_memory("What does my dog love?")
clear_memory()
query_memory("What does my dog love?")
add_fact("My dog's name is YoYo and he hates carrots.", reason="contradictory update")
query_memory("What does my dog love?")
add_fact("My dog's name is YoYo and he is indifferent to carrots.", reason="updated preference")
query_with_recency("What does my dog feel about carrots?")


📍 总结与未来展望

此次实验验证了在推理阶段通过外部记忆系统增强LLM能力的可行性,主要涵盖以下几点:

  • ✅ 可即时注入新知识
  • ✅ 能模拟“遗忘”行为
  • ✅ 可处理信息矛盾
  • ✅ 支持按时间优先级检索

🔭 后续优化建议

  • 智能遗忘机制:引入时间衰减、容量限制或信息价值打分;
  • 多版本记忆管理:保留多个版本并支持冲突检测;
  • 混合排序策略:结合语义相似度与时间因素进行记忆排序;
  • 扩展性提升:支持 Pinecone、Weaviate 等分布式向量存储;
  • 与 LLM 提示融合:将检索出的记忆动态嵌入模型提示上下文;
  • 构建结构化记忆体系:例如情节性、语义性与工作记忆等模块化架构。

本实验为理解和构建具“记忆力”的语言模型系统提供了重要起点。随着架构与逻辑不断优化,有望迈出通用型 AI 记忆系统的第一步。


http://www.hkcw.cn/article/qlBLxceerk.shtml

相关文章

dify应用探索

一个典型的 Agent Multi-Agent 系统 智能导购会根据用户意图分类并传递给相应商品导购Agent,返回商品信息。采用Multi-Agent架构,其中Router Agent负责对用户问题进行意图 分析,并路由到其它商品导购Agent,商品导购Agent负责向厥客收 集商品…

py爬虫的话,selenium是不是能完全取代requests?

selenium适合动态网页抓取,因为它可以控制浏览器去点击、加载网页,requests则比较适合静态网页采集,它非常轻量化速度快,没有浏览器开销,占用资源少。当然如果不考虑资源占用和速度,selenium是可以替代requ…

c++类和对象-继承

参考链接:46 类和对象-继承-继承方式_哔哩哔哩_bilibili 1.概述 作用:提高代码复用率,多个子类和父类有相同之处,又有自己各自的特点。例如基类人有四肢、会走路、说话,不同子类中国人是黑头发,说汉语&am…

MySQL中的锁

MySQL中有哪些锁? 全局锁(FTWRL) 含义:Flush Table with Read Lock的缩写,它会锁定整个数据库实例,让所有表都处于只读状态。 使用全局锁,要执行的命令: flush tables with read lock 之后,整个数据库就处于只读…

探索 Dify 的工作流:构建智能应用的新范式

目录 前言1. 什么是 Dify 的工作流2. 工作流的核心组成2.1 节点(Node)2.2 连接线(Edge)2.3 上下文与变量系统 3. 工作流的典型使用场景3.1 多轮对话与智能客服3.2 文档问答系统3.3 多语言营销文案生成3.4 多模型对比与评估&#x…

分词算法BBPE详解和Qwen的应用

一、TL;DR BPE有什么问题:依旧会遇到OOV问题,并且中文、日文这些大词汇表模型容易出现训练中未出现过的字符Byte-level BPE怎么解决:与BPE一样是高频字节进行合并,但BBPE是以UTF-8编码UTF-8编码字节序列而非字符序列B…

小云天气APP:精准预报,贴心服务

在快节奏的现代生活中,天气变化对我们的日常生活、出行安排以及健康状况都有着重要影响。一款精准、便捷且功能丰富的天气预报应用,无疑是提升生活品质的必备工具。小云天气APP正是这样一款为安卓用户量身定制的天气预报应用,凭借其精准的天气…

阿里云服务器ECS详细购买流程

1、打开云服务器ECS官方页面 打开阿里云服务器ECS页面 点击进入阿里云服务器 2、付费类型选择 阿里云服务器付费类型 3、地域节点 阿里云服务器全球28个地域,中国大陆地域如华北2(北京)、华东1(杭州)、华南1&#xf…

FastAPI+Pyomo实现线性回归解决饮食问题

之前在 FastAPI介绍-CSDN博客 中介绍过FastAPI,在 Pyomo中线性规划接口的使用-CSDN博客 中使用Pyomo解决饮食问题,这里将两者组合,即FastAPI在服务器端启动,通过Pyomo实现线性回归;客户端通过浏览器获取饮食的最优解。…

【C++篇】STL适配器(上篇):栈与队列的底层(deque)奥秘

💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C感兴趣的…

leetcode刷题日记——二叉树的层次遍历

[ 题目描述 ]: [ 思路 ]: BFS,利用队列特性完成对树的层次遍历运行如下 int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {if (!root) {*returnSize 0;return NULL;}struct TreeNode* queue[2000];…

【优选算法 | 队列 BFS】构建搜索流程的核心思维

算法相关知识点可以通过点击以下链接进行学习一起加油!双指针滑动窗口二分查找前缀和位运算模拟链表哈希表字符串模拟栈模拟(非单调栈)优先级队列 很多人学 BFS 的时候都知道“用队列”,但为什么一定是队列?它到底在整个搜索流程中起了什么作…

Retrievers检索器+RAG文档助手项目实战

导读:作为企业级应用开发中的关键技术,LangChain检索器(Retrievers)正成为构建高效RAG系统的核心组件。本文将深入探讨检索器的技术架构与实战应用,帮助开发者掌握这一重要的AI工程技术。 检索器的价值在于提供统一的检…

word中如何快速调整全部表格大小

Step1: 选中一个表格,然后在自动调整选项卡中选择“根据窗口调整表格大小” Step2:选中其他表格 Step3: 按F4即可快速调整

设计模式——中介者设计模式(行为型)

摘要 文章详细介绍了中介者设计模式,这是一种行为型设计模式,通过中介者对象封装多个对象间的交互,降低系统耦合度。文中阐述了其核心角色、优缺点、适用场景,并通过类图、时序图、实现方式、实战示例等多方面进行讲解&#xff0…

20250602在荣品的PRO-RK3566开发板的Android13下的uboot启动阶段配置BOOTDELAY为10s

20250602在荣品的PRO-RK3566开发板的Android13下的uboot启动阶段配置BOOTDELAY为10s 2025/6/2 18:15 缘起:有些时候,需要在uboot阶段做一些事情。 于是,希望在荣品的PRO-RK3566开发板的Android13下的uboot启动停下。 1、【原始的LOG&#xff…

汽车安全体系:FuSa、SOTIF、Cybersecurity 从理论到实战

汽车安全:功能安全(FuSa)、预期功能安全(SOTIF)与网络安全(Cybersecurity) 从理论到实战的安全体系 引言:自动驾驶浪潮下的安全挑战 随着自动驾驶技术从L2向L4快速演进,汽车安全正从“机械可靠…

学习经验分享【40】目标检测热力图制作

目标检测热力图在学术论文(尤其是计算机视觉、深度学习领域)中是重要的可视化分析工具和论证辅助手段,可以给论文加分不少。主要作用一是增强论文的可解释性与说服力:论文中常需解释模型 “如何” 或 “为何” 检测到目标&#xf…

C++ 检查一条线是否与圆接触或相交(Check if a line touches or intersects a circle)

给定一个圆的圆心坐标、半径 > 1 的圆心坐标以及一条直线的方程。任务是检查给定的直线是否与圆相交。有三种可能性: 1、线与圆相交。 2、线与圆相切。 3、线在圆外。 注意:直线的一般方程是 a*x b*y c 0,因此输入中只给出常数 a、b、…

判断用户输入昵称是否存在(Python)

一、运行结果 二、源代码 # 创建一个存储昵称的列表; name_list [章鱼, 张愚, 宇文弑]# 循环输入判断用户输入昵称是否存在 while True:# 获取用户输入的昵称;name input(请输入昵称:)# 判断昵称是否存在;if name in name_list…