内容
="center">
# 突触
**为您的人工智能记忆提供语义搜索功能,无需修改 Engram。**
[](LICENSE)
[](go.mod)
[](https://modelcontextprotocol.io)
[](go.mod)
[](#contributing)
<em>突触是连接记忆并赋予其意义的桥梁。</em>
</div>
---
## 这是什么?
[Engram](https://github.com/Gentleman-Programming/engram) 为您的人工智能代理提供**持久记忆**,并使用 SQLite **FTS5** 进行搜索——快速、基于词汇、基于关键词。但是 FTS5 只匹配*单词*,不匹配*含义*。
**突触**解决了这个问题。它是一个独立的 MCP 服务器,与 Engram 并行运行,读取其数据库**只读**,并在上面添加**语义向量搜索**。相同的记忆,新的感知方式——它通过记忆的**含义**找到它们,即使它们与您的查询**没有共同的关键词**:
| 您搜索… | 突触仍然找到… | 普通 FTS5 为什么会错过它 |
|---|---|---|
| `结账很慢` | `修复订单 API 中的 N+1 查询` | 没有共同的单词 |
| `身份验证一直出错`JWT token 过期` | 不同的词汇 `pago con🇪🇸 | `Stripe 支付集成`🇧 | 不同的## 为什么这样构建? **兄弟,而不是包装** 突触公开了新的apse_*` ,与 Engram 的工具并列*。拦截或替换 `mem_search`。同时运行两者;不会损失任何东西。
数据库,每个所有 `engram.db` 被**只读**从不写入**。突触拥有一个单独的 `synapse.db` 用于隔离使突触**免受 Engram 的模式更改的影响**。
混合搜索。** 词汇(FTS5)语义(向量 KNN通过**互惠(RRF60)融合在单个排名列表中获得**精确关键词匹配**和基于含义的匹配。
-。** 每个 `synapse_search` 都地向量化它所触及的任何新观察结果,并启动一个后台回索引自动收敛100%。在第一次,您永远不需要手动调用 `synapse_backfill` **纯 Go,无 CGO。** 向量存储 中(通过 `modern/sqlite`), 在 Go 中计算——无需 C 编译器,无。单个 `go 跨编译为 macOS、Linux 和 Windows实于 Engram 的。
## 您不会离开 Engram
突触是一个**索引,而不是——类似于 Elasticsearch 位于旁边。Engram**单一真实来源**。
突触嵌入您的 content`,synapse.db` 只记忆的**派**,加上内容哈希名称和指向 Engram 的 `obs_id`:
| 位于 `eng(Engram 所有位于 `syn`(突触所有) |
|---|---|
| 标题、内容、类型、项目、时间戳、编辑、删除 | `obs_id` → 向量LOB)+ 内容 模型 |
因此,**从不持有您的记忆文本**。在搜索时,它从 `engram.db` 读取标题/摘要来构建结果。这意味着 `synapse.db` 是一个**可处置的缓存**:随时删除它,下次 `synapse_backfill`(或搜索)会从 Engram 重建它——您无法通过触摸突触而丢失记忆。
## “Engram 的 `--semantic` 不吗?”名称它们解决了不同的问题。
的 `conflicts` 使用 **LLM 来判断两个记忆是否相互 (`conflicts_with`, `supersedes`, … 这是**冲突检测只检查**TS5 匹配的关键词对**。正如自己的文档所述,它 *"无法独立发现完全无关对。"*
突**语义搜索**:它通过向量嵌入对记忆进行**含义**排序, surfacing hits that share** with your query — 正是关键词门控的。不同的问题,不同的机制;它们组合在一起。
## 工作原理
```mermaidchart LR
Agent代理<br/> Code · OpenCode · Cursor"]
subgraph EngramEngram — 未"]
ET["工具"]
Eengram.dbS5 ET --- E end
apseBox["突触项目"]
ST 个 synapse_*"]
SDBapse.db<br/>向量作为 BLOB")]
end
Agent -- " 标准输入输出" --> Agent -- " 标准输入输出"
ST -.读" .-> E ST -- "方式嵌入" -->["OpenAI ·<br/>本地模型(ama)"]
```
`synapse_search` 调用运行 FTS5NN,然后将两个与 RRF 融合并后的结果。
## 先决条件
| 为什么 |
---|
| **Go 1.25+** (仅用于构建/安装) | 构建工具链 — 无需 C 编译器 |
| **[Engram 已安装](https://github.com/Gentleman-Programming/engram)** | 突触读取其 `engram.db`;它补充 Eng替换它 **嵌入提供 | OpenAI API 或** 通过 [Ollama](https://ollama.com)AI / LM Studio 的免费本地模型(参见 [免费和本地嵌入](#免费和本地嵌入-无-open账单)) 安装
突触 Go** — 无 CGO,无 C 编译器,无构建标签。标准的单行命令即可生效:
**选项 A — 使用 Go 安装(推荐):**
```sh
go install github.com/000Erick/synapse/cmd/synapse@latest
```
二进制文件位于 `$(go env GOPATH)/bin/synapse`。
**选项 B — Homebrew(macOS / Linux):**
```sh
brew install 000Erick/tap/synapse
```
**选项 C — Scoop(Windows):**
```sh
scoop bucket add rick https://github.comrick/scoop-bucket
scoop install synapse
```
**选项 D — 下载预编译二进制文件:**
预编译的 macOS / Linux / Windows 二进制文件(amd64 + arm64)发布在 [Releases](https://github.com/000Erick/synapse/releases) 页面 — 下载并运行,无需。
**选项 E —代码构建:**
```sh
git clone https/000Erickapse.git
apse
cp . .env #您的 OPENAI_APImake build # 生成 ./synapse
make # 运行测试套```
## 将其 MCP 客户端
与 Engram **运行**。保留ram 服务器条目旁边添加突触Claude Desktop / / Cursor** (`clktop_config.json `.mcp.json````json
{
"mcpServers": {
"synapse": {
"command": "/绝对路径/to/synapse",
"env": {
"OPENAI_API_KEY": "sk-...",
"ENGRAM_DB_PATH": "/Users/you/.engram/engram.db"
}
}
**Open (`opencode
{
"https://.ai/config.json",
"mcp": {
"synapse": {
"type": "local",
"command": ["/绝对路径/to/synapse"],
"enabled": true,
"environment": {
"OPENAI_API_KEY": "sk-...",
"ENGRAM_DB_PATH": "/Users/you/.engram/engram.db"
}
}
}
}
```
重启您的客户端。现在您应该会在 Engram 旁边看到五个 `synapse_*` 工具。
## 配置
突触从环境中读取配置(自动加载本地 `.env` 进行开发)。
| 变量 | 默认值 | 描述 |
|---|---|---|
| `OPENAI_API_KEY` | — | **必填** 用于回填和语义搜索。使用本地模型时,设置任意非空占位符(例如 `ollama`)——本地服务器会忽略它 |
| `OPENAI_EMBED_MODEL` | `text-embedding-3-large` | 嵌入模型名称 |
| `SYNAPSE_EMBED_ENDPOINT` | — | OpenAI 兼容的嵌入 URL。设置为使用**免费、本地模型**(Ollama、LocalAI、LM Studio)。为空 = OpenAI |
| `SYNAPSE_EMBED_DIMS` | `0`(OpenAI 默认值) | 本地模型的向量大小(例如 `nomic-embed-text` 的 `768`),因此 `synapse_stats` 正确报告 |
| `S_DB_PATH`/.synapse/synapse.db`触的向量数据库 `ENGRAM` | `~/engram | Engram 的(只读) |
### 免费和本地 OpenAI 账单)
突触使用纯 OpenAI 兼容的 HTTP,因此任何本地它 — **[Ollama](https://), LocalAI, LM Studio** — 作为直接零成本,完全离线**。您的记忆永远不会离开您的机器。
使用 Ollama 的示例:
```sh
ollama pull nomic-embed-text
```
```jsonc
// env 块在您的 MCP 客户端配置中
{
"OPENAI_API_KEY": "ollama", // 任意非空占位符;本地环境中忽略
"OPENAI_EMBED_MODEL": "nomic-embed-text",
"SYNAPSE_EMBED_ENDPOINT": "http://localhost:1141/embeddings",
"SYNAPSEIMS": "768", // nembed-text 返回 768 维向量
"ENGRAM_DB_PATH": "/Users/you/.engengram.db"
}
```
就是这样 — 无需代码更改。混合 FTS5 + 向量F 融自我修复都。
> **切换** 向量是(不同模型生成不同的维度)。突触安全忽略维度不向量**,因此溃 — 但为了切换,删除 `.db` 并运行_backfill` 一次,以使用新模型重新嵌入所有内容。自我修复搜索也会在运行时重新嵌入触及的记忆,因此索引会自动收敛。
## MCP 工具
| 工具 | 描述 |
|---|---|
| `syn` | 两个存活性和性 |
| `_stats` |:实时观察、向量、孤儿、维度、| `synfill` | 幂等批量嵌入化的观察 ⚠️ OpenAI API 调用 — 参见成本* `synapse_search`混合词汇 +搜索(RRF修复 |
|apse_sync` |和删除孤儿向量(从 Engram 中观察) |
后使用
一旦,您的代理就会ram 旁边看到synapse_*` 工具。从那时起:
```text
synapse_health (可选)基本检查两个数据库是否可达
2. synapse_backfill → 运行 ONCE 以向量化您已有的记忆
3. synapse_search → 实际使用的工具 — 用自然语言提问,任何语言
```
步骤 2 是可选的:搜索也会按需向量化回填使您的第一个搜索完整代理在需要回忆时调用 `_search`。
###惰、的向量化
您不需要管理索引 — **`_search` 让**。每次运行一个两速
- ** — 搜索刚刚匹配的任何内容(通过 FTS)如果尚未**内联嵌入,在排名前**几秒前保存的记忆已经出现在语义。
- ** — 后台、行的回填嵌入其他漂移的内容,因此达到 100% 为下一次调用做准备。这是一个无操作(成本),如果内容。
> **工作:** 这发生在 **`synapse上。突**独立的,因此它**拦截 Engram mem_search` / `mem_context` —这些。只要语义调用 `syn`,而保持向量新鲜的原因。无需 cron,无需守护进程,无需手动步骤。
## 成本
ram 运行并拥有一个**巨大**的记忆?好消息:语义的乎意料地低。嵌入按 token 计很小即使是一个庞大的只需几**一次性**。
略估计** 观察结果约 个 token(标题— 编写时的价格,请始终查看 [ 定价](https://openai.com/):
| Engram 中的观察结果text-embedding-` ($0.13 / 1M) | `text-embedding-3-small` ($0.02 / 1M) |
|---|---|---|
| 1,000 | ~$0.03 | ~$0.005 |
| 10,000 | ~$0.33 | ~$0.05 |
| 50,000 | ~$1.60 | ~$0.25 |
|,000 | ~$3.25 | ~$0.50 |
保持成本低的关键点:
- **这是一个一次性回填。** 首次运行后,自我修复搜索只嵌入**新**观察结果 — 您的账单跟踪您写入的内容,而不是您拥有的内容。
-免费。每个 `_search` 只嵌入您的查询(~10–20 个 token)— 一美分的一小部分。
- **选择您的权衡。** `text-embedding-3-large` 提供最佳召回率;`text-embedding-3-small` 约 倍,但仍然优秀(设置 `OPENAI_EMBED_MODEL`)。
- **想要免费和本地?** 完全跳过账单 — 将突触指向 [Ollama](https://ollama.com) 或另一个本地模型,嵌入成本 **$0**。参见 [免费和本地嵌入](#免费和本地嵌入-无-openai-账单)。
简而言之:如果您已经信任 Engram 拥有数千个记忆,那么几美元就能将它们全部升级为**按含义搜索**。
## 烟雾测试(手动)
需要一个真实的_API_KEY` 和一个已填充的 `~/.engram/engram.db`。不是自动化套件的一部分
cp .envenv && $EDITOR .env # 填写 OPENAI_API build
echo '{"method":"tools/call","params":{"name":"synapse_backfill"}}' | ./synapse
echo '{"method":"tools/call","params":{"name":"synapse_search","arguments":{"query":"为什么 checkout 很慢"}}}' | ./syn```
## 架构
突触遵循**形架构** — 领域是纯粹的,基础设施插入端口。
```text
cmdapse 组合根(连接所有内容,MCP 标准输入输出)
internal/
domain 纯类型 + RRF 融合 + 内容哈希(零依赖)
port 接口:EngramReader、Embedder、VectorStore
usecase 健康 · 统计 · 回填 · 搜索 · 同步
engram EngramReader 适配器 — 读取 engram.db 只读
store VectorStore 适配器 — 纯 Go SQLite + synapse.db 上的余弦 KNN
embed Embedder 适配器 — OpenAI 兼容(OpenAI批处理、抖动)
mcp MCP 工具处理程序
```
构建和测试是普通的 无 CGO,无标签:
```sh
make build # CGO_ENABLED=0 go build -o synapse ./cmd/synapse
make test # CGO_ENABLED=0 go test ./...
```
## 贡献
欢迎提出问题和 PR。在打开 PR 之前:运行 `make test`(和理想情况下go test -race ./...`)。保持领域不受基础设施导入的影响,并用测试覆盖新行为。
## 致 **[Engram](https://github.com/Gentleman-Programming/engram)** 由 Gentleman-Programming — 突触依附的记忆。
- **[modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite)** — 使零 CGO 构建成为可能。
- **[模型上下文协议](modelcontextprotocol.io)** — 使所有这些变得可组合的协议。
## 许可证
[MIT](LICENSE) ©s