소스 검색

v0.0.4-debug-修改RAG调试模块代码
- utils_test\RAG_Test\test_rag_enhanced_check.py

WangXuMing 1 개월 전
부모
커밋
f0e67f4b89

+ 61 - 130
core/construction_review/component/ai_review_engine.py

@@ -56,6 +56,10 @@ from typing import Any, Dict, List, Optional, Sequence
 
 from core.base.task_models import TaskFileInfo
 from core.construction_review.component.infrastructure.milvus import MilvusConfig, MilvusManager
+from core.construction_review.component.infrastructure.parent_tool import (
+    enhance_with_parent_docs,
+    extract_first_result
+)
 from core.construction_review.component.infrastructure.relevance import is_relevant_async
 from core.construction_review.component.reviewers.base_reviewer import BaseReviewer
 from core.construction_review.component.reviewers.outline_reviewer import OutlineReviewer
@@ -201,8 +205,10 @@ class AIReviewEngine(BaseReviewer):
             async with self.semaphore:
                 return await check_func(**kwargs)
 
-        # 外层超时配置(单个任务的整体超时时间,略大于内部单次超时15秒)
-        TASK_TIMEOUT = 20
+        # 外层超时配置(单个任务的整体超时时间)
+        # 计算公式: 模型单次超时(15秒) × (1次初始 + 最大重试次数2次) + 缓冲时间(10秒)
+        # = 15 × 3 + 10 = 55秒
+        TASK_TIMEOUT = 55
 
         basic_tasks = []
 
@@ -269,7 +275,9 @@ class AIReviewEngine(BaseReviewer):
                 result = task.result()
                 results.append(result)
             except Exception as e:
-                logger.error(f"[基础审查] 任务执行失败: {str(e)}")
+                logger.error(f"[基础审查] 任务执行失败: {str(e)}", exc_info=True)
+                logger.error(f"[基础审查] 异常类型: {type(e).__name__}")
+                logger.error(f"[基础审查] 异常详情: {repr(e)}")
                 results.append(e)
 
         # 根据配置项分配结果
@@ -337,12 +345,11 @@ class AIReviewEngine(BaseReviewer):
             async with self.semaphore:
                 return await check_func(**kwargs)
 
-        # 外层超时配置(单个任务的整体超时时间,略大于内部单次超时15秒)
-        TASK_TIMEOUT = 20
-
         # 根据配置动态创建技术性检查任务
         technical_tasks = []
-        task_mapping = []  # 任务名称映射
+        task_mapping = []  
+
+        TASK_TIMEOUT = 150
 
         if 'non_parameter_compliance_check' in self.task_info.get_review_config_list():
             task_mapping.append('non_parameter_compliance')
@@ -397,7 +404,9 @@ class AIReviewEngine(BaseReviewer):
                 result = task.result()
                 results.append(result)
             except Exception as e:
-                logger.error(f"[技术审查] 任务执行失败: {str(e)}")
+                logger.error(f"[技术审查] 任务执行失败: {str(e)}", exc_info=True)
+                logger.error(f"[技术审查] 异常类型: {type(e).__name__}")
+                logger.error(f"[技术审查] 异常详情: {repr(e)}")
                 results.append(e)
 
         # 根据配置项分配结果
@@ -425,21 +434,30 @@ class AIReviewEngine(BaseReviewer):
         """
         RAG增强审查
 
+        流程:
+        1. 提取查询对
+        2. 实体增强检索
+        3. 自动拼接父文档内容
+
         Args:
             unit_content: 待审查单元内容
 
         Returns:
             Dict[str, Any]: RAG增强审查结果
         """
-        # 向量检索
+        # Step 1: 向量检索
         query_content = unit_content['content']
-        logger.info("构建查询对")
+        logger.info(f"[RAG增强] 开始处理, 内容长度: {len(query_content)}")
+
+        # Step 2: 查询提取 + 实体增强检索
         query_pairs = query_rewrite_manager.query_extract(query_content)
