---
title: indexbind：面向 Markdown 的本地检索工具
date: '2026-03-30 16:35:00'
updated: '2026-03-30 16:35:00'
draft: false
summary: indexbind 最早只是 mdorigin 的站内搜索需求，后来又在 workspace 的整库试验里长成一个面向 Markdown 的本地检索工具。
slug: indexbind-local-markdown-search-tool
syndication:
- platform: Weibo
  url: https://weibo.com/ttarticle/p/show?id=2309405282322085183684
- platform: X / Twitter
  url: https://x.com/jolestar/status/2038648260823560589
tags:
- indexbind
- markdown
- search
topics:
- ai
- software-engineering
type: post
---

![indexbind 封面图](./cover.png)

最近把一个内部已经用了几轮的检索项目整理出来，名字叫 `indexbind`。

这个项目最早并不是一个独立想法，它是从 [mdorigin：面向 Agent 的内容发布工具](https://jolestar.com/mdorigin-agent-publishing-tool/) 的站内搜索需求里长出来的。

当时我的 blog 系统就是 `workspace` 目录下的 `public/` 子目录。我用 `mdorigin` 把 `public/` 目录下的 Markdown 直接部署到 Cloudflare Workers 上，然后发现还需要一个搜索功能。

我当时有两个要求。一个是搜索要走离线构建，不依赖外部服务，还能在 Node、浏览器和 Worker 里复用。另一个是检索结果需要提供 Markdown 文件名，而不只是站点最后生成的 HTML URL。

最后 `indexbind` 的技术选型是：Node.js 负责 CLI、构建链路和集成，Rust 负责索引构建和查询核心，WASM 负责把同一套核心带到浏览器和 Worker。这样选不是为了多堆一层技术栈，而是因为这几个要求同时存在：构建侧要容易接进现有的 JS/TS 工具链，检索核心要有比较稳的性能和内存控制，还要能部署到 Cloudflare Workers，而不是维护三份搜索代码。

blog 这条链路跑通以后，一个更自然的问题就出来了：既然 `public/` 可以，那整个 `workspace/` 是不是也可以？

于是直接拿 `workspace` 做了整库试验。`public/` 只是其中一个子目录，剩下还有 `drafts`、`notes`、`research`、`archive`、`projects` 这些完全不同的内容。

这时问题就不再只是“能不能搜”，而是哪些目录应该进索引，哪些内容默认可搜，不同目录怎么加权。

试验效果还不错，于是决定把 `indexbind` 值得单独整理出来。它不只是在 `mdorigin` 里给 blog 搜索用，也可以给一个内容仓库按目录、按内容集去建索引。

## 一个最小例子

`indexbind` 现在有两条主要路径：

- Node 侧用 SQLite artifact
- 浏览器和 Worker 侧用 canonical bundle

对应的 CLI 也比较直接：

```bash
npx indexbind build ./docs ./index.sqlite
npx indexbind search ./index.sqlite "rust guide" --text
npx indexbind build-bundle ./docs ./index.bundle
```

如果内容会持续更新，也可以走增量缓存：

```bash
npx indexbind update-cache ./docs ./.indexbind-cache.sqlite --git-diff
npx indexbind export-artifact ./.indexbind-cache.sqlite ./index.sqlite
```

索引在构建阶段产出，后面可以在不同 runtime 里直接复用。

如果 CLI 不够，也可以自己写 builder。

比如在我的 `workspace` 里，我让 Agent 直接写了一个 builder 脚本，决定哪些目录进入索引、metadata 怎么写、不同目录怎么加权。对 Agent 来说，这种扩展本身就是能力。`indexbind` 负责的是索引构建和查询核心，具体这批内容要怎么进索引，还是由你自己的目录结构和内容组织方式来决定。像 `archive` 这种目录，权重就应该低于 `drafts` 和 `public`。

## 如果你想试一下

最简单的方式是：

```bash
npm install indexbind
npx indexbind build ./docs ./index.sqlite
npx indexbind search ./index.sqlite "rust guide" --text
```

如果你的目标是浏览器或者 Worker，就继续看文档站里的 bundle 路径。如果你已经有自己的内容抽取逻辑，也可以直接看 `indexbind/build` 的 programmatic API。CLI 只是最直接的入口，不一定是唯一入口。

如果你在做的是文档系统、博客或发布系统、本地知识库工具，或者 Agent 工作流里的内容检索，那可以试一下 `indexbind`。它已经在我自己的几个 docs 项目、blog 搜索，以及 `workspace` 这类本地知识库和 Agent 检索场景里实际跑过一段时间。

如果你要的是一个现成的搜索产品，那它可能不是最合适的答案。但如果你要的是一套能跟内容一起构建、一起分发、也能比较自然地接进自己系统里的本地检索工具，它值得你看一眼。

如果你的目标是直接搭一个文档或博客系统，也可以直接看 [mdorigin：面向 Agent 的内容发布工具](https://jolestar.com/mdorigin-agent-publishing-tool/)。它本身就内置了 `indexbind`，这条路会更省事。

可以把这个 skill 丢给 Agent，让它帮你接：

[https://github.com/jolestar/indexbind/blob/main/skills/indexbind/SKILL.md](https://github.com/jolestar/indexbind/blob/main/skills/indexbind/SKILL.md)

项目地址：

- GitHub  [https://github.com/jolestar/indexbind](https://github.com/jolestar/indexbind)
- 文档站  [https://indexbind.jolestar.workers.dev](https://indexbind.jolestar.workers.dev)
- npm  [https://www.npmjs.com/package/indexbind](https://www.npmjs.com/package/indexbind)
