test_rag_pipeline.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. RAG链路独立测试工具
  5. 用于快速调通和验证参数合规性检查的RAG检索+LLM审查功能
  6. 核心功能:
  7. 1. rag_enhanced_check() - 完整的RAG检索逻辑
  8. 2. check_parameter_compliance() - 参数合规性检查(与原链路完全一致)
  9. 使用方法:
  10. python test_rag_pipeline.py
  11. """
  12. import sys
  13. import os
  14. import json
  15. import time
  16. import asyncio
  17. from typing import Dict, Any
  18. from core.construction_review.component.infrastructure.milvus import MilvusConfig, MilvusManager
  19. from core.construction_review.component.infrastructure.parent_tool import (
  20. enhance_with_parent_docs,
  21. extract_first_result
  22. )
  23. from core.construction_review.component.reviewers.base_reviewer import BaseReviewer, ReviewResult
  24. from foundation.ai.rag.retrieval.entities_enhance import entity_enhance
  25. from foundation.ai.rag.retrieval.query_rewrite import query_rewrite_manager
  26. from foundation.ai.agent.generate.model_generate import generate_model_client
  27. from core.construction_review.component.reviewers.utils.prompt_loader import prompt_loader
  28. from foundation.observability.logger.loggering import review_logger as logger
  29. # ============================================================================
  30. # 简化的BaseReviewer类 - 用于调用LLM审查
  31. # ============================================================================
  32. class SimpleReviewer(BaseReviewer):
  33. """
  34. 简化的审查器 - 继承BaseReviewer,用于调用LLM审查
  35. """
  36. def __init__(self):
  37. """初始化简化的审查器"""
  38. super().__init__()
  39. self.model_client = generate_model_client
  40. self.prompt_loader = prompt_loader
  41. # 全局审查器实例
  42. simple_reviewer = SimpleReviewer()
  43. # ============================================================================
  44. # 核心RAG链路函数
  45. # ============================================================================
  46. def rag_enhanced_check(milvus_manager, unit_content: dict) -> dict:
  47. """
  48. RAG增强检查 - 完整链路
  49. 流程:
  50. 1. 查询提取 (query_rewrite_manager.query_extract)
  51. 2. 实体增强检索 (entity_enhance.entities_enhance_retrieval)
  52. 3. 父文档增强 (enhance_with_parent_docs)
  53. 4. 提取第一个结果 (extract_first_result)
  54. Args:
  55. milvus_manager: MilvusManager实例
  56. unit_content: 包含content字段的字典,格式: {"content": "待检索的文本内容"}
  57. Returns:
  58. dict: RAG检索结果,包含:
  59. - vector_search: 向量检索结果列表
  60. - retrieval_status: 检索状态
  61. - file_name: 参考文件名
  62. - text_content: 参考文本内容
  63. - metadata: 元数据信息
  64. """
  65. # 创建数据流跟踪字典
  66. pipeline_data = {
  67. "stage": "rag_enhanced_check",
  68. "timestamp": time.time(),
  69. "steps": {}
  70. }
  71. query_content = unit_content['content']
  72. logger.info(f"[RAG增强] 开始处理, 内容长度: {len(query_content)}")
  73. # Step 1: 查询提取
  74. logger.info("=" * 80)
  75. logger.info("Step 1: 查询提取")
  76. logger.info("=" * 80)
  77. logger.info(f"开始查询提取, 输入内容长度: {len(query_content)}")
  78. logger.info(f"输入内容预览: {query_content[:200]}...")
  79. # 执行查询提取
  80. query_pairs = query_rewrite_manager.query_extract(query_content)
  81. logger.info(f"[RAG增强] 提取到 {len(query_pairs)} 个查询对")
  82. # 打印查询对详情
  83. for idx, query_pair in enumerate(query_pairs):
  84. logger.info(f" 查询对 {idx+1}: {query_pair}")
  85. # 保存Step 1的输入输出
  86. pipeline_data["steps"]["1_query_extract"] = {
  87. "input": {
  88. "content_length": len(query_content),
  89. "content_full": query_content,
  90. "content_preview": query_content[:200]
  91. },
  92. "output": {
  93. "query_pairs_count": len(query_pairs),
  94. "query_pairs": [str(qp) for qp in query_pairs], # 转为字符串列表便于查看
  95. "extraction_timestamp": time.time()
  96. }
  97. }
  98. # Step 2: 实体增强检索
  99. logger.info("=" * 80)
  100. logger.info("Step 2: 实体增强检索")
  101. logger.info("=" * 80)
  102. logger.info(f"开始实体增强检索, 输入查询对数量: {len(query_pairs)}")
  103. # 保存输入
  104. entity_enhance_input = {
  105. "query_pairs": [str(qp) for qp in query_pairs],
  106. "query_pairs_count": len(query_pairs)
  107. }
  108. # 详细记录每个查询对的处理过程
  109. entity_enhance_process_details = []
  110. # 手动展开实体增强检索的每个步骤,便于记录数据流
  111. import asyncio
  112. def run_async(coro):
  113. """在合适的环境中运行异步函数"""
  114. try:
  115. loop = asyncio.get_running_loop()
  116. import concurrent.futures
  117. with concurrent.futures.ThreadPoolExecutor() as executor:
  118. future = executor.submit(asyncio.run, coro)
  119. return future.result()
  120. except RuntimeError:
  121. return asyncio.run(coro)
  122. # 导入retrieval_manager
  123. from foundation.ai.rag.retrieval.retrieval import retrieval_manager
  124. bfp_result_lists = []
  125. # 遍历每个查询对进行处理
  126. for idx, query_pair in enumerate(query_pairs):
  127. logger.info(f"\n{'='*60}")
  128. logger.info(f"处理查询对 {idx+1}/{len(query_pairs)}")
  129. logger.info(f"{'='*60}")
  130. # 提取查询对的各个字段
  131. entity = query_pair['entity']
  132. search_keywords = query_pair['search_keywords']
  133. background = query_pair['background']
  134. logger.info(f" 实体(entity): {entity}")
  135. logger.info(f" 搜索关键词(search_keywords): {search_keywords}")
  136. logger.info(f" 背景(background): {background}")
  137. # 记录当前查询对的输入
  138. current_query_detail = {
  139. "index": idx + 1,
  140. "input": {
  141. "entity": entity,
  142. "search_keywords": search_keywords,
  143. "background": background
  144. },
  145. "steps": {}
  146. }
  147. # Step 2.1: 实体召回 (entity_recall)
  148. logger.info(f" Step 2.1: 实体召回 (recall_top_k=5, max_results=5)")
  149. entity_list = run_async(retrieval_manager.entity_recall(
  150. entity,
  151. search_keywords,
  152. recall_top_k=5,
  153. max_results=5
  154. ))
  155. logger.info(f" ✅ 实体召回完成, 召回实体数量: {len(entity_list) if entity_list else 0}")
  156. # 记录实体召回结果
  157. current_query_detail["steps"]["2_1_entity_recall"] = {
  158. "input": {
  159. "entity": entity,
  160. "search_keywords": search_keywords,
  161. "recall_top_k": 5,
  162. "max_results": 5
  163. },
  164. "output": {
  165. "entity_list": entity_list,
  166. "entity_count": len(entity_list) if entity_list else 0
  167. }
  168. }
  169. # Step 2.2: BFP召回 (async_bfp_recall)
  170. logger.info(f" Step 2.2: BFP召回 (top_k=3)")
  171. bfp_result = run_async(retrieval_manager.async_bfp_recall(
  172. entity_list,
  173. background,
  174. top_k=3
  175. ))
  176. logger.info(f" ✅ BFP召回完成, BFP结果数量: {len(bfp_result) if bfp_result else 0}")
  177. logger.info(f" bfp_result: {bfp_result}")
  178. # 记录BFP召回结果
  179. current_query_detail["steps"]["2_2_bfp_recall"] = {
  180. "input": {
  181. "entity_list": entity_list,
  182. "background": background,
  183. "top_k": 3
  184. },
  185. "output": {
  186. "bfp_result": bfp_result,
  187. "bfp_result_count": len(bfp_result) if bfp_result else 0
  188. }
  189. }
  190. bfp_result_lists.append(bfp_result)
  191. entity_enhance_process_details.append(current_query_detail)
  192. logger.info(f"✅ 查询对 {idx+1} 处理完成")
  193. logger.info(f"\n{'='*80}")
  194. logger.info(f"实体增强检索全部完成")
  195. logger.info(f"总查询对数: {len(query_pairs)}")
  196. logger.info(f"总BFP结果数: {len(bfp_result_lists)}")
  197. logger.info(f"{'='*80}")
  198. # 保存Step 2的详细输出
  199. pipeline_data["steps"]["2_entity_enhance_retrieval"] = {
  200. "input": entity_enhance_input,
  201. "output": {
  202. "results_count": len(bfp_result_lists),
  203. "results": bfp_result_lists,
  204. "process_details": entity_enhance_process_details # 每个查询对的详细处理过程
  205. },
  206. "timestamp": time.time()
  207. }
  208. # Step 3: 检查检索结果
  209. if not bfp_result_lists:
  210. logger.warning("[RAG增强] 实体检索未返回结果")
  211. # 保存最终数据流
  212. os.makedirs(r"temp\entity_bfp_recall", exist_ok=True)
  213. with open(rf"temp\entity_bfp_recall\rag_pipeline_data.json", "w", encoding='utf-8') as f:
  214. json.dump(pipeline_data, f, ensure_ascii=False, indent=4)
  215. return {
  216. 'vector_search': [],
  217. 'retrieval_status': 'no_results',
  218. 'file_name': '',
  219. 'text_content': '',
  220. 'metadata': {}
  221. }
  222. logger.info(f"[RAG增强] 实体检索返回 {len(bfp_result_lists)} 个结果")
  223. # Step 4: 父文档增强 (使用独立工具函数)
  224. logger.info("=" * 80)
  225. logger.info("Step 3: 父文档增强")
  226. logger.info("=" * 80)
  227. try:
  228. enhancement_result = enhance_with_parent_docs(milvus_manager, bfp_result_lists)
  229. enhanced_results = enhancement_result['enhanced_results']
  230. enhanced_count = enhancement_result['enhanced_count']
  231. parent_docs = enhancement_result['parent_docs']
  232. # 保存Step 3输出
  233. pipeline_data["steps"]["3_parent_doc_enhancement"] = {
  234. "input": {
  235. "bfp_results_count": len(bfp_result_lists)
  236. },
  237. "output": {
  238. "enhanced_count": enhanced_count,
  239. "parent_docs_count": len(parent_docs),
  240. "parent_docs": parent_docs,
  241. "enhanced_results": enhanced_results
  242. }
  243. }
  244. # 保存增强后的结果
  245. os.makedirs(r"temp\entity_bfp_recall", exist_ok=True)
  246. with open(rf"temp\entity_bfp_recall\enhance_with_parent_docs.json", "w", encoding='utf-8') as f:
  247. json.dump(enhanced_results, f, ensure_ascii=False, indent=4)
  248. logger.info(f"[RAG增强] 成功增强 {enhanced_count} 个结果")
  249. logger.info(f"[RAG增强] 使用了 {len(parent_docs)} 个父文档")
  250. # 打印父文档信息
  251. for idx, parent_doc in enumerate(parent_docs):
  252. logger.info(f" 父文档 {idx+1}: {parent_doc.get('file_name', 'unknown')}")
  253. except Exception as e:
  254. logger.error(f"[RAG增强] 父文档增强失败: {e}", exc_info=True)
  255. # 保存错误信息
  256. pipeline_data["steps"]["3_parent_doc_enhancement"] = {
  257. "input": {
  258. "bfp_results_count": len(bfp_result_lists)
  259. },
  260. "output": {
  261. "error": str(e),
  262. "error_type": type(e).__name__
  263. }
  264. }
  265. # 失败时使用原始结果
  266. enhanced_results = bfp_result_lists
  267. parent_docs = []
  268. # Step 5: 提取第一个结果返回 (使用增强后的结果)
  269. logger.info("=" * 80)
  270. logger.info("Step 4: 提取第一个结果")
  271. logger.info("=" * 80)
  272. final_result = extract_first_result(enhanced_results)
  273. # 保存Step 4输出
  274. pipeline_data["steps"]["4_extract_first_result"] = {
  275. "input": {
  276. "enhanced_results_count": len(enhanced_results)
  277. },
  278. "output": {
  279. "final_result": final_result
  280. }
  281. }
  282. # 保存最终结果用于调试
  283. with open(rf"temp\entity_bfp_recall\extract_first_result.json", "w", encoding='utf-8') as f:
  284. json.dump(final_result, f, ensure_ascii=False, indent=4)
  285. # 保存完整数据流
  286. pipeline_data["final_result"] = final_result
  287. os.makedirs(r"temp\entity_bfp_recall", exist_ok=True)
  288. with open(rf"temp\entity_bfp_recall\rag_pipeline_data.json", "w", encoding='utf-8') as f:
  289. json.dump(pipeline_data, f, ensure_ascii=False, indent=4)
  290. logger.info(f"[RAG增强] 最终提取结果文件名: {final_result.get('file_name', '无')}")
  291. logger.info(f"[RAG增强] 最终提取结果内容长度: {len(final_result.get('text_content', ''))}")
  292. logger.info(f"[RAG增强] 完整数据流已保存到: temp/entity_bfp_recall/rag_pipeline_data.json")
  293. return final_result
  294. # ============================================================================
  295. # 参数合规性检查函数 (与原链路完全一致)
  296. # ============================================================================
  297. async def check_parameter_compliance(trace_id_idx: str, review_content: str, review_references: str,
  298. reference_source: str, review_location_label: str, state: str, stage_name: str) -> Dict[str, Any]:
  299. """
  300. 参数合规性检查 - 实体概念/工程术语知识库
  301. (与原链路完全一致的方法签名和实现)
  302. Args:
  303. trace_id_idx: 追踪ID索引
  304. review_content: 审查内容
  305. review_references: 审查参考信息
  306. reference_source: 参考来源
  307. review_location_label: 审查位置标签
  308. state: 状态字典
  309. stage_name: 阶段名称
  310. Returns:
  311. Dict[str, Any]: 参数合规性检查结果
  312. """
  313. # 从原链路导入Stage枚举
  314. from core.construction_review.component.ai_review_engine import Stage
  315. reviewer_type = Stage.TECHNICAL.value['reviewer_type']
  316. prompt_name = Stage.TECHNICAL.value['parameter']
  317. trace_id = prompt_name + trace_id_idx
  318. # 直接调用原链路的review方法
  319. return await simple_reviewer.review("parameter_compliance_check", trace_id, reviewer_type, prompt_name, review_content, review_references,
  320. reference_source, review_location_label, state, stage_name, timeout=45)
  321. # ============================================================================
  322. # 主测试函数
  323. # ============================================================================
  324. async def main():
  325. """
  326. 主测试函数 - 测试参数合规性检查的完整流程
  327. 流程:
  328. 1. 初始化Milvus Manager
  329. 2. 准备测试内容
  330. 3. 调用RAG获取参考信息
  331. 4. 调用参数合规性检查(与原链路一致)
  332. 5. 保存完整数据流
  333. """
  334. print("\n" + "=" * 80)
  335. print("RAG链路独立测试工具 - 参数合规性检查".center(80))
  336. print("=" * 80 + "\n")
  337. # 初始化Milvus Manager
  338. print("📌 初始化Milvus Manager...")
  339. logger.info("初始化Milvus Manager...")
  340. try:
  341. milvus_manager = MilvusManager(MilvusConfig())
  342. print("✅ Milvus Manager 初始化成功\n")
  343. except Exception as e:
  344. print(f"❌ Milvus Manager 初始化失败: {e}")
  345. logger.error(f"Milvus Manager 初始化失败: {e}", exc_info=True)
  346. return
  347. # 测试内容
  348. test_content = """主要部件说明
  349. 1、主梁总成
  350. 主梁总成由主梁和导梁构成。主梁单节长12m,共7节,每节重10.87t,主梁为主要承载受力构件,其上弦杆上方设有轨道供纵移桁车走行,实现预制梁的纵向移动;下弦设有反滚轮行走轨道,作为导梁纵移、前中支腿移动纵行轨道。导梁长18m,主要是为降低过孔挠度和承受中支腿移动荷载,起安全引导、辅助过孔作用。主梁、导梁为三角桁架构件单元,采用销轴连接,前、后端各设置横联构架。
  351. 图4-1 主梁总成图
  352. 注意事项:
  353. (1)更换上、下弦销轴时,应优先向设备供应方购买符合要求的备件。自行更换时,材料性能必须优于设计零件性能,并按规定进行热处理,否则可能造成人员、设备事故。
  354. (2)销轴不得弯曲受力,不得用销轴作为锤砸工具,不得任意放置及焊接"""
  355. unit_content = {"content": test_content}
  356. print(f"📝 测试内容长度: {len(test_content)} 字符")
  357. print(f"📝 测试内容预览:\n{test_content[:200]}...\n")
  358. # 创建数据流跟踪字典
  359. pipeline_data = {
  360. "stage": "parameter_compliance_check_full_pipeline",
  361. "timestamp": time.time(),
  362. "steps": {}
  363. }
  364. # Step 1: RAG增强检索
  365. print("=" * 80)
  366. print("【Step 1】RAG增强检索".center(80))
  367. print("=" * 80)
  368. logger.info("=" * 80)
  369. logger.info("Step 1: RAG增强检索")
  370. logger.info("=" * 80)
  371. start_time = time.time()
  372. rag_result = rag_enhanced_check(milvus_manager, unit_content)
  373. review_references = rag_result.get('text_content', '')
  374. reference_source = rag_result.get('file_name', '')
  375. # 保存Step 1数据
  376. pipeline_data["steps"]["1_rag_retrieval"] = {
  377. "input": {
  378. "unit_content": unit_content
  379. },
  380. "output": {
  381. "rag_result": rag_result,
  382. "review_references_length": len(review_references),
  383. "reference_source": reference_source
  384. },
  385. "execution_time": time.time() - start_time
  386. }
  387. if not review_references:
  388. logger.warning("RAG检索未返回参考信息,将继续使用空参考进行审查")
  389. print("⚠️ RAG检索未返回参考信息\n")
  390. else:
  391. print(f"✅ RAG检索成功")
  392. print(f" 参考来源: {reference_source}")
  393. print(f" 参考内容长度: {len(review_references)} 字符\n")
  394. # Step 2: 调用参数合规性检查 (使用原链路的方法)
  395. print("=" * 80)
  396. print("【Step 2】参数合规性检查 (LLM审查)".center(80))
  397. print("=" * 80)
  398. logger.info("=" * 80)
  399. logger.info("Step 2: 参数合规性检查")
  400. logger.info("=" * 80)
  401. trace_id_idx = "_test_001"
  402. review_location_label = "测试文档-第1章"
  403. state = None
  404. stage_name = "test_stage"
  405. logger.info(f"开始调用参数合规性检查")
  406. logger.info(f" - trace_id_idx: {trace_id_idx}")
  407. logger.info(f" - review_content长度: {len(test_content)}")
  408. logger.info(f" - review_references长度: {len(review_references)}")
  409. logger.info(f" - reference_source: {reference_source}")
  410. # 保存Step 2输入
  411. pipeline_data["steps"]["2_parameter_compliance_check"] = {
  412. "input": {
  413. "trace_id_idx": trace_id_idx,
  414. "review_content_length": len(test_content),
  415. "review_content_preview": test_content[:200],
  416. "review_references_length": len(review_references),
  417. "review_references_preview": review_references[:200] if review_references else "",
  418. "reference_source": reference_source,
  419. "review_location_label": review_location_label,
  420. "stage_name": stage_name
  421. },
  422. "output": {}
  423. }
  424. start_time = time.time()
  425. try:
  426. # 调用与原链路完全一致的方法
  427. result = await check_parameter_compliance(
  428. trace_id_idx=trace_id_idx,
  429. review_content=test_content,
  430. review_references=review_references,
  431. reference_source=reference_source,
  432. review_location_label=review_location_label,
  433. state=state,
  434. stage_name=stage_name
  435. )
  436. elapsed_time = time.time() - start_time
  437. # 保存Step 2输出
  438. pipeline_data["steps"]["2_parameter_compliance_check"]["output"] = {
  439. "success": result.success,
  440. "execution_time": result.execution_time,
  441. "error_message": result.error_message,
  442. "details": result.details
  443. }
  444. # 保存完整数据流
  445. pipeline_data["final_result"] = {
  446. "success": result.success,
  447. "execution_time": result.execution_time,
  448. "error_message": result.error_message,
  449. "details": result.details
  450. }
  451. os.makedirs(r"temp\entity_bfp_recall", exist_ok=True)
  452. with open(rf"temp\entity_bfp_recall\parameter_compliance_full_pipeline.json", "w", encoding='utf-8') as f:
  453. json.dump(pipeline_data, f, ensure_ascii=False, indent=4)
  454. logger.info(f"✅ 参数合规性检查完成, 总耗时: {elapsed_time:.2f}秒")
  455. logger.info(f"📁 完整数据流已保存到: temp/entity_bfp_recall/parameter_compliance_full_pipeline.json")
  456. except Exception as e:
  457. error_msg = f"参数合规性检查失败: {str(e)}"
  458. logger.error(error_msg, exc_info=True)
  459. # 保存错误信息
  460. pipeline_data["steps"]["2_parameter_compliance_check"]["output"] = {
  461. "error": error_msg,
  462. "error_type": type(e).__name__,
  463. "traceback": str(e)
  464. }
  465. pipeline_data["error"] = {
  466. "error_message": error_msg,
  467. "error_type": type(e).__name__
  468. }
  469. os.makedirs(r"temp\entity_bfp_recall", exist_ok=True)
  470. with open(rf"temp\entity_bfp_recall\parameter_compliance_full_pipeline.json", "w", encoding='utf-8') as f:
  471. json.dump(pipeline_data, f, ensure_ascii=False, indent=4)
  472. print(f"❌ 参数合规性检查失败: {error_msg}\n")
  473. return
  474. # 输出测试结果
  475. print("\n" + "=" * 80)
  476. print("测试结果".center(80))
  477. print("=" * 80)
  478. status_icon = "✅" if result.success else "❌"
  479. print(f"\n{status_icon} 参数合规性检查")
  480. print(f" 执行时间: {result.execution_time:.2f}秒")
  481. if result.success:
  482. print(f" 审查成功!")
  483. print(f" 详细信息: {result.details.get('name', 'N/A')}")
  484. # 如果有RAG参考信息,打印出来
  485. if 'rag_reference_source' in result.details:
  486. print(f"\n 📚 RAG参考信息:")
  487. print(f" 参考来源: {result.details['rag_reference_source']}")
  488. print(f" 参考内容长度: {len(result.details.get('rag_review_references', ''))} 字符")
  489. # 打印审查响应(截取前500字符)
  490. response = result.details.get('response', '')
  491. if response:
  492. print(f"\n 📋 审查响应 (前500字符):")
  493. print(f" {response[:500]}...")
  494. else:
  495. print(f" 错误信息: {result.error_message}")
  496. # 输出文件位置
  497. print("\n" + "=" * 80)
  498. print("详细结果已保存到:".center(80))
  499. print(" 📁 temp/entity_bfp_recall/rag_pipeline_data.json - RAG检索完整数据流")
  500. print(" 📁 temp/entity_bfp_recall/enhance_with_parent_docs.json - 父文档增强结果")
  501. print(" 📁 temp/entity_bfp_recall/extract_first_result.json - 最终提取结果")
  502. print(" 📁 temp/entity_bfp_recall/parameter_compliance_full_pipeline.json - 参数检查完整数据流")
  503. print("=" * 80 + "\n")
  504. print("✅ 测试完成!")
  505. # 保存测试结果摘要
  506. os.makedirs(r"temp\entity_bfp_recall", exist_ok=True)
  507. test_summary = {
  508. "test_type": "parameter_compliance",
  509. "check_display_name": "参数合规性检查",
  510. "timestamp": time.time(),
  511. "result": {
  512. 'success': result.success,
  513. 'execution_time': result.execution_time,
  514. 'error_message': result.error_message,
  515. 'details_summary': {
  516. 'name': result.details.get('name'),
  517. 'has_rag_reference': 'rag_reference_source' in result.details,
  518. 'response_length': len(result.details.get('response', '')),
  519. 'response_preview': result.details.get('response', '')[:200]
  520. }
  521. }
  522. }
  523. with open(rf"temp\entity_bfp_recall\test_summary.json", "w", encoding='utf-8') as f:
  524. json.dump(test_summary, f, ensure_ascii=False, indent=4)
  525. return result
  526. if __name__ == "__main__":
  527. # 运行异步主函数
  528. asyncio.run(main())