# SuperMew 项目说明

> 本文件基于对 `SuperMew/` 目录的源码遍历整理，聚焦其技术栈、Embedding 方法及必需依赖，供 RAG / 向量化 / 知识库相关模块参考。

---

## 1. 项目主要工作

SuperMew 是一个以 **RAG（检索增强生成）** 为核心的智能对话系统，定位为可本地部署的“猫咪机器人”知识库问答平台。其主营业务流程包括：

1. **文档知识库**
   - 支持 PDF、Word（.doc/.docx）、Excel（.xlsx）、HTML 等格式文档上传。
   - 对文档进行三级滑动窗口分块（L1 / L2 / L3）。
   - 将叶子分块（L3）向量化写入 Milvus，父级分块（L1/L2）写入 PostgreSQL。
   - 重复上传同名文档时，先执行事务级清理（Milvus + PostgreSQL + Redis 缓存）。

2. **智能对话**
   - 基于 **LangChain Agent + LangGraph** 的流式对话。
   - Agent 可调用自定义工具，例如：
     - `search_knowledge_base`：检索知识库并回答。
     - `get_current_weather`：天气查询示例。
   - 简单问题直接检索；复杂问题由 LLM 分解为 2–4 个子问题，并行启动子 Agent 检索后合成答案。

3. **混合检索与精排**
   - 稠密向量（Dense）+ BM25 稀疏向量（Sparse）混合检索。
   - 使用 Milvus Hybrid Search + RRF 融合。
   - 对召回结果进行 Jina Rerank 精排，并支持 `rerank_score` 门控过滤。

4. **RAG 可观测性**
   - 在模型“思考”阶段，通过 SSE 实时推送 RAG 每一步状态（Searching / Grading / Rewriting / Auto-merging 等）。
   - 前端可展开查看检索来源、得分、合并层级、页码等详细信息。

5. **用户体系**
   - JWT 鉴权、RBAC 角色控制（admin / user）。
   - 会话历史持久化到 PostgreSQL，Redis 缓存热点会话与父文档。

---

## 2. 技术栈

### 2.1 后端

| 层级 | 技术 | 说明 |
|------|------|------|
| Web 框架 | **FastAPI** | API 层，提供 `/docs` 自动文档与 SSE 流式接口。 |
| ASGI 服务器 | **Uvicorn** | 运行 FastAPI 应用。 |
| LLM 框架 | **LangChain + LangGraph** | Agent、工具调用、RAG 工作流编排。 |
| LLM 接入 | **langchain-openai** | 兼容 OpenAI 协议的 API（如火山方舟等）。 |
| 向量嵌入 | **langchain-huggingface** | 本地 HuggingFace 嵌入模型。 |
| 向量数据库 | **Milvus 2.5+** | 稠密向量索引 + 原生 BM25 稀疏索引。 |
| 关系数据库 | **PostgreSQL 15** | 用户、会话、消息、父级分块存储。 |
| ORM | **SQLAlchemy 2.x** | 数据库模型与访问。 |
| 缓存 | **Redis 7** | 会话列表、消息、父文档缓存。 |
| 认证 | **python-jose + PBKDF2** | JWT HS256 + 密码哈希。 |
| 文档解析 | **PyPDF / docx2txt / unstructured / openpyxl / beautifulsoup4** | PDF、Word、Excel、HTML 解析。 |

### 2.2 前端

| 技术 | 说明 |
|------|------|
| **Vue 3** | 组合式 API + 单文件组件（SFC）。 |
| **TypeScript** | 类型安全。 |
| **Vite** | 构建工具与开发服务器。 |
| **Pinia** | 全局状态管理（auth / sessions / chat / documents）。 |
| **Axios / fetch** | HTTP 客户端；SSE 流式使用 `response.body.getReader()`。 |
| **Marked + Highlight.js** | Markdown 渲染与代码高亮。 |
| **FontAwesome + Sass** | 图标与样式。 |

### 2.3 基础设施（Docker Compose）

| 服务 | 镜像 | 端口 | 用途 |
|------|------|------|------|
| postgres | `postgres:15` | 5432 | 业务数据库 |
| redis | `redis:7-alpine` | 6379 | 缓存 |
| etcd | `quay.io/coreos/etcd:v3.5.18` | 2379 | Milvus 元数据 |
| minio | `minio/minio:RELEASE.2024-05-28T17-19-04Z` | 9000 / 9001 | Milvus 对象存储 |
| standalone | `milvusdb/milvus:v2.5.14` | 19530 / 9091 | Milvus 向量数据库 |
| attu | `zilliz/attu:v2.5.11` | 8080 | Milvus 可视化管理 |

---

## 3. Embedding 具体方法

### 3.1 稠密向量（Dense Embedding）

- **实现文件**：`SuperMew/backend/indexing/embedding.py`
- **使用库**：`langchain_huggingface.HuggingFaceEmbeddings`
- **默认模型**：`BAAI/bge-m3`
- **默认维度**：1024（通过环境变量 `DENSE_EMBEDDING_DIM` 配置，需与 Milvus 集合维度一致）
- **默认设备**：`cpu`（可通过 `EMBEDDING_DEVICE` 改为 `cuda`）
- **归一化**：启用 `normalize_embeddings=True`，配合 Milvus 的 `IP`（内积）距离度量。

