Skip to main content
Glama
README.md
# xilinx-rag

AI 驱动的 Xilinx/AMD FPGA 文档检索 MCP 服务器。混合检索 **SQLite FTS5 关键词** + **ChromaDB 向量嵌入** + **RRF 融合**,为 AI 编程助手(如 Kimi Code)提供 FPGA 数据手册、用户指南、应用笔记和 IP 文档的按需搜索。

## 功能

- **双路混合检索** — FTS5 全文索引(精确关键词匹配)+ BGE 向量嵌入(中文语义匹配),RRF 融合排序
- **7 个 MCP 工具** — `search_docs`、`reindex_docs`、`get_doc_stats`、`list_doc_families`、`fetch_and_index`、`fetch_pdf`、`import_url_list`
- **系列/类型过滤** — 按 `family`(7_Series、Versal_Device…)和 `doc_type`(PG、UG、DS、XAPP…)精确筛选
- **网页抓取** — `fetch_and_index` 抓取 URL 解析入索引,`fetch_pdf` 用 Headless Chromium 渲染 JS 页面并导出 PDF
- **自动分类** — 下载的文档根据标题/URL 关键词自动归入 25+ FPGA 系列目录
- **优雅降级** — 嵌入模型不可用时自动回退纯 FTS5 模式;markitdown 不可用时回退 pypdf2
- **增量索引** — 文件哈希追踪,`reindex_docs` 只处理变更文件

## 快速开始

### 安装

```bash
git clone <repo-url>
cd doc_search_mcp
pip install -e .
```

### 下载嵌入模型(可选)

向量搜索需要模型 `BAAI/bge-small-zh-v1.5`(约 100 MB)。国内用户建议用镜像:

```bash
# 方式一:环境变量自动镜像(推荐)
set HF_ENDPOINT=https://hf-mirror.com        # Windows CMD
$env:HF_ENDPOINT = "https://hf-mirror.com"   # PowerShell

# 方式二:huggingface-cli
huggingface-cli download BAAI/bge-small-zh-v1.5

# 方式三:git clone 模型仓库
git clone https://hf-mirror.com/BAAI/bge-small-zh-v1.5
# 放入 ~/.cache/huggingface/hub/models--BAAI--bge-small-zh-v1.5/snapshots/
```

若无法联网下载模型,系统自动降级为纯 FTS5 关键词搜索模式,搜索功能不受影响。

### 准备文档库

将 Xilinx 文档(PDF)按系列放到子目录:

```
XilinxDocs/
├── 7_Series/           # Artix-7, Kintex-7, Virtex-7
├── UltraScale/         # Kintex/Virtex UltraScale
├── Versal_Device/      # Versal ACAP
├── Zynq_7000/
├── Zynq_UltraScale+_MPSoC/
├── Vivado/
├── Vitis_Products/
├── IP/                 # LogiCORE IP Product Guides
├── ISE/
└── ...
```

目录名即为文档系列(family),文件名中的 `pg195`、`ug901` 等自动提取为 `doc_type`/`doc_id`。

### 构建索引

```bash
# 指定文档库并构建(首次约 50 分钟,处理 3000+ PDF)
xilinx-rag index --docs-root H:\Users\admin\Documents\XilinxDocs

# docs-root 会自动保存到 ~/.xilinx-rag/config.json,后续只需:
xilinx-rag index
```

首次运行会:
1. 解析所有 PDF(pypdf2),滑动窗口分块(500 字符/250 重叠)
2. 写入 SQLite corpus.db(~1.1 GB),建 FTS5 全文索引(~29 秒)
3. 生成向量嵌入写入 ChromaDB(~10 GB,含模型时约 5 小时)

### 查看状态

```bash
xilinx-rag stats
# 输出: {"total_chunks": 1648364, "index_status": "ready", "chroma_size_mb": 10377.7}
```

### 启动 MCP 服务器

```bash
xilinx-rag serve
```

在 MCP 客户端(如 Kimi Code `config.toml`)中配置为子进程启动即可。

## MCP 工具

### `search_docs` — 混合检索

```python
search_docs(query="PCIe XDMA", top_k=5, family="IP", doc_type="PG")
```

返回 FTS5 + 向量 + RRF 融合排序结果,包含文本片段、源文件、页码、系列、文档类型、BM25/向量/融合分数。

### `reindex_docs` — 重建索引

```python
reindex_docs(force=True)   # force=True 全量重建,默认增量更新
```

### `get_doc_stats` — 索引统计

```python
get_doc_stats()
# → total_chunks, index_status, chroma_size_mb
```

