# 题经-python项目 **Repository Path**: qmi_team/qmi-py ## Basic Information - **Project Name**: 题经-python项目 - **Description**: 题经python项目,负责RAG,文档检索优化 - **Primary Language**: Python - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2026-06-28 - **Last Updated**: 2026-07-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 题经-python项目 #### 介绍 题经python项目,负责RAG,文档检索优化 #### 软件架构 ``` ┌─────────────────────────────────────────────────────────┐ │ 题经项目 │ ├─────────────────────────────────────────────────────────┤ │ ├─────────────────────────────────────────────────────┤ │ │ │ RAG功能模块 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ - rag_skill.core: 网页转PDF + 向量数据库存储 │ │ │ │ - rag_skill.url_to_pdf: 网页PDF转换引擎 │ │ │ │ - rag_skill.__main__: 命令行入口 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ 数据存储层 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ - DBUtils.py: MySQL连接池管理 │ │ │ │ - question_resource.py: 资源元数据管理 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ 调度服务层 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ - resource_rag_scheduler.py: 定时任务调度 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ API接口 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ - rag_search_api/: RAG查询接口 │ │ │ │ ├─ run.py: FastAPI应用 │ │ │ │ ├─ signature.py: 签名生成与验证 │ │ │ │ ├─ authenticator.py: 认证管理器 │ │ │ │ └─ security.py: 安全头配置 │ │ └─────────────────────────────────────────────────────────┘ #### 安装教程 1. **安装Python环境** (Python 3.8+) 2. **安装RAG技能核心依赖** ```bash # 从当前目录安装rag_skill作为可安装包 cd rag_skill pip install -e . ``` 3. **安装辅助工具依赖** ```bash # 安装项目中的其他依赖 ``` 4. **配置环境变量** (可选) ```bash export RAG_SEARCH_API_KEY=你的api密钥 export RAG_SKILL_CONFIG=/path/to/config.yaml ``` #### 使用说明 1. **通过命令行工具处理URL** ```bash # 处理单个URL python -m rag_skill --output-dir ./pdfs # 或使用rag_url-skill脚本 python rag_url-skill/scripts/run.py [--output-dir DIR] [--csdn] # 处理多个URL python -m rag_skill --output-dir ./pdfs url1 url2 url3 ``` 2. **启动定时任务调度器** ```bash # 启动资源RAG调度器(每分钟处理2条未索引记录) python resource_rag_scheduler.py ``` 3. **启动fast rag服务** ```bash # 启动fastapi服务,将rag搜索能力暴露出来,java 端会用到 uvicorn rag_search_api.run:app --reload # 也可以使用结构化模块 python -m rag_search_api.run ``` 4**手动查询向量数据库** ```python from rag_skill.core import query_chroma # 查询并获取相似度结果 results = query_chroma("您的查询语句", k=4) for doc, score in results: print(f"相似度: {score:.2f}") print(f"内容: {doc.page_content}") print(f"元数据: {doc.metadata}") ``` 5**使用数据库工具** ```python from DBUtils import DatabasePool # 获取单例连接池 pool = DatabasePool.get_instance( host='localhost', port=3306, user='username', password='password', database='your_db' ) # 执行数据库操作 db = DBUtil(pool) result = db.query_one("SELECT * FROM your_table WHERE id = %s", (1,)) ``` #### 认证与签名功能使用说明 ##### 3.1 API认证机制 **API密钥认证** (Bearer Token): ```bash # API请求头 Authorization: Bearer sk_production_abc123xyz789 ``` **签名验证** (推荐用于生产环境): ```bash # 需要额外的安全头 Authorization: Bearer sk_production_abc123xyz789 X-Signature: generated_signature_from_client X-Timestamp: current_timestamp ``` **获取签名信息** (用于客户端签名生成): ```bash # 发送请求体到此端点获取签名信息 POST /get-signature Content-Type: application/json Authorization: Bearer sk_production_abc123xyz789 { "query": "您的查询内容", "user_id": "用户ID" } # 返回结果包含签名和时间戳 { "signature": "生成的签名", "timestamp": "当前时间戳", "api_key": "sk_production_abc123xyz789" } ``` ##### 3.2 Java客户端示例 ```java // Java API客户端 public class RagSearchClient { private static final String BASE_URL = "http://localhost:8000"; private static final String API_KEY = "你的API密钥"; public String search(String query, String userId) { // 构造请求参数 Map params = new HashMap<>(); params.put("query", query); params.put("user_id", userId); params.put("trace_id", "trace_" + Instant.now().getEpochSecond()); // 生成签名 String signature = generateSignature(params); String timestamp = String.valueOf(Instant.now().getEpochSecond()); // 发送带签名的请求 RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", "Bearer " + API_KEY); headers.set("X-Signature", signature); headers.set("X-Timestamp", timestamp); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("X-Request-ID", "req_" + System.currentTimeMillis()); HttpEntity> entity = new HttpEntity<>(params, headers); ResponseEntity response = restTemplate.exchange( BASE_URL + "/search", HttpMethod.POST, entity, String.class ); return response.getBody(); } /** * 生成Java风格的HMAC-SHA256签名 * 签名算法:params|timestamp * params格式:key=value形式,按key排序,用&连接 * * @param params 请求参数 * @return 签名字符串 */ private String generateSignature(Map params) { try { // 使用TreeMap确保按key排序 TreeMap sortedParams = new TreeMap<>(params); // 构建Java风格的字符串:key=value形式,按key顺序拼接 StringBuilder paramsStr = new StringBuilder(); boolean first = true; for (Map.Entry entry : sortedParams.entrySet()) { if (!first) { paramsStr.append("&"); } paramsStr.append(entry.getKey()).append("=").append(entry.getValue()); first = false; } // 签名内容:params|timestamp String signContent = paramsStr.toString() + "|" + String.valueOf(Instant.now().getEpochSecond()); // 使用HMAC-SHA256生成签名 Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec( API_KEY.getBytes(StandardCharsets.UTF_8), "HmacSHA256" ); sha256_HMAC.init(secret_key); byte[] signatureBytes = sha256_HMAC.doFinal( signContent.getBytes(StandardCharsets.UTF_8) ); return bytesToHex(signatureBytes); } catch (Exception e) { throw new RuntimeException("签名生成失败", e); } } private String bytesToHex(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } public static void main(String[] args) { RagSearchClient client = new RagSearchClient(); try { System.out.println("=== RAG Search API Java客户端示例 ==="); System.out.println("1. 测试签名生成..."); // 构造测试参数 Map testParams = new HashMap<>(); testParams.put("query", "test"); testParams.put("user_id", "123"); // 生成签名 String signature = client.generateSignature(testParams); System.out.println("✓ 签名生成成功: " + signature); System.out.println(" 参数字符串: query=test&user_id=123"); } catch (Exception e) { System.err.println("✗ 错误: " + e.getMessage()); e.printStackTrace(); } } } ``` **Java签名算法特点:** - **参数格式**:`key=value&key2=value2|timestamp` - **参数排序**:按key自然排序(TreeMap实现) - **分隔符**:使用`&`连接参数,使用`|`分隔参数和时间戳 - **值类型**:支持字符串、数值等基本类型 **示例:** ```java // 输入:{"query": "test", "user_id": "123"} // 输出:"query=test&user_id=123|1700000000" // 签名内容:"query=test&user_id=123|1700000000" + HMAC-SHA256(签名内容, API_KEY) ``` #### 使用签名工具 **验证签名生成逻辑(Python端):** ```python from rag_search_api import SignatureValidator from datetime import datetime timestamp = str(int(datetime.now().timestamp())) test_data = {"query": "test", "user_id": "123"} # 验证Python签名生成逻辑 params_str = sorted(test_data, key=lambda k: sorted(test_data.keys())) # 实际实现使用TreeMap确保排序正确 ``` #### Maven依赖 ```xml org.springframework.boot spring-boot-starter-web 2.7.5 com.fasterxml.jackson.core jackson-databind 2.13.4 javax.xml.bind jaxb-api 2.3.1 ``` **完整Java代码文件:** - `/Users/coderman/workspace/teamWorkSpace/qmi-py/RagSearchClient.java` ### 关键更新说明 1. **签名算法统一**: - Java端:采用`key=value&key2=value2|timestamp`格式 - Python端:同步更新,采用相同格式避免验证失败 2. **参数排序保持一致**: - 两端均使用TreeMap自然排序,确保相同参数顺序 3. **增强安全性**: - 时间戳验证:5分钟容差检查 - 安全的签名比较:hmac.compare_digest - 完整的API认证机制 4. **完整的Java示例**: - 完整的RestTemplate实现 - 安全的签名生成方法 - 完整的异常处理机制 - 示例运行代码 这是一个完整的、高度可用的Java客户端实现,确保了签名算法的一致性和安全性。🎯