-        bfp_result_lists =entity_enhance.entities_enhance_retrieval(query_pairs)
-        logger.info(f"bfp_result_lists{bfp_result_lists}")
-        # 检查是否有检索结果
+        logger.info(f"[RAG增强] 提取到 {len(query_pairs)} 个查询对")
+
+        bfp_result_lists = entity_enhance.entities_enhance_retrieval(query_pairs)
+
+        # Step 3: 检查检索结果
         if not bfp_result_lists:
-            logger.warning("RAG检索未返回任何结果")
+            logger.warning("[RAG增强] 实体检索未返回结果")
             return {
                 'vector_search': [],
                 'retrieval_status': 'no_results',
@@ -447,121 +465,34 @@ class AIReviewEngine(BaseReviewer):
                 'text_content': '',
                 'metadata': {}
             }
-        #todo
-        #异步调用查询。查出所有的
-        
-        #todo
-        # 使用bfp_result_list 获取 parent_id ,通过parent_id 获取父文档内容 utils_test\Milvus_Test\test_查询接口.py
-        # llm 异步相关度分析  判断父文档是否与query_content 审查条文相关
-        # 如果相关,则追加到 bfp_result,如果不相关则,则跳过
-        PARENT_COLLECTION = "rag_parent_hybrid"  # TODO: 改成你的父段 collection
-        PARENT_TEXT_FIELD = "text"                   # TODO: 改成你的父段字段名
-        PARENT_OUTPUT_FIELDS: Sequence[str] = ["parent_id", PARENT_TEXT_FIELD]
-
-        def run_async(coro):
-            """在同步函数中跑 async(兼容已有 event loop)"""
-            try:
-                asyncio.get_running_loop()
-                with concurrent.futures.ThreadPoolExecutor() as executor:
-                    return executor.submit(asyncio.run, coro).result()
-            except RuntimeError:
-                return asyncio.run(coro)
-
-        async def _async_condition_query_one(pid: str) -> Optional[Dict[str, Any]]:
-            """
-            condition_query 是同步:用线程池包成 async
-            返回父段 row(或 None)
-            """
-            loop = asyncio.get_running_loop()
-
-
-            def _call():
-                rows = self.milvus.condition_query(
-                    collection_name=PARENT_COLLECTION,
-                    filter=f"parent_id == '{pid}'",
-                    output_fields=PARENT_OUTPUT_FIELDS,
-                    limit=1,
-                )
-                if not rows:
-                    return None
-                row0 = rows[0] or {}
-                # 白名单投影:避免 pk/id 等多余字段
-                return {k: row0.get(k) for k in PARENT_OUTPUT_FIELDS if k in row0}
-
-            return await loop.run_in_executor(None, _call)
-
-        async def _enhance_all():
-            # 1) 收集 parent_id -> 指向哪些 result 需要被拼接
-            pid_to_results: Dict[str, List[Dict[str, Any]]] = {}
-
-            for result_list in bfp_result_lists:
-                for r in (result_list or []):
-                    md = r.get("metadata") or {}
-                    pid = md.get("parent_id")
-                    if not pid:
-                        continue
-                    pid = str(pid)
-                    pid_to_results.setdefault(pid, []).append(r)
-
-            if not pid_to_results:
-                return
-
-            # 2) 逐个 parent_id 串行:查父段 -> LLM 判断 -> 拼接到对应 results
-            for pid, results in pid_to_results.items():
-                parent_doc = await _async_condition_query_one(pid)
-
-                if not parent_doc:
-                    continue
-
-                parent_text = (parent_doc.get(PARENT_TEXT_FIELD) or "").strip()
-                if not parent_text:
-                    continue
-
-                # LLM 判断是否相关(你已经封装好了 is_relevant_async:模型直接输出 relevant true/false)
-                relevant = await is_relevant_async(query_content, parent_text)
-                # print("================\n")
-                # print(query_content)
-                # print("\n=====\n")
-                # print(parent_text)
-                # print("\n=====\n")
-                # print(relevant)
-                # print("\n================\n")
-                if not relevant:
-                    continue
-
-                extra = (
-                    f"{parent_text}\n"
-                )
 
