内容
# 网格
一个自主的、单一二进制的知识库,其主要读取者是编码代理。
您在IDE中编辑纯Markdown。您的代理(Claude Code、Codex)通过MCP搜索它,并在完成一项工作后**写回它学到了什么**,一个决定,一个陷阱,一个事后分析,以便下一个代理继承它。这个写回循环是关键:知识库自我记录,并随着每次运行变得更加智能。Mesh内部没有推理AI;它是快速引擎(解析、索引、图形、检索),而代理是图书管理员。
它是一个Go二进制文件,没有cgo,没有外部服务。从Mesh检索比代理读取整个文件更便宜:它返回排名卡片(标题 + 匹配的片段 + 为什么它出现)并打包适合令牌预算的最佳捆绑包,以便代理一次读取一个笔记而不是三个。
## 诚实的范围
- **核心,零模型:** 基于卡片的廉价检索(FTS + 图形-BM25 + 层级-0,纯Go,无推理,近乎零CPU)加上代理写回飞轮,在单个无胶水二进制文件中。`mesh_search`向代理提供排名卡片(标题 + 片段 + 为什么);**代理读取卡片并选择** 值得获取的1-2个笔记。 一个有能力的编码代理已经比任何附加的重排器都更强的相关性判断者,因此对于代理消费者来说,代理*就是*重排器,免费。 这是代理的整个产品。
- **可选的BYOAI插件(默认关闭,适用于成本敏感或非代理消费者):**
- **向量(`mesh embed`)** 在关键词搜索失败的释义查询上提高召回率(13/20 -> 20/20 在Hive评估中)。在查询释义笔记时值得开启;可以指向云端点以实现零本地CPU,或者跳过(FTS关键词召回率已经是23/25)。
- **交叉编码器重排** 在消费者**信任顶部结果而不读取卡片**时提高顶部-1精度(`answer@1` 3/20 -> 10/20 在释义查询中)。这不是一个有能力的代理(它读取卡片并进行判断);它是一个廉价/小型下游模型、一个盲“获取顶部-1”的管道,或者是一个多租户云部署,其中将排名卸载到本地判断者可以节省租户的计费模型,从而避免读取和排名候选者。除非配置了端点,否则不启用。有关匹配臂测量和对抗性审查,请参见`docs/SPEC.md`。
## 安装
Mesh是一个自包含的Go模块(`github.com/bright-interaction/mesh`,无cgo),位于`bright-interaction/automations`多仓库中。由于该仓库是私有的,因此从检出到安装的路径是一个命令,无需发布仓库,无需公开暴露:
```bash
cd automations/mesh
make install # 构建一个静态二进制文件到 ~/.local/bin/mesh
```
一旦发布为自己的公共仓库,简单的`go install`即可生效:
```bash
go install github.com/bright-interaction/mesh/cmd/mesh@latest
```
模块路径已经是`github.com/bright-interaction/mesh`,因此公开发布只是将`mesh/`子树镜像到自己的仓库并添加版本号,无需代码更改。`docs/RELEASING.md`记录了此过程,`scripts/split-public-repo.sh`执行了它。在此之前,上述检出构建是安装路径。(私有镜像也适用于`GOPRIVATE=github.com/bright-interaction/* go install ...@latest`。)
## 快速入门
```bash
mesh init my-vault # 初始化一个保险库(启动索引 + 首次构建)
mesh new decision "使用 Postgres 而非 Mongo" \
--do "..." --dont "..." --why "..." --vault my-vault # 捕获判断;Mesh填充id/日期/位置
mesh index my-vault # 在编辑后重建索引
mesh watch my-vault # 实时索引编辑(无手动索引;Ctrl-C停止)
mesh search "数据存储选择" --vault my-vault --budget 4000
mesh doctor my-vault # 索引是否新鲜?是否有漂移或lint问题?
```
`mesh watch` 是本地优先的,像Obsidian一样的即时性:编辑笔记后,它立即变得可搜索,无需提交,无需手动`mesh index`。它在启动时、每次更改(去抖动)和周期性安全检查时进行协调,以确保索引始终收敛,因此错过的文件事件不会使索引过时。
已经有一个 Foam / Obsidian 风格的保险库?将其提升到 Mesh 模式的单一幂等传递:
```bash
mesh migrate my-vault # 合成id,更新->何时,提取 ## 相关到相关:
mesh index my-vault
```
## 可选:语义搜索 + 重排(BYOAI,独立)
上面的核心不需要模型。这两个阶段是**可选的**并且**默认关闭**;仅在“诚实的范围”中针对特定情况(释义召回或成本敏感/非代理消费者)打开。Mesh本身不运行任何推理,而是调用**您**控制的HTTP端点,因此它们保留在您的基础设施上:
```bash
# 1. 向量:通过任何OpenAI兼容的/embeddings端点(Ollama等)嵌入笔记
export MESH_EMBED_ENDPOINT=http://localhost:11434/v1
export MESH_EMBED_MODEL=nomic-embed-text
export MESH_EMBED_DOC_PREFIX="search_document: " # nomic-style不对称模型
export MESH_EMBED_QUERY_PREFIX="search_query: "
mesh embed my-vault # 每个笔记一个向量
# 2. 重排:交叉编码器提高top-1精度(参见tools/rerank-server)
export MESH_RERANK_ENDPOINT=http://127.0.0.1:8787/rerank
export MESH_RERANK_MODEL=Xenova/ms-marco-MiniLM-L-6-v2
mesh status my-vault # 显示哪些检索信号是活跃的
```
对于一个非常大的保险库,设置`MESH_HNSW_THRESHOLD=<N>`以构建一个内存HNSW(近似最近邻)索引,一旦保险库至少有N个块向量,就会替换强力余弦扫描。它默认关闭(强力扫描在几千个笔记后仍然小于5毫秒),并且在构建错误时回落到强力扫描,因此它只会加速检索。`mesh status`在活动时显示`ANN/hnsw`。
一旦设置,`mesh search` / `eval` / `mcp`就会融合语义信号并自动应用重排。两者都安全地降级:没有嵌入器意味着仅限词汇,关闭的重排端点会回落到融合顺序。将任一环境变量指向云提供商会将笔记内容发送到盒外,因此请保持本地以保持独立。 一个现成的本地交叉编码器服务器位于`tools/rerank-server/`。
你有一组用于语料库的标注查询?`mesh tune cases.json --test held-out.json` 网格搜索融合权重以最大化answer@1并打印保留结果以及应用获胜者的`MESH_WEIGHT_FTS/GRAPH/VEC`行。它调整融合的排名,因此在运行向量时最有帮助而没有重排器(启用重排器时,交叉编码器拥有顶部结果,融合权重被洗出)。始终传递一个保留的 `--test` 集;根据您报告的查询调整是您欺骗自己的方式。
## 将其连接到您的编码代理
Mesh通过stdio使用MCP(JSON-RPC)。将您的代理指向:
```json
{ "command": "mesh", "args": ["mcp", "--vault", "/abs/path/to/my-vault", "--watch"] }
```
然后代理获取:`mesh_search`(融合,预算感知),`mesh_fetch`(一个笔记或一个锚点),`mesh_god_nodes`(中心地图来定位),`mesh_changed_since`(恢复时的增量),以及写回工具`mesh_append_note` / `mesh_write_entity`。检索合约(如何廉价查询,以及完成后如何写回)作为MCP `initialize`指令和`mesh://contract`资源提供,因此任何代理都可以在无需额外提示的情况下很好地使用它。
`--watch`标志在服务器内运行实时索引器,以便您(或队友)在编辑器中编辑的笔记在同一会话中无需重启即可搜索。监视进度输出到stderr;stdout保持纯JSON-RPC流。省略它以获得经典行为,其中索引仅在代理自己的写回时刷新。
## 团队同步
在任何客户端上与团队共享保险库,无需git。同步**客户端**是开放核心的一部分;**团队同步中心**是商业/专业产品(托管在mesh.brightinteraction.com,或在商业许可下自行托管,参见[LICENSING.md](LICENSING.md))。客户端拉取并与之协调:
```bash
# 在每个队友的笔记本电脑上(针对托管或许可的中心):
mesh join https://mesh.example.com <邀请令牌> my-vault # 克隆,无需git
# ... 在编辑器中编辑笔记 ...
mesh sync my-vault # 推送您的内容,拉取队友的内容
```
协调优先:`mesh sync`是一个三向合并。两个人在同一页面上添加块会自动合并;真正覆盖同一行会保留中心版本并将您的版本保存到一个`*.sync-conflict-*.md`兄弟文件中,以便手动解决。删除和重命名会传播;中心作者将git历史记录归因于每个用户。添加`mesh sync --watch`以获取实时SSE推送(中心更改会立即拉取)。一个独立的`mesh-curator`工作程序可以使用团队自己的BYOAI模型协调非琐碎冲突,并通过正常的同步路径将合并的笔记提交回去(中心本身保持AI免费)。
## 命令
| 命令 | 目的 |
|---|---|
| `mesh init [路径]` | 初始化一个新的保险库 |
| `mesh new <类型> "<标题>"` | 搭建一个笔记(自动填充id、日期、位置、骨架) |
| `mesh migrate [保险库]` | 将Hive/Foam风格的保险库升级到Mesh模式 |
| `mesh index [保险库]` | 解析 + 持久化索引(`.mesh/mesh.db`) |
| `mesh watch [保险库]` | 实时索引每次更改(去抖动 + 周期性协调) |
| `mesh embed [保险库]` | 通过BYOAI端点嵌入笔记(启用语义搜索) |
| `mesh search "<查询>"` | 融合、预算打包的检索(配置时启用语义 + 重排) |
| `mesh status [保险库]` | 索引行计数 + 哪些检索信号是活跃的 |
| `mesh lint [保险库]` | 前置元数据/链接/文件名(非零退出用于CI) |
| `mesh doctor [保险库]` | 索引新鲜度(漂移)、计数、健康状态 |
| `mesh eval <cases.json>` | 网格-1检索测量与FTS基线 |
| `mesh tune <cases.json>` | 从标注查询中学习融合权重(在保留集上验证) |
| `mesh mcp [--vault] [--watch]` | 为代理提供检索 + 写回接口(使用 `--watch` 进行实时索引) |
| `mesh tui [保险库]` | 键盘三窗格终端视图(笔记、排名搜索、预览 + 邻居) |
| `mesh ui [保险库]` | 浏览器图形查看器(力图 + 星系)覆盖同一索引,localhost |
| `mesh serve-ssh [保险库]` | 通过SSH提供TUI,以便队友使用`ssh`浏览图形,无需安装(密钥认证,失败关闭) |
| `mesh join <中心> <邀请> [保险库]` | 加入团队保险库并克隆它(无需git) |
| `mesh sync [保险库]` | 与中心协调(推送本地编辑,拉取队友编辑) |
团队同步**中心**服务器和BYOAI**管理者**是商业/专业层,不在此仓库中(参见下面的版本)。
## 构建
```bash
go build ./...
go test ./...
```
无cgo。存储是纯Go的`modernc.org/sqlite`,以WAL模式运行;`.mesh/`索引是派生的、可删除的工件,markdown是源头。
## 许可证和版本
开放核心,双重许可。本仓库(单用户保险库、图、检索、查看器、CLI、MCP接口和同步**客户端**)是**AGPL-3.0**(参见`LICENSE`)。
**团队同步中心**和**BYOAI同步管理者**是商业产品:
- **托管** 在 mesh.brightinteraction.com(托管团队同步)。
- **主权自我托管** 在商业许可 + 支持下,用于在自己的基础设施上运行中心,适用于欧盟/受监管组织。
核心的商业许可适用于AGPL不适用的情况。参见[LICENSING.md](LICENSING.md)和[docs/OPEN-CORE.md](docs/OPEN-CORE.md)。