11b6171e21
替换原有的通用向量数据库入门内容,新增项目简介、核心概念、快速上手流程、CLI与HTTP API使用方法、配置说明、嵌入提供商选择、安全配置、架构概览、GPU加速、测试命令和常见问题等完整文档内容,适配作为项目的使用指南与测试手册。
244 lines
7.4 KiB
Markdown
244 lines
7.4 KiB
Markdown
# md-vector-db 测试指南
|
||
|
||
> 本文档既用于测试向量数据库的入库和检索功能,也作为新用户的上手指南。
|
||
|
||
## 项目简介
|
||
|
||
md-vector-db 是一个轻量级 Markdown 文档向量数据库——将 `.md` 文件自动分块、嵌入、存入 ChromaDB,通过语义检索快速查找相关内容。提供 **CLI 命令行工具**和 **HTTP API** 两种使用方式。
|
||
|
||
## 核心概念
|
||
|
||
### 向量嵌入
|
||
|
||
向量嵌入是将文本转换成固定长度的浮点数数组,使语义相近的文本在向量空间中距离更近。例如:
|
||
|
||
| 查询 | 匹配结果 | 相似度 |
|
||
|------|----------|--------|
|
||
| "如何配置 GPU" | GPU 加速配置说明 | 0.85 |
|
||
| "python 入门" | Python 基础知识 | 0.82 |
|
||
| "数据库安装" | 安装与配置指南 | 0.79 |
|
||
|
||
### 文档分块
|
||
|
||
长文档不能直接嵌入——模型有最大输入长度限制,且大段文本会稀释语义。md-vector-db 使用**混合分块策略**:
|
||
|
||
1. **按标题拆分**:先在 `#`/`##`/`###` 标题边界切分
|
||
2. **按段落拆分**:章节超过 1000 字符时,在段落边界(双换行)继续切
|
||
3. **硬切兜底**:单个段落仍超限时,按标点符号硬切,同时保留 100 字符重叠
|
||
|
||
### ChromaDB Collection
|
||
|
||
Collection 是 ChromaDB 的数据容器,类似关系数据库的"表"。不同知识库存入不同 collection 实现数据隔离:
|
||
|
||
```bash
|
||
uv run md-vector-db ingest docs/readme.md -C project_a # 项目 A 的知识库
|
||
uv run md-vector-db ingest docs/readme.md -C project_b # 项目 B 的知识库
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
### 1. 安装与配置
|
||
|
||
```bash
|
||
git clone git@lhy-git.liuhangyv.top:Serendipity/md-vector-db.git
|
||
cd md-vector-db
|
||
uv sync
|
||
cp .env.example .env
|
||
```
|
||
|
||
配置文件 `config.yaml` 控制嵌入模式、分块参数和服务端口:
|
||
|
||
```yaml
|
||
embed:
|
||
mode: local # 本地模型(默认, 无需 API Key)
|
||
local_model: BAAI/bge-small-zh-v1.5 # 中文优化, 512 维
|
||
|
||
chunk:
|
||
max_size: 1000 # 分块最大字符数
|
||
overlap: 100 # 相邻块重叠字符数
|
||
|
||
server:
|
||
host: 127.0.0.1
|
||
port: 8000
|
||
```
|
||
|
||
### 2. 入库文档
|
||
|
||
```bash
|
||
# 单文件入库(本篇测试指南)
|
||
uv run md-vector-db ingest md_docs/test-guide.md
|
||
|
||
# 目录批量入库
|
||
uv run md-vector-db ingest-dir ./md_docs/
|
||
|
||
# 指定 collection
|
||
uv run md-vector-db ingest md_docs/test-guide.md -C test_kb
|
||
|
||
# 通过管道直接入库内容
|
||
echo "# 测试文档\n这是一段测试内容。" | uv run md-vector-db ingest - --name pipe-test.md
|
||
```
|
||
|
||
### 3. 语义搜索
|
||
|
||
```bash
|
||
# 基础搜索
|
||
uv run md-vector-db search "如何配置向量数据库" -k 5
|
||
|
||
# 指定 collection
|
||
uv run md-vector-db search "GPU 加速" -k 3 -C test_kb
|
||
|
||
# JSON 输出(供 MCP 等工具消费)
|
||
uv run md-vector-db search "分块策略" -k 3 --json
|
||
```
|
||
|
||
输出示例:
|
||
|
||
```
|
||
--- 结果 1 (相似度: 0.8231) ---
|
||
来源: test-guide.md
|
||
章节: 文档分块
|
||
## 文档分块
|
||
长文档不能直接嵌入——模型有最大输入长度限制...
|
||
|
||
--- 结果 2 (相似度: 0.6104) ---
|
||
来源: readme.md
|
||
章节: 快速开始
|
||
...
|
||
```
|
||
|
||
### 4. 启动 HTTP 服务
|
||
|
||
```bash
|
||
uv run md-vector-db serve --port 8000
|
||
```
|
||
|
||
浏览器打开 `http://localhost:8000/docs` 查看 Swagger UI。
|
||
|
||
API 调用示例:
|
||
|
||
```bash
|
||
# 入库
|
||
curl -X POST http://localhost:8000/api/v1/ingest \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"content": "# 测试\n这是测试文档。", "file_name": "api-test.md"}'
|
||
|
||
# 搜索
|
||
curl -X POST http://localhost:8000/api/v1/search \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"query": "测试文档", "top_k": 3}'
|
||
|
||
# 查看集合
|
||
curl http://localhost:8000/api/v1/collections
|
||
|
||
# 健康检查
|
||
curl http://localhost:8000/api/v1/health
|
||
|
||
# 删除文档
|
||
curl -X DELETE http://localhost:8000/api/v1/documents/api-test.md
|
||
```
|
||
|
||
### 5. 查看统计
|
||
|
||
```bash
|
||
uv run md-vector-db stats
|
||
uv run md-vector-db stats -C test_kb --json
|
||
```
|
||
|
||
## 嵌入 Provider 选择
|
||
|
||
| Provider | 类型 | 默认模型 | 向量维度 | 适用场景 |
|
||
|----------|------|----------|----------|----------|
|
||
| `local` | 本地 GPU/CPU | BAAI/bge-small-zh-v1.5 | 512 | 离线、免费、低延迟 |
|
||
| `openai` | OpenAI 兼容 API | text-embedding-3-small | 1536 | 高质量、多语言 |
|
||
| `dashscope` | 阿里云 DashScope | text-embedding-v4 | 1536 | 国内部署、中文优化 |
|
||
|
||
切换 Provider 只需修改 `config.yaml`:
|
||
|
||
```yaml
|
||
embed:
|
||
mode: api
|
||
provider: openai
|
||
api_base: https://api.siliconflow.cn/v1 # 硅基流动等 OpenAI 兼容服务
|
||
model: BAAI/bge-large-zh-v1.5
|
||
```
|
||
|
||
然后在 `.env` 中设置 `EMBED_API_KEY=sk-xxx`。
|
||
|
||
## 安全配置
|
||
|
||
### API Key 认证
|
||
|
||
在 `.env` 中设置 `MD_VECTOR_API_KEY=your-secret-key`,所有写操作(入库/删除)和搜索都需要在请求头中携带:
|
||
|
||
```bash
|
||
curl -H "x-api-key: your-secret-key" http://localhost:8000/api/v1/search ...
|
||
```
|
||
|
||
不设置则跳过认证(适合本地开发)。
|
||
|
||
### 速率限制
|
||
|
||
默认每个 IP 每 60 秒最多 30 个请求,可在 `auth.py` 中调整。
|
||
|
||
### 路径遍历防护
|
||
|
||
所有文件操作入口(CLI / API / 脚本)统一通过 `is_safe_path()` 拒绝绝对路径和 `..` 目录穿越。
|
||
|
||
## 架构概览
|
||
|
||
```
|
||
src/
|
||
├── core/ # 核心逻辑(零框架依赖)
|
||
│ ├── config.py # YAML + .env → dataclass 配置
|
||
│ ├── db.py # ChromaDB 线程安全封装
|
||
│ ├── embedder.py # 策略模式:Local / OpenAI / DashScope
|
||
│ ├── ingest.py # MarkdownSplitter + DocumentIngestor
|
||
│ ├── search.py # Searcher 语义检索
|
||
│ └── security.py # is_safe_path 路径遍历防护
|
||
├── server/ # FastAPI HTTP 层
|
||
│ ├── app.py # 路由 + CORS + 安全头中间件
|
||
│ ├── auth.py # API Key 认证 + 速率限制
|
||
│ └── deps.py # AppState 依赖注入
|
||
└── cli/
|
||
└── main.py # Typer CLI(5 个命令)
|
||
```
|
||
|
||
**数据流**:MD 文件 → `MarkdownSplitter.split()` → `batch_embed()` → `ChromaDB collection.add()` → `Searcher.search()`
|
||
|
||
**依赖方向**:`config ← db ← embedder ← ingest/search ← server/cli`
|
||
|
||
## GPU 加速
|
||
|
||
本地嵌入模式自动检测 CUDA 设备。实测性能(RTX 4060 Laptop, bge-small-zh-v1.5):
|
||
|
||
| 文件大小 | chunks | CPU | GPU |
|
||
|----------|--------|-----|-----|
|
||
| 60 KB | 320 | 数分钟 | 0.7s |
|
||
| 96 KB | 729 | 卡死 | 1.8s |
|
||
|
||
如果 GPU 不可用,自动回退 CPU。
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
uv run pytest tests/ -v # 全部测试 (70 个)
|
||
uv run pytest tests/test_security.py -v # 安全模块测试
|
||
uv run pytest tests/test_deps.py -v # 依赖注入测试
|
||
uv run pytest tests/ -v -k "search" # 按名称过滤
|
||
uv run pytest tests/ --cov=src --cov-report=term-missing # 覆盖率
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
**Q: `uv sync` 失败,提示找不到 torch?**
|
||
A: 项目配置了从本地 wheel 目录获取 CUDA 版 torch。Linux/Mac 用户可移除 `pyproject.toml` 中的 `[tool.uv]` 配置段后重试。
|
||
|
||
**Q: 第一次运行下载模型很慢?**
|
||
A: 国内用户自动使用 `hf-mirror.com` 镜像。也可设置 `HF_MIRROR` 环境变量指定其他镜像。
|
||
|
||
**Q: 如何清空 collection 重新入库?**
|
||
A: 使用 `delete_document` API 逐个删除,或直接删除 `data/` 目录后重启服务。
|
||
|
||
**Q: 支持非 Markdown 文件吗?**
|
||
A: 当前仅支持 `.md`。通过实现 `Splitter` 接口(Protocol)可扩展支持 PDF、HTML 等格式。
|