关键词搜不到?那就让 AI 懂意思:用本地向量检索笔记
【摘要】 技术笔记攒多了,用关键词搜经常找不到"意思相近但措辞不同"的内容。这篇用 Ollama 本地 embedding 模型把笔记转成向量,再用余弦相似度做语义搜索,全程离线、不依赖云端。
技术笔记写多了会遇一个尴尬:想找"Docker 容器怎么清缓存",但当初记的是"清理 Docker 悬空镜像",关键词对不上就搜不到。传统搜索是"字面匹配",而语义搜索是"意思匹配"——把文字变成向量,意思近的向量也近。这篇用 Ollama 在本地跑 embedding 模型,给自己的笔记做一个离线语义搜索。

一、原理一句话
embedding 模型把一段文字映射成一个高维向量(比如 768 维)。两句话意思越近,它们的向量夹角越小(余弦相似度越接近 1)。搜索时把查询句也 embed,然后跟所有笔记向量比一遍余弦,返回最像的那几条。
二、用 Ollama 跑 embedding
Ollama 不只出文本,也提供 embedding 接口。先拉一个嵌入模型:
ollama pull nomic-embed-text
调用方式(HTTP):
curl http://localhost:11434/api/embeddings \
-d '{"model":"nomic-embed-text","prompt":"清理 Docker 悬空镜像"}'
返回 embedding 字段,是个浮点数组。
三、Python 实现检索
import requests, numpy as np, glob, os, json, re
EMB_API = "http://localhost:11434/api/embeddings"
MODEL = "nomic-embed-text"
def embed(text: str) -> list:
r = requests.post(EMB_API, json={"model": MODEL, "prompt": text}, timeout=60)
return r.json()["embedding"]
def cosine(a, b) -> float:
a, b = np.array(a), np.array(b)
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
# 1) 离线建库:把每篇笔记 embed 存好
index = []
for path in glob.glob("notes/*.md"):
text = open(path, encoding="utf-8").read()[:2000]
index.append({"path": path, "vec": embed(text)})
json.dump(index, open("index.json", "w"))
# 2) 在线查询
q = embed("Docker 容器怎么清缓存")
scores = [(d["path"], cosine(q, d["vec"])) for d in index]
scores.sort(key=lambda x: -x[1])
for path, s in scores[:3]:
print(f"{s:.3f} {path}")
第一次跑把笔记向量存成 index.json,之后查询只 embed 那一句、做一遍余弦,几百篇笔记也是毫秒级。
四、为什么用本地
- 离线可用:不联网也能搜,适合含敏感内容的笔记。
- 零成本:模型一次装好,后续不花钱。
- 可控:向量库就在本地文件,想清空重来随时的事。
代价是本地 7B 级别嵌入模型精度不如云端大模型,但对"个人笔记检索"这个量级完全够用。
五、踩过的坑
- 向量维度不一致:换 embedding 模型后维度可能不同(768 vs 1024),旧
index.json必须重建,否则余弦算出 NaN。模型一换就重跑建库。 - 长文截断:喂整篇 5000 字,embedding 模型和相似度都失真。截断到前 1500~2000 字,反而更聚焦主题。
- 余弦前不归一化:直接用点积会被向量长度带偏,务必除以各自模长做归一化(上面
cosine已做)。 - 索引没落盘:每次查询都重新 embed 所有笔记,慢且费算力。建一次库存文件,查询只 embed 查询句。
| 步骤 | 动作 | 注意 |
|---|---|---|
| 建库 | 笔记 → embed → 存 json | 模型换了要重建 |
| 查询 | 查询句 → embed → 余弦 | 只 embed 一句 |
| 排序 | 按相似度降序取 TopK | 归一化后再算 |
小结
语义搜索没那么玄:把文字交给 embedding 模型变成向量,用余弦相似度比"谁跟查询句意思更近",关键词对不上的内容也能捞出来。用 Ollama 在本地跑,离线、免费、隐私不外流,几百篇笔记检索毫无压力。真正的工程要点就两个——模型换了重建索引、查询时只 embed 那一句话。想再进阶,可以加个前端页面或接进笔记软件,不过核心逻辑到这就齐了。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)