```python
HuggingFaceEmbeddings(
    model_name=model_name,                 # 默认 BAAI/bge-m3
    model_kwargs={"device": device},       # 默认 cpu
    encode_kwargs={"normalize_embeddings": True},
)
```

### 3.2 稀疏向量 / BM25（Milvus 2.5+ 原生）

项目已迁移至 **Milvus 2.5+ 原生 BM25**，不再在客户端维护 `bm25_state.json`。

- **实现文件**：`SuperMew/backend/indexing/milvus_client.py`
- **核心做法**：
  1. Schema 中为 `text` 字段启用中文分析器：
     ```python
     schema.add_field(
         "text", DataType.VARCHAR, max_length=65535,
         enable_analyzer=True,
         analyzer_params={"type": "chinese"},
         enable_match=True,
     )
     ```
  2. 绑定 BM25 计算函数，由 Milvus 服务端自动根据 `text` 生成 `sparse_embedding`：
     ```python
     bm25_function = Function(
         name="text_bm25_emb",
         function_type=FunctionType.BM25,
         input_field_names=["text"],
         output_field_names=["sparse_embedding"],
     )
     schema.add_function(bm25_function)
     ```
  3. 为 `sparse_embedding` 建立 `SPARSE_INVERTED_INDEX`，度量类型为 `BM25`。

### 3.3 文档分块策略

- **实现文件**：`SuperMew/backend/indexing/document_loader.py`
- **策略**：三级层次化滑动窗口分块（L1 / L2 / L3）

| 层级 | 默认 chunk_size | 默认 chunk_overlap | 用途 |
|------|----------------|-------------------|------|
| L1 | 2400 | 300 | 粗粒度父块 |
| L2 | 1600 | 200 | 中粒度父块 |
| L3 | 800  | 100 | 叶子检索块 |

- **分隔符（针对中文优化）**：
  ```python
  separators=["\n\n", "。", "！", "？", "\n", "，", "、", " ", ""]
  ```
- **元数据**：每个 chunk 记录 `chunk_id`、`parent_chunk_id`、`root_chunk_id`、`chunk_level`、`page` 等。

### 3.4 存储策略

- **Leaf-only 向量化**：仅 L3 叶子块写入 Milvus（稠密向量 + 稀疏向量）。
- **父级分块**：L1 / L2 写入 PostgreSQL 的 `parent_chunks` 表，便于检索时 Auto-merging 向上聚合上下文。
- **文本清洗**：入库前通过 `sanitize_text()` 进行 Unicode NFC 规范化，并过滤零宽字符、BOM、控制字符、PUA 区字符及孤立 UTF-16 代理项。

### 3.5 检索流水线

- **实现文件**：`SuperMew/backend/rag/utils.py`
- **流程**：
  1. 查询生成稠密向量。
  2. `MilvusStore.hybrid_retrieve()` 同时发起 Dense（IP, `ef=64`）与 Sparse（BM25）两路 `AnnSearchRequest`。
  3. 使用 `RRFRanker(k=60)` 融合两路结果。
  4. **Auto-merging**：同一父块下命中子块数 ≥ `AUTO_MERGE_THRESHOLD`（默认 2）时，用父块替换子块（L3 → L2 → L1）。
  5. **Rerank**：调用 Jina Rerank API 精排，按 `RERANK_MIN_SCORE` 过滤，最终截断到 `top_k`。
- **降级策略**：Hybrid 失败时自动降级为纯 Dense 检索；完全失败返回空结果。

---

## 4. 必需依赖

### 4.1 Python 依赖（pyproject.toml）

项目要求 **Python >= 3.12**，推荐用 `uv` 管理。

```toml
[project]
dependencies = [
    "rich>=14.2.0",
    "fastapi>=0.115.0",
    "uvicorn>=0.30.0",
    "python-dotenv>=1.0.1",
    "requests>=2.32.0",
    "pymilvus>=2.5.0",
    "python-multipart>=0.0.9",
    "pydantic>=2.8.0",
    "langchain>=0.2.14",
    "langchain-core>=0.2.37",
    "langchain-community>=0.2.12",
    "langchain-text-splitters>=0.2.2",
    "langchain-huggingface>=0.1.0",
    "langchain-openai>=0.1.22",
    "sentence-transformers>=3.0.0",
    "langgraph>=0.2.31",
    "pypdf>=4.3.1",
    "docx2txt>=0.8",
    "unstructured",
    "openpyxl",
    "tabulate",
    "msoffcrypto-tool",
    "sqlalchemy>=2.0.36",
    "psycopg2-binary>=2.9.10",
    "redis>=5.2.1",
    "passlib[bcrypt]>=1.7.4",
    "python-jose[cryptography]>=3.3.0",
    "beautifulsoup4>=4.12.0",
]

[project.optional-dependencies]
study = [
    "langchain-classic>=0.2.0",
    "chromadb>=0.5.5",
    "bilibili-api-python>=17.0.0",
]
```