-                # 3) 拼接到所有属于该 parent_id 的条目 text_content
-                for r in results:
-                    r["text_content"] = (r.get("text_content") or "") + extra
+        # Step 4: 父文档增强 (使用独立工具函数 - 显式返回)
+        try:
+            enhancement_result = enhance_with_parent_docs(self.milvus, bfp_result_lists)
+            enhanced_results = enhancement_result['enhanced_results']
+            enhanced_count = enhancement_result['enhanced_count']
 
-        run_async(_enhance_all())
-        logger.info(f"RAG检索返回了 {len(bfp_result_lists)} 个查询对结果")
-        # 获取第一个查询对的第一个结果
-        first_result_list = bfp_result_lists[0]
+            # 保存增强后的结果
+            with open(rf"temp\entity_bfp_recall\enhance_with_parent_docs.json", "w", encoding='utf-8') as f:
+                json.dump(enhanced_results, f, ensure_ascii=False, indent=4)
 
-        if not first_result_list:
-            logger.warning("第一个查询对无检索结果")
-            return {
-                'vector_search': [],
-                'retrieval_status': 'no_results',
-                'file_name': '',
-                'text_content': '',
-                'metadata': {}
-            }
+            logger.info(f"[RAG增强] 成功增强 {enhanced_count} 个结果")
+            logger.info(f"[RAG增强] 使用了 {len(enhancement_result['parent_docs'])} 个父文档")
+        except Exception as e:
+            logger.error(f"[RAG增强] 父文档增强失败: {e}", exc_info=True)
+            # 失败时使用原始结果
+            enhanced_results = bfp_result_lists
+
+        # Step 5: 提取第一个结果返回 (使用增强后的结果)
+        final_result = extract_first_result(enhanced_results)
+
+        # 保存最终结果用于调试
+        with open(rf"temp\entity_bfp_recall\extract_first_result.json", "w", encoding='utf-8') as f:
+            json.dump(final_result, f, ensure_ascii=False, indent=4)
+
+        return final_result
 
-        first_result = first_result_list[0]
-        file_name = first_result['metadata'].get('file_name', 'unknown')
-        text_content = first_result['text_content']
 
