# BidiRag 使用指南 ## 概述 `BidiRag` 是 BidiRAG 项目的高级封装类,提供统一的接口来: - 加载和处理 HTML 文档 - 使用多种 RAG 方法进行文档检索 - 支持关键词检索和自然语言查询 - 支持从招投标公告中提取结构化信息 ## 快速开始 ### 基本用法 ```python from bdirag.bidi_rag import BidiRag # 1. 初始化 BidiRag(推荐用于招投标公告) rag = BidiRag(rag_method='bm25_html_tree') # 2. 添加文档 rag.add_documents(["path/to/announcement1.html", "path/to/announcement2.html"]) # 3. 检索文档 results = rag.retrieve( query="招标人和中标人", top_k=5, keywords=["招标人", "中标人", "采购人"] ) # 4. 查看结果 for doc, score in results: print(f"Score: {score:.3f}") print(doc.page_content) print("-" * 80) ``` ### 关键词搜索 ```python # 搜索包含特定关键词的文档 results = rag.search_keywords(["招标人"], top_k=10) # 搜索同时包含多个关键词的文档(AND 逻辑) results = rag.search_keywords(["招标人", "中标人"], top_k=10) ``` ### 使用不同的 RAG 方法 ```python # BM25 方法(关键词检索,无需 embedding 模型) rag = BidiRag(rag_method='bm25') # TF-IDF 方法 rag = BidiRag(rag_method='tfidf') # HTML 结构感知方法(推荐用于招投标公告) rag = BidiRag(rag_method='bm25_html_tree') # 语义检索方法(需要 embedding 模型) rag = BidiRag(rag_method='naive') # 混合搜索方法 rag = BidiRag(rag_method='hybrid_search') ``` ### 完整问答(需要 LLM) ```python from openai import OpenAI # 配置 LLM 客户端 llm_client = OpenAI( api_key="your-api-key", base_url="https://api.openai.com/v1" ) # 使用支持 LLM 的 RAG 方法 rag = BidiRag( rag_method='naive', llm_client=llm_client, llm_model='gpt-4o' ) rag.add_texts([ "招标公告:招标人XX局,项目预算100万", "中标公告:中标人XX公司,金额98万" ]) # 完整问答 result = rag.query( query="谁是招标人?", keywords=["招标人", "采购人"] ) print("答案:", result.answer) print("检索到的文档数:", len(result.retrieved_docs)) ``` ## API 参考 ### BidiRag 类 #### 初始化参数 ```python BidiRag( rag_method: str = 'bm25_html_tree', # RAG 方法名称 chunk_size: int = 512, # 文档块大小 chunk_overlap: int = 50, # 块重叠大小 vector_store_type: str = 'faiss', # 向量存储类型 embedding_model_name: str = None, # Embedding 模型名称 llm_client=None, # LLM 客户端 llm_model: str = "gpt-4o", # LLM 模型名称 index_name: str = "default" # 索引名称 ) ``` #### 主要方法 ##### `add_documents(sources, rebuild_index=True)` 添加文档文件(支持 HTML、PDF、DOCX、TXT 等) - `sources`: 文件路径或目录路径(字符串或列表) - `rebuild_index`: 是否重建索引 - 返回: 添加的文档数量 ```python rag.add_documents(["doc1.html", "doc2.html"]) rag.add_documents("path/to/documents/") # 目录 ``` ##### `add_texts(texts, metadata=None, rebuild_index=True)` 添加文本文档 - `texts`: 文本内容列表 - `metadata`: 元数据列表(可选) - `rebuild_index`: 是否重建索引 - 返回: 添加的文档数量 ```python rag.add_texts([ "招标公告...", "中标公告..." ]) ``` ##### `retrieve(query, top_k=None, keywords=None, return_scores=True)` 检索相关文档 - `query`: 搜索查询(自然语言或关键词) - `top_k`: 返回结果数量 - `keywords`: 额外关键词过滤(可选) - `return_scores`: 是否返回相似度分数 - 返回: 文档列表(带分数) ```python results = rag.retrieve( query="采购信息", top_k=5, keywords=["招标人", "采购人", "中标人"] ) ``` ##### `query(query, top_k=None, keywords=None)` 完整 RAG 流程:检索 + 生成答案(需要 LLM) - `query`: 搜索查询 - `top_k`: 检索文档数量 - `keywords`: 关键词过滤 - 返回: RAGResult 对象(包含答案和检索文档) ```python result = rag.query( query="项目预算是多少?", keywords=["预算", "金额"] ) print(result.answer) ``` ##### `search_keywords(keywords, top_k=None)` 基于关键词精确搜索 - `keywords`: 关键词列表(AND 逻辑) - `top_k`: 最大结果数量 - 返回: 文档列表 ```python results = rag.search_keywords(["招标人", "中标人"], top_k=10) ``` ##### `get_document_count()` 获取已加载的文档数量 ##### `list_available_methods()` 列出所有可用的 RAG 方法 ##### `get_method_info()` 获取当前 RAG 方法的信息 ##### `clear()` 清除所有文档和索引 ## 可用的 RAG 方法 ### 无需 Embedding 模型的方法 | 方法名 | 描述 | 适用场景 | |--------|------|----------| | `bm25` | BM25 关键词检索 | 快速关键词匹配 | | `tfidf` | TF-IDF 检索 | 简单关键词匹配 | | `keyword` | 关键词检索(BM25/TF-IDF) | 基础关键词搜索 | | `bm25_html_tree` | HTML 结构感知的 BM25 | **招投标公告(推荐)** | ### 需要 Embedding 模型的方法 | 方法名 | 描述 | 特点 | |--------|------|------| | `naive` | 基础语义检索 | 简单向量相似度搜索 | | `rerank` | 重排序检索 | 检索后使用重排序模型优化 | | `hybrid_search` | 混合搜索 | 结合向量搜索和关键词搜索 | | `multi_query` | 多查询检索 | 生成多个查询进行检索 | | `hyde` | 假设文档嵌入 | 基于假设文档的检索 | | `step_back` | 后退一步检索 | 生成更一般的查询 | | `parent_document` | 父文档检索 | 检索小块,返回大块 | | `contextual_compression` | 上下文压缩 | 压缩检索到的上下文 | ### 需要 LLM 的高级方法 | 方法名 | 描述 | 特点 | |--------|------|------| | `adaptive` | 自适应检索 | 根据查询难度自适应策略 | | `self_rag` | 自反思检索 | 检索后进行自我评估 | | `corrective` | 纠正性检索 | 检索后进行纠正 | | `flare` | FLARE 方法 | 生成与检索交替 | | `raptor` | RAPTOR 方法 | 递归树聚合 | | `ensemble` | 集成检索 | 多种方法集成 | ## 实用示例 ### 示例 1:从招投标公告中提取信息 ```python from bdirag.bidi_rag import BidiRag # 使用 HTML 结构感知方法 rag = BidiRag(rag_method='bm25_html_tree') # 添加公告 html_content = """

