聊聊我最近干的一件事,给本地的 AI 助手装了个"脑子"。
不是那种花里胡哨的"AI记忆技能啥的",是真的能自己提取事实、反思经验、跨天关联记忆的系统。全本地跑(你电脑内存得大点),不花一分钱 API 费用。
整个过程踩了无数坑,换了6个模型才找到能用的组合。从头说起吧。
之前一直在折腾OpenClaw。它自带一套记忆系统,说实话设计得挺优雅,Markdown 文件加向量检索,MEMORY.md 存长期记忆,按日期存每日笔记,memory_search 做语义检索,嵌入模型跑在 Ollama 本地上,不花一分钱。
用了一段时间发现一个要命的点。这套记忆是手写的。AI 助手得自己判断什么值得记、怎么组织语言。没有自动提取,没有反思,就是一本"自己记的笔记本"。有时候重要的事忘了记,有时候记了一堆废话。
Hindsight 是什么
平常没事乐意刷 GitHub ,那时候看到 Hindsight,vectorize-io/hindsight,17.7k stars。简介就一句话,"learn, not just remember"。
这话说的,我直接开始翻文档。
它不是又一个向量数据库。模仿的是人类记忆的三层结构。World 是世界事实,比如"Docker重启后 HuggingFace 缓存不会持久"。Experience 是 Agent 自己的经历,比如"我修了3小时才找到离线模式开关在哪"。Mental Model 是从大量记忆里自动反思、提炼出来的认知。
存入的时候 LLM 自动判断是 World 还是 Experience,提取实体、关系、时间线。记忆攒够了,可以调用 Reflect 接口让它反思、提炼出 Mental Model——从具体记忆里抽象出认知。这一步不会自动触发,需要手动或用定时任务调用。
检索也不是简单算个余弦相似度就完事。查询先转成向量,粗检索走两条路,向量加关键词,然后用 Reranker 精排,最后两级分数过滤。比普通的向量搜索多了精排这一步,精度高不少。
支持 8 种 LLM Provider,看到 ollama 的时候心里一喜,能完全本地跑,一分钱不花。三个 API 也设计得清爽,Retain 存入,Recall 检索,Reflect 反思。
好了,不废话了,开干。
下载源码
第一步很简单。打开终端,git clone 一下:
bash git clone https://github.com/vectorize-io/hindsight.git
放在 Downloads 目录下。GitHub 直连慢的话,用镜像加速:
bash git clone https://ghproxy.com/https://github.com/vectorize-io/hindsight.git
下载完进目录看一眼,结构挺清晰的,docker 配置在 docker/docker-compose/local-ollama/ 下面。
下载 HuggingFace 模型,第一个坑
Hindsight 需要两个 HuggingFace 模型。BAAI/bge-small-en-v1.5,嵌入模型,384维,纯英文。cross-encoder/ms-marco-MiniLM-L-6-v2,重排序模型。
问题是 HuggingFace 在国内被墙了。直连?不存在的。
解决方案是用国内镜像 hf-mirror.com 下载。先装 huggingface-cli:
bash pip install -U huggingface_hub
然后设置镜像 endpoint,让下载请求走国内镜像:
bash # Windows PowerShell$env:HF_ENDPOINT = "https://hf-mirror.com"# Linux / Macexport HF_ENDPOINT="https://hf-mirror.com"
下载两个模型:
bash huggingface-cli download BAAI/bge-small-en-v1.5 huggingface-cli download cross-encoder/ms-marco-MiniLM-L-6-v2
下完之后文件会自动放到本地 HuggingFace 缓存目录里(~/.cache/huggingface/hub),不用手动整理目录结构。这一步不难,但下载速度取决于镜像,耐心等一会就好。
Docker 部署
Hindsight 用 Docker 部署。它自带一个 compose 文件,在 docker/docker-compose/local-ollama/ 目录下。我选的是 local-ollama 这个配置,不走 llama.cpp sidecar,直接连本机已有的 Ollama 服务。毕竟我机器上 Ollama 早就在跑了,没必要再起一个。
bash cd hindsight/docker/docker-compose/local-ollama/ docker compose up -d
注意,默认的 docker-compose 配置里 Ollama 地址是占位符,需要改成你本机的地址。Windows 下用 host.docker.internal:11434,Linux 下用宿主机内网 IP。同时建议把 PostgreSQL 数据目录挂载出来做持久化,不然删了容器记忆全丢。
容器起来了。但这只是开始。真正的噩梦在选模型的时候。
LLM 踩坑,三个模型,两个失败
Hindsight 需要一个 LLM 来自动提取记忆事实。你给它一段对话内容,它要用 LLM 从中提取出结构化的事实。这个 LLM 必须能理解中文,还得能按 Hindsight 要求的格式输出。
我试了三个模型。
第一个,gemma4:latest。Gemma 系列我一直觉得不错,跑起来也快。结果一存入中文内容,提取出来 0 条事实。零。啥都没有。完全不认识中文。中文内容喂进去,模型一脸茫然,啥也提取不出来。Hindsight 的日志里显示 "0 units extracted",我看着这个数字陷入了沉思。
第二个,deepseek-r1:14b。DeepSeek 的 R1 推理模型,中文能力肯定没问题吧?而且 14b 参数量也不小了。结果调用直接返回 404。deepseek-r1 的 API 接口跟 OpenAI 格式不兼容,而且 R1 默认输出带 <think> 推理标签,会污染 Hindsight 的结构化提取结果。Hindsight 期望的是标准的 OpenAI compatible 接口输出,r1 走的是自己的推理协议,不是简单的 chat completion。能跑是能跑,但接口和输出格式都对不上,Hindsight 认不了。
第三个,qwen2.5:7b。通义千问 2.5 的 7B 版本。我想着阿里做中文起家的,中文理解应该靠谱。一存入中文内容,完美!实体、时间、关系全部正确提取。中文事实提取 zero-shot 直接通过。而且 Qwen2.5 全系完美兼容 OpenAI Chat Completion 标准,输出干净没有多余标签,这是它能适配 Hindsight 的核心原因。7B 参数量,跑在 Ollama 上,速度也还行。零成本,零延迟(相对于远程 API),完美。
嵌入模型踩坑,又是三个模型
LLM 搞定了,还得选嵌入模型。Hindsight 需要嵌入模型把文本变成向量,才能做语义检索。又是三个模型,又是两个失败。
第一个,bge-small-en-v1.5,Hindsight 默认带的。384维,纯英文。存入中文内容没问题,LLM 提取事实用的是 qwen2.5,跟嵌入模型无关。但检索的时候,中文 query 完全匹配不到中文记忆。英文 query 能搜到英文记忆,中文 query 搜中文记忆?为零。原因很简单,这个模型根本不认识中文 token。中文内容被它拆成一堆乱码 token,向量表征完全没有语义。
第二个,qwen3-embedding:8b,Ollama 本地的。通义千问的嵌入模型,8B 参数量,中文肯定没问题吧?确实中文能力没问题。但是,4096 维。Hindsight 内部用的 PostgreSQL 加 pgvector 做向量存储,pgvector 的 HNSW 索引在高维度下性能会暴跌,Hindsight 框架也内置了维度校验,实测 4096 维直接报错。
你能想象那种感觉吗?模型中文能力完美、Ollama 本地跑着也没问题,就是维度超了,用不了。就好比你买了张超大号沙发,回家发现门框太小,搬不进去。
第三个,bge-m3:latest,BAAI 出的多语言嵌入模型。1024 维,中英文双修。1024 小于 2000,维度没问题。中文检索?完美。英文检索?也没问题。终于搞定了。
最终配置
最终整套系统的配置:
LLM 用 qwen2.5:7b,Ollama 本地,自动提取记忆事实。嵌入用 bge-m3:latest,Ollama 本地,1024维,文本向量化。Reranker 用 cross-encoder/ms-marco-MiniLM-L-6-v2,HuggingFace 本地,检索结果精排。数据库用 PostgreSQL + pgvector 向量扩展,Docker 内置。
Docker 容器叫 hindsight-local-ollama,API 在 http://localhost:8888,记忆库命名 pangxiao-main。全部本地,零云端依赖,零 API 费用。
历史记忆导入
系统搭好了,得把之前的记忆搬过来。
我把 17 个日记文件(从 2026-03-25 到 2026-06-27)全部读了一遍,每个文件总结成一段自然语言摘要,然后通过 Hindsight 的 Retain API 逐条存入。
24 条原始内容存入,成功率 100%。但 Hindsight 的 LLM(qwen2.5:7b)从这 24 条原始内容中,自动提取出了 85 条结构化事实。
这就是"learn, not just remember"的意思。你给它一段话,它不只是存原文,而是自动拆解出里面的实体、关系、时间线,存成结构化的记忆单元。
用 Recall API 测了一下,查"Agent Chat 项目的关键决策"。返回的记忆准确命中了相关内容,而且带出了时间线和实体关联。比 OpenClaw 原生的向量搜索精准不少,因为有 Reranker 精排。
PowerShell 调 API 的坑
还有一个比较蠢的坑。我用 PowerShell 调 Hindsight API 的时候,中文内容老是变成乱码。
排查了半天发现是 PowerShell 的编码问题。默认用 GBK 编码发送请求,但 Hindsight 期望的是 UTF-8。解决方案是在 Python 脚本里用 json.dumps(payload, ensureascii=False).encode('utf-8') 显式转成 UTF-8 字节流再发送。如果不想用 Python,也可以在 PowerShell 里全局设 UTF-8:[Console]::OutputEncoding = [System.Text.Encoding]::UTF8,$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'。另外 Python 的 urllib 会自动读系统代理,但代理会拦截 localhost 请求,得在代码里设 os.environ['no</em>proxy'] = 'localhost,127.0.0.1' 绕过。
都是小问题,但每个都得踩一遍。
一周后,Docker 重启,又炸了
部署完大概一周,有一天我重启了 Docker。然后 Hindsight 就起不来了。
看日志,报错信息是 reranker 模型 cross-encoder/ms-marco-MiniLM-L-6-v2 启动时要联网验证 HuggingFace 元数据。但网络不通,验证失败,服务直接挂。
这就很离谱。模型文件明明在本地缓存里,你为什么要联网验证?
原因是 HuggingFace Transformers 库默认会检查模型是否有更新,即使本地有缓存也要联网比对版本号。在国内网络环境下,这个联网请求直接超时,导致启动失败。
修复方案三步走。docker-compose.yaml 加两个环境变量,HFHUBOFFLINE=1 告诉 HuggingFace 不要联网,TRANSFORMERS_OFFLINE=1 告诉 Transformers 库走纯离线模式。然后挂载本机 HuggingFace 缓存到容器里。最后容器重建,服务正常启动。
数据完好无损,记忆从 92 条涨到了 117 条——部署后持续对话又写入了新的内容,自动提取出 25 条新事实。
这个坑其实很常见。国内用 HuggingFace 模型的项目,Docker 重启后多多少少都会遇到这个问题。解决方案就是加离线环境变量加挂载本地缓存。
两层记忆系统怎么配合
最终我形成了两层记忆架构。
第一层是 OpenClaw 原生记忆。存储靠手动写 Markdown 文件,检索用向量加 BM25 混合搜索,强项是项目技术细节、配置、SOP,每次会话自动加载加手动搜,成本为零。
第二层是 Hindsight。存储靠 LLM 自动提取结构化事实,检索用多阶段召回加 Reranker 精排,强项是对话偏好、决策脉络、跨天关联,手动调 API(也可以用 LLM Wrapper 自动),成本为零,全本地。
OpenClaw 原生记忆是"我主动记的笔记本",Hindsight 是"自动帮我提炼记忆的大脑"。一个管细节,一个管脉络。两层各有所长,互不冲突,配合使用。
六个模型,两个系统,零成本
回顾一下整个过程,光是选模型就试了 6 个。
6 个模型,4 个失败,每个失败的原因还都不一样。有完全不认识中文的、有接口不兼容的、有维度超限的。这种踩坑密度也是没谁了。
但最终结果是好的。两个系统配合,117 条结构化记忆,全部跑在本地,零云端依赖,零 API 费用。
最后
整个过程走下来,最大的感受是,本地搭一套能用的 AI 记忆系统,真不难,但坑是真多。
给后来人几个建议。LLM 直接上 qwen2.5:7b,中文事实提取稳,别浪费时间试 gemma。嵌入模型用 bge-m3,1024维不超限,中英文都行。HuggingFace 模型一定加离线环境变量,不然 Docker 重启必挂。本地缓存挂载到容器里,别让容器自己下载。PowerShell 调 API 注意编码,显式 UTF-8。
搭完之后最大的变化是,以前问 AI 助手"上个月遇到的最大困难是什么",它得翻 30 天日记。现在 Recall 一下就出来了,还带时间线和关联。
这才像记忆该有的样子。(给大家提个醒,使用openclaw要注意一个窗口只能记住20轮对话,多余的会被压缩,看不到以前的对话了,当然可以自己去调整,但还是建议大家去开新窗口对话)
夜雨聆风