# https://github.com/raphaelmansuy/edgequake 项目说明书

生成时间：2026-06-28 09:58:06 UTC

## 目录

- [项目概览](#page-overview)
- [Lib 模块](#page-edgequake_webui-src-lib)
- [Lib 模块](#page-sdks-ruby-lib)
- [Src 模块](#page-edgequake-crates-edgequake-core-src)

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

## 项目概览

### 相关页面

相关主题：[Lib 模块](#page-edgequake_webui-src-lib)

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

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

- [README.md](https://github.com/raphaelmansuy/edgequake/blob/main/README.md)
- [edgequake_webui/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/README.md)
- [edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs)
- [edgequake_webui/src/lib/export-conversation.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/export-conversation.ts)
- [edgequake_webui/src/lib/graph/clustering.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/graph/clustering.ts)
- [edgequake_webui/src/lib/utils/progress-formatter.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/utils/progress-formatter.ts)
- [mcp/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/mcp/README.md)
- [mcp/package.json](https://github.com/raphaelmansuy/edgequake/blob/main/mcp/package.json)
- [legacy/edgequake-pdf/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/legacy/edgequake-pdf/README.md)
- [sdks/typescript/package.json](https://github.com/raphaelmansuy/edgequake/blob/main/sdks/typescript/package.json)
- [zz-reference/001-pgvector/002-fundamentals/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/zz-reference/001-pgvector/002-fundamentals/README.md)
- [zz-reference/002-apache-age/002-fundamentals/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/zz-reference/002-apache-age/002-fundamentals/README.md)
</details>

# 项目概览

## 一、项目定位与核心目标

EdgeQuake 是一个面向检索增强生成（RAG）场景的开源框架，核心特色在于将 **知识图谱（Knowledge Graph）** 与传统向量检索相结合，提供实体抽取、关系发现、上下文聚合与多租户隔离等能力。从最新发布的 v0.12.11 Docker Quickstart 可知，官方推荐使用 `quickstart.sh` 一键脚本或 `docker-compose.quickstart.yml` 完成部署，以降低使用门槛 [v0.12.11 Release](https://github.com/raphaelmansuy/edgequake/releases/tag/v0.12.11)。

框架定位为 **多组件、可扩展的 RAG 平台**，围绕以下目标构建：

- **图谱化记忆**：在文档之上构建实体（Entity）与关系（Relationship）图谱，让 LLM 拥有可遍历的长期记忆。
- **多租户与工作区**：通过 `Workspace` 隔离不同业务方的知识库、LLM 与 Embedding 配置。
- **跨工具集成**：通过 MCP（Model Context Protocol）Server 让 Claude、IDE 等外部 Agent 直接消费图谱。
- **可观测的前端体验**：基于 Next.js 提供可视化图谱、文档管理、流式查询接口。

资料来源：[README.md]()、[edgequake_webui/README.md]()

## 二、系统架构与代码组织

EdgeQuake 仓库采用 **Cargo Workspace + 多前端 SDK** 的分层结构，主要子项目如下表所示。

| 子项目 | 技术栈 | 主要职责 |
| ------ | ------ | -------- |
| `edgequake/crates/edgequake-core` | Rust | 实体抽取、关键词抽取、查询编排、租户请求模型 |
| `edgequake_webui/` | Next.js 16 + React 19 + Tailwind 4 | Web 控制台、图谱可视化、API Explorer |
| `mcp/` | TypeScript + MCP SDK 1.12 | 对外暴露 `document_*`、`graph_query` 等工具 |
| `sdks/typescript/` | TypeScript（tsup 构建） | 通用 REST 客户端，可被 Node/Bun 消费 |
| `legacy/edgequake-pdf/` | Rust CLI | 高质量 PDF→Markdown 转换，含多列版面与可选视觉 OCR |
| `zz-reference/` | Markdown 文档 | pgvector、Apache AGE 等外部依赖的速查参考 |

仓库内嵌了 `zz-reference/001-pgvector` 与 `zz-reference/002-apache-age` 两份资料目录，分别记录向量库与图数据库的安装、类型与操作语义，说明底层存储采用 **pgvector + Apache AGE** 组合：向量存于 `vector`/`halfvec` 等类型，关系图存储于 agtype 图模型中 [pgvector 002-fundamentals](https://github.com/raphaelmansuy/edgequake/blob/main/zz-reference/001-pgvector/002-fundamentals/README.md)、[apache-age 002-fundamentals](https://github.com/raphaelmansuy/edgequake/blob/main/zz-reference/002-apache-age/002-fundamentals/README.md)。

资料来源：[edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs]()、[edgequake_webui/README.md]()、[mcp/package.json]()、[sdks/typescript/package.json]()

```mermaid
flowchart LR
    User[用户 / Agent] -->|HTTP/SSE| WebUI[Next.js WebUI]
    User -->|MCP 协议| MCPServer[MCP Server]
    MCPServer -->|REST| Backend[Rust edgequake-core]
    WebUI -->|REST| Backend
    Backend -->|SQL + agtype| PG[(PostgreSQL<br/>pgvector + Apache AGE)]
    Backend -->|HTTP| LLM[LLM Provider<br/>OpenAI/Ollama/...]
    PDF[edgequake-pdf CLI] -->|Markdown| Backend
```

## 三、关键能力与典型流程

**1. 工作区与自定义实体**：创建工作区时可通过 `CreateWorkspaceRequest` 配置 LLM 模型、Embedding 模型以及实体类型。请求结构内置 `entity_types: Option<Vec<String>>`，并附带 `entity_types_strict` 控制是否将未知类型回退为 `OTHER/CONCEPT`，文档中提及的 SPEC-085 正是用于支持 UI 自定义实体 [edgequake-core multitenancy/requests.rs]()。

**2. 文档导入与进度跟踪**：WebUI 通过统一的 `IngestionProgress` 模型向用户呈现分块、PDF 解析、嵌入等阶段，`progress-formatter.ts` 负责把秒数格式化为 `1h 1m`、`30s`、`ETA: 90s` 等可读字符串，保证长时间任务的可观测性 [progress-formatter.ts]()。

**3. 图谱可视化与社区检测**：`edgequake_webui/src/lib/graph/clustering.ts` 使用 `graphology-communities-louvain` 对实体进行 Louvain 社区检测，并按社区着色，最多支持 20 种循环配色；孤立节点使用默认色，与 SPEC-0716/0717 对应 [clustering.ts]()。

**4. 会话导出**：对话窗口提供 Markdown/JSON 两种导出格式，`export-conversation.ts` 会把消息内容、引用来源、时间戳一起写入文件，并在文件名中执行安全清洗 [export-conversation.ts]()。

**5. MCP 集成**：MCP Server 通过 `document_upload_file`、`graph_query` 等工具，让 Claude/Cursor 等 Agent 直接调用 EdgeQuake，文件类型支持 `.txt`/`.md`/`.pdf` [mcp/README.md]()。

**6. PDF 转写**：`legacy/edgequake-pdf` 提供 Rust 实现的 PDF→Markdown 转换器，覆盖字符定位、多列布局、表格识别、H1–H6 标题和代码块，并能通过 `OPENAI_API_KEY` 调用 `gpt-4o-mini` 进行图片 OCR [legacy/edgequake-pdf/README.md]()。

## 四、社区关注与已知约束

围绕 EdgeQuake 的使用，社区形成了若干重点话题，本页简要列出与项目结构相关的几条：

- **#85 自定义实体**：希望在创建工作区时通过 UI 选择实体类型，而不是依赖后端代码常量。该能力在 `CreateWorkspaceRequest::entity_types` 中已经预留接口 [edgequake-core multitenancy/requests.rs]()。
- **#50 本体（Ontology）**：希望在文档处理阶段引入可定义的本体与同义词典，提升实体一致性。
- **#160 VectorChord 替代 pgvector**：因 pgvector 单向量维度上限 2000，希望切换到 VectorChord 以支持更长向量。
- **#55 Docker 构建失败**：构建前端镜像时若缺失 `next-env.d.ts` 会失败，需在 Docker 上下文中补齐文件。
- **#250/#251/#253/#255 版本与目录**：`models.toml` 通过 `include_str!` 编译进二进制，无法在运行时覆盖；UI 版本号曾落后于 API；上传重复文档时确认替换会出现空操作提示；OpenAI 兼容提供方会在模型名前自动拼接 `provider/`，导致已含 `/` 的模型名重复加前缀。
- **v0.12.4 → v0.12.11 发布节奏**：Docker 快速启动脚本自 v0.12.4 起持续打磨，建议用户始终使用最新版镜像以获得稳定性改进 [v0.12.11 Release](https://github.com/raphaelmansuy/edgequake/releases/tag/v0.12.11)。

资料来源：[README.md]()、[edgequake_webui/README.md]()、[mcp/README.md]()、[legacy/edgequake-pdf/README.md]()、[zz-reference/001-pgvector/002-fundamentals/README.md]()

## See Also

- [知识图谱与查询机制（Knowledge Graph & Query）](#)
- [MCP Server 集成（Model Context Protocol）](#)
- [WebUI 控制台使用指南（edgequake_webui）](#)
- [工作区与多租户（Workspaces & Multitenancy）](#)
- [PDF 转写工具（edgequake-pdf）](#)

---

<a id='page-edgequake_webui-src-lib'></a>

## Lib 模块

### 相关页面

相关主题：[项目概览](#page-overview), [Lib 模块](#page-sdks-ruby-lib)

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

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

- [edgequake_webui/src/lib/export-conversation.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/export-conversation.ts)
- [edgequake_webui/src/lib/graph/clustering.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/graph/clustering.ts)
- [edgequake_webui/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/README.md)
- [edgequake/crates/edgequake-core/src/types/entity.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/entity.rs)
- [edgequake/crates/edgequake-core/src/types/relationship.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/relationship.rs)
- [mcp/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/mcp/README.md)
</details>

# Lib 模块

## 概述

`edgequake_webui/src/lib/` 是 EdgeQuake WebUI 中专门承载业务工具、图算法封装与数据转换逻辑的纯函数层。它位于 React 组件（`app/`、`components/`）与后端 API 客户端（`api/`）之间，负责把后端返回的原始实体、关系、消息流转换为前端可直接消费的结构（如 Markdown 文档、可视化节点、社区配色等）。该目录文件以 TypeScript 实现，遵循"无副作用、可独立测试"的设计原则（参见模块顶部的 JSDoc 中 `@module` / `@implements` / `@enforces` 标注）。 资料来源：[edgequake_webui/README.md]()、[edgequake_webui/src/lib/export-conversation.ts:1-15]()

## 核心子模块

### 对话导出工具 (`export-conversation.ts`)

`export-conversation.ts` 实现 `FEAT0727`（导出 Markdown）与 `FEAT0728`（导出 JSON），并通过 `BR0724`、`BR0725` 强制约束元数据完整性与文件名安全。其内部 `formatMessageMarkdown` 会按角色（`user` / `assistant`）渲染标题并附带时间戳；若消息携带 `context.sources`，会折叠成 `<details>` 块，把每条 source 的标题、得分（保留两位小数）和前 200 字符内容一并输出，供离线审阅与归档使用。 资料来源：[edgequake_webui/src/lib/export-conversation.ts:24-60]()

该模块依赖 `ConversationWithMessages` 与 `ServerMessage` 类型契约，这些类型决定了导出函数可处理的最小字段集合；任何对消息结构的后端改动（如新增工具调用轨迹）都需要同步更新此处的渲染分支。

### 图聚类分析 (`graph/clustering.ts`)

`graph/clustering.ts` 封装 Louvain 社区发现算法，用于在知识图谱可视化中为不同社区分配稳定的配色。模块首先通过 `graphology-communities-louvain` 对 `Graphology` 实例 `forEachNode` 遍历，得到 `node -> communityId` 的映射后聚合为 `Community[]`，并附带全局 `modularity` 指标。 资料来源：[edgequake_webui/src/lib/graph/clustering.ts:48-90]()

颜色取自固定调色板 `COMMUNITY_COLORS`，由 `BR0713` 约束"最多 20 种社区颜色，超出循环复用"；孤立节点依据 `BR0714` 回退到默认色。`ClusteringResult` 同时返回 `nodeToCommuntiy`（注意源码中的拼写）与 `communities` 列表，便于上层组件既可按节点直接查色，又可整体渲染图例。

```mermaid
flowchart LR
  A[Graphology Graph] --> B[louvain]
  B --> C[nodeToCommuntiy Map]
  C --> D[Community List + Modularity]
  D --> E[Sigma.js Node Coloring]
  E --> F[Knowledge Graph UI]
```

## 架构与模块依赖

`lib/` 处于 WebUI 分层架构的中间层：上层组件（`components/`、`app/`）调用其导出函数，下层 `api/` 通过 `edgequake.ts`、`client.ts`、`chat.ts`、`conversations.ts`、`auth.ts`、`cost.ts` 等模块对接后端 `/api/v1/*`。后端服务侧的领域模型（`Entity`、`Relationship` 等 Rust 结构体）则定义了实体归一化规则——例如实体名归一化与去重、关系 source_id 多源追加——这些规则最终通过 API 反映在前端 lib 的输入类型上。 资料来源：[edgequake/crates/edgequake-core/src/types/entity.rs:18-50](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/entity.rs)、[edgequake/crates/edgequake-core/src/types/relationship.rs:18-55](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/relationship.rs)、[mcp/README.md]()

## 常见使用模式与陷阱

- **空图短路**：`detectCommunities` 在 `graph.order === 0` 时直接返回空结果与 `modularity: 0`，调用方需避免对结果再做 `.map().filter()` 链式调用导致 `Cannot read properties of undefined`。 资料来源：[edgequake_webui/src/lib/graph/clustering.ts:55-65]()
- **拼写陷阱**：返回字段名为 `nodeToCommuntiy`（源码中"Community"误拼为"Communtiy"），升级 TypeScript SDK 或新增消费者时请保持一致，否则会触发类型错误。 资料来源：[edgequake_webui/src/lib/graph/clustering.ts:42-44]()
- **导出长内容截断**：Markdown 导出仅展示 source 内容前 200 字符，超长引用需通过 JSON 导出保留完整字段，这是 `BR0724` 与前端展示成本的折中设计。 资料来源：[edgequake_webui/src/lib/export-conversation.ts:36-48]()

## See Also

- [EdgeQuake WebUI README](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/README.md)
- [edgequake-core 类型定义](https://github.com/raphaelmansuy/edgequake/tree/main/edgequake/crates/edgequake-core/src/types)
- [MCP Server 使用说明](https://github.com/raphaelmansuy/edgequake/blob/main/mcp/README.md)

---

<a id='page-sdks-ruby-lib'></a>

## Lib 模块

### 相关页面

相关主题：[Lib 模块](#page-edgequake_webui-src-lib), [Src 模块](#page-edgequake-crates-edgequake-core-src)

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

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

- [edgequake_webui/src/lib/export-conversation.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/export-conversation.ts)
- [edgequake_webui/src/lib/graph/clustering.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/graph/clustering.ts)
- [edgequake_webui/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/README.md)
- [edgequake/crates/edgequake-core/src/types/entity.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/entity.rs)
- [edgequake/crates/edgequake-core/src/types/relationship.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/relationship.rs)
- [edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs)
- [edgequake/crates/edgequake-core/src/keyword_extractor.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/keyword_extractor.rs)
</details>

# Lib 模块

## 概述

`edgequake_webui/src/lib/` 是 EdgeQuake WebUI 前端工程中的**核心工具与领域逻辑库目录**，承担了跨多个 React 组件复用的纯函数、类型定义、领域服务封装以及第三方 SDK 适配职责。它与 `src/components/`（UI 组件层）和 `src/app/`（Next.js 路由层）共同构成 WebUI 的三层架构：UI 组件层负责渲染，路由层负责页面装配，而 `lib/` 层则沉淀了与具体框架无关、可独立测试的业务能力 资料来源：[edgequake_webui/README.md]()

社区关注的两类典型需求——**会话数据导出** 与**知识图谱可视化分析**——其底层实现均位于此目录。具体而言：

- **会话导出** 由 `src/lib/export-conversation.ts` 提供，对应需求 FEAT0727/FEAT0728（导出为 Markdown / JSON）资料来源：[edgequake_webui/src/lib/export-conversation.ts]()
- **图谱社区检测** 由 `src/lib/graph/clustering.ts` 提供，对应需求 FEAT0716/FEAT0717（Louvain 社区发现与节点着色）资料来源：[edgequake_webui/src/lib/graph/clustering.ts]()

## 目录结构与职责划分

`lib/` 目录采用**领域子目录 + 顶层模块** 的扁平化组织方式，便于在大型前端项目中保持良好的可发现性。基于现有源码文件可识别出以下子领域：

```
src/lib/
├── export-conversation.ts   # 会话导出（Markdown / JSON）
└── graph/
    └── clustering.ts        # 图谱社区检测与着色
```

| 文件路径 | 领域 | 主要导出符号 | 关联需求 |
|---------|------|------------|---------|
| `export-conversation.ts` | 会话与消息 | `formatMessageMarkdown`、导出函数 | FEAT0727、FEAT0728 |
| `graph/clustering.ts` | 图可视化 | `detectCommunities`、`Community`、`ClusteringResult` | FEAT0716、FEAT0717 |

> 表中列出的需求编号来源于各文件头部的 `@implements` 注解，是 WebUI 工程内部的可追溯性约定。

## 核心模块详解

### 会话导出（`export-conversation.ts`）

该模块提供**将服务端消息结构序列化为 Markdown 与 JSON** 的纯函数工具，目标是让用户能在 WebUI 内一键保存完整对话上下文。模块入口对消息格式做了清晰的角色识别：`message.role === "user"` 渲染为 `**You**`，否则渲染为 `**Assistant**`，并在每条消息前附带本地化时间戳 资料来源：[edgequake_webui/src/lib/export-conversation.ts:18-30]()

导出 Markdown 时，若消息携带 `context.sources`（检索增强引用），会自动在消息体尾部追加一个 `<details>` 折叠块，列出每条来源的标题、相似度得分与前 200 字符的引用片段。这一行为由业务规则 BR0724（元数据必须随消息导出）和 BR0725（下载文件名需要消毒以避免非法字符）共同约束 资料来源：[edgequake_webui/src/lib/export-conversation.ts:5-12]()

类型层面，模块依赖 `@/types` 中的 `ConversationWithMessages` 与 `ServerMessage`，因此导出的结构与后端 API 响应保持强一致——这是 WebUI 与 Rust 后端（如 [`edgequake-core/src/types/entity.rs`]() 中定义的 `Entity` 类型）协同工作的基础。

### 图谱社区检测（`graph/clustering.ts`）

该模块封装了**对知识图谱进行 Louvain 社区发现并自动着色** 的完整流程。底层依赖 `graphology`（图数据结构）与 `graphology-communities-louvain`（社区发现算法）两个成熟的图分析库 资料来源：[edgequake_webui/src/lib/graph/clustering.ts:34-38]()

模块内部维护了一个 20 色的社区调色板（`COMMUNITY_COLORS`），业务规则 BR0713 规定当社区数量超过 20 时颜色循环复用，BR0714 则规定孤立节点统一使用默认颜色 资料来源：[edgequake_webui/src/lib/graph/clustering.ts:8-30]() `detectCommunities` 函数在图为空（`graph.order === 0`）时返回空结果，避免对空图执行 Louvain 算法抛出异常 资料来源：[edgequake_webui/src/lib/graph/clustering.ts:54-60]()

返回的 `ClusteringResult` 同时包含 `communities`（社区列表）、`nodeToCommuntiy`（节点→社区映射，注意源码拼写为 `Communtiy`）与 `modularity`（模块度评分），调用方可据此驱动 Sigma.js 渲染层的样式更新。

## 架构与依赖关系

```mermaid
flowchart LR
    UI[React 组件层<br/>components/] --> Lib[lib/ 工具与领域层]
    Lib --> Types[@/types<br/>共享类型]
    Lib --> Graph[graphology<br/>+ louvain]
    Lib --> API[EdgeQuake API<br/>Rust 后端]
    API --> Core[edgequake-core<br/>Entity / Relationship]
    Types --> Core
```

WebUI 通过 `lib/` 层将**后端数据模型**（如 [`edgequake-core/src/types/entity.rs`]() 中的 `Entity` 与 [`relationship.rs`]() 中的 `Relationship`）映射为前端友好的 TypeScript 类型，再交由组件层消费。这种分层使得后端的实体类型变更（如自定义实体配置需求 SPEC-085，见 [`multitenancy/requests.rs`]()）只需在 `@/types` 中调整一次即可全栈生效。

## 使用模式与失败模式

**典型调用流程**：

1. 组件通过 `@/lib/export-conversation` 引入导出函数，传入从 `useConversations` Hook 取到的 `ConversationWithMessages` 对象。
2. 组件通过 `@/lib/graph/clustering` 的 `detectCommunities(graph)` 得到社区结果，再将 `nodeToCommuntiy` 映射应用到 Sigma.js 节点样式。

**已知失败模式**：

- **空图输入**：`detectCommunities` 已对 `order === 0` 做了短路返回，调用方无需额外判空；但若传入 `undefined` 仍会触发 `graph.forEachNode` 的运行时异常。
- **导出文件名冲突**：BR0725 仅做字符消毒，不保证文件系统唯一性；同名文件在浏览器下载时会由浏览器自动追加 `(1)`、`(2)` 后缀。
- **类型漂移**：当后端新增字段（如社区关注的"#85: Allow custom entity configuration from the UI"需求 [#85]() 所涉及的 `entity_types` 字段，见 [`multitenancy/requests.rs`]()）时，前端 `ServerMessage` 类型必须同步更新，否则导出内容会缺失新字段。

## 参见

- [WebUI 总体架构](../README.md)
- [实体类型定义（Rust 后端）](../../edgequake/crates/edgequake-core/src/types/entity.rs)
- [关系类型定义（Rust 后端）](../../edgequake/crates/edgequake-core/src/types/relationship.rs)
- [工作区请求与自定义实体配置](../../edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs)
- [关键词提取提示词模板](../../edgequake/crates/edgequake-core/src/keyword_extractor.rs)
- 社区讨论：自定义实体配置 UI（[#85]()）、文档导入失败（[#25]()）

---

<a id='page-edgequake-crates-edgequake-core-src'></a>

## Src 模块

### 相关页面

相关主题：[Lib 模块](#page-sdks-ruby-lib)

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

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

- [edgequake/crates/edgequake-core/src/keyword_extractor.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/keyword_extractor.rs)
- [edgequake/crates/edgequake-core/src/types/entity.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/entity.rs)
- [edgequake/crates/edgequake-core/src/types/relationship.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/relationship.rs)
- [edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs)
- [edgequake_webui/src/lib/export-conversation.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/export-conversation.ts)
- [edgequake_webui/src/lib/graph/clustering.ts](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/src/lib/graph/clustering.ts)
- [mcp/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/mcp/README.md)
- [edgequake_webui/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/README.md)
- [sdks/typescript/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/sdks/typescript/README.md)
- [legacy/edgequake-pdf/README.md](https://github.com/raphaelmansuy/edgequake/blob/main/legacy/edgequake-pdf/README.md)
</details>

# Src 模块

## 概述

`Src` 模块特指 EdgeQuake 项目的核心源码目录——`edgequake/crates/edgequake-core/src/`，它是整个 RAG（图增强检索）引擎的领域模型与业务逻辑中枢。该模块以 Rust 编写，向下封装了 LLM 提示工程、实体/关系归一化、关键词抽取等核心算法，向上通过 HTTP API 暴露给 WebUI、SDK、MCP Server 等前端组件使用。

模块的设计目标是把"知识图谱构建流水线"沉淀到领域层：把"分块 → 抽取 → 归一 → 入图 → 检索"这一完整链路建模为可被多种客户端复用的纯 Rust 类型与函数。社区反馈中常见的文档上传错误 ([Issue #253](https://github.com/raphaelmansuy/edgequake/issues/253))、自定义实体类型 ([Issue #85](https://github.com/raphaelmansuy/edgequake/issues/85))、增量重建 ([Issue #252](https://github.com/raphaelmansuy/edgequake/issues/252)) 等诉求，都是围绕该模块暴露出的类型与流水线行为展开的。

```mermaid
flowchart LR
    UI[WebUI / SDK / MCP] --> API[HTTP API 层]
    API --> Core[edgequake-core/src]
    Core --> KW[keyword_extractor]
    Core --> Ent[types/entity]
    Core --> Rel[types/relationship]
    Core --> MT[types/multitenancy]
    KW --> LLM[(LLM Provider)]
    Ent --> Graph[(Graph Store)]
    Rel --> Graph
    MT --> Tenant[(Workspace/Tenant)]
```

## 核心子模块

### 关键词抽取（keyword_extractor）

`keyword_extractor.rs` 负责把用户查询拆解为高层关键词与底层关键词，供后续图谱检索的局部-全局混合召回使用。其核心是一个 LLM 提示模板：使用 few-shot 示例引导模型输出形如 `{"high_level_keywords":[...], "low_level_keywords":[...]}` 的 JSON 结构；模块对模型返回结果进行 JSON 抽取与容错解析，最终归一化为 `ExtractedKeywords` 类型 资料来源：[edgequake/crates/edgequake-core/src/keyword_extractor.rs:1-120]()。

这种"high/low"双层关键词设计是 EdgeQuake 在查询阶段同时支持"语义向量检索"与"图遍历"的关键——high-level 关键词驱动概念级社区发现，low-level 关键词驱动实体级精确匹配。WebUI 中"图谱 + 来源 + 引用"的检索结果展示即是该模块的下游产物 资料来源：[edgequake_webui/src/lib/export-conversation.ts:1-60]()。

### 类型系统（types）

类型系统是 `Src` 模块的"骨架"，由 `entity.rs`、`relationship.rs` 等文件共同构成：

- **Entity**：领域实体的不可变视图。`Entity::new` 会对 `entity_name` 调用 `normalize_name` 实现大小写无关的归一化；`entity_type` 在构造时被强制 `to_uppercase`；`source_id` 采用 `"id1|id2"` 的管道分隔格式承载多源追溯 资料来源：[edgequake/crates/edgequake-core/src/types/entity.rs:1-90]()。
- **Relationship**：连接两个实体的边。`Relationship::new` 同时对 `source_entity` 与 `target_entity` 做 `trim + to_uppercase` 归一化，并通过 `Self::generate_id` 派生出稳定的边 ID；`add_source` 同样使用管道分隔追加，避免重复来源 资料来源：[edgequake/crates/edgequake-core/src/types/relationship.rs:1-80]()。

归一化策略保证"Alice"与"alice"以及"ALICE"在图谱中指向同一个节点，从而显著降低 LLM 抽取结果中的实体碎片化问题。这一行为直接回应了社区中"重建图谱以派生新实体"（[Issue #252](https://github.com/raphaelmansuy/edgequake/issues/252)）的诉求：归一化越早做，后续增量派生越简单。

### 多租户与工作区（multitenancy/requests）

`types/multitenancy/requests.rs` 定义了创建工作区所需的入参类型 `CreateWorkspaceRequest`。其中关键字段 `entity_types: Option<Vec<String>>` 允许调用方在创建工作区时自定义实体类型集合（如 General、Manufacturing、Healthcare、Legal、Research 等预设），这是社区中"允许在 UI 创建工作区时自定义实体配置"（[Issue #85](https://github.com/raphaelmansuy/edgequake/issues/85)）功能的核心落点 资料来源：[edgequake/crates/edgequake-core/src/types/multitenancy/requests.rs:1-80]()。

模块同时提供 `entity_types_strict` 字段控制是否将未知类型强制重映射为 `OTHER/CONCEPT`，以及 `with_llm_model` 这类链式构造器用于设置工作区级 LLM 模型（如 `"gemma3:12b"` 或 `"ollama/gemma3:12b"`）。这些设计呼应了 [Issue #255](https://github.com/raphaelmansuy/edgequake/issues/255) 提出的"模型名已含斜杠时跳过自动前缀"需求——模型字符串由调用方显式提供，避免后端做多余改写。

## 与其他模块的协作

`Src` 模块不直接处理 HTTP 路由与渲染，而是作为"无状态领域核心"被各前端调用。`mcp/README.md` 中描述的 `document_upload_file` 等 MCP 工具，本质上把文件内容送入 `Src` 的抽取流水线；`sdks/typescript/README.md` 中列举的 `client.documents`、`client.entities` 等子模块则把 `Src` 的类型映射为 TypeScript 客户端 SDK 资料来源：[mcp/README.md:1-80]()、资料来源：[sdks/typescript/README.md:1-80]()。

`edgequake_webui/src/lib/graph/clustering.ts` 中的 Louvain 社区发现也消费 `Src` 导出的图数据：前端在拿到实体/关系后，使用 20 色调色板为社区着色，并将孤立节点 fallback 到默认色 资料来源：[edgequake_webui/src/lib/graph/clustering.ts:1-80]()。

## 常见失败模式与注意要点

1. **模型名称被双重前缀**：当 `EDGEQUAKE_LLM_PROVIDER=openai` 时若用户传入已含 `/` 的模型串（如 `openai/gpt-4o`），旧版本会再次拼接为 `openai/openai/gpt-4o`；在 `Src` 模块下游的 LLM provider 适配层应先做"含斜杠则跳过前缀"判断，参见 [Issue #255](https://github.com/raphaelmansuy/edgequake/issues/255)。
2. **上传同名文档**：上传已存在文档时 UI 会弹出"替换/取消"对话框；如选择替换但后端未真正写入，会触发 [Issue #253](https://github.com/raphaelmansuy/edgequake/issues/253) 描述的 popup 异常——这是 `Src` 模块的"upsert"语义与前端 state 未同步导致。
3. **重建整图的开销**：新增自定义实体后若触发整图重建（[Issue #252](https://github.com/raphaelmansuy/edgequake/issues/252)），耗时与代价来自 `entity.rs` 中 `add_source` 对 `source_id` 字符串的重复扫描；批量派生场景下应考虑改为 `HashSet<String>` 存储。

## 参见

- [快速上手与 Docker 部署（README）](https://github.com/raphaelmansuy/edgequake#readme)
- [WebUI 架构与组件](https://github.com/raphaelmansuy/edgequake/blob/main/edgequake_webui/README.md)
- [TypeScript SDK 模块清单](https://github.com/raphaelmansuy/edgequake/blob/main/sdks/typescript/README.md)
- [MCP Server 工具规范](https://github.com/raphaelmansuy/edgequake/blob/main/mcp/README.md)
- [EdgeQuake PDF 转换器](https://github.com/raphaelmansuy/edgequake/blob/main/legacy/edgequake-pdf/README.md)

---

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

---

## Doramagic 踩坑日志

项目：raphaelmansuy/edgequake

摘要：发现 14 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 依赖 Docker 环境。

## 1. 安装坑 · 依赖 Docker 环境

- 严重度：medium
- 证据强度：runtime_trace
- 发现：安装/运行入口包含 Docker 命令：docker run -d --name edgequake -p 8080:8080 -e DATABASE_URL="postgres://user:password@your-db-host:5432/edgequake" -e EDGEQUAKE_LLM_PROVIDER=openai -e OPENAI_API_KEY="sk-..." ghcr.io/raphaelmansuy/edgequake:latest # Verify curl http://localhost:8080/health
- 对用户的影响：非工程用户可能没有 Docker，启动成本明显增加。
- 复现命令：`docker run -d --name edgequake -p 8080:8080 -e DATABASE_URL="postgres://user:password@your-db-host:5432/edgequake" -e EDGEQUAKE_LLM_PROVIDER=openai -e OPENAI_API_KEY="sk-..." ghcr.io/raphaelmansuy/edgequake:latest # Verify curl http://localhost:8080/health`
- 证据：identity.distribution | https://github.com/raphaelmansuy/edgequake | docker run -d --name edgequake -p 8080:8080 -e DATABASE_URL="postgres://user:password@your-db-host:5432/edgequake" -e EDGEQUAKE_LLM_PROVIDER=openai -e OPENAI_API_KEY="sk-..." ghcr.io/raphaelmansuy/edgequake:latest # Verify curl http://localhost:8080/health

## 2. 安装坑 · 来源证据：Derive new entities without rebuilding entire graph and embeddings

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Derive new entities without rebuilding entire graph and embeddings
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/raphaelmansuy/edgequake/issues/252 | 来源类型 github_issue 暴露的待验证使用条件。

## 3. 安装坑 · 来源证据：feat: Skip provider prefixing in model names if model already contains a slash '/'

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：feat: Skip provider prefixing in model names if model already contains a slash '/'
- 对用户的影响：可能影响升级、迁移或版本选择。
- 证据：community_evidence:github | https://github.com/raphaelmansuy/edgequake/issues/255 | 来源类型 github_issue 暴露的待验证使用条件。

## 4. 安装坑 · 来源证据：models.toml is not overridable at runtime

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：models.toml is not overridable at runtime
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/raphaelmansuy/edgequake/issues/251 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 5. 配置坑 · 来源证据：Database Foreign Key Error When Querying Multiple Workspaces Causes Slow Performance

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Database Foreign Key Error When Querying Multiple Workspaces Causes Slow Performance
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/raphaelmansuy/edgequake/issues/259 | 来源类型 github_issue 暴露的待验证使用条件。

## 6. 配置坑 · 来源证据：UI Displays Incorrect Application Version Compared to API Version

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：UI Displays Incorrect Application Version Compared to API Version
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/raphaelmansuy/edgequake/issues/250 | 来源类型 github_issue 暴露的待验证使用条件。

## 7. 配置坑 · 来源证据：Upload document error

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Upload document error
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/raphaelmansuy/edgequake/issues/253 | 来源类型 github_issue 暴露的待验证使用条件。

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

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

## 9. 运行坑 · 运行可能依赖外部服务

- 严重度：medium
- 证据强度：source_linked
- 发现：项目说明出现 external service/cloud/webhook/database 等运行依赖关键词。
- 对用户的影响：本地安装成功不等于能力可用，外部服务不可用会阻断体验。
- 证据：packet_text.keyword_scan | https://github.com/raphaelmansuy/edgequake | matched external service / cloud / webhook / database keyword

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

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

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

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

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

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

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

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

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

<!-- canonical_name: raphaelmansuy/edgequake; human_manual_source: deepwiki_human_wiki -->
