内容
# Mneme - Go 版
[中文文档](README-chs.md)
高性能的语义代码搜索,适用于 Claude Code,由 Go 提供支持,并具有可插拔的向量存储后端。
## 功能特点
- **语义搜索** - 使用自然语言查询找到相关的代码
- **多种后端** - DuckDB(嵌入式)、chromem-go(纯 Go 版)或 Qdrant(高扩展性)
- **多种嵌入模型** - SiliconFlow 和 Qwen
- **单二进制文件** - 对于 DuckDB 和 chromem 后端,无需基础设施
- **MCP 集成** - 通过 stdio JSON-RPC 直接与 Claude Code 集成
- **钩子系统** - 轻量级钩子跟踪编辑、会话和上下文使用
- **解剖图** - 增量文件扫描器为 Claude 构建项目摘要
- **会话记忆** - 自动总结过去的会话以节省上下文令牌
- **大脑** - 项目级编码规则,作为 Claude 警告显示
- **错误日志** - 按项目划分的错误历史,与传入的编辑相匹配
## 快速开始
### 前置条件
- Go 1.21+
- SiliconFlow 或 Qwen API 密钥
### 构建
```bash
go build -o ./bin/mneme ./cmd
```
### 初始化一个项目
在任何 Git 仓库中运行:
```bash
cd /path/to/your/project
mneme init --yes
```
这会在 Claude Code 的 `settings.json` 中安装五个钩子,扫描所有源文件到解剖图(`.mneme/anatomy.md`),并将项目上下文规则写入 `~/.claude/CLAUDE.md`。
### 注册到 Claude Code(MCP 服务器)
```bash
claude mcp add mneme \
-e EMBEDDING_API_KEY=$EMBEDDING_API_KEY \
-e EMBEDDING_PROVIDER=$EMBEDDING_PROVIDER \
-- /path/to/bin/mneme
```
注册后,Claude Code 可以索引代码库并进行语义搜索,无需进一步配置。
## 功能教程
### 解剖扫描
解剖图是每个源文件的 Markdown 索引:其语言、估计的令牌数和从内容生成的单行描述。Claude 在打开文件之前会读取此信息,因此它可以决定是否读取文件。
**首次扫描(在 `init` 时自动进行):**
```bash
mneme scan
# ✓ Scanned 142 files → .mneme/anatomy.md
```
**增量扫描(快速,默认):**
在后续运行中,只重新提取自上次扫描以来修改的文件。未更改的文件从缓存的解剖图中读取。典型的干净仓库在不到 2 秒内完成。
```bash
mneme scan
# ✓ Scanned 3 files → .mneme/anatomy.md
```
**强制完整扫描:**
```bash
mneme scan --force
# ✓ Scanned 142 files → .mneme/anatomy.md
```
在进行大型重构或文件重命名后运行 `scan` 以保持地图的准确性。
---
### 会话记忆
每次 Claude Code 会话结束时,钩子会将结构化的摘要行写入 `~/.claude/mneme-memory.md`。此文件被注入到未来的会话中,为 Claude 提供一个紧凑的历史记录,记录您一直在处理的内容 - 而无需重新读取代码。
一行记录如下:
```
## 2026-04-20T09:15:00Z (12 turns)
Files: cmd/cmd_scan.go (feature×2), pkg/scanner/extractor.go (refactor×1)
Patterns: feature×2, refactor×1
Summary: Added 2 feature(s). Refactored 1 area(s).
```
**查看最近的会话:**
```bash
mneme stats
```
输出显示 `=== Recent Sessions ===` 下的最后五行会话记录。
**手动合并:
当记忆文件增长到 50 行以上(大约两个月的每日使用)时,会话启动钩子会自动合并它。您也可以手动触发此操作:
```bash
mneme memory consolidate
# consolidated 37 session row(s)
```
旧会话(>7 天)被折叠成一个区块,以保留近期记录而不会膨胀上下文:
```
> Consolidated session (284 actions from 37 sessions before 2026-04-13)
```
---
### 统计信息
查看当前项目的钩子活动、编辑模式和记忆行:
```bash
mneme stats
```
示例输出:
```
project: abc123-myrepo
=== Hook Totals ===
pre-read: 14
pre-write: 8
session-start: 3
stop: 3
hook_errors: 0
=== Edit Patterns ===
feature: 5
refactor: 3
bugfix: 1
=== Recent Sessions (last 5) ===
2026-04-20T09:15:00Z 12 turns feature×2, refactor×1
2026-04-19T14:03:22Z 7 turns bugfix×1
```
**浪费诊断** - 检测浪费上下文的模式(重复读取、大文件不变):
```bash
mneme stats --waste
```
**JSON 输出**适用于脚本或仪表板:
```bash
mneme stats --json
```
---
### 大脑(编码规则)
大脑允许您为项目附加基于正则表达式的警告规则。当 Claude 即将写入匹配规则模式的文件时,写入前钩子会将警告消息注入钩子响应中 - 在编辑前提醒 Claude 项目约定。
**添加规则:**
```bash
mneme cerebrum add \
--pattern "pkg/state/" \
--message "All state mutations must go through AtomicWrite; never write files directly." \
--comment "State package write guard"
```
**列出规则:**
```bash
mneme cerebrum list
# 1 pkg/state/ → All state mutations must go through AtomicWrite; never write files directly.
# (State package write guard)
```
**删除规则:**
```bash
mneme cerebrum remove 1 --yes
```
规则存储在项目内的 `.mneme/cerebrum.json` 中。
---
### 错误日志
错误日志是每个项目的错误日志,您遇到的错误记录在此。当 Claude 即将编写代码时,写入前钩子会检查更改的行是否与已知的错误模式匹配,如果匹配,则会在钩子输出中追加提醒。
**手动记录错误:**
```bash
mneme buglog add \
--description "Forgot to hold the lock before writing memory.md" \
--code "state.AtomicWrite(memPath, data)" \
--file "pkg/state/memory.go"
```
**列出记录的错误:**
```bash
mneme buglog list
# 1 2026-04-18 pkg/state/memory.go
# Forgot to hold the lock before writing memory.md
```
**从写入后钩子自动记录:
在 Claude 将提交分类为 bugfix 后,写入后钩子会自动更新错误日志条目。这样,无需手动输入即可被动构建错误历史。
**清除日志:**
```bash
mneme buglog clear --yes
```
---
### MCP 工具(高级)
当作为 MCP 服务器运行时,mneme 除了索引/搜索外,还会暴露三个额外的工具。
| 工具 | 描述 |
|---|---|
| `describe_codebase` | 返回结构化文本的完整解剖图 |
| `get_project_rules` | 返回当前项目的活跃大脑规则 |
| `find_similar_bugs` | 在错误日志中搜索与代码片段匹配的条目 |
这些工具在二进制文件通过 `claude mcp add` 注册后自动可用。
---
## 配置
所有配置均通过环境变量或 `~/.mneme/config.yaml` 配置文件进行。
**优先级:环境变量 > 配置文件 > 默认值**
示例 `~/.mneme/config.yaml`:
```yaml
embedding_api_key: sk-xxx
embedding_provider: qwen
embedding_model: text-embedding-v4
db_backend: chromem
chromem_path: ~/.mneme/chromem
```
| 变量 | 默认值 | 描述 |
|---|---|---|
| `EMBEDDING_API_KEY` | (必填) | SiliconFlow 或 Qwen API 密钥 |
| `EMBEDDING_PROVIDER` | `siliconflow` | `siliconflow` 或 `qwen` |
| `EMBEDDING_MODEL` | `BAAI/bge-large-zh-v1.5` | 嵌入模型 ID |
| `DB_BACKEND` | `duckdb` | 向量存储后端:`duckdb`、`qdrant`、`chromem` |
| `DB_PATH` | `~/.mneme/db.duckdb` | DuckDB 文件路径(仅限 duckdb 后端) |
| `QDRANT_URL` | `http://localhost:6333` | Qdrant 服务 URL(HTTP 端口;gRPC 6334 自动使用) |
| `QDRANT_COLLECTION` | `mneme` | Qdrant 集合名称 |
| `CHROMEM_PATH` | `~/.mneme/chromem` | chromem-go 持久化目录 |
| `LOG_LEVEL` | `info` | `info` 或 `debug` |
## 后端
### DuckDB(默认)
零配置嵌入式数据库。适用于具有中等代码库的单机使用。
```bash
export DB_BACKEND=duckdb
export DB_PATH="$HOME/.mneme/db.duckdb"
```
### chromem-go
纯 Go 嵌入式向量存储。无需外部进程。自动持久化到磁盘。
```bash
export DB_BACKEND=chromem
export CHROMEM_PATH="$HOME/.mneme/chromem"
```
### Qdrant
外部 Qdrant 服务,支持 gRPC。适用于大型代码库或共享/多进程部署。集合在首次插入时自动创建。
```bash
# 启动 Qdrant(Docker)
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
# 配置
export DB_BACKEND=qdrant
export QDRANT_URL="http://localhost:6333"
export QDRANT_COLLECTION="mneme"
```
HTTP 端口(6333)被内部自动转换为 gRPC 端口(6334)。
## MCP 资源
| 资源 | 描述 |
|---|---|
| `codebase://index` | 索引代码库。POST 请求包含 `{"codebase_path": "/path/to/repo"}` |
| `codebase://search` | 语义搜索。POST 请求包含 `{"query": "...", "top_k": 10}` |
## 架构
```
MCP stdio 请求
→ cmd/main.go (子命令调度)
→ cmd/mcp_server.go (JSON-RPC via stdin/stdout)
→ pkg/context/ (indexer.go: split + embed + store;
searcher.go: embed query + retrieve)
→ pkg/embedding/ (CachedClient wraps SiliconFlow/Qwen with MD5 cache)
→ pkg/vectordb/ (factory.go selects DuckDB / Qdrant / chromem)
→ pkg/splitter/ (function-boundary splitting for Go/Py/JS; 50-line chunks otherwise)
钩子流水线(Claude Code 事件 → cmd/hook_*.go):
session-start → write memory row, lazy consolidate, upsert session
pre-read → anatomy lookup, emit description for Claude
pre-write → cerebrum rule match, buglog match, emit warnings
post-write → classify edit, upsert to ledger and buglog
stop → increment stop counter
状态文件(每个项目,位于 .mneme/ 内):
anatomy.md → file map regenerated by `scan`
ledger.json → cumulative hook counters
session.json → current session edits
cerebrum.json → coding rules
buglog.json → bug history
全局状态(~/.claude/):
mneme-memory.md → session history, consolidated on demand
```
所有跨包契约均在 `pkg/types.go` 中定义为接口(`Store`、`EmbeddingProvider`、`Indexer`、`Searcher`、`Splitter`)。
包布局:
- `cmd/` - 二进制入口点 + 所有子命令和钩子
- `pkg/` - 核心接口和类型
- `pkg/config/` - 基于环境的配置
- `pkg/context/` - 索引和搜索编排
- `pkg/embedding/` - SiliconFlow 和 Qwen 提供商,带缓存
- `pkg/vectordb/` - DuckDB、Qdrant 和 chromem 后端;工厂选择器
- `pkg/splitter/` - 语言感知代码分块
- `pkg/mcp/` - MCP 协议服务器
- `pkg/state/` - 账本、会话、解剖、内存和锁定原语
- `pkg/scanner/` - 文件遍历器和解剖提取器(增量)
- `pkg/consolidator/` - 内存行合并
- `pkg/hook/` - 钩子事件解析助手
- `pkg/waste/` - 上下文浪费模式检测
## 开发
```bash
# 构建
go build -o ./bin/mneme ./cmd
# 运行所有测试
go test -v ./...
# 运行单个测试
go test -v ./tests -run TestScanIncrementalSucceeds
# 运行 Qdrant 集成测试(需要运行的 Qdrant 实例)
QDRANT_URL=http://localhost:6333 go test -v -tags qdrant_integration ./tests
# 调试日志
LOG_LEVEL=debug ./bin/mneme
# 从项目中卸载钩子
mneme init --uninstall --yes
```
## 许可证
MIT