super-mew-reference.md 12 KB

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(内积)距离度量。

    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 字段启用中文分析器:

      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

      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 叶子检索块
  • 分隔符(针对中文优化)

    separators=["\n\n", "。", "!", "?", "\n", ",", "、", " ", ""]
    
  • 元数据:每个 chunk 记录 chunk_idparent_chunk_idroot_chunk_idchunk_levelpage 等。

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 管理。

[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 / APIfastapiuvicornpython-multipartpydantic
  • LLM / RAGlangchain*langgraphlangchain-openailangchain-huggingface
  • 向量库pymilvus
  • Embeddingsentence-transformersHuggingFaceEmbeddings 底层需要)
  • 文档解析pypdfdocx2txtunstructuredopenpyxlbeautifulsoup4
  • 数据持久化sqlalchemypsycopg2-binaryredis
  • 认证安全passlib[bcrypt]python-jose[cryptography]

4.2 前端依赖(frontend/package.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,然后执行:

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.pybackend/indexing/milvus_client.pybackend/indexing/document_loader.pybackend/rag/utils.py 四个文件。