### `list_doc_families` — 列出系列

```python
list_doc_families()
# → 所有 family 目录及文件数
```

### `fetch_and_index` — 抓取网页

```python
fetch_and_index(url="https://docs.xilinx.com/...", family="Vivado", save_html=True)
```

### `fetch_pdf` — 导出 PDF

```python
fetch_pdf(url="https://docs.xilinx.com/...", family="Versal_Device")
```

用 Playwright + Edge 渲染 JS 页面,自动探测 AMD 文档门户的 Fluid Topics PDF 附件。

### `import_url_list` — 批量导入

```python
import_url_list(file_path="urls.txt", family="IP")
```

## 配置

核心参数在 `src/xilinx_rag/config.py`:

| 参数 | 默认值 | 说明 |
|------|--------|------|
| `DATA_DIR` | `~/.xilinx-rag/` | 索引/缓存目录 |
| `CHROMA_PATH` | `~/.xilinx-rag/chroma_db` | ChromaDB 持久化存储 |
| `CHUNK_SIZE` | 500 | 分块大小(字符) |
| `CHUNK_OVERLAP` | 250 | 分块重叠量 |
| `EMBED_MODEL` | `BAAI/bge-small-zh-v1.5` | 向量嵌入模型(512 维) |
| `TOP_K_BM25` | 20 | FTS5 候选数 |
| `TOP_K_VECTOR` | 20 | 向量候选数 |
| `RRF_K` | 60 | RRF 融合平滑常数 |

文档根目录优先级:CLI `--docs-root` > 环境变量 `XILINX_DOCS_ROOT` > `~/.xilinx-rag/config.json`

### 环境变量

| 变量 | 说明 |
|------|------|
| `XILINX_DOCS_ROOT` | 文档库根路径 |
| `HF_ENDPOINT` | HuggingFace 镜像地址(国内设 `https://hf-mirror.com`) |

## 架构

```
PDF / HTML 文件          Curl / Playwright(网页)
       │                        │
       ▼                        ▼
   parser.py              search_tools.py
   (pypdf2 解析)         (抓取+解析)
       │                        │
       ▼                        ▼
   ParsedChunk ────────► HybridRetriever.add_chunks()
                              │
               ┌──────────────┴──────────────┐
               ▼                              ▼
         SQLite FTS5                    ChromaDB
         (关键词索引)                  (向量嵌入)
               │                              │
               ▼                              ▼
       ┌─────────────────────────────────────────┐
       │  search() → RRF 融合                    │
       │  (FTS5 BM25 ∩ 向量余弦距离)            │
       └─────────────────────────────────────────┘
                              │
                              ▼
                      MCP 工具返回结果
```

## 存储

| 路径 | 大小(3000+ PDF) | 说明 |
|------|-------------------|------|
| `~/.xilinx-rag/corpus.db` | ~1.1 GB | SQLite — 文本语料 + FTS5 全文索引 |
| `~/.xilinx-rag/chroma_db/` | ~10.4 GB | ChromaDB — 向量嵌入(可选) |
| `~/.xilinx-rag/file_hashes.json` | ~500 KB | 已索引文件 SHA-256 |
| `~/.xilinx-rag/config.json` | ~100 B | 用户配置 |

## 技术栈

| 组件 | 库 | 用途 |
|------|-----|------|
| MCP 框架 | `mcp >= 1.0.0`(FastMCP) | MCP 服务器生命周期 |
| 关键词搜索 | SQLite FTS5(内建) | 全文检索 + BM25 排序 |
| 向量存储 | `chromadb >= 0.5` | 持久化向量嵌入 |
| 嵌入模型 | `sentence-transformers >= 3.0` | BAAI/bge-small-zh-v1.5(512 维) |
| PDF 解析 | `pypdf2 >= 3.0` | PDF 文本提取 |
| HTML 解析 | `beautifulsoup4 >= 4.12`、`lxml >= 5.0` | 网页内容提取 |
| 浏览器 | `playwright >= 1.40` | JS 渲染 + PDF 导出 |
| 构建 | `hatchling` | PEP 621 wheel 构建 |

## 搜索性能

| 指标 | 值 |
|------|-----|
| 首次搜索(含模型加载) | ~28 秒 |
| 后续搜索(模型已驻内存) | <500 ms |
| FTS5 索引重建 | ~29 秒 |
| 向量嵌入重建(3000+ PDF) | ~5 小时(CPU) |
| 索引存储总量 | ~12 GB |

## 许可证

未指定。

Maintenance

ActivitySlowing
ResponsivenessNo issues