内容
# Unhollow
你的编码代理每次会话都从空白内存开始。 Unhollow 它。
Unhollow 是一个微小的本地 MCP 服务器,提供对三层项目知识的语义搜索:
1. **记忆**:会话学习事实,您的代理在工作时记录下来(艰难的修复、决策理由、用户反馈、微妙的错误原因)
2. **AI 优化的 Wiki**:密集的、检索形状的文档,涵盖每个子系统,由代理本身生成
3. **实时文档**:您的架构计划、设计文档、CLAUDE.md 以及您维护的任何长篇 Markdown 文档
代理通过含义查询所有内容,而不是文件名:`memory_search("为什么在麦克风路径上禁用 AGC")` 返回正确的部分,即使没有文件在名称中提及 "AGC"。所有内容都在本地运行:一个 45 MB 的 ONNX 嵌入模型在 CPU 上运行,一个 SQLite 数据库。零 API 调用,零成本,任何内容都不离开您的机器。
该名称是继承而来的:该系统是从 [Hollow](https://github.com/VitalikPro13/HOLLOW) 中提取的,这是一个分布式 E2EE 聊天应用程序,它在数月的代理驱动开发中逐渐发展而来。给代理的记忆取一个名字是当之无愧的。
## 为什么
编码代理每次会话都健忘。项目指令文件(CLAUDE.md、AGENTS.md)有所帮助,但它们有严格的大小预算:它们被加载到每个提示中,因此只能容纳始终相关的规则。其他所有内容,深入的子系统知识,“我们尝试过但失败了”的历史,违反时默默破坏的耦合,要么在每次会话中花费大量时间重新发现,要么丢失。
Unhollow 按知识的回忆方式进行分割:
| 层级 | 存储位置 | 回忆方式 |
|---|---|---|
| 始终相关的规则 | CLAUDE.md / 代理指令 | 每个提示(预算内) |
| 子系统参考 | Wiki | 按需,通过含义 |
| 会话学习 | 记忆文件 | 按需,通过含义 |
| 设计意图 | 现有文档 | 按需,通过含义 |
此设置已在 Hollow(Flutter + Rust,桌面/移动端,约 50 个 Wiki 文件,数百个记忆)上经过实战测试。它是一个代理每天早上重新推导架构和一个说“这在 `couplings_gotchas.md` 中已经涵盖了,并且有一个记忆说我们已经尝试过”的代理之间的区别。
## 工作原理
```
记忆/*.md ─┐
Wiki/*.md ─────┼─> 分块器 ─> 本地 ONNX 嵌入 ─> sqlite-vec
文档(计划, ┘ (按 ## 分割) (全 MiniLM-L6-v2, (向量搜索,
CLAUDE.md...) ## 标题) 384 维,CPU) 增量更新)
```
- **分块**:Wiki 文件和文档在 `## `标题处分割;每个部分是一个检索单位。记忆文件每个文件都是一个块,并在其前面加上文件名和描述以提高嵌入质量。
- **增量重新索引**:块经过内容哈希;`memory_reindex()` 只重新嵌入更改的内容,因此它在几秒钟内运行。
- **三个 MCP 工具**:`memory_search(query, limit)`、`memory_reindex(force)`、`memory_stats()`。
## 快速入门
1. **将此仓库复制到您的项目中**(例如 `tools/unhollow/`)或单独克隆它。
2. **安装依赖项**(Python 3.10+):
```bash
pip install -r requirements.txt
```
3. **配置**:复制 `unhollow.config.example.json` 到 `unhollow.config.json` 并设置您的路径。相对路径相对于配置文件。所有键都是可选的;不存在的源将被跳过。
```json
{
"memory_dirs": ["~/.claude/projects/YOUR-PROJECT-SLUG/memory"],
"wiki_dir": "wiki",
"docs": ["../../CLAUDE.md", "../../docs/ARCHITECTURE.md"]
}
```
4. **在您的项目的 `.mcp.json`(Claude Code)或代理的 MCP 配置中注册 MCP 服务器**:
```json
{
"mcpServers": {
"unhollow": {
"command": "python",
"args": ["-u", "tools/unhollow/server.py"],
"env": { "PYTHONUNBUFFERED": "1" }
}
}
}
```
在第一次运行时,服务器将下载嵌入模型(~45 MB,一次)到 `models/`。
5. **生成 Wiki**:将 `prompts/generate-wiki.md` 粘贴到您的代理在仓库根目录下。这是最具影响力的步骤;提示编码了我们关于制作便于检索的文档的所有经验。
6. **构建索引**:要求您的代理运行 `memory_reindex()`。
7. **让代理实际使用它**(不要跳过此步骤):将 `prompts/agent-instructions-snippet.md` 中的代码块粘贴到您的 AI 始终读取的内容中 — CLAUDE.md、AGENTS.md、Cursor 规则、自定义系统提示。它教会代理在设计、争论或重新调查之前进行搜索,并在编写后重新索引。如果没有它,服务器将闲置。
## 仓库内容
```
server.py, chunker.py, embedder.py, store.py, config.py # MCP 服务器(约 400 行)
unhollow.config.example.json # 配置模板
wiki/ # 您生成的 Wiki 将位于此处
prompts/generate-wiki.md # Wiki 生成提示(从此处开始)
prompts/agent-instructions-snippet.md # 粘贴到 CLAUDE.md 中的代码块,使代理使用该工具
prompts/memory-conventions.md # 记忆文件格式 + 索引规则
skills/compush/SKILL.md # 会话总结技能(见下文)
```
## 使其保持活跃的工作流程
过时的文档比没有文档更糟糕。包含的 **compush** 技能(`skills/compush/`)是 Claude Code 的会话结束例行程序:将它复制到 `~/.claude/skills/compush/` 或 `.claude/skills/compush/` 并在结束时说 `/compush`。它引导代理完成:
1. 保存/更新 **记忆**(先搜索,更新而不是重复)
2. 更新 **Wiki** 文件,会话更改触及的部分
3. 仅当持久规则更改时,触及 **代理指令**(强制执行严格预算)
4. 将 **实时文档** 与会话触及的内容进行协调,仅此而已
5. **提交和推送**(按名称暂存的文件)
6. **重新索引**
每个步骤都限定在当前会话中,因此它保持快速并且永远不会变成审计。
## 常见问题
**是否需要 GPU 或 API 密钥?** 不需要。嵌入在 CPU 上通过 onnxruntime 运行;对约 2 MB 的语料库进行完整重新索引需要不到一分钟,增量重新索引需要几秒钟。
**我的代码是否被发送到任何地方?** 不会。唯一的网络访问是一次从 HuggingFace 下载模型。搜索和索引是完全本地的。
**我可以使用不同的嵌入模型吗?** 是的:在配置文件中设置 `hf_model_id`、`embedding_dim` 和 `max_tokens`。默认的(all-MiniLM-L6-v2)对于块大小的文本具有良好的速度/质量权衡。
**如果我不使用 Claude Code 怎么办?** 服务器是标准 MCP,适用于 stdio;任何支持 MCP 的代理都可以使用它。记忆目录格式只是带有前置元数据的 Markdown,可用于任何可以写入文件的代理。
**为什么不直接使用 grep?** grep 查找单词;这个查找含义。“为什么消息会乱序” 检索 Lamport-clock 部分,即使它与之没有任何共同的单词。两者皆可使用。
## 许可证
MIT