**核心依赖分组说明**：

- **Web / API**：`fastapi`、`uvicorn`、`python-multipart`、`pydantic`
- **LLM / RAG**：`langchain*`、`langgraph`、`langchain-openai`、`langchain-huggingface`
- **向量库**：`pymilvus`
- **Embedding**：`sentence-transformers`（`HuggingFaceEmbeddings` 底层需要）
- **文档解析**：`pypdf`、`docx2txt`、`unstructured`、`openpyxl`、`beautifulsoup4`
- **数据持久化**：`sqlalchemy`、`psycopg2-binary`、`redis`
- **认证安全**：`passlib[bcrypt]`、`python-jose[cryptography]`

### 4.2 前端依赖（frontend/package.json）

```json
{
  "dependencies": {
    "@fortawesome/fontawesome-free": "^6.4.0",
    "axios": "^1.6.0",
    "highlight.js": "^11.7.0",
    "marked": "^9.1.0",
    "pinia": "^2.1.0",
    "vue": "^3.3.0"
  },
  "devDependencies": {
    "@types/marked": "^4.3.0",
    "@types/node": "^20.0.0",
    "@vitejs/plugin-vue": "^4.2.0",
    "sass": "^1.63.0",
    "typescript": "^5.0.0",
    "vite": "^4.3.0",
    "vue-tsc": "^3.3.4"
  }
}
```

### 4.3 Docker 基础设施依赖

启动完整依赖环境需要安装 **Docker + Docker Compose**，然后执行：

```bash
docker compose up -d
```

涉及的容器服务：PostgreSQL、Redis、etcd、MinIO、Milvus standalone、Attu。

---

## 5. 关键环境变量

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `ARK_API_KEY` | - | LLM API Key |
| `MODEL` | - | 主模型名 |
| `FAST_MODEL` | `MODEL` | 快速模型（复杂度分类、子问题分解） |
| `GRADE_MODEL` | `gpt-4.1` | 文档评分模型 |
| `BASE_URL` | - | OpenAI 兼容 API 基地址 |
| `EMBEDDING_MODEL` | `BAAI/bge-m3` | 本地嵌入模型 |
| `EMBEDDING_DEVICE` | `cpu` | 嵌入设备（cpu / cuda） |
| `DENSE_EMBEDDING_DIM` | `1024` | 稠密向量维度 |
| `RERANK_MODEL` | - | Rerank 模型名 |
| `RERANK_BINDING_HOST` | - | Rerank API 地址 |
| `RERANK_API_KEY` | - | Rerank API Key |
| `MILVUS_HOST` | `127.0.0.1` | Milvus 地址 |
| `MILVUS_PORT` | `19530` | Milvus 端口 |
| `DATABASE_URL` | - | PostgreSQL 连接串 |
| `REDIS_URL` | `redis://127.0.0.1:6379/0` | Redis 连接 |
| `JWT_SECRET_KEY` | - | JWT 密钥 |
| `ADMIN_INVITE_CODE` | `supermew-admin-2026` | 管理员邀请码 |

---

## 6. 核心目录结构

```
SuperMew/
├── backend/
│   ├── app.py                    # FastAPI 入口
│   ├── api/                      # HTTP 路由
│   ├── chat/                     # 对话、Agent 运行时、SSE 推送、会话存储
│   ├── rag/                      # RAG 工作流（LangGraph）与检索工具
│   ├── indexing/                 # 文档加载、分块、Embedding、Milvus 写入
│   ├── tools/                    # Agent 可调用的工具
│   ├── infra/                    # 数据库、缓存、认证
│   ├── db/                       # SQLAlchemy ORM 模型
│   └── schemas/                  # Pydantic 模型
├── frontend/                     # Vite + Vue 3 + TypeScript 前端
├── docker-compose.yml            # 基础设施编排
├── pyproject.toml                # Python 依赖
└── README.md                     # 项目原 README
```

---

## 7. 总结

SuperMew 是一个工程化较完整的 RAG 参考项目，核心亮点包括：

- **本地 Embedding**：基于 `langchain-huggingface` 运行 `BAAI/bge-m3` 等本地模型生成稠密向量。
- **Milvus 2.5+ 原生 BM25**：利用服务端 `FunctionType.BM25` 自动生成稀疏向量，避免客户端维护 BM25 状态。
- **三级分块 + Auto-merging**：L1/L2/L3 层次化切分，仅 L3 入向量库，检索时自动向上合并。
- **Hybrid Search + RRF + Jina Rerank**：兼顾语义召回与词匹配，并提供精排序。
- **自适应复杂问题处理**：简单问题直发检索，复杂问题分解为子问题并行执行子 Agent。
- **实时可观测 SSE**：RAG 每一步实时推送到前端，解决“静默思考”问题。

如需复刻其 Embedding 与检索链路，重点关注 `backend/indexing/embedding.py`、`backend/indexing/milvus_client.py`、`backend/indexing/document_loader.py` 与 `backend/rag/utils.py` 四个文件。
