内容
# ariadne
一款**原生、本机优先、多语言内存服务器**,适用于 [Claude Code](https://claude.com/claude-code)(以及任何 MCP 客户端)。使用 Go + [Qdrant](https://qdrant.tech) + [bge-m3](https://huggingface.co/BAAI/bge-m3) — 无需 Docker,无需云端,无需 API 密钥。
作为嵌入式向量数据库内存后端的一种替代方案,这些后端在多个并发 Claude 会话下可能会崩溃或资源耗尽。ariadne 是一个**服务器**:一个 Qdrant 处理并发写入,因此整个单写入器 / 锁饥饿类根本不存在。
## 为什么
- **稳定** — Qdrant 服务器,而不是嵌入式 HNSW 在压缩时会出现 SIGSEGV。
- **多语言** — bge-m3 支持 100+ 种语言;跨语言召回有效(英语查询可以找到乌克兰语笔记,在 uk/ru/en/es/de/it/pl/ro/hu/lt/lv/et/fi/fr/ar 之间的余弦相似度约为 0.8-0.94)。
- **混合搜索** — 密集(bge-m3)+ BM25 稀疏(纯 Go 分词器;Qdrant 在服务器端计算 IDF)与 RRF 融合。精确术语/代码/名称排名明显。
- **原生** — Qdrant 二进制文件 + Ollama(Metal),所有内容都在笔记本电脑上运行。
## 组件
| 路径 | 描述 |
|---|---|
| `cmd/ariadne` | MCP 服务器(stdio)。工具:`memory_save`、`memory_recall`、`memory_delete`、`memory_move`。 |
| `cmd/import` | 从 chromadb sqlite、markdown 内存文件或 JSONL(批量嵌入)进行回填。 |
| `cmd/hook` | Claude Code 会话钩子(`ariadne-hook`):会话启动自动召回,会话结束自动捕获。 |
| `cmd/install` | 一次性安装程序(macOS/Linux):预检查,重用或安装 Qdrant,服务,MCP,技能,钩子。 |
| `cmd/ariadnectl` | 控制 + 健康核心(`status -json`,启动/停止,备份/导出)。 |
| `internal/store` | 存储核心:嵌入(Ollama),BM25 稀疏,Qdrant 混合。 |
| `cmd/ariadne-tray` | 跨平台托盘监视器(macOS/Linux/Windows)— 纯 Go,本地化,通过 `ariadnectl` 核心。 |
| `skills/ariadne` | Claude Code 技能:召回/保存学科 + `doctor.sh`/`recall.sh`。 |
| `deploy/` | LaunchAgent / systemd 模板:Qdrant 服务,每日 memfiles-sync,托盘自动启动。 |
| `poc/` | 验证堆栈的独立实验。 |
## 设置
### 一条命令(Linux + macOS)
```bash
curl -fsSL https://raw.githubusercontent.com/mclaut/ariadne/main/install.sh | sh
```
无需手动操作:`install.sh` 引导 Go 和源代码(GitHub tarball — 无需 git),然后运行安装程序,自动安装 Ollama、Qdrant、模型、服务和 — 在 Linux 上 — 托盘及其桌面依赖项。直接传递安装程序标志,例如更轻的摘要模型或预览:
```bash
curl -fsSL https://raw.githubusercontent.com/mclaut/ariadne/main/install.sh | sh -s -- -summary-model qwen2.5:3b
curl -fsSL https://raw.githubusercontent.com/mclaut/ariadne/main/install.sh | sh -s -- -dry-run
```
(sudo — 用于 apt 包和 Linux 上的 Ollama — 在终端上提示,因此管道正常。Windows:PowerShell 路径在路线图中。)
### 从克隆(或进行修改)
```bash
go run ./cmd/install -dry-run # 预检查 + 计划,不会更改任何内容
go run ./cmd/install -yes # 执行
```
安装程序谨慎处理现有的基础设施:
- **已经运行的 Qdrant 被重用,从不重启或重新配置** — Ariadne 只添加自己的集合。如果端口繁忙且 **不是** Qdrant,则安装程序会中止。使用 `-qdrant-host/-qdrant-rest/-qdrant-grpc` 指向远程实例(例如 GPU 工作站),使用 `-ollama` 指向远程嵌入器。
- **GPU / RAM / 磁盘在前端进行检查**,并明确说明不足之处(无 GPU → 诚实的“嵌入在 CPU 上,速度慢 10 倍”警告;<6GiB RAM 或 <5GiB 磁盘 → 硬性失败)。
- 幂等:重新运行会跳过已经到位的所有内容。
它安装 Qdrant 二进制文件 + 服务(macOS LaunchAgent / Linux systemd 用户单元,仅限环回),将 Go 二进制文件编译到 `~/.ariadne/bin`,拉取 `bge-m3`,创建集合,在 `~/.claude.json` 中注册 MCP 服务器(保留备份)并安装 Claude Code 技能。
### 手动设置
**运行时位于 `~/.ariadne`**(二进制文件、数据、备份、日志)— 仓库仅包含源代码。在 macOS 上,这不仅仅是品味问题:launchd 代理**无法**在 `~/Desktop`/`~/Documents` 下执行程序或写入日志(TCC)— 它们会以 `EX_CONFIG` 和空日志退出。将运行时保持在这些文件夹之外。
```bash
mkdir -p ~/.ariadne/{bin,backups,logs}
# 1. Qdrant(原生二进制文件 — 无 Docker)
curl -sL https://github.com/qdrant/qdrant/releases/latest/download/qdrant-aarch64-apple-darwin.tar.gz \
| tar xz -C ~/.ariadne/bin
# 2. Ollama + bge-m3(原生,Metal)
brew install ollama && brew services start ollama
ollama pull bge-m3
# 3. 构建 + 安装
go build -o ~/.ariadne/bin/ariadne ./cmd/ariadne
go build -o ~/.ariadne/bin/ariadnectl ./cmd/ariadnectl
go build -o ~/.ariadne/bin/import ./cmd/import
# 4. Qdrant 作为服务(参见上文的 TCC 注释)
sed "s|__HOME__|$HOME|g" deploy/com.ariadne.qdrant.plist > ~/Library/LaunchAgents/com.ariadne.qdrant.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.ariadne.qdrant.plist
# 5. 注册到 Claude Code — 添加到 ~/.claude.json mcpServers:
# "ariadne": { "type": "stdio", "command": "<home>/.ariadne/bin/ariadne" }
```
**安全:** Qdrant 默认情况下没有身份验证 — 模板将其固定到 `127.0.0.1`(`QDRANT__SERVICE__HOST`)。永远不要在 LAN 上公开它:您的记忆以明文有效载荷存储。
通过 env 进行配置(默认值在括号中):`ARIADNE_QDRANT_HOST` [localhost],`ARIADNE_QDRANT_PORT` [6334],`ARIADNE_OLLAMA` [http://localhost:11434],`ARIADNE_MODEL` [bge-m3],`ARIADNE_COLLECTION` [ariadne]。
## Claude Code 技能
`skills/ariadne/` 教导 Claude Code 何时召回,保存什么(不保存什么),以及如何操作堆栈;`tools/doctor.sh` 检查整个链条(二进制文件 → 服务 → 模型 → 集合 → 绑定 → MCP 注册),而 `tools/recall.sh "query"` 在不使用 MCP 的情况下进行 CLI 召回。安装(真正的副本 — 符号链接的技能在会话启动时不会被发现):
```bash
cp -R skills/ariadne ~/.claude/skills/ariadne
```
## 会话钩子 — 自动召回和自动捕获
安装程序注册了两个 Claude Code 生命周期钩子(`cmd/hook`,二进制文件 `ariadne-hook`;跳过 `-skip-hooks`):
- **会话启动 → 自动召回。** 当项目中存在记忆(wing = 目录名称)时,会话启动时,顶部命中作为上下文注入 — Claude 在您的第一个消息之前“记住”项目。没有记忆的项目完全干净启动;失败是沉默的,永远不会阻塞会话。
- **会话结束 → 自动捕获。** detached 工作器(会话退出永远不会被阻塞)解析转录本,提取确定性事实(分支,提交,持续时间),并要求**本地 Ollama 聊天模型**编写 4-8 个句子的摘要 — 带有原因,修复,开放项的决策。每个会话一个精选的日记记忆;永远不会存储原始转录本。琐碎的会话被跳过(最小回合保护 + 总结器可以回答 `SKIP`)。日志:`~/.ariadne/logs/capture.log`。
通过 env 进行配置:`ARIADNE_CAPTURE=0` 禁用捕获,`ARIADNE_SUMMARY_MODEL` [qwen2.5:7b],`ARIADNE_CAPTURE_MIN_TURNS` [3]。摘要模型仅在捕获时加载,捕获后立即卸载,因此它只占用 RAM 很短的时间;对于较小的占用空间,设置 `ARIADNE_SUMMARY_MODEL=qwen2.5:3b`(~2GB vs ~4.7GB,在某种摘要质量下)— 或将 `-summary-model` 传递给安装程序,以便它拉取该模型。
## 监视器
托盘/菜单栏监视器每 5 秒轮询 `ariadnectl status -json`,并显示绿色/橙色/红色/灰色图标,按服务显示详细信息,并启动/停止/重启/备份操作;当服务出现问题时,它会通知。`ariadne-tray` 界面是本地化的 — **7 种语言**(英语,Українська,Deutsch,Italiano,Español,Français,Polski)带有实时 **🌐 语言**切换器,显示活动语言。选择在 `~/.ariadne/lang` 中持续存在,`ariadnectl` 遵循它,因此整个界面保持在一种语言中。在 `internal/i18n` 中添加一种语言是一个块。
- **`ariadne-tray`** (纯 Go,`fyne.io/systray`)是所有平台的监视器:安装程序将其构建到 `~/.ariadne/bin` 并注册自动启动 — Linux 上的 `~/.config/autostart` 条目,macOS 上的 `com.ariadne.tray` LaunchAgent(迁移自任何旧 Swift 监视器,因此您获得一个图标)。在 Linux 上,它需要一个 StatusNotifierItem 主机(KDE/XFCE 原生;GNOME 上安装“AppIndicator 和 KStatusNotifierItem”扩展)。跨编译为 Windows。
## 备份和可移植性
两个不同的概念:
- **备份/还原** — 快速,完整,原生 Qdrant 快照(包括向量;一对一还原,与嵌入模型绑定)。用于损坏后恢复。
```bash
ariadnectl backup # 快照 → ./backups/,轮换(保留 10 个)
ariadnectl restore <file> # 从快照中恢复集合(破坏性)
```
- **导出/导入** — 一个便携的 JSONL,包含 `{text, wing, room}`(无向量,因此在不同机器之间移动并使用任何模型重新嵌入)。用于迁移/检查。
```bash
ariadnectl export [file] # 所有记忆 → JSONL
import -source jsonl -file export.jsonl # 重新嵌入 + 插入导出
```
`import` 还可以从存档的 chromadb sqlite(`-source chroma -db <file>`)或 markdown 内存文件(`-source memfiles`)进行回填。所有导入都是幂等的(基于内容哈希的 ID)。对于 memfiles,`-sync` 使集合与磁盘保持一致:编辑的文件替换其旧块,已删除文件的文件块被清除。安装程序注册了一个每日代理(`com.ariadne.sync` / `ariadne-sync.timer`),为您运行此操作;手动运行大型笔记编辑后。
## 状态
v1 — 工作中。混合多语言召回,会话钩子(自动召回 + 精炼自动捕获)和时间有序日记都已上线;日常使用中有数千个记忆。批量导入为大量回填提供了加速。学习稀疏升级(bge-m3 SPLADE 在 CUDA 盒上)是可选的,如果 BM25 对于形态丰富的语言来说太弱。
## 许可证
MIT