<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Code Search on Hypho</title><link>https://blog.hypho.cn/tags/code-search/</link><description>Recent content in Code Search on Hypho</description><image><title>Hypho</title><url>https://blog.hypho.cn/papermod-cover.png</url><link>https://blog.hypho.cn/papermod-cover.png</link></image><generator>Hugo -- 0.148.2</generator><language>zh-cn</language><lastBuildDate>Mon, 18 May 2026 10:04:30 +0800</lastBuildDate><atom:link href="https://blog.hypho.cn/tags/code-search/index.xml" rel="self" type="application/rss+xml"/><item><title>Semble 代码搜索：给编程 Agent 用的检索工具，真比 grep 更适合生产吗？</title><link>https://blog.hypho.cn/posts/semble-code-search-for-agents/</link><pubDate>Mon, 18 May 2026 10:04:30 +0800</pubDate><guid>https://blog.hypho.cn/posts/semble-code-search-for-agents/</guid><description>Semble 是一个面向编程 Agent 的本地代码搜索工具，声称比 grep+read 少用约 98% token。本文从 MCP 集成、BM25+静态向量混合检索、索引延迟、上下文噪声和生产落地边界出发，分析它适合哪些 AI 编程工作流，什么时候能提升代码理解效率，以及什么时候仍然应该保留传统 grep、完整阅读和人工代码审查。</description><content:encoded><![CDATA[<p>我对“给 Agent 做代码搜索”这类工具一直有点警惕。</p>
<p>原因很简单：很多产品把问题讲成“grep 太笨，向量检索更聪明”，最后落地却变成另一个黑盒。Agent 找不到符号定义时，开发者至少还能看见它 grep 了什么；如果换成一个语义搜索服务，结果看起来更像魔法，但错的时候也更难排查。</p>
<p>所以看到 HN 上的 <a href="https://github.com/MinishLab/semble">Semble</a> 时，我第一反应不是“又一个代码 RAG”，而是问一个更工程化的问题：<strong>编程 Agent 到底需要什么样的代码搜索？</strong></p>
<p>Semble 的答案挺明确：它不是给人做 IDE 搜索，也不是给企业做大规模代码知识库，而是给 Claude Code、Codex、Cursor、OpenCode 这类编程 Agent 提供一个本地、低延迟、少 token 的代码检索层。HN 原帖标题也很直接：<a href="https://news.ycombinator.com/item?id=48169874">Show HN: Semble – Code search for agents that uses 98% fewer tokens than grep</a>。截至我写这篇时，项目在 GitHub 上已经超过 1000 stars，最近提交也在 2026 年 5 月，至少不是一个空 README 项目。</p>
<h2 id="为什么-grep-对-agent-不够友好">为什么 grep 对 Agent 不够友好</h2>
<p>人用 grep，其实会做很多隐性判断。</p>
<p>你搜 <code>auth</code>，看到 30 个文件，会快速扫目录名、测试文件、legacy 文件，再决定先打开哪个。你会知道 <code>auth_test.py</code> 不是主实现，<code>compat/</code> 里可能只是兼容层，<code>AuthProvider</code> 的定义比调用点更重要。</p>
<p>Agent 就没这么省。</p>
<p>它通常会先 grep，一个关键词命中几十个文件，然后 read 一堆文件。每多读一个文件，就多消耗上下文窗口、多花钱、多增加模型注意力噪声。更麻烦的是，Agent 经常会被“看起来相关”的调用代码带偏，最后改了外围逻辑，真正的核心函数反而没碰。</p>
<p>用人话说：grep 的问题不是搜不到，而是<strong>搜出来之后太需要人类判断</strong>。</p>
<p>这也是 Semble 这个选题值得写的地方。它服务的搜索意图很清楚：如果你在搭建 AI 编程工作流，是否应该给 Agent 加一个专门的代码检索层，而不是继续让它 grep/read 暴力翻仓库？</p>
<h2 id="semble-的技术路线不是纯向量搜索而是混合检索">Semble 的技术路线：不是纯向量搜索，而是混合检索</h2>
<p>从 README 看，Semble 的实现没有走“把整个仓库丢进大 embedding 模型”的路线。它先用 <a href="https://github.com/chonkie-inc/chonkie">Chonkie</a> 做代码感知切块，然后同时跑两套检索：</p>
<ul>
<li>基于 <a href="https://github.com/MinishLab/model2vec">Model2Vec</a> 的静态 embedding，默认用代码专用的 <a href="https://huggingface.co/minishlab/potion-code-16M">potion-code-16M</a> 做语义相似度；</li>
<li>基于 <a href="https://github.com/xhluca/bm25s">bm25s</a> 的 BM25，负责精确词、符号名、API 名称等词法匹配。</li>
</ul>
<p>两路结果再用 Reciprocal Rank Fusion 融合，并叠加一些代码场景的 rerank 信号：符号查询提高词法权重、定义位置加权、identifier stem 匹配、同文件多 chunk 命中加权、测试和 legacy 文件降权等。</p>
<p>这个设计我比较认可。</p>
<p>因为代码搜索和普通文档 RAG 不一样。你搜“where is authentication handled”时，语义检索有用；但你搜 <code>save_pretrained</code>、<code>Foo::bar</code>、<code>config_parser</code> 时，语义模型再聪明也不能把精确符号匹配丢掉。纯向量搜索在代码库里最容易犯的错，就是把“意思相近”排到“真正定义”前面。</p>
<p>Semble 的混合路线本质上是在承认一件事：<strong>代码检索不是语义理解比赛，而是语义、符号和工程上下文的排序问题。</strong></p>
<p>这和我之前写 RAG 重排时的判断是一致的：向量召回只解决“可能相关”，真正影响可用性的往往是第二阶段排序。相关讨论可以看这篇：<a href="https://blog.hypho.cn/posts/rerank-bi-encoder-cross-encoder/">向量数据库已经很快了，为什么还要重排？</a>。Semble 把这个思路压缩到本地代码搜索里，算是一个很实用的工程版本。</p>
<h2 id="它为什么强调少用-98-token">它为什么强调“少用 98% token”</h2>
<p>Semble README 里反复强调 token 节省：相对 grep+read，返回更小的相关代码片段，声称可以少用约 98% token。它的 <code>semble savings</code> 统计也比较朴素：把“命中文件全文字符数”和“实际返回片段字符数”做差，再按 4 字符约等于 1 token 估算。</p>
<p>这个口径不完美，但方向对。</p>
<p>对编程 Agent 来说，token 成本不是唯一问题。更关键的是上下文污染：模型读了太多不相关文件，就会开始“合理化”错误线索。你以为只是多花几分钱，实际可能是让 Agent 在错误文件里自信地改代码。</p>
<p>我更愿意把 Semble 的价值理解成：它不是单纯省钱，而是在帮 Agent 缩小可操作空间。</p>
<p>比如一个 Agent 要找“配置加载后如何合并环境变量”，传统 grep 可能先命中一堆文档、测试、旧兼容代码。Semble 这种混合检索如果能把定义、主实现和同文件上下文排到前面，Agent 后续 read 的内容就更接近真正需要改的地方。</p>
<p>说白了就是：少读错代码，比少读代码更重要。</p>
<h2 id="mcp-很方便但生产里我更建议保留-bash-入口">MCP 很方便，但生产里我更建议保留 Bash 入口</h2>
<p>Semble 支持 MCP Server，可以通过 <code>uvx --from &quot;semble[mcp]&quot; semble</code> 接进 Claude Code、Codex、OpenCode、Cursor 等工具；也支持 CLI 和 Python API。README 里还特别提到，对 Claude Code 或 Codex CLI 的 sub-agent，Bash integration 可能比 MCP 更实用，因为有些 sub-agent 不会直接拿到顶层 MCP schema。</p>
<p>这个细节挺真实。</p>
<p>很多 Agent 工具链在 demo 里 MCP 很顺，但一到多 Agent、子任务、CI、沙箱环境，MCP 工具的可见性、权限和生命周期就会变复杂。相比之下，一个 <code>semble search &quot;authentication flow&quot; ./repo</code> 的 CLI 命令更笨，但更容易写进 <code>AGENTS.md</code>、CI 脚本和审计日志。</p>
<p>我的建议是：</p>
<ul>
<li>个人开发或轻量项目，可以先用 MCP，体验自然语言代码搜索；</li>
<li>团队级工作流，最好同时配置 CLI/Bash 入口，让 Agent 的搜索行为可复现；</li>
<li>对关键仓库，不要让搜索工具自动替代人工审查，至少要保留“搜索结果来自哪些文件、哪些行”的可追踪信息。</li>
</ul>
<p>这和我之前写 <a href="https://blog.hypho.cn/posts/claude-code-routines/">Claude Code routines</a> 时的观点类似：真正可靠的 Agent 工作流，不是给模型更多自由，而是把常用动作沉淀成可重复、可观察的例程。</p>
<h2 id="semble-适合什么场景">Semble 适合什么场景</h2>
<p>我会把 Semble 放在“中小型代码库 + 高频 Agent 修改”的位置上，而不是一上来就当企业代码搜索平台。</p>
<p>它最适合的场景大概有三类。</p>
<p>第一，Agent 经常需要理解陌生模块。比如让 Codex 修一个 bug，它需要先知道认证逻辑、缓存逻辑、数据模型在哪里。Semble 能把“自然语言问题”映射到代码片段，比单纯 grep 一个关键词更贴近 Agent 的提问方式。</p>
<p>第二，仓库不大但语言混杂。Semble 的 benchmark 覆盖 63 个仓库、19 种语言，README 宣称平均仓库索引用时约 263ms、查询 p50 约 1.5ms，且 CPU 本地运行。即便实际项目里会慢一些，这个量级也意味着它可以放进交互式 Agent 循环，而不是只能做离线索引。</p>
<p>第三，团队已经开始关心 Agent token 和上下文质量。尤其是用 Claude Code、Cursor、Codex 做大仓库修改时，传统 grep/read 会让模型吞掉大量文件。Semble 至少给了一个更精细的入口。</p>
<p>但它不适合所有情况。</p>
<p>如果你的仓库强依赖跨服务调用、运行时配置、数据库 schema、RPC IDL，单纯代码检索不够。Agent 需要的不只是“哪段代码相关”，还包括“这段代码在生产里如何被调用”。这类场景更像系统级知识图谱或内部开发者平台问题，Semble 只能解决其中的局部搜索。</p>
<p>另外，Semble 目前仍是新项目。虽然 GitHub stars 和提交活跃度不错，也有 <code>src/</code>、<code>tests/</code>、PyPI 包和 benchmark，但生产落地仍要验证版本稳定性、索引缓存策略、大仓库内存占用、私有代码安全审计等问题。它不是白皮书阶段，不过也还没到“闭眼上全公司”的成熟度。</p>
<h2 id="我会怎么接入">我会怎么接入</h2>
<p>如果让我在团队里试 Semble，我不会一开始就替换 grep。</p>
<p>我会先把它作为 Agent 的“第一查询工具”：当任务是理解业务逻辑、找实现位置、找相似代码时，优先用 <code>semble search</code>；当任务是精确确认字符串、配置项、错误码、迁移脚本时，仍然用 grep 或 ripgrep。两者并不冲突。</p>
<p>一个比较稳的 <code>AGENTS.md</code> 规则可以是：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">当你需要理解某个功能在哪里实现时，先使用 semble search；
</span></span><span class="line"><span class="cl">当你需要确认具体符号、错误信息、配置 key 是否存在时，再使用 rg/grep 做精确验证；
</span></span><span class="line"><span class="cl">修改代码前必须 read 目标文件的完整相关上下文，不得只依赖搜索片段。
</span></span></code></pre></div><p>最后一句很重要。</p>
<p>搜索结果只能帮 Agent 找入口，不能替代阅读上下文。尤其是代码修改任务，chunk 级结果可能漏掉初始化、副作用、类型约束和调用顺序。如果 Agent 只看一个片段就动手，Semble 再准也救不了它。</p>
<p>这也是我对“Agent 工具化”的基本态度：工具应该让模型少走弯路，而不是让模型少承担验证责任。像 <a href="https://blog.hypho.cn/posts/statewright-state-machine-agent-guardrails/">Statewright 用状态机给编程 Agent 加护栏</a> 这类项目关注的是执行过程约束，Semble 关注的是上下文获取质量。两个方向其实可以叠加：先让 Agent 找对代码，再用状态机限制它怎么改。</p>
<h2 id="结论值得试但不要神化">结论：值得试，但不要神化</h2>
<p>Semble 最打动我的地方，不是“98% token saving”这个数字，而是它把编程 Agent 的一个高频痛点讲清楚了：Agent 不缺搜索命令，缺的是低噪声、低延迟、可落地的代码上下文入口。</p>
<p>它的混合检索路线也比“全靠 embedding”的方案更接地气。BM25 负责符号和关键词，静态代码 embedding 负责自然语言意图，rerank 负责把定义、主实现、文件上下文排上来。这个组合不性感，但工程上合理。</p>
<p>我的判断是：如果你已经在用 Claude Code、Codex 或 Cursor 做真实代码修改，Semble 值得作为辅助检索层试一轮；如果你还没有稳定的 Agent 工作流，先别急着引入更多工具，先把任务拆分、测试、审查和回滚做好。</p>
<p>搜索只是第一步。</p>
<p>真正的生产级 AI 编程，靠的是“找得准、改得小、测得全、回得去”。Semble 解决的是第一项，而且解决得还挺有意思。</p>
]]></content:encoded></item></channel></rss>