政府采购中标公告

采购人XX市财政局
中标人XX科技有限公司
中标金额500万元
""" rag.add_texts([html_content]) # 检索招标人信息 results = rag.retrieve( query="采购人信息", keywords=["采购人", "招标人"] ) for doc, score in results: print(f"\n找到采购人信息 (score: {score:.3f}):") print(doc.page_content) ``` ### 示例 2:批量处理多个公告 ```python import os from bdirag.bidi_rag import BidiRag rag = BidiRag(rag_method='bm25_html_tree') # 处理目录中的所有 HTML 文件 announcement_dir = "data/announcements/" rag.add_documents(announcement_dir) print(f"已加载 {rag.get_document_count()} 个公告") # 搜索特定信息 results = rag.retrieve( query="太阳能路灯采购", top_k=10, keywords=["路灯", "照明", "采购"] ) print(f"\n找到 {len(results)} 个相关公告") ``` ### 示例 3:关键词精化搜索 ```python rag = BidiRag(rag_method='bm25') # 添加文档 rag.add_texts([ "招标人A公司,预算100万", "招标人B公司,中标人C公司,预算200万", "采购人D单位,预算150万" ]) # 只搜索包含"招标人"的文档 results = rag.retrieve( query="公司信息", keywords=["招标人"] ) # 只搜索同时包含"招标人"和"中标人"的文档 results = rag.retrieve( query="公司信息", keywords=["招标人", "中标人"] ) ``` ## 常见问题 ### Q: 为什么检索结果为空? A: 可能的原因: 1. 文档索引未构建 - 确保调用了 `add_documents()` 或 `build_index()` 2. 关键词不匹配 - 检查关键词是否在文档中存在 3. 使用关键词过滤时 - 确保文档包含所有指定的关键词 ### Q: 如何选择 RAG 方法? A: 建议: - **招投标公告检索**: 使用 `bm25_html_tree`(保留 HTML 结构) - **快速关键词搜索**: 使用 `bm25` 或 `tfidf` - **语义理解搜索**: 使用 `naive` 或 `hybrid_search` - **需要生成答案**: 使用支持 LLM 的方法(如 `naive` + `llm_client`) ### Q: 如何配置 Embedding 模型? A: 默认使用 `BAAI/bge-large-zh-v1.5` 模型: ```python # 使用默认模型 rag = BidiRag(rag_method='naive') # 或使用其他模型 rag = BidiRag( rag_method='naive', embedding_model_name='BAAI/bge-base-zh-v1.5' ) ``` ### Q: 如何配置 LLM? A: 示例使用 OpenAI API: ```python from openai import OpenAI llm_client = OpenAI( api_key="your-api-key", base_url="https://api.openai.com/v1" # 或使用其他兼容 API ) rag = BidiRag( rag_method='naive', llm_client=llm_client, llm_model='gpt-4o' ) ``` ## 测试和示例 运行测试: ```bash python examples/test_bidi_rag.py ``` 运行完整示例: ```bash python examples/demo_bidi_rag.py ``` ## 注意事项 1. **网络问题**: 如果使用 embedding 模型,需要访问 HuggingFace。如遇网络问题,可以: - 使用无需 embedding 的方法(`bm25`, `tfidf`, `keyword`, `bm25_html_tree`) - 配置代理或镜像 - 下载模型到本地 2. **内存使用**: 大量文档时注意内存使用,可以分批处理 3. **关键词过滤**: 使用 `keywords` 参数时,文档必须包含所有关键词(AND 逻辑) 4. **HTML 处理**: `bm25_html_tree` 方法会解析 HTML 结构,适合结构化文档 ## 技术支持 如有问题,请查看: - 示例代码: `examples/` 目录 - 测试代码: `examples/test_bidi_rag.py` - RAG 方法实现: `bdirag/rag_methods/` 目录