# https://github.com/Tamariskwhisper962/Localbrain 项目说明书

生成时间：2026-06-22 22:24:54 UTC

## 目录

- [概述与系统架构](#page-overview)
- [核心引擎：索引与数据管道](#page-engine)
- [搜索、重排序与洞察](#page-search)
- [适配器、配置与部署](#page-adapters)

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

## 概述与系统架构

### 相关页面

相关主题：[核心引擎：索引与数据管道](#page-engine), [适配器、配置与部署](#page-adapters)

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

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

- [README.md](https://github.com/Tamariskwhisper962/Localbrain/blob/main/README.md)
- [src/localbrain/context.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/context.py)
- [src/localbrain/core/indexer.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/indexer.py)
- [src/localbrain/core/chunking.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/chunking.py)
- [src/localbrain/core/embed/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/embed/registry.py)
- [src/localbrain/core/loaders/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/loaders/registry.py)
- [src/localbrain/core/db.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/db.py)
- [src/localbrain/services/indexing_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/indexing_service.py)
- [src/localbrain/services/insights_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/insights_service.py)
- [src/localbrain/adapters/mcp_server.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/mcp_server.py)
- [src/localbrain/adapters/__init__.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/__init__.py)
- [src/localbrain/adapters/web/__init__.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/web/__init__.py)
</details>

# 概述与系统架构

## 项目定位与核心能力

Localbrain 是一款**本地优先（local-first）的个人知识库检索工具**，通过在用户机器上完成文件读取、文本分块、向量化与语义检索，让自然语言查询能够直接命中本地的 Markdown、纯文本等文档。README 中明确指出：用户数据始终留在本机，索引与查询均不依赖外部云服务，断网后已索引的内容仍可继续使用 资料来源：[README.md]()。

围绕这一目标，系统提供三组核心能力：

1. **本地语义索引** —— 通过本地嵌入模型将文档切片写入本地向量库；
2. **多入口适配** —— 同时面向 MCP（Model Context Protocol）、Web 控制台和 CLI 提供薄入口，让 Claude Code 等外部 AI 工具也能消费本地知识；
3. **自反馈回路** —— 通过查询聚类与知识空白报告，为索引的持续优化提供数据支撑。

## 分层架构

代码以 `src/localbrain/` 为根，按 **core / services / adapters** 三层组织，并由一个组合根（composition root）统一装配：

```mermaid
flowchart TD
    A["适配层 Adapters<br/>MCP Server · Web UI · CLI"] --> B["服务层 Services<br/>IndexingService · SearchService · InsightsService"]
    B --> C["核心层 Core<br/>Indexer · Searcher · Scanner · Insights"]
    C --> D["基础设施<br/>SQLite(file_index/sources/queries) · Chroma(vector store) · Embedding Providers"]
    A -.启动.-> E["AppContext (context.py)<br/>composition root"]
    E --> B
    E --> C
    E --> D
```

各层职责：

- **核心层（core/）** 承担单一职责的领域逻辑，例如 `core/indexer.py` 只负责"load→chunk→embed→store + file_index 更新"流程，并以 `yield {"phase":...}` 形式对外暴露进度事件 资料来源：[src/localbrain/core/indexer.py]();`core/chunking.py` 只负责段落优先的贪心分块与相邻 overlap 合并 资料来源：[src/localbrain/core/chunking.py]()。
- **服务层（services/）** 是面向用例的薄编排，例如 `IndexingService.run()` 负责"扫源 → 生成 ChangeSet → 调用 Indexer → 流式返回进度"，并以 `rebuild=True` 控制是否全量重建 资料来源：[src/localbrain/services/indexing_service.py]();`InsightsService` 仅作为 `Insights.cluster(...)` 的薄包装，用于查询聚类与知识空白 资料来源：[src/localbrain/services/insights_service.py]()。
- **适配层（adapters/）** 是面向协议的入口：`adapters/__init__.py` 中描述其为"core·services 之上的薄入口" 资料来源：[src/localbrain/adapters/__init__.py]()；`mcp_server.py` 基于 FastMCP 暴露 `search / add_path / remove_path` 等工具，让 Claude Code 通过 stdio 直接调用本地知识 资料来源：[src/localbrain/adapters/mcp_server.py]()；`adapters/web/__init__.py` 则声明 Web 端为 FastAPI 后端 + 静态单页架构 资料来源：[src/localbrain/adapters/web/__init__.py]()。

## 关键数据流：索引与检索

系统通过 `AppContext` 把所有依赖拼装到一处：构造嵌入 provider、连接 SQLite、初始化 Chroma 向量库、构建 `Scanner/Indexer/Searcher/FileIndex/SourceStore`，并由各适配器按需取用 资料来源：[src/localbrain/context.py]()。两侧数据流如下：

| 流向 | 触发 | 关键步骤 | 落点 |
| --- | --- | --- | --- |
| **写入（索引）** | `add_path` / `run(rebuild)` | Loader 按扩展名匹配 → `chunk_text` 分块 → EmbeddingProvider 编码 → Chroma 写入 → `file_index` 记录 hash/mtime/chunk_ids | 向量库 + SQLite |
| **读取（检索）** | MCP `search` / Web 查询 | `Searcher` 在 Chroma 上做向量召回 → 可选 Reranker 重排 → 返回带分数的命中片段 | 调用方 |

可插拔扩展点体现在两处 registry：嵌入侧支持 `fastembed / ollama / sentence-transformers` 三种 provider，按配置名懒加载 资料来源：[src/localbrain/core/embed/registry.py]()；加载器侧通过 `_LOADERS: list[Loader]` 列表按 `supports(path)` 选择，当前内置 `TextLoader` 资料来源：[src/localbrain/core/loaders/registry.py]()。

## 持久化、配置与可扩展性

SQLite 作为元数据库，`core/db.py` 中声明了三张表：`sources`（注册路径与 glob）、`file_index`（path / hash / mtime / size / chunk_ids / source_id）和 `queries`（id / text / ts / hit / top_score），并启用 WAL 与 `check_same_thread=False` 以适配多适配器并发 资料来源：[src/localbrain/core/db.py]()。向量库落盘到 `chroma_dir`，文件名以 `provider.model_id` 作为 collection 命名空间，避免不同模型切换时混用 资料来源：[src/localbrain/context.py]()。

扩展建议：

- **新增文件类型**：实现 `Loader.supports` 并注册到 `_LOADERS` 列表即可被 `get_loader` 自动选中 资料来源：[src/localbrain/core/loaders/registry.py]()。
- **新增嵌入后端**：在 `core/embed/` 下实现 `EmbeddingProvider`，并在 `make_provider` 中追加分支 资料来源：[src/localbrain/core/embed/registry.py]()。
- **新增 AI 客户端**：只需在 `adapters/` 下添加薄入口，复用 `AppContext` 与服务层，无需触碰 core 资料来源：[src/localbrain/adapters/__init__.py]()。

## See Also

- [MCP 服务器适配器](MCP服务器适配器.md)
- [核心索引器](核心索引器.md)
- [嵌入与检索](嵌入与检索.md)

---

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

## 核心引擎：索引与数据管道

### 相关页面

相关主题：[概述与系统架构](#page-overview), [搜索、重排序与洞察](#page-search)

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

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

- [src/localbrain/context.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/context.py)
- [src/localbrain/core/indexer.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/indexer.py)
- [src/localbrain/core/chunking.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/chunking.py)
- [src/localbrain/core/loaders/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/loaders/registry.py)
- [src/localbrain/core/store.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/store.py)
- [src/localbrain/core/embed/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/embed/registry.py)
- [src/localbrain/core/embed/ollama_provider.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/embed/ollama_provider.py)
- [src/localbrain/adapters/mcp_server.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/mcp_server.py)
- [src/localbrain/services/insights_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/insights_service.py)
- [CHANGELOG.md](https://github.com/Tamariskwhisper962/Localbrain/blob/main/CHANGELOG.md)
</details>

# 核心引擎：索引与数据管道

## 概述

Localbrain 的核心引擎围绕"扫描 → 加载 → 分块 → 嵌入 → 持久化"五个阶段构建了一条可增量更新的数据管道。该管道的职责是把本地文件系统中的纯文本/结构化文档，转换为 Chroma 向量库中可语义检索的向量记录，并维护一份 SQLite 文件索引以追踪每个路径的哈希与对应分块。引擎本身不直接面向用户，所有调用都通过 `AppContext` 这一组合根注入到上层服务（`IndexingService` / `SearchService` / `InsightsService`）中，再由 MCP、CLI、Web 三种适配器暴露。

资料来源：[src/localbrain/context.py:1-40]()、[CHANGELOG.md:0.1.0]()

## 架构总览：组合根

`AppContext` 在 `src/localbrain/context.py` 中扮演组合根（composition root）的角色——它一次性装配配置、嵌入 provider、向量库、文件索引、扫描器、索引器等所有依赖。适配层只需要 `AppContext()` 一行即可获得完整的服务栈，避免在 MCP、CLI、Web 三个入口分别重复拼装。

```mermaid
graph LR
    A[适配器 MCP/CLI/Web] --> B[AppContext 组合根]
    B --> C[Scanner 扫描]
    B --> D[Indexer 索引]
    B --> E[VectorStore 向量库]
    B --> F[FileIndex SQLite]
    B --> G[Insights 洞察]
    C -->|ChangeSet| D
    D -->|embed + store| E
    D -->|update| F
```

资料来源：[src/localbrain/context.py:1-40]()

## 数据管道：扫描到写入

### 1. 扫描阶段

`Scanner` 负责遍历已注册源（文件夹/文件），通过 `mtime + 内容哈希` 双重比对，产出 `ChangeSet`（包含 `new` / `modified` / `deleted` 三类路径）。这种"变更即差异"的设计让索引过程天然支持增量更新：未发生变化的文件直接跳过，从而避免重复嵌入。扫描完成后，`ChangeSet` 被交给 `Indexer.apply()`。

资料来源：[src/localbrain/core/indexer.py:1-40]()

### 2. 加载与分块

`Indexer` 根据路径扩展名从 `Loader` 注册表中选择合适的加载器，目前内置 `TextLoader` 用于 `.md` / `.txt` 等纯文本。文本随后进入 `chunk_text()`：它首先按双换行切分为段落，再以"段优先 + 字符窗口回退"的贪心策略在 `chunk_size`（默认 1000）内累积；若某段超出窗口，则按 `chunk_size - overlap` 步长切分。最后，相邻分块会拼接前一个分块的尾部 `overlap`（默认 150 字符），形成"重叠上下文"，保证检索时不会在块边界丢失语义。

```python
# 摘自 src/localbrain/core/chunking.py
step = max(1, size - overlap)
for i in range(0, len(p), step):
    chunks.append(p[i:i + size])
```

资料来源：[src/localbrain/core/loaders/registry.py:1-15]()、[src/localbrain/core/chunking.py:1-40]()

### 3. 嵌入与持久化

每个分块经 `EmbeddingProvider.embed_texts()` 编码为向量。`Indexer.apply()` 会以流式方式（`yield` 进度事件）依次处理删除、新增和修改三类目标：先调用 `VectorStore.delete_documents()` 清理旧向量，再写入新向量与元数据，最后在 `FileIndex` 中登记新哈希与 `chunk_ids`。`VectorStore` 内部按 `model_id` 命名规则拆分 `docs__<tag>` 与 `queries__<tag>` 两个 Chroma 集合，并使用 cosine 距离空间——这样切换嵌入模型时不会出现"新旧向量混合"的数据污染问题。

资料来源：[src/localbrain/core/indexer.py:30-50]()、[src/localbrain/core/store.py:1-40]()

## 嵌入 Provider 注册表

`make_provider()` 采用字符串查表 + 懒加载（lazy import）的策略，把 provider 实现与业务解耦。当前内置三种实现：

| Provider 名称 | 后端 | 适用场景 |
| --- | --- | --- |
| `fastembed` | Qdrant 出品的本地 ONNX 推理 | 默认选项，零额外服务 |
| `ollama` | 调用本地 Ollama HTTP `/api/embeddings` | 已部署 Ollama 的环境 |
| `sentence-transformers` | HuggingFace transformers | 需要自定义/实验性模型 |

例如 `OllamaProvider` 直接通过 `urllib.request` 与 `http://localhost:11434/api/embeddings` 通信，并以 `ollama:<model>` 作为 `model_id` 写入向量库标签。注册表还接受 `fp16` 参数用于推理精度控制。

资料来源：[src/localbrain/core/embed/registry.py:1-20]()、[src/localbrain/core/embed/ollama_provider.py:1-30]()

## 与上层服务的耦合

核心引擎并不直接处理用户请求——它通过 `IndexingService` / `InsightsService` 等服务类与适配器对接。例如，MCP 适配器在 `mcp_server.py` 中通过 `AppContext` 拿到 `IndexingService` 后，将其 `add_path()` / `remove_source()` 方法注册为 `@mcp.tool()` 工具；`InsightsService.report()` 则把质询日志聚类为 FAQ 与知识空缺报告。这种"core 决定能力边界，adapters 决定暴露方式"的分层让 CLI 与 Web 也能复用同一套索引语义。

资料来源：[src/localbrain/adapters/mcp_server.py:1-30]()、[src/localbrain/services/insights_service.py:1-15]()

## 常见失败模式

- **嵌入模型未下载**：`fastembed` 首次使用会从 HuggingFace 拉取模型权重，需保持网络可达；`CHANGELOG.md` 指出 0.1.1 已将模型加载改为 lazy，从而保证 MCP 握手不被阻塞。
- **路径 glob 不匹配**：`add_path` 默认 `*.md,*.txt`，若文件夹内全是 `.pdf` 等无内置 loader 的类型，`is_supported()` 会返回 `None`，导致整条路径被静默跳过。
- **Windows 控制台编码**：0.1.1 之前的版本在 cp949 终端输出韩文/em-dash 时会崩溃，升级至 0.1.1 后已强制 UTF-8。
- **向量库分集合未隔离**：若手动修改 `model_id` 字符串，建议先备份 `chroma/` 目录，避免误把不同维度的向量写入同一集合。

资料来源：[CHANGELOG.md:0.1.1]()、[src/localbrain/core/loaders/registry.py:1-15]()

## See Also

- 核心引擎：搜索与重排
- 核心引擎：嵌入与运行时
- 适配器：MCP / CLI / Web
- 数据模型：Source / FileRecord / ChangeSet

---

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

## 搜索、重排序与洞察

### 相关页面

相关主题：[核心引擎：索引与数据管道](#page-engine), [适配器、配置与部署](#page-adapters)

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

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

- [src/localbrain/context.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/context.py)
- [src/localbrain/core/search.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/search.py)
- [src/localbrain/core/rerank/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/rerank/registry.py)
- [src/localbrain/core/rerank/base.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/rerank/base.py)
- [src/localbrain/core/rerank/cross_encoder.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/rerank/cross_encoder.py)
- [src/localbrain/core/insights.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/insights.py)
- [src/localbrain/core/clustering.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/clustering.py)
- [src/localbrain/services/insights_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/insights_service.py)
- [src/localbrain/services/search_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/search_service.py)
- [src/localbrain/services/indexing_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/indexing_service.py)
- [src/localbrain/adapters/mcp_server.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/mcp_server.py)
- [src/localbrain/adapters/cli.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/cli.py)
- [src/localbrain/core/indexer.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/indexer.py)
- [src/localbrain/core/db.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/db.py)
- [src/localbrain/core/embed/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/embed/registry.py)
</details>

# 搜索、重排序与洞察

## 1. 模块定位与职责切分

Localbrain 的"搜索 · 重排序 · 洞察"三大能力位于 `core` 层，并由 `services` 层包装后通过 `adapters` 暴露给 MCP / CLI / Web 三类入口。组装这一切的是 `AppContext`——它读取 `Config`、构造嵌入 provider、向量存储、文件索引以及**搜索器、reranker、洞察对象**，是唯一的"组合根"。

```mermaid
flowchart LR
    A[adapter: MCP/CLI/Web] --> B[services: SearchService / IndexingService / InsightsService]
    B --> C[core: Searcher / Indexer / Insights]
    C --> D[(VectorStore + SQLite file_index/queries)]
    C --> E[EmbeddingProvider]
    C --> F[make_reranker → cross-encoder]
    style C fill:#eef
    style F fill:#fee
```

资料来源：[src/localbrain/context.py:1-40]()

## 2. 搜索与重排序流程

`Searcher` 负责从 `VectorStore` 中拉取候选，再（可选）交给 `make_reranker` 工厂返回的 reranker 重排。`make_reranker` 是一个**懒加载的注册表**，根据配置选择实现（如 `cross_encoder`），未配置时关闭该阶段以节省资源。CLI 提供 `--no-rerank` 开关用于对比实验，资料来源：[src/localbrain/adapters/cli.py:17]()；服务侧在 `SearchService` 中统一封装。

MCP 端 `@mcp.tool() search` 直接暴露给 LLM，签名仅三参：

| 参数 | 类型 | 作用 |
|---|---|---|
| `query` | `str` | 自然语言问题 |
| `k` | `int = 5` | 返回条数 |
| `path_prefix` | `str \| None` | 限定到某子目录 |

资料来源：[src/localbrain/adapters/mcp_server.py:21-24]()

`Searcher` 在拉取候选时还会把本次查询写入 `queries` 表（`id / text / ts / hit / top_score`），这是后续洞察分析的"原始数据"。资料来源：[src/localbrain/core/db.py:21-26]()

## 3. 索引与候选的"源头"——增量更新

搜索的候选集合由 `Indexer.apply()` 维护：它对 `ChangeSet.new / modified` 跑"加载→分块→嵌入→存储"流水线，对 `ChangeSet.deleted` 调用 `store.delete_documents` 同步清理，保证向量库与 `file_index` 一致。资料来源：[src/localbrain/core/indexer.py:36-50]()

`IndexingService` 暴露 `add_source / remove_source / list_sources / run` 四个用例：`remove_source` 会先把该源下所有 chunk 从向量库中删除，再删除 `file_index` 记录和 `sources` 行。资料来源：[src/localbrain/services/indexing_service.py:13-29]()

## 4. 洞察：FAQ 聚类与知识空缺报告

`InsightsService` 是 `Insights` 的薄包装，对外仅暴露 `report(min_similarity, gap_score)`，内部委托给 `self._ctx.insights.cluster(...)`。资料来源：[src/localbrain/services/insights_service.py:9-13]()

`cluster` 把 `queries` 表中的历史问句做相似度聚类：

- **FAQ 候选**：达到 `min_similarity` 的簇被认为在反复问同一类问题，可整理成标准答案。CLI 默认阈值 `0.80`，资料来源：[src/localbrain/adapters/cli.py:21]()。

这套设计让"知识是否够用"成为可观测信号，而不是凭感觉。资料来源：[src/localbrain/core/insights.py]()、[src/localbrain/core/clustering.py]()

## 5. 失败模式与排查要点

| 症状 | 根因 | 处置 |
|---|---|---|
| 搜索召回为空 | 嵌入模型已换但未重建 | `index --rebuild` 重建向量库 |
| 召回相关但顺序差 | 未启用 reranker 或模型缺失 | 检查 `make_reranker` 配置，或临时 `--no-rerank` 验证 |
| 洞察报告簇很少 | `min_similarity` 设得过高 | CLI/服务调低至 `0.7` 试运行 |
| MCP `search` 报缺工具 | stdio 客户端未指向 `mcp_server` | 在 `Connection` 面板核对入口 |

资料来源：[src/localbrain/services/indexing_service.py:31-50]()、[src/localbrain/adapters/mcp_server.py:21-30]()

## See Also

- [架构总览与组合根](./architecture.md)
- [嵌入与运行时](./embedding-runtime.md)
- [MCP 接入指南](./mcp-integration.md)

---

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

## 适配器、配置与部署

### 相关页面

相关主题：[概述与系统架构](#page-overview), [搜索、重排序与洞察](#page-search)

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

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

- [src/localbrain/adapters/cli.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/cli.py)
- [src/localbrain/adapters/mcp_server.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/mcp_server.py)
- [src/localbrain/adapters/web/server.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/web/server.py)
- [src/localbrain/services/indexing_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/indexing_service.py)
- [src/localbrain/services/model_service.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/services/model_service.py)
- [src/localbrain/config.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/config.py)
- [src/localbrain/context.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/context.py)
- [src/localbrain/core/embed/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/embed/registry.py)
- [src/localbrain/core/db.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/db.py)
- [src/localbrain/core/loaders/registry.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/loaders/registry.py)
- [src/localbrain/core/indexer.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/core/indexer.py)
- [README.md](https://github.com/Tamariskwhisper962/Localbrain/blob/main/README.md)
</details>

# 适配器、配置与部署

## 1. 适配器层在整体架构中的位置

Localbrain 采用清晰的三层结构：`core` (领域核心) → `services` (业务编排) → `adapters` (对外接口)。`adapters/__init__.py` 中明确说明 "adapters — MCP / CLI / Web. core·services 위의 얇은 진입점"，即适配器是位于核心之上的"薄入口"层，仅负责协议转换与参数解析，不承载业务逻辑 资料来源：[src/localbrain/adapters/__init__.py:1-1]()。

目前仓库提供三种适配器入口，覆盖了本地知识库与外部 AI 工具的所有典型交互场景：

- **MCP 适配器** ([src/localbrain/adapters/mcp_server.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/mcp_server.py))：基于 `mcp.server.fastmcp.FastMCP` 实例 `FastMCP("localbrain")`，通过 stdio 与 Claude Code 等兼容客户端直连，对外暴露 `search`、`add_path`、`remove_path` 等工具函数 资料来源：[src/localbrain/adapters/mcp_server.py:1-15]()。
- **CLI 适配器** ([src/localbrain/adapters/cli.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/cli.py))：使用 `argparse` 注册子命令，面向脚本化与运维场景。
- **Web 适配器** ([src/localbrain/adapters/web/__init__.py](https://github.com/Tamariskwhisper962/Localbrain/blob/main/src/localbrain/adapters/web/__init__.py))：FastAPI 后端 + 静态单页，提供可视化控制台。

所有适配器共享同一个 `AppContext`（定义于 `src/localbrain/context.py`），构造时即初始化 services，因此各协议层看到的"业务能力"完全一致 资料来源：[src/localbrain/context.py:1-15]()。

```mermaid
flowchart LR
    A[MCP stdio 客户端] --> B[adapters/mcp_server.py]
    C[终端 / 脚本] --> D[adapters/cli.py]
    E[浏览器] --> F[adapters/web]
    B --> G[AppContext]
    D --> G
    F --> G
    G --> H[services/*]
    H --> I[core/*]
```

## 2. CLI 命令矩阵

`adapters/cli.py` 通过 `parser.add_subparsers` 注册了完整的命令行表面。下表汇总了各子命令的关键参数与用途 资料来源：[src/localbrain/adapters/cli.py:1-50]()：

| 子命令 | 关键参数 | 默认值 | 作用 |
|---|---|---|---|
| `add-source` | `path`, `--globs`, `--no-recursive` | `--globs=*.md,*.txt` | 注册索引源 |
| `list-sources` | — | — | 列出已注册源 |
| `index` | `--source-id`, `--rebuild` | 全量源 | 增量 / 全量索引 |
| `search` | `query`, `-k`, `--path-prefix`, `--no-rerank` | `k` 来自 config | 语义检索 |
| `stats` | — | — | 索引状态 |
| `insights` | `--min-similarity` | `0.80` | 知识图谱 / FAQ 报告 |

`index --rebuild` 会清空 `file_index` 中对应源的全部记录并触发全量重建，常用于"模型更换"后向新集合回填数据 资料来源：[src/localbrain/services/indexing_service.py:1-30]()。

## 3. 配置系统

`AppContext.__init__` 是唯一的"组合根"（composition root），它从 `Config.load()` 读取配置，并据此物化所有依赖 资料来源：[src/localbrain/context.py:1-30]()：

- **嵌入 Provider**：`make_provider(config.embedding.provider, model, fp16)`，通过字符串名路由到具体实现。`core/embed/registry.py` 支持 `fastembed`、`ollama`、`sentence-transformers` 三家 资料来源：[src/localbrain/core/embed/registry.py:1-20]()。
- **持久层**：`connect(config.db_path)` 创建 SQLite 连接，启用 `journal_mode=WAL` 并预建 `sources`、`file_index`、`queries` 三张表 资料来源：[src/localbrain/core/db.py:1-30]()。
- **向量库**：`VectorStore(config.chroma_dir, provider.model_id)` 将 Chroma 集合与嵌入模型 ID 绑定，便于后续按模型隔离。
- **索引流水线**：`scanner` 与 `indexer` 在此装配，`indexer.apply(source, cs)` 是 `load → chunk → embed → store + file_index 刷新` 的单职责入口 资料来源：[src/localbrain/core/indexer.py:1-20]()。

## 4. 部署与典型运行模式

由于三种适配器共享同一 `AppContext`，部署方式可以按使用场景灵活切换：

1. **本地 MCP 模式**：`python -m localbrain.adapters.mcp_server` 启动 stdio 进程，Claude Code 等客户端通过 MCP 协议调用 `search` / `add_path` 工具，从而将本地文档接入大模型 资料来源：[src/localbrain/adapters/mcp_server.py:1-30]()。
2. **CLI 模式**：`python -m localbrain.adapters.cli <subcmd>` 适合定时任务、CI 中的批量索引与检索。
3. **Web 模式**：`adapters/web` 暴露 FastAPI + 浏览器控制台，便于人工浏览索引状态、添加源与查看洞察。

`README.md` 给出的标准流程是：选择文件夹 → 等待进度条 100% → 自然语言搜索 → 在连接面板中管理 MCP 客户端；其强调 "Your data remains on your machine" 与 "It uses local models" 资料来源：[README.md:1-50]()。当 `embedding.provider` 选择 `ollama` 或 `fastembed` 时，整条链路（嵌入、检索、问答）均可在离线环境内完成，符合本地优先的部署哲学。

## See Also

- [README.md](https://github.com/Tamariskwhisper962/Localbrain/blob/main/README.md) — 项目概览与使用流程
- `src/localbrain/core/indexer.py` — 索引管线的单职责实现
- `src/localbrain/services/insights_service.py` — FAQ 聚类与知识图谱入口

---

<!-- evidence_pipeline_checked: true -->

---

## Doramagic 踩坑日志

项目：Tamariskwhisper962/Localbrain

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<!-- canonical_name: Tamariskwhisper962/Localbrain; human_manual_source: deepwiki_human_wiki -->
