LongtermChatExternalSources记忆原理揭秘:Embedding向量化与余弦相似度检索的完整拆解
【免费下载链接】LongtermChatExternalSourcesGPT-3 chatbot with long-term memory and external sources项目地址: https://gitcode.com/gh_mirrors/lo/LongtermChatExternalSources
LongtermChatExternalSources 是一个开源的GPT-3 长期记忆聊天机器人,核心能力正是 Embedding 向量化与余弦相似度检索。这篇教程带你逐行看懂 chat.py 的记忆实现,10 分钟搞懂 AI 聊天机器人"记住过去"的完整原理。
为什么聊天机器人需要长期记忆?
默认的 GPT-3 API 是无状态的——每次请求都是全新的,聊完即忘。这个项目用一套纯文件 + 向量的方案解决记忆问题,架构非常轻量:
| 目录 | 角色 | 类比 |
|---|---|---|
| nexus/ | 每条对话的消息 + 向量 | 情景记忆(海马体) |
| internal_notes/ | GPT-3 生成的记忆摘要 | 陈述记忆(压缩笔记) |
| gpt3_logs/ | 每次调用的提示词与输出 | 调试日志 |
🧠 一句话概括:每条消息都变成一个高维向量存盘,提问时再靠向量夹角找出最相关的旧记忆。
Embedding 向量化:把文字变成 1536 维向量
记忆的入口在 gpt3_embedding 函数:
def gpt3_embedding(content, engine='text-embedding-ada-002'): content = content.encode(encoding='ASCII',errors='ignore').decode() response = openai.Embedding.create(input=content,engine=engine) vector = response['data'][0]['embedding'] # this is a normal list return vector关键点:
- 调用 OpenAI 的
text-embedding-ada-002模型,将任意文本编码为1536 维浮点向量 - 发送前先用 ASCII 编码过滤掉非英文字符(
errors='ignore'),兼容当时 API 的限制 - 向量的魔法在于:语义越相近的两段文字,向量方向越接近
可以直接翻一下真实数据感受 nexus/log_1674383041.28684_USER.json:一句good morning raven就对应一个包含 speaker、时间戳、uuid 和上千行向量的 JSON 文件。
余弦相似度:找出"意思相近"的记忆
拿到查询向量后,如何判断哪条旧记忆最相关?答案在 similarity 函数:
def similarity(v1, v2): return np.dot(v1, v2)/(norm(v1)*norm(v2)) # return cosine similarity这就是教科书级的余弦相似度公式:cos θ = 点积 / (模长 × 模长)。
- 结果范围是 -1 ~ 1,越接近 1 表示两条记忆方向越一致(越相关)
- 只比较方向、忽略长度,因此"早上好"和"清晨问候"能被判为高相似,而不受句子长短影响
检索逻辑在 fetch_memories 函数 中:遍历nexus/全部历史消息,逐条打分、排序,跳过与当前消息完全相同的向量,最后返回Top 10条最相关记忆。
完整检索链路:AI "想起过去"的 6 个步骤
主循环 chat.py 第 141-172 行 把上面的零件串成流水线,每一轮对话都执行:
- 用户输入 → 向量化:
gpt3_embedding(a),连同 uuid、时间戳存为nexus/log_时间戳_USER.json - 载入全部历史:load_convo 按时间正序读取
nexus/下所有 JSON - 检索情景记忆:
fetch_memories(vector, conversation, 10)取余弦相似度最高的 10 条 - 摘要压缩:summarize_memories 把 10 条记忆拼成文本块,用 prompt_notes.txt 让 GPT-3 写成
-开头的笔记列表,再为笔记块本身生成向量,存入internal_notes/ - 组装提示词:prompt_response.txt 中
<<NOTES>>和<<CONVERSATION>>两个占位符分别填入摘要笔记和最近 4 条消息 - 生成并存档回复:
text-davinci-003输出答案,回复同样向量化后存回nexus/,完成一轮闭环
流程图直观版:
用户输入 ──▶ Embedding 向量化 ──▶ 余弦相似度检索 Top10 记忆 ▲ │ │ ▼ 回复存档 ◀── GPT-3 生成 ◀── 摘要笔记 + 最近4条消息用真实数据验证记忆效果
打开 internal_notes/notes_1674383045.5926764.json,能看到 GPT-3 实际压缩出的记忆笔记:
- User: Asked about difficulty sleeping
- Raven: Suggested establishing a regular sleep schedule…
- User: Asked about the singularity
- Raven: Explained the concept of the singularity…
8 条原始对话被浓缩成 8 行要点,uuids/times字段保留了可回溯的溯源链。此外,dream_sequence.py 是作者预留的"梦境"模块,复用了同一套向量化与相似度能力,用于离线提炼用户偏好原则(提示词见 prompt_dream_user.txt),属于项目规划中的扩展方向。
快速上手:5 步跑通你的记忆型 GPT-3 聊天机器人
按照 README.md 的说明操作:
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/lo/LongtermChatExternalSources - 创建虚拟环境:
python3 -m venv env并激活 - 安装依赖:
pip install openai numpy - 将 OpenAI API Key 写入项目根目录的
openaiapikey.txt(末尾不要换行) - 运行:
python chat.py,即可在命令行与"有记忆"的 RAVEN 对话
常见问题
Q1:为什么不用向量数据库,而是逐文件遍历?消息量小时暴力扫描足够,且架构零依赖、完全透明;代码里的 TODO 注释也表明后续计划引入时间邻近召回等优化(见 chat.py 第 58 行)。
Q2:记忆会无限膨胀吗?每条消息一个 JSON 文件,笔记是增量摘要而非全量重算,配合uuid索引便于后续去重与归档。
Q3:换成中文能用吗?当前errors='ignore'会丢弃非 ASCII 字符,直接输入中文会被清空;改造该过滤逻辑即可支持,这也是动手练习的好切入点。
总结:LongtermChatExternalSources 用不到 200 行代码演示了 RAG 时代记忆系统的雏形——向量化存记忆、余弦相似度找记忆、大模型压缩记忆。吃透 chat.py 后,你就能为任何无状态大模型应用挂上"长期记忆"。
【免费下载链接】LongtermChatExternalSourcesGPT-3 chatbot with long-term memory and external sources项目地址: https://gitcode.com/gh_mirrors/lo/LongtermChatExternalSources
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考