diff --git a/README.md b/README.md index c1bd540..b4bbc08 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 基于 RAG 的 JasperReports JRXML 模板 + Markdown 文档智能检索系统,作为构建 JRXML 自定义 Agent 的前置工作。 -支持 JRXML 模板和 Markdown 文档的语义分块、向量化、Chroma 持久化存储,以及自然语言查询。 +支持 JRXML 模板和 Markdown 文档的语义分块、向量化、Chroma 持久化存储,以及自然语言查询。**三个核心步骤均支持增量处理**。 ## 项目结构 @@ -10,102 +10,126 @@ rag_jrxml/ ├── collect_jrxml.py # JRXML 文件收集 ├── jrxml_chunker.py # JRXML 语义分块引擎 (v3.0) -├── jrxml_banch_chunker.py # JRXML 批量分块 (单类型) ├── md_chunker.py # Markdown 语义分块引擎 -├── batch_chunker.py # 统一批量分块入口 (JRXML + MD) +├── batch_chunker.py # 统一批量分块入口 (JRXML + MD, 支持增量) ├── down_embedding_model.py # 嵌入模型下载 ├── embed_chunks.py # Chunk 向量化 (支持增量) ├── import_to_chroma.py # Chroma 向量入库 (支持增量) ├── query_chroma.py # 语义搜索查询 ├── config.py # 统一配置管理 (.env) -├── .env # 环境变量配置 -├── .env.example # 配置模板 +├── .env / .env.example # 环境变量配置 ├── requirements.txt # Python 依赖 ├── jrxml_source/ # JRXML 源文件 ├── jrxml_chunker_output/ # 分块输出 -│ ├── all_chunks.json -│ ├── processing_stats.json -│ └── per_file/ -├── models/ # 本地嵌入模型 ├── embeddings/ # 向量输出 -│ ├── embeddings.npy -│ ├── chunks.json -│ └── embeddings.pkl ├── chroma_db/ # Chroma 持久化数据库 -└── docs/ - └── file_guide.md +└── docs/file_guide.md # 详细文件功能说明 ``` -## 快速开始 - -### 环境要求 +## 环境要求 - Python 3.11+ - NVIDIA GPU (推荐 8GB+ 显存) 或 CPU - CUDA 12.1+ (GPU 模式) -### 安装 +## 安装与配置 ```bash pip install -r requirements.txt -``` - -### 配置 - -```bash -cp .env.example .env # 编辑 .env 调整模型、路径等参数 +cp .env.example .env # 编辑 .env 调整模型、路径等参数 ``` 主要配置项: | 变量 | 说明 | 默认值 | -|---|---|---| +| --- | --- | --- | | `EMBEDDING_MODEL_NAME` | 嵌入模型 (Hub 名) | `Qwen/Qwen3-Embedding-0.6B` | | `EMBEDDING_MODEL_PATH` | 本地模型路径 | `models/Qwen3-Embedding-0.6B` | | `MAX_CHUNK_SIZE` | 单个 chunk 最大字符数 | `2000` | | `BATCH_SIZE` | 向量化批大小 | `16` | | `CHROMA_COLLECTION_NAME` | Chroma 集合名 | `jrxml_chunks` | -### 完整流程 +--- + +## 首次使用 — 全量建库 + +从头构建向量数据库,三个步骤顺序执行: + +### 步骤 1:收集 & 分块 ```bash -# 1. 收集 JRXML 文件 +# 收集 JRXML 模板文件 python collect_jrxml.py -# 2. 统一分块 (JRXML + Markdown) +# 统一分块 (JRXML + Markdown 混合目录) python batch_chunker.py ./jrxml_source --output ./jrxml_chunker_output - -# 3. 下载嵌入模型 (首次) -python down_embedding_model.py - -# 4. 向量化 -python embed_chunks.py - -# 5. 导入 Chroma -python import_to_chroma.py - -# 6. 查询 -python query_chroma.py ``` -### 增量更新 +输出 `jrxml_chunker_output/all_chunks.json` 和 `processing_stats.json`。 -新增或修改部分文件时,无需重新处理全部数据: +### 步骤 2:向量化 ```bash -# 分块新文件 -python batch_chunker.py ./new_files --output ./jrxml_chunker_output/new_batch +# 下载嵌入模型 (仅首次) +python down_embedding_model.py -# 增量向量化 (只处理新 chunks) -python embed_chunks.py ./jrxml_chunker_output/new_batch/all_chunks.json --incremental +# 全量向量化 +python embed_chunks.py +``` -# 增量导入 (不删除已有数据) +输出 `embeddings/embeddings.npy`、`chunks.json` 等文件。 + +### 步骤 3:导入 Chroma + +```bash +# 全量导入 (创建新集合) +python import_to_chroma.py +``` + +输出 `chroma_db/` 持久化向量数据库。 + +### 步骤 4:查询 + +```bash +# 交互模式 +python query_chroma.py + +# 单次查询 +python query_chroma.py "如何修改报表标题" +python query_chroma.py "SQL查询怎么写" --filter_field query +python query_chroma.py "报表参数" --threshold 0.5 --n_results 10 +``` + +--- + +## 增量更新 — 追加新模板 + +已有数据库后,添加新模板无需重建。将新文件放入源目录后: + +```bash +# 步骤 1:增量分块 (自动跳过已处理文件,合并到已有结果) +python batch_chunker.py ./jrxml_source --incremental + +# 步骤 2:增量向量化 (只对新 chunks 编码,合并到已有向量) +python embed_chunks.py --incremental + +# 步骤 3:增量导入 (追加到已有集合,不删除现有数据) python import_to_chroma.py --incremental ``` +三个 `--incremental` 标志各自的工作逻辑: + +| 步骤 | 如何识别已处理 | 无新数据时 | +| --- | --- | --- | +| `batch_chunker` | 对比 `processing_stats.json` 中的文件路径 | 输出 "没有新文件需要处理" | +| `embed_chunks` | 按 `(context, chunk_id)` 去重 | 输出 "没有新 chunks 需要向量化" | +| `import_to_chroma` | 查询 Chroma 已有 ID | 输出 "没有新数据需要导入" | + +--- + ## 分块类型 -### JRXML 分块 +### JRXML | 类型 | 说明 | |---|---| @@ -126,7 +150,7 @@ python import_to_chroma.py --incremental | `subreport` | 子报表元素 | | `component` | 组件元素 (列表等) | -### Markdown 分块 +### Markdown | 类型 | 说明 | |---|---| @@ -140,22 +164,6 @@ python import_to_chroma.py --incremental | `section_changelog` | 更新日志章节 | | `code` | 代码块 | -## 查询 - -```bash -# 交互模式 -python query_chroma.py - -# 单次查询 -python query_chroma.py "如何修改报表标题" - -# 按类型过滤 -python query_chroma.py "SQL怎么写" --filter_field query - -# 设置阈值和数量 -python query_chroma.py "报表参数" --threshold 0.5 --n_results 10 -``` - ## 支持的 JRXML 数据源 SQL/JDBC · HQL/Hibernate · XPath/XML · JSON · JSONQL · CSV · Data Adapter (Excel/XML/HTTP) · Bean Collection · Empty diff --git a/docs/file_guide.md b/docs/file_guide.md index 0ad8958..33fa0c8 100644 --- a/docs/file_guide.md +++ b/docs/file_guide.md @@ -8,10 +8,6 @@ **功能**: 从 JasperReports 模板库目录递归收集 `.jrxml` 文件,复制到项目 `jrxml_source` 目录。 -**输入**: 源目录路径(硬编码,可按需修改) - -**输出**: `jrxml_source/` 目录 - **使用方式**: ```bash python collect_jrxml.py @@ -21,21 +17,19 @@ python collect_jrxml.py ## 2. jrxml_chunker.py — JRXML 语义分块引擎 (v3.0) -**功能**: 将单个 JRXML 文件按语义结构拆分,每个 chunk 包含人类可读描述、原始 XML 和结构化元数据。 +**功能**: 将单个 JRXML 文件按语义结构拆分。被 `batch_chunker.py` 调用,也可单独使用。 **输入**: 单个 `.jrxml` 文件路径(或目录) **输出**: `JRXMLChunk` 列表,字段包括: - `chunk_id`: 文件内序号 -- `chunk_type`: 分块类型 (如 `query`, `band_detail`, `chart` 等) +- `chunk_type`: 分块类型 (`query`, `band_detail`, `chart` 等) - `human_description`: 人类可读描述 - `raw_xml`: 原始 XML 片段 - `context`: 所属报表名称 - `metadata`: 元数据 (report_name, band_name, element_kind 等) -**支持的数据源**: SQL, HQL, XPath, JSON, JSONQL, CSV, Data Adapter, Bean Collection, Empty - -**使用方式**: +**单独使用**: ```bash python jrxml_chunker.py report.jrxml # 单文件 python jrxml_chunker.py ./jrxml_source/ # 目录 @@ -43,39 +37,16 @@ python jrxml_chunker.py ./jrxml_source/ # 目录 --- -## 3. jrxml_banch_chunker.py — JRXML 批量分块 (单类型) +## 3. md_chunker.py — Markdown 语义分块引擎 -**功能**: 批量处理目录下所有 JRXML 文件,生成统计报告和按文件分类的输出。是旧版入口,被 `batch_chunker.py` 取代。 - -**使用方式**: -```bash -python jrxml_banch_chunker.py ./jrxml_source --output ./output -``` - ---- - -## 4. md_chunker.py — Markdown 语义分块引擎 - -**功能**: 将 Markdown 文件按标题层级、代码块、表格等结构化元素智能分块。 - -**输入**: 单个 `.md` 文件路径(或目录) - -**输出**: `MDChunk` 列表,字段包括: -- `chunk_id`: 文件内序号 -- `chunk_type`: 分块类型 (`section_h1`, `code`, `section_installation` 等) -- `human_description`: 人类可读描述 -- `raw_content`: 原始 Markdown 内容 -- `context`: 所属文档标题 -- `metadata`: 元数据 (heading, heading_level, language 等) +**功能**: 将 Markdown 文件按标题层级、代码块、表格等结构化元素智能分块。被 `batch_chunker.py` 调用,也可单独使用。 **分块策略**: -- 按标题层级 (H1/H2/H3) 划分段落 -- 代码块作为独立 chunk -- 表格作为独立 chunk -- H2 标题自动识别特殊类型(安装、配置、API、示例等) +- 按标题层级 (H1/H2/H3) 划分段落,H2 自动识别特殊类型 +- 代码块、表格作为独立 chunk - 过长段落按段落/句子二次拆分 -**使用方式**: +**单独使用**: ```bash python md_chunker.py doc.md # 单文件 python md_chunker.py ./docs/ # 目录 @@ -83,58 +54,63 @@ python md_chunker.py ./docs/ # 目录 --- -## 5. batch_chunker.py — 统一批量分块入口 +## 4. batch_chunker.py — 统一批量分块入口 -**功能**: 统一入口,支持 JRXML 和 Markdown 文件混合批量处理,生成合并的 chunks 和统计报告。 - -**输入**: 包含 `.jrxml` / `.md` 文件的目录 +**功能**: 统一入口,支持 JRXML + Markdown 混合批量处理。**支持增量模式**。 **输出**: - `all_chunks.json`: 所有 chunks 合并 -- `processing_stats.json`: 处理统计 (成功/失败/耗时/类型分布) +- `processing_stats.json`: 处理统计 (文件级 chunk 数量、类型分布) -**使用方式**: +**全量模式** — 首次建库: ```bash -python batch_chunker.py ./mixed_source -python batch_chunker.py ./mixed_source --output ./my_output +python batch_chunker.py ./jrxml_source --output ./jrxml_chunker_output ``` +**增量模式** (`--incremental`) — 追加新文件: +```bash +python batch_chunker.py ./jrxml_source --incremental +``` + +增量模式逻辑: +1. 加载已有 `processing_stats.json`,获取已处理文件列表 +2. 扫描输入目录,自动跳过已处理文件 +3. 只分块新增文件 +4. 合并新旧 `all_chunks.json` 和统计数据后保存 + --- -## 6. down_embedding_model.py — 嵌入模型下载 +## 5. down_embedding_model.py — 嵌入模型下载 -**功能**: 从 HuggingFace Hub 下载嵌入模型到本地。支持国内镜像加速和断点续传。 +**功能**: 从 HuggingFace Hub 下载嵌入模型到本地。支持国内镜像 (`hf-mirror.com`)、断点续传。 -**使用方式**: ```bash python down_embedding_model.py ``` --- -## 7. embed_chunks.py — Chunk 向量化 +## 6. embed_chunks.py — Chunk 向量化 -**功能**: 使用嵌入模型将 chunks 转换为向量。支持 GPU/CPU、FP16 半精度,**支持增量模式**。 - -**输入**: chunks JSON 文件 (默认 `jrxml_chunker_output/all_chunks.json`) +**功能**: 将 chunks 转换为向量。支持 GPU/CPU、FP16 半精度,**支持增量模式**。 **输出**: - `embeddings/embeddings.npy`: 向量矩阵 (float32) - `embeddings/chunks.json`: 原始 chunks -- `embeddings/chunk_id_map.json` / `chunk_type_map.json`: 映射文件 -- `embeddings/embeddings.pkl`: 完整数据 pickle +- `embeddings/chunk_id_map.json` / `chunk_type_map.json` +- `embeddings/embeddings.pkl`: 完整 pickle -**全量模式**: +**全量模式** — 首次向量化: ```bash python embed_chunks.py -python embed_chunks.py --batch_size 2 -python embed_chunks.py --model_path "sentence-transformers/all-MiniLM-L6-v2" +python embed_chunks.py --batch_size 2 # 调整批大小 +python embed_chunks.py --model_path "all-MiniLM-L6-v2" # 换模型 +python embed_chunks.py --no_fp16 # 禁用半精度 ``` -**增量模式** (`--incremental` / `-i`): +**增量模式** (`--incremental` / `-i`) — 只编码新 chunks: ```bash -# 只向量化新增 chunks,自动合并到已有向量数据 -python embed_chunks.py ./new_chunks/all_chunks.json --incremental +python embed_chunks.py --incremental ``` 增量模式逻辑: @@ -145,67 +121,55 @@ python embed_chunks.py ./new_chunks/all_chunks.json --incremental --- -## 8. import_to_chroma.py — Chroma 向量入库 +## 7. import_to_chroma.py — Chroma 向量入库 **功能**: 将向量数据导入 Chroma 持久化数据库。**支持增量模式**。 -**输入**: `embeddings/embeddings.npy` + `embeddings/chunks.json` - -**输出**: `chroma_db/` 持久化数据库 - -**全量模式** (删除旧集合重建): +**全量模式** — 首次导入 (删除旧集合重建): ```bash python import_to_chroma.py ``` -**增量模式** (`--incremental` / `-i`): +**增量模式** (`--incremental` / `-i`) — 追加新记录: ```bash -# 追加新记录到已有集合,不删除已有数据 python import_to_chroma.py --incremental ``` 增量模式逻辑: -1. 使用 `get_or_create_collection` (不删除已有数据) -2. 查询已有 ID,跳过已导入的记录 -3. 只追加新增数据 +1. `get_or_create_collection` (不删除已有数据) +2. 查询 Chroma 已有 ID +3. 跳过已导入的记录,只追加新数据 --- -## 9. query_chroma.py — 语义搜索查询 +## 8. query_chroma.py — 语义搜索查询 -**功能**: 通过自然语言查询 Chroma 数据库,检索相关的 JRXML/Markdown chunks。 +**功能**: 通过自然语言查询 Chroma 数据库。 **两种模式**: -- 命令行单次查询: `python query_chroma.py "查询内容"` -- 交互模式: `python query_chroma.py` (支持连续查询) +- **单次查询**: `python query_chroma.py "查询内容"` +- **交互模式**: `python query_chroma.py`(支持连续查询和内联命令) **交互模式命令**: ``` filter:<类型> 按 chunk_type 过滤 (如 filter:query) -t:<阈值> 设置相似度阈值 0~1 -k:<数量> 设置返回结果数 +t:<阈值> 相似度阈值 0~1 (如 t:0.5) +k:<数量> 返回结果数 (如 k:10) ``` -**使用方式**: +**使用示例**: ```bash -python query_chroma.py # 交互模式 -python query_chroma.py "如何修改报表标题" # 单次查询 +python query_chroma.py # 交互模式 +python query_chroma.py "如何修改报表标题" # 单次查询 python query_chroma.py "SQL怎么写" --filter_field query python query_chroma.py "参数" --threshold 0.5 --n_results 10 ``` --- -## 10. config.py — 统一配置管理 +## 9. config.py — 统一配置管理 -**功能**: 从 `.env` 文件加载所有配置项,所有脚本通过此模块获取配置。 - -**配置分组**: -- 模型配置: `EMBEDDING_MODEL_NAME`, `EMBEDDING_MODEL_PATH`, `HF_ENDPOINT` -- 硬件配置: `USE_GPU`, `USE_FP16`, `BATCH_SIZE` -- 目录配置: `JRXML_SOURCE_DIR`, `CHUNKER_OUTPUT_DIR`, `EMBEDDINGS_DIR`, `CHROMA_DB_PATH` -- 分块配置: `MAX_CHUNK_SIZE` -- 查询配置: `DEFAULT_N_RESULTS`, `SIMILARITY_THRESHOLD` +**功能**: 从 `.env` 加载所有配置,所有脚本通过此模块获取配置项。 ```bash python config.py # 打印当前配置 @@ -213,30 +177,89 @@ python config.py # 打印当前配置 --- -## 数据流全景 +## 10. jrxml_banch_chunker.py — 旧版入口 (已废弃) + +**功能**: JRXML 单类型批量分块。已被 `batch_chunker.py` 取代,保留以兼容旧流程。 + +--- + +## 使用场景 + +### 场景 A:首次构建数据库 + +```bash +# 1. 准备源文件 +python collect_jrxml.py +# 将 Markdown 文档放入 jrxml_source/ 或指定目录 + +# 2. 全量分块 +python batch_chunker.py ./jrxml_source + +# 3. 下载模型 + 全量向量化 +python down_embedding_model.py +python embed_chunks.py + +# 4. 全量导入 +python import_to_chroma.py + +# 5. 开始查询 +python query_chroma.py +``` + +### 场景 B:追加新模板/文档 + +```bash +# 将新 .jrxml / .md 文件放入源目录后: + +# 1. 增量分块 — 自动跳过已处理文件 +python batch_chunker.py ./jrxml_source --incremental + +# 2. 增量向量化 — 只编码新 chunks +python embed_chunks.py --incremental + +# 3. 增量导入 — 追加到已有数据库 +python import_to_chroma.py --incremental +``` + +### 场景 C:更换嵌入模型 + +```bash +# 1. 编辑 .env 修改 EMBEDDING_MODEL_NAME / EMBEDDING_MODEL_PATH +# 2. 下载新模型 +python down_embedding_model.py + +# 3. 重新向量化 (全量) +python embed_chunks.py + +# 4. 重建数据库 +python import_to_chroma.py +``` + +--- + +## 数据流 ``` ┌─────────────────────┐ -│ JasperReports 模板库 │ (.jrxml) -│ Markdown 文档 │ (.md) +│ JRXML 模板 (.jrxml) │ +│ Markdown 文档 (.md) │ └──────────┬──────────┘ │ collect_jrxml.py / 手动放置 ▼ ┌─────────────────────┐ -│ jrxml_source/ │ 源文件目录 -│ docs/ │ +│ jrxml_source/ │ └──────────┬──────────┘ - │ batch_chunker.py (调用 jrxml_chunker.py + md_chunker.py) + │ batch_chunker.py [--incremental] ▼ ┌──────────────────────┐ -│ jrxml_chunker_output/│ all_chunks.json + processing_stats.json +│ jrxml_chunker_output/│ all_chunks.json └──────────┬───────────┘ - │ embed_chunks.py (Qwen3-Embedding, 支持增量) + │ embed_chunks.py [--incremental] ▼ ┌─────────────────┐ │ embeddings/ │ embeddings.npy + chunks.json └────────┬────────┘ - │ import_to_chroma.py (ChromaDB, 支持增量) + │ import_to_chroma.py [--incremental] ▼ ┌─────────────────┐ │ chroma_db/ │ Chroma 向量数据库