# https://github.com/arttttt/mnemo 项目说明书

生成时间：2026-06-22 02:03:02 UTC

## 目录

- [Overview & System Architecture](#page-overview)
- [Recall Pipeline & LLM Integration](#page-recall)
- [Data Model, Storage & Memory Operations](#page-data)
- [Configuration, Client Setup & Deployment](#page-deploy)

<a id='page-overview'></a>

## Overview & System Architecture

### 相关页面

相关主题：[Recall Pipeline & LLM Integration](#page-recall), [Data Model, Storage & Memory Operations](#page-data), [Configuration, Client Setup & Deployment](#page-deploy)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mnemo/adapters/cli/app.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/cli/app.py)
- [src/mnemo/adapters/mcp/server.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/mcp/server.py)
- [src/mnemo/infrastructure/composition.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/composition.py)
- [src/mnemo/application/use_cases/recall_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/recall_project.py)
- [src/mnemo/application/recall/bundle.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/bundle.py)
- [src/mnemo/application/recall/assemble_stage.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/assemble_stage.py)
- [src/mnemo/application/retrieval.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/retrieval.py)
- [src/mnemo/domain/memory.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/domain/memory.py)
- [src/mnemo/adapters/embedding/hash_embedder.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/embedding/hash_embedder.py)
- [src/mnemo/application/use_cases/update_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/update_project.py)
- [src/llmkit/types.py](https://github.com/arttttt/mnemo/blob/main/src/llmkit/types.py)
- [src/llmkit/config.py](https://github.com/arttttt/mnemo/blob/main/src/llmkit/config.py)
- [src/llmkit/ports/nli.py](https://github.com/arttttt/mnemo/blob/main/src/llmkit/ports/nli.py)
- [src/mnemo/application/use_cases/interfaces/create_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/interfaces/create_project.py)
- [src/mnemo/application/use_cases/interfaces/update_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/interfaces/update_project.py)
- [src/mnemo/application/use_cases/interfaces/delete_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/interfaces/delete_project.py)
- [src/mnemo/application/use_cases/interfaces/list_projects.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/interfaces/list_projects.py)
- [src/mnemo/application/use_cases/interfaces/browse_memory.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/interfaces/browse_memory.py)
</details>

# Overview & System Architecture

## 系统定位与核心能力

mnemo 是一个面向 AI 编码代理的**本地记忆系统**。它把"问题、解决方案、推理过程"这类长寿命知识以**带类型的 Memory** 形式持久化到本地，并通过 MCP 协议与 CLI 两条入口暴露给宿主代理。从 0.3.0 版本起，记忆不仅可以被检索（`search` / `browse`），还能回答问题——`recall` 工具会基于项目记忆合成一个**有据可查的回答**，并在没有相关记忆时返回 `No relevant memories found.`，绝不依赖模型的世界知识 资料来源：[src/mnemo/application/use_cases/recall_project.py:1-15]()。

CLI 的自描述把这种定位浓缩成一句话："mnemo - local memory for AI coding agents. Store and search typed memories locally." 资料来源：[src/mnemo/adapters/cli/app.py:1-15]()。MCP 端的 `remember` 工具也明确写着 "No LLM runs on write"——写入是纯结构化的，没有模型开销 资料来源：[src/mnemo/adapters/mcp/server.py:1-30]()。

## 架构分层与依赖注入

系统采用经典的**端口—适配器 + 用例（hexagonal）分层**，所有用例在容器启动时一次性绑定到具体的实现：

```mermaid
flowchart TB
  subgraph Entry["接入层 (Adapters)"]
    CLI["CLI (Typer)<br/>store / recall / ..."]
    MCP["MCP Server<br/>remember / search / browse"]
  end
  subgraph App["应用层 (Use Cases)"]
    Remember["RememberMemory"]
    Search["SearchMemory"]
    Browse["BrowseMemory"]
    Recall["RecallProject"]
    Proj["Create/Update/List/Delete Project"]
    Del["DeleteMemory"]
  end
  subgraph Domain["领域层"]
    Memory["Memory entity"]
    Scope["Scope / MemoryType"]
  end
  subgraph Infra["基础设施 (llmkit + repos)"]
    Embedder["TextEmbedder (hash | pplx)"]
    Reranker["Reranker (opt)"]
    Generator["Generator (opt)"]
    Repo["MemoryRepository / ProjectRepository"]
  end
  CLI --> App
  MCP --> App
  App --> Domain
  App --> Infra
```

`build_container()` 把所有用例串成一个对象图：`remember`、`search`、`browse`、`recall`、`delete` 以及项目相关的若干用例统一装配；其中 `recall` 用例会拿到可选的 `reranker` 与 `generator`，由配置决定是否注入 资料来源：[src/mnemo/infrastructure/composition.py:1-25]()。这种"全用例聚合到一个容器对象"的设计，让 CLI 和 MCP 只需调用一次 `build_container()` 就能拿到完整服务集，避免重复装配。

## 核心数据模型与 Recall 管道

`Memory` 是顶层实体，包含 `content`、`type`、`scope`、`project`、`related_files`、`tags`、`topic_key`、`session_id`、`status`、`supersedes`、`hash`、`created_at`、`updated_at` 等字段，并通过 `Memory.create()` 工厂方法强制校验——空内容会被拒绝，`scope=GLOBAL` 时 `project` 自动归一为 `GLOBAL_PROJECT` 资料来源：[src/mnemo/domain/memory.py:1-30]()。

`recall` 是 0.3.0 的核心能力，背后是一条**多阶段管道**：

1. **检索**：用 `TextEmbedder` 把 query 编码成向量后取回相关记忆；
2. **重排**：可选的 `Reranker` 重新排序前 `top_k`；
3. **组装**：`AssembleStage` 把记忆按 `type.value` 分组，形成 `RecallSection`；
4. **生成**：可选的 `Generator`（如 Gemma 4 E2B-it 官方 QAT GGUF）综合成回答文本。

`RecallBundle` 始终承载**结构化分组**，`summary` 仅在生成阶段运行后才被填充——这意味着即使关闭生成器，bundle 仍然自带结构信息 资料来源：[src/mnemo/application/recall/bundle.py:1-20]()。`AssembleStage` 是纯函数，不依赖模型，因此可以作为未来 LLM 合成阶段的稳定接缝 资料来源：[src/mnemo/application/recall/assemble_stage.py:1-20]()。

## 双入口与混合检索语义

CLI 与 MCP 共享同一份容器，但呈现形式不同：CLI 默认把 `recall` 结果以 JSON 打印，并把模型耗时/内存写到日志（受 `MNEMO_LOG_LEVEL` 控制）；MCP 则把 `recall` / `search` / `browse` 暴露为工具，给 AI 代理调用 资料来源：[src/mnemo/adapters/cli/app.py:25-60]() 资料来源：[src/mnemo/adapters/mcp/server.py:1-50]()。

检索层有一条被显式保护的**不变量**：`Retrieval` 对象要求 `text` 与 `vector` **要么同时存在、要么都不存在**——单独存在任何一半都会被构造函数拒绝，因为这意味着 store 将只用一半信号排序，几乎总是调用方构造请求时的 bug（例如忘了把 query 编码成向量）。这条规则将错误**前移到用例边界**，避免在存储层深处崩溃 资料来源：[src/mnemo/application/retrieval.py:1-30]()。

## 可选模型与依赖边界

模型相关能力被刻意隔离在 `llmkit` 子包内，仅暴露 `Generator`、`Reranker`、`Nli` 等 `Protocol` 端口以及 `Vector` / `NliScores` 等共享类型 资料来源：[src/llmkit/ports/nli.py:1-10]() 资料来源：[src/llmkit/types.py:1-15]()。`ModelConfig` 用 `OnnxSource` / `GgufSource` 描述模型来源，用 `Residency`（默认 `Transient`）描述加载策略，且这些选项由消费者在代码里选定，不通过环境变量读取 资料来源：[src/llmkit/config.py:1-15]()。

默认嵌入器走 `hash` 路径——确定性、无外部依赖、纯词袋——用于离线/测试骨架；生产路径是 `pplx-embed-v1-0.6b` 的 int8 ONNX 模型，由 llmkit 的 ONNX 编码器托管 资料来源：[src/mnemo/adapters/embedding/hash_embedder.py:1-25]() 资料来源：[src/mnemo/infrastructure/composition.py:10-25]()。如果用户没装 `mnemo[recall]` 额外依赖，reranker/generator 适配器会抛出**可操作的 RuntimeError**，CLI 将其打印为一行错误而非 traceback 资料来源：[src/mnemo/adapters/cli/app.py:40-55]()。

## 项目管理作为一等公民

除了记忆实体本身，`mnemo` 还把 **Project** 提升为一等公民：项目有独立的用例 `CreateProjectUseCase`、`UpdateProjectUseCase`、`DeleteProjectUseCase`、`ListProjectsUseCase`，以及一个无 query 的 `BrowseMemoryUseCase` 用例 资料来源：[src/mnemo/application/use_cases/interfaces/create_project.py:1-5]() 资料来源：[src/mnemo/application/use_cases/interfaces/update_project.py:1-5]() 资料来源：[src/mnemo/application/use_cases/interfaces/delete_project.py:1-5]() 资料来源：[src/mnemo/application/use_cases/interfaces/list_projects.py:1-5]() 资料来源：[src/mnemo/application/use_cases/interfaces/browse_memory.py:1-15]()。

`UpdateProjectUseCaseImpl` 的文档注释特别指出：描述字段是后续**项目级语义近似匹配（tier-2）**的输入，因此需要与创建解耦、允许独立编辑 资料来源：[src/mnemo/application/use_cases/update_project.py:1-15]()。这种"项目元数据可演化、记忆内容亦可演化（通过 `topic_key` 复用）"的双轨设计，让长期使用下的知识库可以保持整洁而不重复。

## See Also

- Recall 功能详解（recall 管道、bundle 字段、生成器配置）
- CLI 命令参考（store / recall / project 子命令）
- MCP 工具参考（remember / search / browse / recall）
- Memory 与 Project 领域模型

---

<a id='page-recall'></a>

## Recall Pipeline & LLM Integration

### 相关页面

相关主题：[Overview & System Architecture](#page-overview), [Data Model, Storage & Memory Operations](#page-data)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mnemo/application/use_cases/recall_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/recall_project.py)
- [src/mnemo/application/use_cases/interfaces/recall_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/interfaces/recall_project.py)
- [src/mnemo/application/recall/builder.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/builder.py)
- [src/mnemo/application/recall/request.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/request.py)
- [src/mnemo/application/recall/bundle.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/bundle.py)
- [src/mnemo/application/recall/gather_stage.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/gather_stage.py)
- [src/mnemo/application/recall/rerank_stage.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/rerank_stage.py)
- [src/mnemo/application/recall/assemble_stage.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/assemble_stage.py)
- [src/mnemo/application/recall/synthesize_stage.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/synthesize_stage.py)
- [src/mnemo/application/recall/synthesis_prompt.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/synthesis_prompt.py)
- [src/mnemo/infrastructure/composition.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/composition.py)
- [src/mnemo/adapters/cli/app.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/cli/app.py)
- [src/mnemo/adapters/mcp/server.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/mcp/server.py)
- [src/mnemo/adapters/embedding/hash_embedder.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/embedding/hash_embedder.py)
- [src/mnemo/domain/memory.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/domain/memory.py)
</details>

# Recall Pipeline & LLM Integration

## 概述与设计目标

`recall` 是 mnemo 0.3.0 引入的**唯一可选 LLM 读路径**，它把"按相关性检索"升级为"按问题回答"。在 CLI 中通过 `mnemo recall <project> <query>` 调用 资料来源：[src/mnemo/adapters/cli/app.py]();在 MCP 中通过 `recall` 工具暴露 资料来源：[src/mnemo/adapters/mcp/server.py]()。

它的设计目标有三条：

1. **回答而非罗列**：生成器（默认 Gemma 4 E2B-it 官方 QAT GGUF）从一批相关记忆合成简洁、有据可查的答复。
2. **永远基于记忆**：当无相关记忆时，模型必须回复固定拒绝语 `No relevant memories found.`，禁止使用外部知识。
3. **模型可降级**：reranker 与 generator 都是可选端口——只有当对应模型被配置时才会进入管线；没有生成器时，recall 回退为按类型分组的结构化结果。

资料来源：[src/mnemo/application/use_cases/recall_project.py:1-15]()、[src/mnemo/application/recall/synthesis_prompt.py:1-15]()。

## 管线架构与阶段

`build_recall_pipeline` 根据可用端口动态拼装阶段，遵循"`embedder -> reranker -> generator`，每项精炼各司其职"的退化哲学。资料来源：[src/mnemo/application/recall/builder.py:1-44]()。

```mermaid
flowchart LR
    A[RecallRequest<br/>project + query + limit] --> B[GatherStage<br/>hybrid retrieve]
    B --> C{Reranker?}
    C -- configured --> D[RerankStage<br/>re-order by query]
    C -- none --> E
    D --> E[AssembleStage<br/>group by type]
    E --> F{Generator?}
    F -- configured --> G[SynthesizeStage<br/>LLM prose]
    F -- none --> H
    G --> H[RecallBundle<br/>sections + summary?]
```

**GatherStage（必备）**：调用相同的混合检索（嵌入 + 词法），使用 `SearchCriteria(scope="project", project=request.project)`，并把检索结果放入 `GATHERED` 槽位。资料来源：[src/mnemo/application/recall/gather_stage.py:1-39]()。

**RerankStage（可选）**：当注入 `Reranker` 时插入，按查询对 `GATHERED` 重排，`top_k=20`。资料来源：[src/mnemo/application/recall/rerank_stage.py]()。

**AssembleStage（必备）**：纯函数，把 `GATHERED` 按 `memory.type.value` 分组到 `RecallSection`，产出 `RecallBundle(project, sections)`。资料来源：[src/mnemo/application/recall/assemble_stage.py:1-26]()。

**SynthesizeStage（可选）**：当注入 `Generator` 时追加；空 bundle 直接 no-op（无内容可总结），否则调用 `build_synthesis_prompt` 并用 `dataclasses.replace` 原地填充 `summary` 字段。资料来源：[src/mnemo/application/recall/synthesize_stage.py:1-30]()。

## 数据契约：Request、Bundle 与拒绝语

**输入 `RecallRequest`** 是 frozen dataclass，`__post_init__` 显式拒绝空查询——空查询会静默退化为"无导向转储"，因此被 `ValueError` 拦截并给出可操作提示。资料来源：[src/mnemo/application/recall/request.py:1-26]()。

**输出 `RecallBundle`** 始终携带结构化分组；`summary` 只有在生成器阶段运行后才会被填充。`RecallSection` 持有 `(type, memories)` 元组；`RecallBundle.total` 聚合所有 section 的记忆数。资料来源：[src/mnemo/application/recall/bundle.py:1-31]()。

**合成 prompt 模板**把记忆按类型排版（`## <type>` 分组），先列记忆再重复问题以重新锚定注意力；指令明确要求只用给定记忆、不得使用外部知识，并在不相关时输出 `No relevant memories found.`。资料来源：[src/mnemo/application/recall/synthesis_prompt.py:1-44]()。

## 集成点、配置与失败模式

`infrastructure/composition.py` 中的 `build_container` 在 `recall` 字段上装配管线，依赖注入全部来自 `Config`：

| 端口 | 默认/可选 | 行为 |
|---|---|---|
| Embedder | `pplx`（pplx-embed-v1-0.6b int8 ONNX）/ `hash`（离线） | `hash` 仅词法，用于测试与离线场景 资料来源：[src/mnemo/adapters/embedding/hash_embedder.py:1-31]() |
| Reranker | 可选 | 未配置时管线跳过重排 |
| Generator | 可选；`off` 显式关闭 | 缺失时 CLI/MCP 抛 `RuntimeError`，提示安装 `mnemo[recall]` 或设为 `off` |
| `rerank_top_k` | 20 | RerankStage 上限 |
| `generator_max_tokens` | 512 | SynthesizeStage 输出上限 |

资料来源：[src/mnemo/infrastructure/composition.py]()

**常见失败模式**：

- **空查询**：`RecallRequest.__post_init__` 抛 `ValueError`，CLI 转为 `typer.BadParameter`。资料来源：[src/mnemo/application/recall/request.py:18-25]()、[src/mnemo/adapters/cli/app.py]()。
- **缺失可选端口**：CLI 捕获 `RuntimeError` 并以 `typer.Exit(1)` 输出可操作消息（不再打印 traceback）。资料来源：[src/mnemo/adapters/cli/app.py]()。
- **MCP 视图轻量化**：`recall` MCP 工具返回 `{project, summary, sources:[{id,type}, …]}`，刻意省略记忆正文以减轻调用方上下文负担。资料来源：[src/mnemo/adapters/mcp/server.py]()。

## See Also

- [Memory Domain Model](./Memory-Domain-Model) — `Memory` 实体与不变量
- [Search & Retrieval](./Search-Retrieval) — GatherStage 复用的混合检索路径
- [CLI Commands](./CLI-Commands) — `store/search/browse/recall` 等命令参考
- [MCP Server](./MCP-Server) — `recall` 工具与上下文裁剪策略

---

<a id='page-data'></a>

## Data Model, Storage & Memory Operations

### 相关页面

相关主题：[Overview & System Architecture](#page-overview), [Recall Pipeline & LLM Integration](#page-recall)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mnemo/domain/memory.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/domain/memory.py)
- [src/mnemo/application/retrieval.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/retrieval.py)
- [src/mnemo/application/search_criteria.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/search_criteria.py)
- [src/mnemo/application/use_cases/browse_memory.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/browse_memory.py)
- [src/mnemo/application/recall/bundle.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/bundle.py)
- [src/mnemo/application/recall/gather_stage.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/gather_stage.py)
- [src/mnemo/application/recall/assemble_stage.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/recall/assemble_stage.py)
- [src/mnemo/application/use_cases/recall_project.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/use_cases/recall_project.py)
- [src/mnemo/adapters/cli/app.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/cli/app.py)
- [src/mnemo/adapters/mcp/server.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/mcp/server.py)
- [src/mnemo/adapters/embedding/hash_embedder.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/embedding/hash_embedder.py)
- [src/mnemo/infrastructure/composition.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/composition.py)
- [src/mnemo/application/pipeline/proposed_memory.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/application/pipeline/proposed_memory.py)
- [README.md](https://github.com/arttttt/mnemo/blob/main/README.md)
</details>

# 数据模型、存储与记忆操作

## Memory 实体：域核心与写入不变式

`Memory` 是 mnemo 中唯一被持久化的领域实体——它承载 agent 跨会话需要保留的所有决策、bug、进度与规则片段。所有 `Memory` 实例都通过 `Memory.create()` 工厂方法构造，而非直接调用构造函数，从而在写入前强制执行关键不变式检查。

| 字段 | 类型 | 含义 |
|---|---|---|
| `id` | `str` | 唯一标识符，由 `domain.generators.new_id()` 生成 |
| `content` | `str` | 记忆正文；空串或纯空白会被拒绝 |
| `type` | `MemoryType` | 枚举化的记忆类型（默认 `working-notes`） |
| `scope` | `Scope` | `PROJECT` 或 `GLOBAL`；后者把 `project` 强制覆盖为哨兵 |
| `project` | `str \| None` | 项目 slug；全局记忆时取 `GLOBAL_PROJECT` |
| `related_files` / `tags` | `list[str]` | 反向索引与关键字过滤的载体 |
| `topic_key` | `str \| None` | 稳定键；复用时旧记忆被 `supersedes` 取代 |
| `status` | `str` | 写入路径返回 `"created"` / `"duplicate"` / `"superseded"` |
| `hash` | `str` | 由 `content_hash` 计算，用于去重判定 |
| `created_at` / `updated_at` | `str` | ISO-8601 UTC 时间戳 |

工厂在校验阶段分别处理：`not content or not content.strip()` 拒绝空内容；`Scope(scope)` 与 `MemoryType(type)` 把字符串入参归一化为枚举；当 `scope is Scope.GLOBAL` 时直接把 `project` 覆盖为 `GLOBAL_PROJECT`，从而保证后续"项目内 + 全局"联合查询的语义一致。`topic_key` 复用路径返回 `"superseded"` 状态以维持历史可追溯（资料来源：[src/mnemo/domain/memory.py:24-55]()）。

## 检索请求：双轨混合排序

mnemo 的检索不是纯语义、也不是纯 FTS，而是一次**双轨**的混合排序。请求载体是 `Retrieval` 数据类，它同时承载 `text`（FTS 词法腿）与 `vector`（稠密腿）。`__post_init__` 强制不变式：两者要么都提供（一次搜索），要么都不提供（过滤式浏览）；只提供其一会被立即拒绝并附明确错误——因为只用一半信号排序几乎总意味着调用方构建请求时漏掉了查询的向量化（资料来源：[src/mnemo/application/retrieval.py:18-28]()）。

`SearchCriteria` 是与具体后端解耦的过滤规约：`scope`（`project` / `global` / `all`）、`project`、`type`、`tags`、`related_files`、`created_after`。`created_after` 在构造时即被解析为 `datetime` 并规范化为 UTC——这是因为域内的 `created_at` 始终是 UTC ISO 字符串，存储层依赖字符串比较排序，提前归一化可同时保证进程内匹配器与 SQL `>=` 子句行为一致（资料来源：[src/mnemo/application/search_criteria.py:25-38]()）。

## 浏览模式：无查询的过滤读取

`BrowseMemoryUseCaseImpl` 提供"按过滤条件列出最近记忆"的语义——它的请求体 `Retrieval` 中 `text` 与 `vector` 均为 `None`，因此**不进入任何相关性排序**。结果按 `created_at` 倒序返回，且不带分数字段。返回的 `BrowseResult` 是面向客户端的精简视图（`id / type / scope / project / content / related_files / created_at`），刻意省略 `tags`、`topic_key`、`session_id` 等内部字段以减小线缆体积（资料来源：[src/mnemo/application/use_cases/browse_memory.py:1-30]()）。

MCP 层的 `browse` 工具在文档中明确推荐用于"按类型/时间分类检索"的场景，因为此场景下语义查询只会带来无意义的偏序。

## Recall 流水线：分阶段的数据流

v0.3.0 引入的 `recall` 是 mnemo 中**唯一**可选的 LLM 读取工具。它的产物是 `RecallBundle`：`RecallSection` 元组（按 `type` 分组），加一个可选的 `summary`——后者仅当生成器阶段实际运行时填充，否则分组与顺序本身就承载结构（资料来源：[src/mnemo/application/recall/bundle.py:11-30]()）。

`GatherStage` 是流水线的相关性步骤——它**复用**了 `search` 的同一条混合检索路径（嵌入查询 → 稠密 + 词法），并把范围固定在"命名项目 + 全局记忆"内，上限为请求中的 `limit`（资料来源：[src/mnemo/application/recall/gather_stage.py:18-35]()）。`AssembleStage` 是纯分组阶段、不涉及任何模型调用，它将 `GATHERED` 按 `memory.type.value` 聚合为有序的 `RecallSection` 元组，为后续可选的生成器提供结构化输入（资料来源：[src/mnemo/application/recall/assemble_stage.py:12-25]()）。

CLI 与 MCP 同时暴露这一入口：`mnemo recall <project> <query>` 与 `recall` MCP 工具共用 `RecallProjectUseCaseImpl.execute()`。当生成器关闭时，`RecallBundle` 仅承载分组与顺序本身；当生成器启用时，**Gemma 4 E2B-it**（QAT GGUF）会基于这些分组合成简洁、基于证据的回答，并在无相关记忆时回复 `No relevant memories found.`——它**绝不会**越过记忆库引入外部知识。模型时延与 RAM 信息由 `MNEMO_LOG_LEVEL` 控制送往日志，最终结构以 JSON 输出到终端（资料来源：[README.md:1-20](), [src/mnemo/application/use_cases/recall_project.py:18-40](), [src/mnemo/adapters/cli/app.py:60-90]()）。

嵌入器的选择同样会影响所有上述操作的存储与召回质量：`hash` 嵌入器是确定性的、零依赖的占位实现（仅捕获词袋重叠、不具备语义能力），适合离线测试；生产路径默认走 `pplx`（`pplx-embed-v1-0.6b` 的 int8 ONNX，通过 `llmkit` 在 CPU 上推理），由 `composition._build_embedder()` 集中切换（资料来源：[src/mnemo/adapters/embedding/hash_embedder.py:10-35](), [src/mnemo/infrastructure/composition.py:55-90]()）。

---

## See Also

- [README.md](https://github.com/arttttt/mnemo/blob/main/README.md) — 项目总览、核心原则与 v0.3.0 发布说明
- 数据写入路径（`remember` / `topic_key` upsert 行为）由 MCP `remember` 工具与 `Memory.create()` 共同约束
- 嵌入器选择（`hash` / `pplx`）与生成器（`MNEMO_GENERATOR`）在 `infrastructure.composition` 中集中配置

---

<a id='page-deploy'></a>

## Configuration, Client Setup & Deployment

### 相关页面

相关主题：[Overview & System Architecture](#page-overview)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mnemo/infrastructure/config.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/config.py)
- [src/mnemo/infrastructure/composition.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/composition.py)
- [src/mnemo/infrastructure/logging_config.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/logging_config.py)
- [src/mnemo/adapters/setup/client_installer.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/client_installer.py)
- [src/mnemo/adapters/setup/client_registry.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/client_registry.py)
- [src/mnemo/adapters/setup/cli_client_installer.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/cli_client_installer.py)
- [src/mnemo/adapters/setup/mcp_servers_json_installer.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/mcp_servers_json_installer.py)
- [src/mnemo/adapters/setup/json_config.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/json_config.py)
- [src/mnemo/adapters/cli/app.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/cli/app.py)
- [src/mnemo/adapters/mcp/server.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/mcp/server.py)
- [src/llmkit/config.py](https://github.com/arttttt/mnemo/blob/main/src/llmkit/config.py)
</details>

# Configuration, Client Setup & Deployment

本页说明 mnemo 作为本地记忆系统在**配置加载、AI 编码代理客户端集成、以及部署入口**三方面的设计——一个运行在用户机器上的进程，如何通过环境变量与客户机原生 JSON 配置文件，把 SQLite 仓储、嵌入器、Recall 管道接到 Typer CLI 和 MCP 服务器上。

## 配置体系

mnemo 的运行时参数来源于两层：**进程级环境变量**与**客户机自己的 JSON 配置文件**。这两层在 composition root 汇合，最终冻结成一个不可变的依赖图。

### `Config` 与环境变量

`Config` dataclass 描述一个可启动的 mnemo 实例所需的所有字段，包括数据目录、嵌入器名称、Recall 阶段的 rerank / generate 模型选择及其 tokens 上限。它由 [src/mnemo/infrastructure/config.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/config.py) 从环境变量读取，例如 `MNEMO_EMBEDDER`、`MNEMO_GENERATOR`、`MNEMO_RERANKER`、`MNEMO_LOG_LEVEL` 等。日志子系统单独由 [src/mnemo/infrastructure/logging_config.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/logging_config.py) 暴露，配置加载与日志初始化解耦。

### 模型描述（llmkit）

外置模型的"在哪里、以何种生命周期加载"由 `ModelConfig` 描述，见 [src/llmkit/config.py](https://github.com/arttttt/mnemo/blob/main/src/llmkit/config.py)。它把 `OnnxSource` / `GgufSource` 与 `Residency` 策略封装在一起，由消费者（mnemo）自行构造并传入 `llmkit.build`，而不是从环境变量解析——生命周期策略被视为代码侧决策，不暴露给运维。

### JSON 配置文件读写

为避免破坏 Cursor / Claude Desktop 等客户机自己的 JSON 配置，[src/mnemo/adapters/setup/json_config.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/json_config.py) 提供最小化的 `load_json` / `save_json`：保留未知键、不重排顺序，文件缺失或为空时返回空字典，写入时附加换行符以利于版本控制 diff。

## 客户端安装器（Client Installer）

不同 AI 代理客户端拥有各自专属的接入方式，但统一通过一个端口（port）暴露，使调用者不必关心实现差异。

### 安装器协议

[src/mnemo/adapters/setup/client_installer.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/client_installer.py) 定义了 `ClientInstaller` Protocol，包含三个动作：`detect()` 判断客户端是否在本机安装；`describe()` 返回一行可读的接线说明（用于 `--dry-run` 与交互提示）；`install()` 实际写入配置并返回 `InstallResult`。所有实现都向该端口适配。

### 注册与具体实现

[src/mnemo/adapters/setup/client_registry.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/client_registry.py) 维护 slug → 安装器的注册表，使 `mnemo setup <client>` 命令按名称查找实现。具体策略遵循"客户机用什么工具，就用什么工具"：

- [src/mnemo/adapters/setup/cli_client_installer.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/cli_client_installer.py) 通过调用客户机官方的 `mcp add` 子进程完成接线；
- [src/mnemo/adapters/setup/mcp_servers_json_installer.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/setup/mcp_servers_json_installer.py) 通过读写 `mcp_servers.json` 完成接线。

`install()` 是**幂等**的——重复运行不会破坏已有配置。

## 部署入口

### composition root

[src/mnemo/infrastructure/composition.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/infrastructure/composition.py) 是整个应用的组合根：从 `Config` 出发构建 SQLite 仓储、项目 gate、嵌入器（`hash` 或 `pplx`）、调度器、session_provider，然后装配出全部 use case 实例（`remember`、`search`、`browse`、`recall`、`create_project` 等）。它是 CLI 与 MCP 服务器共享的唯一构造路径，保证两条入口拿到的是同一份依赖图。

### CLI 与 MCP 适配器

- **CLI**：[src/mnemo/adapters/cli/app.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/cli/app.py) 用 Typer 暴露 `store` / `search` / `browse` / `recall` / `setup` 等命令，每次调用都重新走一遍 `build_container()`，因此配置变更无需重启进程外的服务。`recall` 命令在 reranker / generator 缺失时会把 actionable `RuntimeError` 直接打到 stderr 而非 traceback。
- **MCP 服务器**：[src/mnemo/adapters/mcp/server.py](https://github.com/arttttt/mnemo/blob/main/src/mnemo/adapters/mcp/server.py) 把同一组 use case 暴露为 `mcp.tool()`，包括 `remember`、`search`、`browse`、`recall`、`create_project`、`update_project`、`delete_project`、`list_projects`，从而被 Cursor、Claude Desktop 等代理直接发现与调用。

## 配置与部署流程

```mermaid
flowchart LR
    A[环境变量 MNEMO_*] --> B[Config dataclass]
    B --> C[composition root]
    D[客户机 JSON 配置] --> E[json_config 读写]
    E --> F[ClientInstaller.install]
    F --> G[mcp_servers.json / mcp add CLI]
    C --> H[use cases 容器]
    H --> I[CLI 适配器]
    H --> J[MCP 适配器]
    J --> K[Cursor / Claude Desktop 等]
    I --> L[终端用户]
```

## See Also

- `recall` 命令 / MCP 工具的相关开关（`MNEMO_GENERATOR`、`MNEMO_RERANKER`、`MNEMO_LOG_LEVEL`）详见 Recall 页面。
- 嵌入器 `hash` 与 `pplx` 的取舍详见 Embedding 页面。
- 项目 gate 与 near-match 候选建议见 Project Model 页面。

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：arttttt/mnemo

摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：配置坑 - 可能修改宿主 AI 配置。

## 1. 配置坑 · 可能修改宿主 AI 配置

- 严重度：medium
- 证据强度：source_linked
- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- 证据：capability.host_targets | https://github.com/arttttt/mnemo | host_targets=mcp_host, claude_code, claude, cursor

## 2. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://github.com/arttttt/mnemo | README/documentation is current enough for a first validation pass.

## 3. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://github.com/arttttt/mnemo | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://github.com/arttttt/mnemo | no_demo; severity=medium

## 5. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://github.com/arttttt/mnemo | no_demo; severity=medium

## 6. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://github.com/arttttt/mnemo | issue_or_pr_quality=unknown

## 7. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://github.com/arttttt/mnemo | release_recency=unknown

<!-- canonical_name: arttttt/mnemo; human_manual_source: deepwiki_human_wiki -->
