Files
md-vector-db/docs/superpowers/specs/2026-07-05-md-vector-db-design.md
T

7.5 KiB

md-vector-db 设计文档

日期: 2026-07-05 作者: 刘航宇 状态: 已确认

1. 项目概述

构建一个 Markdown 文档向量数据库,支持文档入库、嵌入、检索,并通过 HTTP API 供其他项目调用。

核心目标

  • 支持 ~1000 篇 Markdown 文档的存储与检索
  • 混合嵌入方案:默认本地模型,可切换到 API
  • HTTP API 对外暴露检索能力
  • CLI 命令行管理工具

2. 技术栈

选型 理由
语言 Python 3.13 向量库生态最成熟
向量库 ChromaDB 嵌入式运行,也支持 HTTP 服务模式
嵌入模型 BAAI/bge-small-zh-v1.5(本地默认) 中文优化,仅 100MB
嵌入 API OpenAI 兼容协议 可切到 DashScope/硅基流动/OpenAI
HTTP 框架 FastAPI + uvicorn 轻量高性能
包管理 uv 用户标准工具链

3. 目录结构

md-vector-db/
├── pyproject.toml
├── config.yaml                  # 用户配置文件
├── src/
│   ├── core/
│   │   ├── __init__.py
│   │   ├── db.py                # ChromaDB 初始化与配置
│   │   ├── embedder.py          # 嵌入模型抽象(本地/API)
│   │   ├── ingest.py            # Markdown 解析→分块→入库
│   │   └── search.py            # 检索接口
│   ├── server/
│   │   ├── __init__.py
│   │   └── app.py               # FastAPI 路由
│   └── cli/
│       ├── __init__.py
│       └── main.py              # 命令行入口
├── data/                        # ChromaDB 持久化目录
├── md_docs/                     # 待入库的 Markdown 源文件
├── scripts/
│   └── serve.py                 # 启动 HTTP 服务
└── tests/
    ├── test_embedder.py
    ├── test_ingest.py
    ├── test_search.py
    └── test_api.py

4. 核心模块设计

4.1 embedder.py — 嵌入层

class Embedder:
    def __init__(self, config: EmbedConfig):
        if config.mode == "local":
            self.model = SentenceTransformer(config.local_model)
        elif config.mode == "api":
            self.client = OpenAI(base_url=config.api_base, api_key=config.api_key)

    def embed(self, texts: list[str]) -> list[list[float]]:
        """返回嵌入向量列表"""

    @property
    def dimension(self) -> int:
        """返回向量维度"""
  • local 模式:首次运行自动下载 BAAI/bge-small-zh-v1.5
  • api 模式:兼容 OpenAI/DashScope/硅基流动(OpenAI 协议)
  • 切换方式:修改 config.yaml 中的 embed.mode

4.2 ingest.py — 文档入库

分块策略(混合切分):

  1. 按 Markdown 标题(#/##/###)拆分章节
  2. 若章节超过 1000 字符,按段落边界(\n\n)继续拆分
  3. 每个 chunk 保留元数据:source_file, section_title, heading_level, chunk_index

入库流程:

Markdown 文件 → 读取 → 提取标题结构 → 分块
→ 逐块 embed → ChromaDB collection.add()

去重: 同一文件重复入库时,先删除旧 chunks 再重新插入(以 source_file 为键)。

4.3 search.py — 检索

def search(query: str, top_k: int = 10, filters: dict | None = None) -> list[SearchResult]:
    """
    - query 嵌入 → ChromaDB 相似度搜索
    - 支持按 source_file、heading_level 过滤
    - 返回: [(content, source_file, section_title, score), ...]
    """

4.4 db.py — 数据库层

class VectorDB:
    def __init__(self, persist_dir: str = "./data"):
        self.client = chromadb.PersistentClient(path=persist_dir)

    def get_or_create_collection(self, name: str) -> Collection:
        ...
  • ChromaDB 数据持久化到 data/ 目录
  • 默认 collection 名称:markdown_docs

5. HTTP API

端点设计

方法 路径 说明
POST /api/v1/ingest 入库 Markdown(传文件路径或原始内容)
POST /api/v1/search 语义检索
GET /api/v1/collections 列出所有文档集合
DELETE /api/v1/documents/{file_name} 删除指定文件的文档
GET /api/v1/health 健康检查

请求/响应示例

入库:

POST /api/v1/ingest
{
  "file_path": "D:/docs/my-note.md"
}
// 或
{
  "content": "# 标题\n正文内容...",
  "file_name": "my-note.md"
}
 { "status": "ok", "chunks": 12, "file": "my-note.md" }

检索:

POST /api/v1/search
{
  "query": "如何配置向量数据库",
  "top_k": 10
}
 {
    "results": [
      {
        "content": "...匹配片段...",
        "source_file": "setup-guide.md",
        "section_title": "向量数据库配置",
        "heading_level": 2,
        "score": 0.923
      }
    ]
  }

启动方式

# 嵌入式模式(直接调用 core 模块)
python -c "from src.core.search import search; print(search('关键词'))"

# HTTP 服务模式(供其他项目调用)
uv run scripts/serve.py --port 8000

6. CLI 工具

# 入库单个文件
uv run src/cli/main.py ingest path/to/file.md

# 入库整个目录
uv run src/cli/main.py ingest-dir ./md_docs/

# 命令行搜索
uv run src/cli/main.py search "关键词" --top-k 10

# 启动服务
uv run src/cli/main.py serve --port 8000

# 查看统计
uv run src/cli/main.py stats

7. 配置设计

# config.yaml
chroma:
  persist_dir: ./data
  collection_name: markdown_docs

embed:
  mode: local           # local | api
  local_model: BAAI/bge-small-zh-v1.5
  api_base: ""          # api 模式下填写
  api_key: ""           # api 模式下填写

chunk:
  max_size: 1000        # 分块最大字符数
  overlap: 100          # 相邻块重叠字符数

server:
  host: 0.0.0.0
  port: 8000

8. 依赖

[project]
name = "md-vector-db"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
    "chromadb>=0.5.0",
    "sentence-transformers>=3.0.0",
    "fastapi>=0.115.0",
    "uvicorn[standard]>=0.30.0",
    "pyyaml>=6.0",
    "markdown-it-py>=3.0.0",
    "typer>=0.12.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0",
    "httpx>=0.27.0",
]

9. 测试计划

测试 覆盖
test_embedder.py 本地/API 模式嵌入,维度验证
test_ingest.py Markdown 解析、分块、入库、去重
test_search.py 检索、元数据过滤
test_api.py FastAPI 端点集成测试

目标覆盖率:80%+

10. 自检清单

  • 无 TBD/TODO 占位符
  • 模块间接口定义清晰(core/server/cli 分层)
  • 功能范围明确(入库、检索、CLI、HTTP API)
  • 无内部矛盾(本地模型+API 双模、嵌入+服务双模)
  • 已确定分块策略(混合切分:标题+段落)