主题
05 - Semble:专为 AI Agent 打造的极速代码搜索引擎
GitHub: MinishLab/semble官网: minish.ai/packages/sembleLicense: MIT 技术栈: Python + Model2Vec + BM25 + Reciprocal Rank Fusion 核心定位: 让 AI Agent 用约 98% 更少的 token 找到正确代码,CPU 上 250ms 建库,1.5ms 查询,与代码 Transformer 模型相当的精度。
1. 项目背景
1.1 AI Agent 的检索痛点
像 Claude Code、Codex、Cursor、OpenCode 这种 AI Coding Agent,搜代码的默认套路是:
grep -r在整个仓库扫一遍- 把所有匹配读进上下文(一次几万到几十万 token)
- LLM 自己挑选有用的
这个套路在大代码库上代价非常高:
- 一次"搜认证流程"可能要消耗 45,692 token
- 查询延迟和 LLM 思考延迟双高
- 准确率被"匹配数过多"反噬
1.2 Semble 的解题思路
把"AI 搜代码"看成一个专用 IR 问题:用代码专用的 静态嵌入 + BM25 + 代码感知重排,在 CPU 上做到亚秒级,token 消耗压到 grep+read 的 2%。
1.3 实测数据
| 指标 | Semble | 备注 |
|---|---|---|
| Token 消耗 | 566 | grep+read 路径 45,692,降低 ~98% |
| 索引速度 | ~250ms | 比代码专用 Transformer 快 ~200 倍 |
| 查询延迟 | ~1.5ms | 比 Transformer 快 ~10 倍 |
| NDCG@10 | 0.854 | 与 CodeRankEmbed 等 137M 参数模型相当(仅低 0.008) |
| 资源 | CPU only | 无 GPU、无 API Key、无外部服务 |
2. 核心概览
2.1 双路检索 + 代码感知重排
用户查询
│
┌───────────────┴───────────────┐
▼ ▼
语义检索 词法检索
(Model2Vec 嵌入) (BM25)
potion-code-16M 适合精确符号匹配
│ │
└──────────────┬────────────────┘
│
▼
RRF (Reciprocal Rank Fusion)
倒数排名融合两路得分
│
▼
代码感知重排
• 自适应加权
• 定义提升
• 标识符词干
• 文件聚合
• 噪声惩罚
│
▼
Top-K Chunks
│
▼
喂给 LLM2.2 关键组件
| 组件 | 作用 |
|---|---|
| Model2Vec | MinishLab 自研的"无 Transformer 静态嵌入"模型,CPU 上极快 |
| potion-code-16M | 专为代码训练的 Model2Vec 模型(16M 参数) |
| BM25 | 经典词法检索,擅长精确符号 / API 名称匹配 |
| RRF | 双路融合而不让一路压制另一路 |
| 代码感知重排 | 按代码特性优化最终排名 |
3. 实现原理
3.1 Model2Vec 静态嵌入
传统语义检索要跑 Transformer(BERT/CodeBERT),CPU 上几秒一条嵌入。Model2Vec 的做法:
Transformer 训练(一次,离线)
↓
蒸馏成静态嵌入表(每个 token 一个固定向量)
↓
推理时只做查表 + 平均池化
↓
CPU 上每秒可生成上万条嵌入potion-code-16M 是专为代码设计的版本(16M 参数 ≈ 几十 MB),相比传统 Transformer:
- 索引速度快约 200×
- 查询速度快约 10×
- 准确率仅低 0.008 NDCG@10(在 99% 水平)
3.2 双路融合:为什么需要 BM25
纯向量检索的弱点:
- 用户搜
Foo::bar,BM25 一发就中;向量需要绕远 - 用户搜常量名
MAX_RETRY_COUNT,BM25 直接命中文件
纯 BM25 的弱点:
- 用户搜"如何验证用户身份",BM25 一筹莫展;向量游刃有余
Semble 的策略:两路同时跑,用 RRF 合并:
RRF score(d) = Σ over runs (1 / (k + rank(d)))其中 k 是平滑常数(典型值 60),rank(d) 是文档在该路检索中的排名。
3.3 代码感知重排
RRF 之后还有一层"代码语境"重排:
| 信号 | 规则 |
|---|---|
| 自适应加权 | 符号类查询(如 Foo::bar)增加词法权重;自然语言查询保持平衡 |
| 定义提升 | 定义所在 chunk 比仅引用所在 chunk 排名更高 |
| 标识符词干 | 查询词词干化后与标识符词干匹配(如 auth ↔ authenticate) |
| 文件聚合 | 同一文件命中多个 chunk → 该文件整体排名提升 |
| 噪声惩罚 | 测试文件、兼容性 shim、generated 代码降权 |
最终输出 K 个 chunk,每个带 file_path / start_line / end_line / content,可直接喂给 LLM。
3.4 索引存储
- 索引存在单文件或内存中
- 索引文件可在多机/CI 之间共享
- 支持本地路径或 Git 仓库 URL
4. 完整使用步骤
4.1 安装
4.1.1 pip 安装
bash
pip install semble4.1.2 推荐:作为 MCP Server 安装到 Claude Code
bash
claude mcp add semble -s user -- uvx --from "semble[mcp]" semble需要预先安装
uv:bashcurl -LsSf https://astral.sh/uv/install.sh | sh
4.1.3 其他 AI 工具
bash
# Cursor / Codex / OpenCode 同样通过 MCP 配置
# Codex 示例
codex mcp add semble -- uvx --from "semble[mcp]" semble
# 通用 MCP 配置文件(如 ~/.config/codex/config.toml)
[mcp_servers.semble]
command = "uvx"
args = ["--from", "semble[mcp]", "semble"]4.2 命令行用法
bash
# 基础搜索
semble search "authentication flow" ./my-project
# 调整 top-K
semble search "save_pretrained" ./my-project --top-k 10
# 找相关代码(基于已有结果)
semble find-related src/auth.py 42 ./my-project
# 生成 Claude Code sub-agent 模板
semble init4.3 Python API
python
from semble import SembleIndex
# 索引本地目录
index = SembleIndex.from_path("./my-project")
# 或索引 git 仓库
# index = SembleIndex.from_git("https://github.com/MinishLab/model2vec")
# 自然语言或代码片段搜索
results = index.search("save model to disk", top_k=3)
# 查看结果
result = results[0]
print(result.chunk.file_path) # "model2vec/model.py"
print(result.chunk.start_line) # 127
print(result.chunk.end_line) # 150
print(result.chunk.content) # 代码片段
# 找相关代码
related = index.find_related(result, top_k=3)4.4 在 Claude Code 中使用
安装好 MCP 后,直接用自然语言:
"找一下处理用户认证的代码"
→ Claude 调用 semble.search("用户认证")
→ 返回 ~3-10 个最相关 chunk
→ Claude 基于 chunk 回答 / 改代码
"找一些和 save_pretrained 类似的函数"
→ Claude 调用 semble.find_related5. 适用场景
5.1 强推场景
✅ 极致 Token 节省
某次实测:
传统 grep + read: 45,692 tokens
Semble: 566 tokens
节省比例: 98.76%✅ CPU 资源受限
- 索引 250ms,查询 1.5ms,跑在普通笔记本完全没压力
- 无需 GPU,无需付费 API
✅ 代码语义搜索
"加密用户密码的地方" → 语义路命中
"validateUser 调用了哪些函数" → 词法路命中
"和 fetchRates 类似的方法" → 向量路命中✅ 离线/隔离环境
- 不需要任何外部服务、API Key
- 适合企业内网、安全合规场景
5.2 慎用场景
⚠️ 需要调用图分析:Semble 不提供"谁调用 X"这类关系查询,请配合 code-review-graph / GitNexus 使用。
⚠️ 超大单仓库(>10M LoC):纯静态嵌入对极长函数体的语义捕获略弱,可能需要叠加 Transformer。
5.3 不适用场景
❌ 需要重命名 / 重构辅助:Semble 不动代码,只搜代码。
❌ 需要"爆炸半径":用图谱派方案。
6. 与其他项目的对比
| 维度 | Semble | code-review-graph | GitNexus | code-graph-rag-mcp |
|---|---|---|---|---|
| 索引速度 | 250ms / 仓库 | 500 文件 10s | 分钟级 | 100+ 文件/秒 |
| 查询速度 | 1.5ms | 0.4–1.5ms | ~ms | <100ms |
| Token 节省 | 98% | 8.2× 平均 | 未公开 | 5.5× faster |
| 结构关系 | ❌ | ✅ | ✅ | ✅ |
| 语义搜索 | ✅✅✅ | ✅ | ✅ | ✅✅ |
| 资源消耗 | 极轻 | 中 | 中 | 中 |
| 安装复杂度 | 一行 pip install | 一键 install | 多步骤 + 易踩 onnxruntime | tgz + Node 24+ |
| MCP 工具数 | 少(聚焦 search) | 28 | 7 | 26 |
一句话总结:
- 想要"最简单的,单一职责的,token 最省的代码语义搜索" → Semble
- 想要"图 + 语义全套" → code-review-graph 或 code-graph-rag-mcp
- 想要"图 + 浏览器可视化 + 7 Skills" → GitNexus
7. 关键工程亮点
7.1 Model2Vec:MinishLab 的杀手锏
MinishLab 是 Model2Vec 这套"静态嵌入"方法的提出者,目标就是"把 Transformer 蒸馏成 KV 表":
- 训练:一次离线,用 Transformer 算所有 token 嵌入,再做权重学习
- 推理:变成简单的查表 + 池化(O(L),L 是 token 数)
- 适用:embedding 时间是瓶颈、CPU-only、低延迟场景
这是 Semble 能在 CPU 上做到 250ms 全仓库索引的根因。
7.2 与传统 Transformer 嵌入的差距
NDCG@10 对比:
- CodeRankEmbed(专业代码 Transformer):0.862
- Semble:0.854
- 差距:0.008
但速度差距:
- 索引:~200×
- 查询:~10×
工程上这是非常划算的取舍。
7.3 与 grep+read 对比的 Token 经济性
某测试场景:
| 流程 | Token |
|---|---|
| grep + LLM 选 + read | 45,692 |
| Semble + LLM 用 | 566 |
| 比例 | 0.0124 → 降 ~98% |
按 Claude Sonnet 4 价格,每次查询节省约 0.10–0.50 美元。一个团队一天几百次查询,月省成本可观。
8. 已知限制
| 限制 | 说明 |
|---|---|
| 仅做搜索 | 不提供 callers / callees / impact / rename |
| 静态嵌入对超长函数体略弱 | 长函数(>500 行)的语义可能被稀释 |
| 模型固定 | 默认 potion-code-16M,自定义模型需要重训 Model2Vec |
| 不直接支持增量更新(早期版本) | 大改动重新索引非常快(仅 250ms),实际不是大问题 |
9. 参考链接
- GitHub: https://github.com/MinishLab/semble
- 官网: https://minish.ai/packages/semble/introduction/
- HuggingFace 模型: https://huggingface.co/minishlab/potion-code-16M
- 知乎《Semble:专为 AI Agent 打造的极速代码搜索引擎》
- HN 讨论: https://news.ycombinator.com/item?id=47910885
- Medium《Claude Code + Semble: The 98% Token-Saving Hack You Need》