-        return {
-        'file_name': file_name,
-        'text_content': text_content,
-        'metadata': first_result['metadata']
-        }
-        
     async def check_grammar(self, trace_id_idx: str, review_content: str, review_references: str,
                           review_location_label: str, state: str, stage_name: str) -> Dict[str, Any]:
         """
@@ -664,10 +595,10 @@ class AIReviewEngine(BaseReviewer):
         if str(check_completeness_dir) not in sys.path:
             sys.path.insert(0, str(check_completeness_dir))
         
-        from components.data_loader import CSVDataLoader
-        from components.prompt_builder import PromptBuilder
-        from components.llm_client import LLMClient
-        from components.result_processor import ResultProcessor
+        from check_completeness.components.data_loader import CSVDataLoader
+        from check_completeness.components.prompt_builder import PromptBuilder
+        from check_completeness.components.llm_client import LLMClient
+        from check_completeness.components.result_processor import ResultProcessor
         
         name = "completeness_check"
         start_time = time.time()
@@ -906,7 +837,7 @@ class AIReviewEngine(BaseReviewer):
         prompt_name = Stage.TECHNICAL.value['non_parameter']
         trace_id = prompt_name+trace_id_idx
         return await self.review("non_parameter_compliance_check", trace_id, reviewer_type, prompt_name, review_content, review_references,
-                               reference_source, review_location_label, state, stage_name)
+                               reference_source, review_location_label, state, stage_name, timeout=45)
 
     async def check_parameter_compliance(self, trace_id_idx: str, review_content: str, review_references: str,
                                         reference_source: str, review_location_label: str, state: str, stage_name: str) -> Dict[str, Any]:
@@ -929,7 +860,7 @@ class AIReviewEngine(BaseReviewer):
         prompt_name = Stage.TECHNICAL.value['parameter']
         trace_id = prompt_name+trace_id_idx
         return await self.review("parameter_compliance_check", trace_id, reviewer_type, prompt_name, review_content, review_references,
-                               reference_source, review_location_label, state, stage_name)
+                               reference_source, review_location_label, state, stage_name, timeout=45)
 
     async def outline_check(self, trace_id_idx: str, outline_content: Dict[str, Any],
                                    state:dict,stage_name:str) -> Dict[str, Any]:

+ 231 - 0
core/construction_review/component/infrastructure/parent_tool.py

@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+@Project   : lq-agent-api
+@File      : parent_tool.py
+@IDE       : VsCode
+@Author    : 王旭明
+@Date      : 2025-12-30
+@Description: 父文档增强工具 - 提供父文档查询和拼接功能
+"""
+
+from typing import Any, Dict, List, Optional
+
+from foundation.observability.logger.loggering import server_logger as logger
+
+
+# =============================== 配置 ===============================
+
+PARENT_COLLECTION = "rag_parent_hybrid"  # 父文档集合名称
+PARENT_OUTPUT_FIELDS = ["parent_id", "text"]  # 父文档查询字段
+
+
+# =============================== 核心工具函数 ===============================
+
+def fetch_parent_document(
+    milvus_manager,
+    parent_id: str,
+    collection_name: str = PARENT_COLLECTION,
+    output_fields: List[str] = PARENT_OUTPUT_FIELDS
+) -> Optional[Dict[str, Any]]:
+    """
+    查询单个父文档
+
+    Args:
+        milvus_manager: MilvusManager 实例
+        parent_id: 父文档ID
+        collection_name: 集合名称
+        output_fields: 需要返回的字段列表
+
+    Returns:
+        父文档字典,如果不存在返回None
+    """
+    try:
+        rows = milvus_manager.condition_query(
+            collection_name=collection_name,
+            filter=f"parent_id == '{parent_id}'",
+            output_fields=output_fields,
+            limit=1,
+        )
+
+        if not rows or not rows[0]:
+            logger.debug(f"[父文档工具] 父文档 {parent_id} 不存在")
+            return None
+
+        # 只返回需要的字段
+        result = {k: rows[0].get(k) for k in output_fields if k in rows[0]}
+        logger.debug(f"[父文档工具] 父文档 {parent_id} 查询成功, 内容长度: {len(result.get('text', ''))}")
+        return result
+
+    except Exception as e:
+        logger.error(f"[父文档工具] 查询父文档 {parent_id} 失败: {e}")
+        return None
+
+
+def enhance_with_parent_docs(
+    milvus_manager,
+    bfp_result_lists: List,
+    top_k: int = 3,
+    max_parent_text_length: Optional[int] = None
+) -> Dict[str, Any]:
+    """
+    使用父文档增强检索结果 (显式返回版本)
+
+    流程:
+    1. 统计所有 parent_id 的出现频率
+    2. 按频率排序,取 top-k 个 parent_id
+    3. 查询这 k 个父文档
+    4. 将所有父文档拼接在一起
+    5. 创建新的结果列表,添加父文档内容
+    6. 显式返回增强后的结果
+
+    Args:
+        milvus_manager: MilvusManager 实例
+        bfp_result_lists: 检索结果列表 (不会被修改)
+        top_k: 提取前k个父文档ID (默认3个)
+        max_parent_text_length: 单个父文档最大长度限制 (None=不限制)
+
+    Returns:
+        Dict[str, Any]: 增强结果,包含:
+            - enhanced_results: 增强后的结果列表
+            - enhanced_count: 成功增强的结果数量
+            - parent_docs: 使用的父文档列表
+            - combined_text: 拼接后的父文档文本
+    """
+    # Step 1: 统计 parent_id 出现频率
+    parent_id_freq = {}
+    for result_list in bfp_result_lists:
+        if not result_list:
+            continue
+        for result in result_list:
+            metadata = result.get('metadata', {})
+            parent_id = metadata.get('parent_id')
+            if parent_id:
+                parent_id = str(parent_id)
+                parent_id_freq[parent_id] = parent_id_freq.get(parent_id, 0) + 1
+
+    if not parent_id_freq:
+        logger.info("[父文档工具] 没有发现父文档ID")
+        return {
+            'enhanced_results': [],
+            'enhanced_count': 0,
+            'parent_docs': [],
+            'combined_text': ''
+        }
+
+    # Step 2: 按频率排序,取 top-k 个 parent_id
+    top_parent_items = sorted(
+        parent_id_freq.items(),
+        key=lambda x: x[1],
+        reverse=True
+    )[:top_k]
+
+    top_parent_ids = [pid for pid, freq in top_parent_items]
+    logger.info(f"[父文档工具] 提取 top-{len(top_parent_ids)} 父文档ID: {top_parent_ids}")
+    logger.debug(f"[父文档工具] 父文档频率: {dict(top_parent_items)}")
+
+    # Step 3: 批量查询父文档内容
+    parent_docs = []
+    for parent_id in top_parent_ids:
+        parent_doc = fetch_parent_document(
+            milvus_manager=milvus_manager,
+            parent_id=parent_id
+        )
+
+        if parent_doc and parent_doc.get('text'):
+            parent_text = parent_doc['text']
+
+            # 可选: 截断过长的父文档
+            if max_parent_text_length and len(parent_text) > max_parent_text_length:
+                parent_text = parent_text[:max_parent_text_length] + "\n...(内容过长已截断)"
+                logger.debug(f"[父文档工具] 父文档 {parent_id} 内容过长,已截断到 {max_parent_text_length} 字符")
+
+            parent_docs.append({
+                'parent_id': parent_id,
+                'text': parent_text
+            })
+            logger.info(f"[父文档工具] 成功查询父文档 {parent_id}, 内容长度: {len(parent_text)}")
+        else:
+            logger.warning(f"[父文档工具] 父文档 {parent_id} 查询失败或内容为空")
+
+    if not parent_docs:
+        logger.warning("[父文档工具] 所有父文档查询均失败")
+        return {
+            'enhanced_results': [],
+            'enhanced_count': 0,
+            'parent_docs': [],
+            'combined_text': ''
+        }
+
+    # Step 4: 将所有父文档拼接在一起
+    combined_parent_text = "\n".join([
+        f"【父文档 {i+1}】\n{doc['text']}"
+        for i, doc in enumerate(parent_docs)
+    ])
+    logger.info(f"[父文档工具] 拼接了 {len(parent_docs)} 个父文档, 总长度: {len(combined_parent_text)}")
+
+    # Step 5: 创建新的增强结果列表
+    enhanced_results = []
+    enhanced_count = 0
+
+    for result_list in bfp_result_lists:
+        enhanced_list = []
+        if not result_list:
+            enhanced_results.append(enhanced_list)
+            continue
+
+        for result in result_list:
+            # 创建新的结果字典 (不修改原数据)
+            enhanced_result = {
+                'text_content': result.get('text_content', '') + f"\n{combined_parent_text}\n",
+                'metadata': result.get('metadata', {}),
+                'hybrid_similarity': result.get('hybrid_similarity'),
+                'rerank_score': result.get('rerank_score'),
+                'bfp_rerank_score': result.get('bfp_rerank_score'),
+                'bfp_rerank_parent_id': result.get('bfp_rerank_parent_id', '')
+            }
+            enhanced_list.append(enhanced_result)
+            enhanced_count += 1
+
+        enhanced_results.append(enhanced_list)
+
+    logger.info(f"[父文档工具] 成功增强 {enhanced_count} 个结果")
+
+    # Step 6: 显式返回增强结果
+    return {
+        'enhanced_results': enhanced_results,
+        'enhanced_count': enhanced_count,
+        'parent_docs': parent_docs,
+        'combined_text': combined_parent_text
+    }
+
+
+def extract_first_result(bfp_result_lists: List) -> Dict[str, Any]:
+    """
+    从检索结果中提取第一个有效结果
+
+    Args:
+        bfp_result_lists: 检索结果列表
+
+    Returns:
+        第一个结果的格式化字典
+    """
+    if not bfp_result_lists or not bfp_result_lists[0]:
+        logger.warning("[父文档工具] 第一个查询对无检索结果")
+        return {
+            'vector_search': [],
+            'retrieval_status': 'no_results',
+            'file_name': '',
+            'text_content': '',
+            'metadata': {}
+        }
+
+    first_result = bfp_result_lists[0][0]
+    return {
+        'file_name': first_result['metadata'].get('file_name', 'unknown'),
+        'text_content': first_result['text_content'],
+        'metadata': first_result['metadata'],
+        'retrieval_status': 'success',
+        #'vector_search': bfp_result_lists
+    }

