🔍 Memory Semantic Search

把 Markdown 笔记变成能理解语义的搜索引擎

💡 一句话:用 Embedding API + SQLite,让你的 Markdown 支持语义搜索

❓ 解决了什么痛点?

你有很多 Markdown 笔记(比如 MEMORY.md、项目文档),但传统的 Ctrl+F 只能搜字面关键字。如果你想找"怎么部署项目",但笔记里写的是"deployed to Zeabur",就搜不到。

这个 Skill 把笔记内容变成向量,实现语义搜索——就算用词不同,只要意思相近,就能搜出来。

📋 实际运行示例

步骤一:建索引(只需执行一次)

$ python3 scripts/index.py ~/.openclaw/workspace

Workspace: /home/tony/.openclaw/workspace Found 5 markdown files (MEMORY.md, SOUL.md, ...) Total chunks: 15 Embedded 10/15 chunks ← 第1批:10个chunk调API Embedded 15/15 chunks ← 第2批:剩下的5个 Done. Total indexed chunks: 15

✅ 这一步扫描所有 .md 文件,切成小块,调用 embedding API 把每块变成向量,存入 SQLite。文件改了会自动增量更新。

步骤二:语义搜索

$ python3 scripts/search.py "Claw Arena 部署在哪里"

--- Result 1 (score: 0.6655) --- File: MEMORY.md (lines 29-81) Claw Arena 从 API key 模式重构为 Skill + API 架构, 部署到 Zeabur,Hong Kong region... --- Result 2 (score: 0.647) --- File: MEMORY.md (lines 1-39) 2026-02-10: Claw Arena 重构完成,部署到 Zeabur, Skill 发布到 ClawHub...

👆 笔记里写的是"部署到 Zeabur",搜的是"部署在哪里"——措辞不同但语义匹配,score 0.67。语义搜索的核心能力。

⚙️ 工作流程

📄扫描 .md 文件
✂️切块 (chunk)
🤖Embedding API
文本 → 向量
💾存入 SQLite
↓ 搜索时 ↓
💬用户提问
🤖问题 → 向量
📐余弦相似度
本地计算
🎯Top-K 结果

📐 余弦相似度:如何判断"意思像不像"?

🌍 直观理解(30秒)

向量 = 指向语义空间的箭头 "部署项目" → 箭头指向 东北方向 "deploy app" → 箭头也指向 东北方向 "中午吃什么" → 箭头指向 西南方向

余弦相似度就是算两个箭头夹角:夹角越小(方向越近),相似度越高;夹角越大,越不相关。

🔢 数学公式

两个向量 A 和 B(例如都是 1024 维)

相似度 = (A·B) / (|A| × |B|) = (A₁×B₁ + A₂×B₂ + ... + A₁₀₂₄×B₁₀₂₄) / (A的长度 × B的长度)

结果范围:-1 ~ 1

-1 → 完全相反方向(意思相反) 0 → 互相垂直(毫无关系) 1 → 方向完全一致(意思几乎一样)

🔄 本 Skill 的计算过程

1. 查询 "Claw Arena 部署在哪里" → Q_vec (1024维) 2. 从 SQLite 读取所有 chunk 向量 C₁, C₂, ... 3. for each C: score = cosine(Q_vec, C) 4. 按 score 从高到低排序,取 top-5

⚡ 为什么合适?

轻量:不需要训练,直接算余弦
高效:SQLite 里存的向量,本地直接算,不调 API
语义友好:embedding 后的向量天然把意思相近的句子聚在一起

🛠 技术栈

🐍 Python 3(纯 stdlib) 💾 SQLite(向量存储) 🔗 OpenAI 兼容 Embedding API 📐 余弦相似度

零外部依赖,不需要 pip install。API 兼容 OpenAI / 讯飞 / Gemini / Ollama 等。

📊 实测数据

15
索引 chunks
(5 个 md 文件)
0.67
最高相似度 score
(语义精准命中)
<2s
单次搜索耗时
(1 次 API 调用)

💡 即使扩展到 1000+ chunks,搜索依然是"1 次 API 调用 + 本地向量计算",速度不变,成本仅一次 embedding。

📁 项目结构

memory-semantic-search/ ├── SKILL.md # Skill 描述和使用说明 ├── README.md # 项目文档(含安装、使用、环境变量) ├── .gitignore # 排除敏感数据和临时文件 └── scripts/ ├── index.py # 索引:扫描 → 切块 → embedding → 存储 └── search.py # 搜索:查询 → embedding → 相似度计算 → 排序

⚠️ SQLite 数据库文件(*.sqlite)和 __pycache__ 已加入 .gitignore,不会上传敏感数据。