在 VPS 上用 OpenClaw + Ollama 做本地记忆检索:避开地区限制的最小方案

用 Ollama 的 nomic-embed-text 做本地 embeddings,把 OpenClaw 的 MEMORY.md 与 daily notes 建成 SQLite 语义索引,在 VPS 上实现可追溯的记忆检索,绕开地区限制与云 API 依赖。

TL;DR:如果你在 VPS 上折腾“记忆检索 / 语义检索”,又不想被云 API 的地区限制、Key 配置来回拉扯,一个很稳的起点是:Ollama 跑 embedding(nomic-embed-text)+ SQLite 存索引。你写下来的 MEMORY.mdmemory/*.md 都能被“像搜索一样”找回来。

我想要的其实很简单:记得住、找得到

我并不需要一个“会编故事的记忆系统”。我只想要两件事:

  • 能记住:偏好、称呼、一些长期信息(比如环境配置、常用命令)
  • 能检索:当我问“之前那件事怎么弄的?”能把相关片段找出来(最好还能告诉我出处在哪个文件、哪几行)

一旦把需求说清楚,你会发现“记忆检索”本质上就是:

  1. 把笔记切成小段(chunk)
  2. 每段做 embedding(向量)
  3. 存到本地(我这里选 SQLite,一个文件就够)
  4. 查询时做相似度排序,把最相关的段落返回

为什么我没有继续用云端 API(以及地区限制那一下)

把 embedding 放到云端当然省事,但它也把不确定性带进了链路:

  • 有些地区/出口 IP 会直接被拦(接口返回类似 User location is not supported
  • OAuth 登录(比如 ChatGPT/Codex)并不会自动给你“可用于 embedding 的 API key”
  • 记忆文件本身往往很琐碎,我更倾向于它留在自己的机器上

于是路线就很自然:embedding 本地化

环境:Ghost + OpenClaw + Ollama 都在同一台 VPS 上

我这里的前提是:

  • Ghost 博客本身就是 Docker 跑在这台 VPS 上
  • Ollama 也是 Docker 跑在这台 VPS 上(端口只监听本机 127.0.0.1:11434
  • OpenClaw 的 workspace 在 ~/.openclaw/workspace

先确认 Ollama 容器是否在跑:

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

确认 API 能响应:

curl -sS http://127.0.0.1:11434/api/version

第一步:先拉一个 embedding 模型(轻量优先)

我没有上来就选“大而全”的模型,而是先用一个足够稳、体积适中的 embedding:

  • nomic-embed-text

拉取:

curl -sS http://127.0.0.1:11434/api/pull \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"nomic-embed-text\"}"

确认模型已经在本地:

curl -sS http://127.0.0.1:11434/api/tags | head -c 400

做一次最小 embedding 测试(能返回数组就行):

curl -sS http://127.0.0.1:11434/api/embeddings \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"nomic-embed-text\",\"prompt\":\"测试一下embedding是否可用\"}" \
  | head -c 200

第二步:把 OpenClaw 的记忆文件做成“可检索索引”

OpenClaw 这边我会把长期信息写到:

  • ~/.openclaw/workspace/MEMORY.md

把每日碎片写到:

  • ~/.openclaw/workspace/memory/*.md

然后用两个脚本做索引与查询:

  • tools/memory_index.py:建索引(切块 + 调 Ollama embeddings + 写 SQLite)
  • tools/memory_search.py:查询(embedding 问题 + 余弦相似度 + TopK 返回)

建索引:

cd ~/.openclaw/workspace
python3 tools/memory_index.py

查询示例:

cd ~/.openclaw/workspace
python3 tools/memory_search.py "我应该怎么称呼你?"

想返回更多结果:

TOPK=10 python3 tools/memory_search.py "今天我们做了什么?"

我比较喜欢它的一点是:输出不仅给你“相关段落”,还会带上文件路径 + 行号范围,方便回头定位、改写、整理。

小坑记录:交互界面退不出来、jobs 不是 job

这种 VPS 环境里会遇到很现实的小问题,比如某些工具突然弹出 TUI 或卡在交互状态。

一般我会按这个顺序退出:

  • q / Esc
  • Ctrl + C
  • 最后手段:Ctrl + Z 挂起,再用 jobs 看后台任务,kill %1 清掉

注意:bash 内建命令是 jobs,不是 job

下一步(可选):从“检索”升级到“检索 + 总结”

到这里其实已经够用了:能记、能搜、能追溯。

如果你想再进一步,可以做一个小升级:

  • 先检索 TopK 片段
  • 再让本地 LLM(比如 Ollama 的某个小模型)把片段总结成一句“答案”

这就是常说的 RAG(检索增强生成)。我倾向于先把检索跑稳,再决定要不要加生成层。