+ 4 - 2
core/construction_review/component/reviewers/base_reviewer.py

@@ -37,7 +37,7 @@ class BaseReviewer(ABC):
     
     #@obverse
     async def review(self, name: str, trace_id: str, reviewer_type: str, prompt_name: str, review_content: str, review_references: str = None,
-                    reference_source: str = None, review_location_label: str = None,state:str =None,stage_name:str = None,) -> ReviewResult:
+                    reference_source: str = None, review_location_label: str = None,state:str =None,stage_name:str = None, timeout: int = 60) -> ReviewResult:
         """
         执行审查
 
@@ -54,6 +54,7 @@ class BaseReviewer(ABC):
             review_references: 审查参考内容 (可选)
             stage_name: 阶段名称 (可选,用于进度更新)
             state: 状态字典 (可选,用于进度更新)
+            timeout: 模型调用超时时间,默认60秒 (可选)
 
 
         Returns:
@@ -79,7 +80,8 @@ class BaseReviewer(ABC):
             # 调用模型
             model_response = await self.model_client.get_model_generate_invoke(
                 trace_id=trace_id,
-                task_prompt_info=task_prompt_info
+                task_prompt_info=task_prompt_info,
+                timeout=timeout
             )
             if reference_source:
                 result = self.format_result(model_response, name, reference_source, review_references)

+ 2 - 2
core/construction_review/component/reviewers/utils/inter_tool.py

@@ -468,8 +468,8 @@ class InterTool:
                         continue
                     return self._determine_risk_level(risk_str)
 
-        # 处理直接的风险等级字符串
-        risk_str = risk_input.lower()
+        # 处理直接的风险等级字符串 - 先转换为字符串避免 dict 类型错误
+        risk_str = str(risk_input).lower()
         if "高" in risk_str or "high" in risk_str:
             return "high"
         elif "中" in risk_str or "medium" in risk_str:

+ 8 - 47
utils_test/RAG_Test/debug_query_extract.py

@@ -20,53 +20,14 @@ def debug_query_extract():
     """
     # 测试数据
     review_content = """
-相关准备工作
-1、技术准备
-四川公路桥梁建设集团有限公司 镇广C4项目经理部JQ220t-40m架桥机安装及拆除专项施工方案
-(1)应将架桥机随机文件和有关技术资料准备齐全,认真组织安装人员学习阅
-读本方案,并以此为依据结合实际工况及地貌拟定有关安装施工方案。
-(2)安装前,应对设备散件进行全面检查、清理,如发现有损伤、腐蚀或其它
-缺陷,应在安装前予以处理,合格后方可安装。
-(3)应对架桥机运梁轨道进行如下检查:
-1)架桥机运梁轨道基础应有足够的承压能力,应能满足架桥机运梁平车载重安
-全运行。轨道下部如有支垫是否具有强大的刚性和一定的密度,特殊端部的支垫必
-须采用刚性支垫,严禁使用腐蚀的枕木。
-2)轨道钢轨正面、侧面的不平度不应大于1/1500,全长范围内不应大于10毫
-米。
-3)轨道安装的允许偏差:
-①轨道实际中心线对轨道设计中心线的位置偏移允许偏差为3毫米。
-②轨距允许偏差为±5毫米。
-③轨道纵向不平度应小于 1/1500,且全行程不超过10毫米。
-④同一断面上两轨道的标高相对偏差不超过5毫米。
-4)轨道接头应符合下列要求:
-①接头左、右、上三面错位不应大于2毫米。
-②两平行轨道接口的位置应错开,其错开距离不应等于架桥机运梁平车前后车
-轮的轮距。
-第19页
-四川公路桥梁建设集团有限公司 镇广C4项目经理部JQ220t-40m架桥机安装及拆除专项施工方案
-③接头间隙应为1~2毫米,伸缩缝接头间隙应符合设计要求,其偏差不应大于
-±1毫米。
-④轨道的悬空部位是否得到了加强。
-5)施工期间的基本要求及安全规定
-①架桥机安装属于高空作业,施工前技术员及现场指挥员向参加施工的所有人
-员详细介绍安装工序、技术要求和指挥信号。
-②严禁在施工的架桥机下面逗留通过,与安装施工无关人员不准擅自进入施工
-现场。
-③现场施工人员必须按有关安全规定佩戴好安全用品(安全带、安全帽、绝缘
-鞋等)。
-④施工现场使用的氧气瓶、乙炔瓶必须保证立放并固定好,两瓶之间距离不得
-小于5m。
-6)架桥机组装
-①安装原则:按从下至上的顺序进行安装,且必须在下部结构安装固定牢固以
-后,才能进行上部结构的安装。同时,在安装过程中,在运输及吊装能力允许的情
-况下,尽量保持设备各部件的整体性,一方面能有效减少危险作业点,另一方面有
-利于提高设备现场安装工效。
-②安装场地:架桥拼装在桥台台背后路基上,拼装场地选址位于路基上,拼装
-场地面积宽15m,长 100m,架桥机主体最大宽度为9m(移动轨道 18m),路基宽度
-满足安装场地所需,路基及便道顶面承载力满足接卸拼装所需的承载要求。
-③辅助机械设备:根据施工现场实际情况,选择1台25T汽车吊作为主要安装
-设备,架桥机主梁拼装采用分节进行吊装,整机重量最大的组件为三节主梁同时起
-吊,总重18t,采用2 台50t汽车吊满足吊装要求。
+主要部件说明
+1、主梁总成
+主梁总成由主梁和导梁构成。主梁单节长12m,共7节,每节重10.87t,主梁为主要承载受力构件,其上弦杆上方设有轨道供纵移桁车走行,实现预制梁的纵向移动;下弦设有反滚轮行走轨道,作为导梁纵移、前中支腿移动纵行轨道。导梁长18m,主要是为降低过孔挠度和承受中支腿移动荷载,起安全引导、辅助过孔作用。主梁、导梁为三角桁架构件单元,采用销轴连接,前、后端各设置横联构架。
+
+图4-1 主梁总成图
+注意事项:
+(1)更换上、下弦销轴时,应优先向设备供应方购买符合要求的备件。自行更换时,材料性能必须优于设计零件性能,并按规定进行热处理,否则可能造成人员、设备事故。
+(2)销轴不得弯曲受力,不得用销轴作为锤砸工具,不得任意放置及焊接
 
 """
     query_rewrite_manager = QueryRewriteManager()

