内容
# recall
基于 [zvec](https://github.com/alibaba/zvec) 向量库的个人本地知识库 —— 把你的 GitHub stars、Chrome 书签、以及 codex / claude-code 的会话记录索引起来,用一条命令做混合检索,并以 MCP 形式直接接入 Claude Code / Codex。
## 特性
- **本地 / 离线**:数据与索引全部存放在 `~/.recall`,不上传任何云端。
- **免 torch 嵌入**:用 `fastembed` + `BAAI/bge-small-zh-v1.5`(512 维),无需 torch/transformers;首次运行下载约 100MB 模型到 HF 缓存。嵌入器可插拔(保留 `ApiEmbedder` 桩)。
- **混合检索**:向量召回 (HNSW) + 全文(FTS)召回 + RRF 重排 + 标量过滤。
- **MCP + CLI 双形态**:既可当命令行工具,也可作为 MCP server(stdio, 纯 stdlib JSON-RPC)。
- **三类数据源**:GitHub stars / Chrome 书签 / 会话日志。
- **增量同步**:基于 `~/.recall/state.json` 水位线,只处理新增内容。
## 快速开始 (从零)
> 下文 `<REPO_DIR>` 指你 clone 后的仓库目录。
**前置条件**
- Python >= 3.11
- [uv](https://github.com/astral-sh/uv)(推荐)或 pip
- `gh` CLI 并已登录 —— 仅 `stars` 数据源需要:`gh auth login`
- macOS —— 仅 `bookmarks` 数据源与 launchd 定时任务需要(其余平台可跳过这两项)
**安装**
```bash
git clone https://github.com/tjcjc/recall.git
cd recall # = <REPO_DIR>
uv venv
uv pip install -e . # 或: uv pip install zvec fastembed
```
> 首次 `sync` / `search` 会下载约 100MB 的 bge 模型到 HuggingFace 缓存目录。
**首次运行**
```bash
python -m recall.cli sync # 增量收集 + 嵌入 + 入库
python -m recall.cli search "rust 异步运行时"
```
安装为 editable 后,也可直接用 `recall` 命令(等价于 `python -m recall.cli`)。
## 架构 / 数据流
职责分层:**fastembed** 只做文本→向量的一次性转换(可替换);**zvec** 是知识库本体,负责存储、双索引(HNSW + FTS)、hybrid 召回、RRF 融合、标量过滤、持久化。
```
文本 ──[fastembed]──► 向量 ──┐
├──[zvec: 存/索引/检索/融合]──► 结果
元数据/原文 ────────────────┘
预处理(可换) 知识库本体(核心)
```
### 建库(sync)
```
GitHub stars (gh) Chrome 书签 codex+claude 会话 jsonl
stars.py bookmarks.py sessions.py (过滤 harness 噪声)
└──────────────────┴──────────────────┘
│ 统一 record {id,title,url,source,lang,ts,text}
▼
sync.py 编排(增量:state.json,只处理新增/改动)
│ 批量 texts
▼
fastembed (bge-small-zh) 文本 → 512 维向量
│ record + vector
▼
┌─────────────────── zvec ───────────────────┐
│ upsert (≤1024/批) │
│ HNSW 向量索引(embedding) + FTS 全文索引(text)│
│ 标量字段 title/url/source/lang/ts │
│ 持久化 → ~/.recall/db (WAL) │
└─────────────────────────────────────────────┘
```
### 检索(search)
```
query (+ 可选 --source / --topk)
├──────────────► fastembed encode ──► 512 维 query 向量 ─┐ VectorQuery
└─ 原文 ─────────────────────────────────────────────┐ │ FtsQuery
▼ ▼
┌──────────────────── zvec.query() ───────────────────────┐
│ FTS 召回(BM25类) ‖ HNSW 召回(向量近邻) 两路并行 │
│ └────────► RrfReRanker 融合排序 │
│ filter: source='stars' 标量过滤 │
└──────────────────────────┬──────────────────────────────┘
▼
top-k {id,score,title,url,source,...}
├─► CLI 漂亮打印(人手动用)
└─► MCP knowledge_search(Claude Code / Codex 自动调)
```
入口:`recall` 或 `python -m recall.cli`(构建后为单文件二进制 `dist/recall`)。
## 使用
四个子命令,二进制与 venv 两种形式等价:
```bash
# 同步(增量收集 + 嵌入 + 入库)。可选 --source 限定单一数据源
recall sync
recall sync --source stars # stars | bookmarks | sessions
python -m recall.cli sync
# 混合检索
recall search "rust 异步运行时" --topk 10
recall search "向量数据库" --source bookmarks
python -m recall.cli search "rust 异步运行时"
# 知识库文档数
recall stats
python -m recall.cli stats
# 以 MCP server 形式运行(stdio)
recall mcp
python -m recall.cli mcp
```
## 构建单文件二进制
如需自带 zvec / onnxruntime / fastembed 原生库的单文件二进制:
```bash
.venv/bin/pyinstaller recall.spec --noconfirm
# 产物: dist/recall
```
入口为 `build_entry.py`,spec 为 `recall.spec`。
## MCP 接入
暴露两个工具:`knowledge_search(query, source?, topk?)` 与 `knowledge_stats()`。下文路径请替换为你的实际仓库路径 `<REPO_DIR>`。
**Claude Code** —— 项目级 `.mcp.json`:
```json
{
"mcpServers": {
"recall": {
"command": "<REPO_DIR>/.venv/bin/python",
"args": ["-m", "recall.cli", "mcp"],
"env": {
"PYTHONPATH": "<REPO_DIR>"
}
}
}
}
```
**Codex** —— `~/.codex/config.toml`:
```toml
[mcp_servers.recall]
command = "<REPO_DIR>/.venv/bin/python"
args = ["-m", "recall.cli", "mcp"]
env = { PYTHONPATH = "<REPO_DIR>" }
```
> 构建出二进制后,可把 `command` 换成 `<REPO_DIR>/dist/recall`、`args` 换成 `["mcp"]`,省去 PYTHONPATH。
## 定时更新 (macOS only)
用 macOS launchd 每天 9:00 自动增量同步,模板见 [`launchd.plist.example`](./launchd.plist.example)(含安装 / 立即运行 / 查看 / 卸载说明)。launchd 需要绝对路径,请把模板中的占位符替换为你的实际路径(例如 `/Users/<YOUR_USERNAME>/recall`)。
## 配置
`~/.recall/config.toml`(首次运行自动创建;修改后重跑任意命令即生效):
| 字段 | 说明 |
| --- | --- |
| `db_path` | zvec collection 目录,默认 `~/.recall/db` |
| `model_name` | fastembed 模型,默认 `BAAI/bge-small-zh-v1.5`(512 维) |
| `embedder` | `fastembed`(本地)或 `api`(桩) |
| `state_path` | 增量水位线,默认 `~/.recall/state.json` |
| `chrome_bookmarks_path` | 书签文件路径(可选覆盖) |
| `[sources]` | `stars` / `bookmarks` / `sessions` 各自开关 |
存储位于 `~/.recall/db`(zvec collection);嵌入模型缓存于 HuggingFace 默认缓存目录。
## 数据源说明
| 数据源 | 索引内容 | 依赖 |
| --- | --- | --- |
| `stars` | GitHub 收藏仓库(名称 / 描述 / 语言等) | `gh` CLI(需 `gh auth login`) |
| `bookmarks` | Chrome 书签标题与 URL | macOS only:`~/Library/Application Support/Google/Chrome/Default/Bookmarks` |
| `sessions` | codex 与 claude-code 的会话 jsonl 日志 | `~/.codex/sessions`、`~/.claude/projects` |