
🧠 SummerMemory — 我自己搭的 AI 记忆系统
💡 零成本 · 全中文 · 毫秒级 · 干翻商业方案
SummerMemory 记忆系统采用PostgreSQL+pgvector做向量数据库
Ollama jina-embeddings-v2-base-zh+BM25+LLM重排
jieba中文分词
纯本地全免费。不比商业的记忆系统差,搜索记忆毫秒级,比网络延迟还小
🎬 我为什么要做这个?
我玩 AI 有一段时间了,日常用它改代码、写文档、总结日报、控制家里的智能设备。
用着用着,我发现一个问题:它老是忘事。
我前天告诉它"我看了一本书",今天问它"我最近看了什么书",它说不知道。
我让它搜"我最近使用的前端技术",它搜不到,但明明近期有让它优化 Vue 的代码。
我算是发现了,它的记忆系统有三个问题:中文搜不准、不懂变通、搜不到。
所以我就自己做了一个,我称它为 SummerMemory。
🎯 这个项目是干什么的?
简单说:让 AI 记住事情,而且能准确找到。
❌ OpenClaw 记忆系统的问题
第一个:中文搜不准
比如存了"我买了苹果和香蕉",但日后搜"水果"搜不到。
因为字面上没有"水果"这两个字。
第二个:不懂变通
存了"我开车去上班",搜"通勤"搜不到。
因为它不知道"开车去上班"就是"通勤"。
✅ SummerMemory 怎么解决?
我用了这些技术:
PostgreSQL+pgvector 做向量数据库,Ollama jina-embeddings-v2-base-zh+BM25+LLM 重排,jieba 中文分词,纯本地全免费。不比商业的记忆系统差,搜索记忆毫秒级,比网络延迟还小。
核心思路:把文字变成数字,用数学方法算相似度。
🔬 技术拆解
第一步:什么是"向量"?
向量就是一组数字。电脑不认识字,但认识数字。
比如:
"开心" → [0.25, -0.34, 0.56, ...]
"愉快" → [0.23, -0.33, 0.55, ...]
"快乐" → [0.26, -0.35, 0.57, ...]
"悲伤" → [-0.80, 0.45, -0.23, ...]
你看,"开心"、"愉快"、"快乐"的数字很接近,因为意思差不多。
"悲伤"的数字差很远,因为意思不一样。
这就是向量搜索:意思相近的文字,数字也相近。
第二步:什么是"分词"?
中文没有空格,得靠工具拆分。
jieba 能把一句话拆成最小的单位。
比如"我昨天去超市买了苹果和香蕉",拆成:
["我", "昨天", "去", "超市", "买", "了", "苹果", "和", "香蕉"]
中文词语讲究成双成对,"苹果"是一个词,"超市"是一个词。但"还买"不是一个词,jieba 会把它拆开。
第三步:什么是"BM25"?
BM25 是一种搜索算法,看一个词出现多少次。
你搜"苹果",文章里"苹果"出现 5 次的,比出现 1 次的分数高。
还有一个聪明的地方:如果一个词在所有文章里都出现(比如"的"、"是"),重要性就低。如果一个词只在少数文章里出现(比如"苹果"),重要性就高。
第四步:什么是"混合搜索"?
向量搜索能理解语义,但不够精确。
BM25 搜索能精确匹配,但不懂语义。
所以 SummerMemory 把两种结合起来:
- 同时用两种方式搜索
- 合并结果
- 向量分占 60%,BM25 分占 40%
- 按总分排序
这样既能理解语义,又能精确匹配。
第五步:什么是"LLM 重排"?(计划做的)
LLM 就是大语言模型。重排就是用 AI 重新给搜索结果排序。
比如你搜"健康食物",返回 10 条结果。AI 看一眼,把最相关的放前面。
这个功能还没做,后面会加。
📝 举个完整的例子
你跟 AI 说:
"我昨天去超市买了苹果和香蕉,还买了一盒牛奶,花了 50 块钱"
SummerMemory 处理流程:
第一步:切分
切成三块:
- "我昨天去超市买了苹果和香蕉"
- "还买了一盒牛奶"
- "花了 50 块钱"
第二步:转向量
把每块文字变成数字:
- "苹果" → [0.12, -0.34, 0.56, ...]
- "香蕉" → [0.11, -0.33, 0.55, ...]
- "牛奶" → [0.23, -0.45, 0.67, ...]
"苹果"和"香蕉"的数字很接近,因为都是水果。"牛奶"的数字差远一点,因为是饮料。
第三步:分词
jieba 这个框架常用于电商的关键字匹配搜索,分词可以更好地匹配用户的搜索意图。
["我", "昨天", "去", "超市", "买", "了", "苹果", "和", "香蕉"]
🦙 jina-embeddings-v2-base-zh 是什么?
这是 Ollama 里用的一个模型,专门用来把中文变成向量。
它的名字可以拆开看:
- Jina AI:开发这个模型的公司
- embeddings:把文字变成向量的模型类型
- v2:第二代模型
- base:基础版本,平衡精度和性能
- zh:专门针对中文优化
为什么要用这个模型?
- 它是专门针对中文优化的,中文效果比英文模型好
- 8192 token context,支持长文本不截断
- 768 维向量,精度更高
- Q5_K_M 量化后仅 116MB,CPU 就能跑,不需要 GPU
- 它是开源免费的,不用花钱
🔍 搜索流程演示
过几天,你问 AI:"我之前买了什么水果?"
第一步:查询转向量
"水果" → [0.15, -0.38, 0.52, ...]
第二步:向量搜索
"苹果"的向量 [0.12, -0.34, 0.56, ...] 和"水果"很接近。得分:0.85
第三步:BM25 搜索
查询分词:["我", "之前", "买", "了", "什么", "水果"]
原文里有"我"、"买"、"了",但没有"水果"。得分:0.60
第四步:混合排序
最终得分 = 0.85 × 0.6 + 0.60 × 0.4 = 0.75
第五步:返回结果
AI 回答:"你之前买了苹果和香蕉,都是水果哦!"
📊 性能数据
| 指标 | 数值 | 说明 |
|---|---|---|
| 📊 总文件数 | 80 个 | 记忆文件 |
| 📦 总 chunks | 768 个 | 分块后的记忆片段 |
| ⚡ 搜索速度 | 12-425ms | 和系统性能有关,仅供参考 |
| 🧬 向量维度 | 768 维 | jina-embeddings-v2-base-zh |
| 💾 数据库大小 | ~120MB | 768 条记录 |
| 🔄 索引速度 | ~2s/文件 | 含 embedding 生成 |
| 💰 总成本 | ¥0 | 纯本地,零费用 |
🆚 SummerMemory vs OpenClaw 内置 vs 商业方案
| 对比维度 | 🧠 SummerMemory | 🔧 OpenClaw 内置 | 💰 商业方案 |
|---|---|---|---|
| 💰 成本 | ✅ 完全免费 | ✅ 免费 | ❌ $70-500/月 |
| 🏠 部署 | ✅ 本地服务器部署 | ✅ 本地 | ❌ 云端托管 |
| 🔒 隐私 | ✅ 零泄露风险 | ✅ 本地 | ❌ 数据上传第三方 |
| 📖 全文搜索 | ✅ BM25 + jieba | ❌ 不支持 | ✅ 有 |
| ✂️ 中文分词 | ✅ jieba 深度优化 | ❌ 无 | ⚠️ 通用分词 |
| 🧬 向量维度 | ✅ 768 维 | 384 维 | 768-1536 维 |
| 🔗 混合搜索 | ✅ 向量+BM25 | ❌ 仅向量 | ✅ 有(但要钱) |
| ⚡ 搜索速度 | ✅ 12-425ms | 100-500ms | 50-200ms + 网络延迟 |
| 📊 可视化 | ✅ D3.js 力导向图 | ❌ 无 | ⚠️ 需额外付费 |
| 🔧 自定义 | ✅ 完全可控 | ❌ 受限 | ⚠️ API 受限 |
🏗️ 服务架构
三层服务,全部本地服务器运行
- 🐘 PostgreSQL 18.1 + pgvector — Docker 容器,端口 5432,存储向量+全文数据
- 🦙 Ollama — Docker 容器,端口 11434,提供 Embedding 推理
- 🧠 SummerMemory Server — Python HTTP 服务,端口 11435,systemd 管理,开机自启,故障自愈
数据规模: 80 文件 → 768 chunks → ~120MB
🗺️ 图谱可视化
我还做了一个图谱可视化界面,把所有记忆用一张图画出来。
节点代表文件,连线代表关系。节点越大,内容越多;连线越粗,关系越紧密。
支持搜索、拖拽、点击查看详情。用 Vue 3 + force-graph 做的,支持中英文切换。
浏览器打开 https://ai.likefr.com/graph 就能看。
💬 一句话总结
🧠 SummerMemory = PostgreSQL + pgvector + Ollama + jieba + BM25
纯本地 · 全免费 · 中文优化 · 毫秒级搜索 · 不比商业方案差!
别人花 $500/月 买的记忆系统,我用 Docker 搞定了 🚀
🔗 开源地址
SummerMemory 已经开源,欢迎 Star!
📅 诞生于 2026-05-30 | 🔧 持续优化中 | 💪 Likefr × Summer