+ 30 - 51
utils_test/RAG_Test/test_rag_enhanced_check.py

@@ -10,70 +10,49 @@ import os
 import asyncio
 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 
+
+from core.base.task_models import TaskFileInfo
 from core.construction_review.component.ai_review_engine import AIReviewEngine
 from foundation.observability.logger.loggering import server_logger as logger
 
-# 实例化AIReviewEngine
-review_engine = AIReviewEngine()
+# 构建测试用的 TaskFileInfo
+test_file_info = {
+    'file_id': 'test_file_001',
+    'user_id': 'test_user',
+    'callback_task_id': 'test_task_001',
+    'file_name': 'test_document.pdf',
+    'file_type': 'pdf',
+    'review_config': ['non_parameter_compliance_check', 'parameter_compliance_check'],
+    'project_plan_type': '桥梁施工方案',
+    'tendency_review_role': 'reviewer',
+    'launched_at': 0
+}
+
+# 创建 TaskFileInfo 实例
+task_file_info = TaskFileInfo(test_file_info)
+
+# 实例化AIReviewEngine (传入 task_file_info)
+review_engine = AIReviewEngine(task_file_info=task_file_info)
 
 # 记录开始时间
 import time
 start_time = time.time()
-query = """ 相关准备工作
-1、技术准备
-四川公路桥梁建设集团有限公司 镇广C4项目经理部JQ220t-40m架桥机安装及拆除专项施工方案
-(1)应将架桥机随机文件和有关技术资料准备齐全,认真组织安装人员学习阅
-读本方案,并以此为依据结合实际工况及地貌拟定有关安装施工方案。
-(2)安装前,应对设备散件进行全面检查、清理,如发现有损伤、腐蚀或其它
-缺陷,应在安装前予以处理,合格后方可安装。
-(3)应对架桥机运梁轨道进行如下检查:
-1)架桥机运梁轨道基础应有足够的承压能力,应能满足架桥机运梁平车载重安
-全运行。轨道下部如有支垫是否具有强大的刚性和一定的密度,特殊端部的支垫必
-须采用刚性支垫,严禁使用腐蚀的枕木。
-2)轨道钢轨正面、侧面的不平度不应大于1/1500,全长范围内不应大于10毫
-米。
-3)轨道安装的允许偏差:
-①轨道实际中心线对轨道设计中心线的位置偏移允许偏差为3毫米。
-②轨距允许偏差为±5毫米。
-③轨道纵向不平度应小于 1/1500,且全行程不超过10毫米。
-④同一断面上两轨道的标高相对偏差不超过5毫米。
-4)轨道接头应符合下列要求:
-①接头左、右、上三面错位不应大于2毫米。
-②两平行轨道接口的位置应错开,其错开距离不应等于架桥机运梁平车前后车
-轮的轮距。
-第19页
-四川公路桥梁建设集团有限公司 镇广C4项目经理部JQ220t-40m架桥机安装及拆除专项施工方案
-③接头间隙应为1~2毫米,伸缩缝接头间隙应符合设计要求,其偏差不应大于
-±1毫米。
-④轨道的悬空部位是否得到了加强。
-5)施工期间的基本要求及安全规定
-①架桥机安装属于高空作业,施工前技术员及现场指挥员向参加施工的所有人
-员详细介绍安装工序、技术要求和指挥信号。
-②严禁在施工的架桥机下面逗留通过,与安装施工无关人员不准擅自进入施工
-现场。
-③现场施工人员必须按有关安全规定佩戴好安全用品(安全带、安全帽、绝缘
-鞋等)。
-④施工现场使用的氧气瓶、乙炔瓶必须保证立放并固定好,两瓶之间距离不得
-小于5m。
-6)架桥机组装
-①安装原则:按从下至上的顺序进行安装,且必须在下部结构安装固定牢固以
-后,才能进行上部结构的安装。同时,在安装过程中,在运输及吊装能力允许的情
-况下,尽量保持设备各部件的整体性,一方面能有效减少危险作业点,另一方面有
-利于提高设备现场安装工效。
-②安装场地:架桥拼装在桥台台背后路基上,拼装场地选址位于路基上,拼装
-场地面积宽15m,长 100m,架桥机主体最大宽度为9m(移动轨道 18m),路基宽度
-满足安装场地所需,路基及便道顶面承载力满足接卸拼装所需的承载要求。
-③辅助机械设备:根据施工现场实际情况,选择1台25T汽车吊作为主要安装
-设备,架桥机主梁拼装采用分节进行吊装,整机重量最大的组件为三节主梁同时起
-吊,总重18t,采用2 台50t汽车吊满足吊装要求。"""
+query = """ 主要部件说明
+1、主梁总成
+主梁总成由主梁和导梁构成。主梁单节长12m,共7节,每节重10.87t,主梁为主要承载受力构件,其上弦杆上方设有轨道供纵移桁车走行,实现预制梁的纵向移动;下弦设有反滚轮行走轨道,作为导梁纵移、前中支腿移动纵行轨道。导梁长18m,主要是为降低过孔挠度和承受中支腿移动荷载,起安全引导、辅助过孔作用。主梁、导梁为三角桁架构件单元,采用销轴连接,前、后端各设置横联构架。
+
+图4-1 主梁总成图
+注意事项:
+(1)更换上、下弦销轴时,应优先向设备供应方购买符合要求的备件。自行更换时,材料性能必须优于设计零件性能,并按规定进行热处理,否则可能造成人员、设备事故。
+(2)销轴不得弯曲受力,不得用销轴作为锤砸工具,不得任意放置及焊接"""
 unit_content= {
     "content" : query,
 }
 result = review_engine.rag_enhanced_check(unit_content)
+
+
 print(result)
 
 end_time = time.time()
 elapsed_time = end_time - start_time
 print(f"\nRAG增强检查完成,耗时: {elapsed_time:.2f}秒")
-
-