|
|
@@ -4,13 +4,11 @@ AI审查引擎
|
|
|
"""
|
|
|
|
|
|
import asyncio
|
|
|
-import time
|
|
|
-from typing import Dict, List, Any, Optional, Callable
|
|
|
+from enum import Enum
|
|
|
from dataclasses import dataclass
|
|
|
-from datetime import datetime
|
|
|
-
|
|
|
+from typing import Dict, List, Any
|
|
|
from foundation.logger.loggering import server_logger as logger
|
|
|
-
|
|
|
+from core.construction_review.component.reviewers.base_reviewer import BaseReviewer,BaseRAGReviewer
|
|
|
@dataclass
|
|
|
class ReviewResult:
|
|
|
"""审查结果"""
|
|
|
@@ -21,24 +19,76 @@ class ReviewResult:
|
|
|
rag_enhanced: Dict[str, Any]
|
|
|
overall_risk: str
|
|
|
|
|
|
-class AIReviewEngine:
|
|
|
+class Stage(Enum):
|
|
|
+ """工作流状态"""
|
|
|
+ BASIC = {
|
|
|
+ 'reviewer_type':'basic',
|
|
|
+ 'sensitive': 'sensitive_word_check',
|
|
|
+ 'semantic': 'semantic_logic_check',
|
|
|
+ 'completeness': 'completeness_check',
|
|
|
+ 'timeliness': 'timeliness_check',
|
|
|
+ 'reference': 'reference_check'
|
|
|
+ }
|
|
|
+ TECHNICAL = {
|
|
|
+ 'reviewer_type':'technical',
|
|
|
+ 'mandatory': 'mandatory_standards_check',
|
|
|
+ 'technical': 'technical_parameters_check',
|
|
|
+ 'design': 'design_values_check'
|
|
|
+ }
|
|
|
+ RAG = {
|
|
|
+ 'reviewer_type':'rag',
|
|
|
+ 'rag': 'rag_enhanced_review',
|
|
|
+ 'vector': 'vector_search_review',
|
|
|
+ 'hybrid': 'hybrid_search_review'
|
|
|
+ }
|
|
|
+ AI = {
|
|
|
+ 'reviewer_type':'ai',
|
|
|
+ 'professional': 'professional_suggestion',
|
|
|
+ 'standardization': 'standardization_suggestion',
|
|
|
+ 'completeness': 'completeness_suggestion',
|
|
|
+ 'readability': 'readability_suggestion'
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+class AIReviewEngine(BaseReviewer):
|
|
|
"""AI审查引擎 - 支持审查条目并发"""
|
|
|
|
|
|
- def __init__(self, max_concurrent_reviews: int = 20):
|
|
|
+ def __init__(self, max_concurrent_reviews: int = 8):
|
|
|
+ super().__init__()
|
|
|
self.max_concurrent_reviews = max_concurrent_reviews
|
|
|
self.semaphore = asyncio.Semaphore(max_concurrent_reviews)
|
|
|
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- async def basic_compliance_check(self, unit_content: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
+ async def basic_compliance_check(self,trace_id_idx: str, unit_content: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
"""基础合规性检查"""
|
|
|
- # 词句语法检查
|
|
|
- grammar_result = await self.check_grammar(unit_content['content'])
|
|
|
+ review_content = unit_content['content']
|
|
|
+ review_references = unit_content.get('review_references')
|
|
|
+
|
|
|
+ logger.info(f"开始基础合规性检查, 内容长度: {len(review_content)}")
|
|
|
+
|
|
|
+ async def check_with_semaphore(check_func, *args):
|
|
|
+ async with self.semaphore:
|
|
|
+ return await check_func(*args)
|
|
|
+
|
|
|
+ basic_tasks = [
|
|
|
+ check_with_semaphore(self.check_grammar, trace_id_idx, review_content, review_references),
|
|
|
+ check_with_semaphore(self.check_semantic_logic, trace_id_idx, review_content, review_references),
|
|
|
+ check_with_semaphore(self.check_completeness, trace_id_idx, review_content, review_references)
|
|
|
+ ]
|
|
|
+
|
|
|
+
|
|
|
+ grammar_result, semantic_result, completeness_result = await asyncio.gather(*basic_tasks, return_exceptions=True)
|
|
|
|
|
|
- # 语义逻辑检查
|
|
|
- semantic_result = await self.check_semantic_logic(unit_content['content'])
|
|
|
|
|
|
- # 条文完整性检查
|
|
|
- completeness_result = await self.check_completeness(unit_content['content'])
|
|
|
+
|
|
|
+ if isinstance(grammar_result, Exception):
|
|
|
+ grammar_result = {"error": str(grammar_result), "success": False}
|
|
|
+ if isinstance(semantic_result, Exception):
|
|
|
+ semantic_result = {"error": str(semantic_result), "success": False}
|
|
|
+ if isinstance(completeness_result, Exception):
|
|
|
+ completeness_result = {"error": str(completeness_result), "success": False}
|
|
|
|
|
|
return {
|
|
|
'grammar_check': grammar_result,
|
|
|
@@ -47,16 +97,30 @@ class AIReviewEngine:
|
|
|
'overall_score': self._calculate_basic_score(grammar_result, semantic_result, completeness_result)
|
|
|
}
|
|
|
|
|
|
- async def technical_compliance_check(self, unit_content: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
+ async def technical_compliance_check(self, trace_id_idx: str, unit_content: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
"""技术性合规检查"""
|
|
|
- # 强制性标准符合性检查
|
|
|
- mandatory_result = await self.check_mandatory_standards(unit_content['content'])
|
|
|
-
|
|
|
- # 设计值符合性检查
|
|
|
- design_value_result = await self.check_design_values(unit_content['content'])
|
|
|
-
|
|
|
- # 技术参数精确检查
|
|
|
- technical_param_result = await self.check_technical_parameters(unit_content['content'])
|
|
|
+ review_content = unit_content['content']
|
|
|
+ review_references = unit_content.get('review_references')
|
|
|
+ logger.info(f"开始技术性合规检查,内容长度: {len(review_content)}")
|
|
|
+ async def check_with_semaphore(check_func, *args):
|
|
|
+ async with self.semaphore:
|
|
|
+ return await check_func(*args)
|
|
|
+
|
|
|
+ technical_tasks = [
|
|
|
+ check_with_semaphore(self.check_mandatory_standards, trace_id_idx, review_content,review_references),
|
|
|
+ check_with_semaphore(self.check_design_values, trace_id_idx, review_content,review_references),
|
|
|
+ check_with_semaphore(self.check_technical_parameters, trace_id_idx, review_content,review_references)
|
|
|
+ ]
|
|
|
+
|
|
|
+ mandatory_result, design_value_result, technical_param_result = await asyncio.gather(*technical_tasks, return_exceptions=True)
|
|
|
+
|
|
|
+ # 处理异常结果
|
|
|
+ if isinstance(mandatory_result, Exception):
|
|
|
+ mandatory_result = {"error": str(mandatory_result), "success": False}
|
|
|
+ if isinstance(design_value_result, Exception):
|
|
|
+ design_value_result = {"error": str(design_value_result), "success": False}
|
|
|
+ if isinstance(technical_param_result, Exception):
|
|
|
+ technical_param_result = {"error": str(technical_param_result), "success": False}
|
|
|
|
|
|
return {
|
|
|
'mandatory_standards': mandatory_result,
|
|
|
@@ -83,41 +147,50 @@ class AIReviewEngine:
|
|
|
'enhanced_suggestions': self.generate_enhanced_suggestions(reranked_results)
|
|
|
}
|
|
|
|
|
|
- # 基础合规性审查 - 原子化组件方法
|
|
|
- async def check_grammar(self, content: str) -> Dict[str, Any]:
|
|
|
+
|
|
|
+ async def check_grammar(self, trace_id_idx: str, review_content: str = None, review_references: str = None) -> Dict[str, Any]:
|
|
|
"""语法检查"""
|
|
|
- await asyncio.sleep(0.1) # 模拟处理时间
|
|
|
- return {"score": 85, "issues": []}
|
|
|
+ reviewer_type = Stage.BASIC.value['reviewer_type']
|
|
|
+ prompt_name = Stage.BASIC.value['sensitive']
|
|
|
+ trace_id = prompt_name+trace_id_idx
|
|
|
+ return await self.review("语法检查", trace_id, reviewer_type, prompt_name, review_content,review_references)
|
|
|
|
|
|
- async def check_semantic_logic(self, content: str) -> Dict[str, Any]:
|
|
|
+ async def check_semantic_logic(self, trace_id_idx: str, review_content: str = None, review_references: str = None) -> Dict[str, Any]:
|
|
|
"""语义逻辑检查"""
|
|
|
- logger.info(f"开始执行语法检查,内容:{content}")
|
|
|
- await asyncio.sleep(0.1)
|
|
|
- return {"score": 90, "logic_issues": []}
|
|
|
+ reviewer_type = Stage.BASIC.value['reviewer_type']
|
|
|
+ prompt_name = Stage.BASIC.value['semantic']
|
|
|
+ trace_id = prompt_name+trace_id_idx
|
|
|
+ return await self.review("语义逻辑检查", trace_id, reviewer_type, prompt_name, review_content,review_references)
|
|
|
|
|
|
- async def check_completeness(self, content: str) -> Dict[str, Any]:
|
|
|
+ async def check_completeness(self, trace_id_idx: str, review_content: str = None, review_references: str = None) -> Dict[str, Any]:
|
|
|
"""完整性检查"""
|
|
|
- logger.info(f"开始执行完整性检查,内容:{content}")
|
|
|
- await asyncio.sleep(0.1)
|
|
|
- return {"score": 88, "missing_items": []}
|
|
|
+ reviewer_type = Stage.BASIC.value['reviewer_type']
|
|
|
+ prompt_name = Stage.BASIC.value['completeness']
|
|
|
+ trace_id = prompt_name+trace_id_idx
|
|
|
+ return await self.review("完整性检查", trace_id, reviewer_type, prompt_name, review_content,review_references)
|
|
|
|
|
|
- async def check_mandatory_standards(self, content: str) -> Dict[str, Any]:
|
|
|
+ async def check_mandatory_standards(self, trace_id_idx: str, review_content: str = None, review_references: str = None) -> Dict[str, Any]:
|
|
|
"""强制性标准检查"""
|
|
|
- logger.info(f"开始执行强制性标准检查,内容:{content}")
|
|
|
- await asyncio.sleep(0.3)
|
|
|
- return {"compliance_rate": 92, "violations": []}
|
|
|
+ reviewer_type = Stage.TECHNICAL.value['reviewer_type']
|
|
|
+ prompt_name = Stage.TECHNICAL.value['mandatory']
|
|
|
+ trace_id = prompt_name+trace_id_idx
|
|
|
+ return await self.review("强制性标准检查", trace_id, reviewer_type, prompt_name, review_content,review_references)
|
|
|
|
|
|
- async def check_design_values(self, content: str) -> Dict[str, Any]:
|
|
|
+ async def check_design_values(self, trace_id_idx: str, review_content: str = None, review_references: str = None) -> Dict[str, Any]:
|
|
|
"""设计值检查"""
|
|
|
- await asyncio.sleep(0.2)
|
|
|
- return {"accuracy": 87, "deviations": []}
|
|
|
+ reviewer_type = Stage.TECHNICAL.value['reviewer_type']
|
|
|
+ prompt_name = Stage.TECHNICAL.value['design']
|
|
|
+ trace_id = prompt_name+trace_id_idx
|
|
|
+ return await self.review("设计值检查", trace_id, reviewer_type, prompt_name, review_content,review_references)
|
|
|
|
|
|
- async def check_technical_parameters(self, content: str) -> Dict[str, Any]:
|
|
|
+ async def check_technical_parameters(self, trace_id_idx: str, review_content: str = None, review_references: str = None) -> Dict[str, Any]:
|
|
|
"""技术参数检查"""
|
|
|
- await asyncio.sleep(0.2)
|
|
|
- return {"precision": 90, "errors": []}
|
|
|
+ reviewer_type = Stage.TECHNICAL.value['reviewer_type']
|
|
|
+ prompt_name = Stage.TECHNICAL.value['technical']
|
|
|
+ trace_id = prompt_name+trace_id_idx
|
|
|
+ return await self.review("技术参数检查", trace_id, reviewer_type, prompt_name, review_content,review_references)
|
|
|
|
|
|
- # RAG检索增强 - 原子化组件方法
|
|
|
+ # RAG检索增强
|
|
|
async def vector_search(self, content: str) -> List[Dict[str, Any]]:
|
|
|
"""向量检索"""
|
|
|
await asyncio.sleep(0.1)
|
|
|
@@ -153,7 +226,12 @@ class AIReviewEngine:
|
|
|
basic_score = basic.get('overall_score', 0)
|
|
|
technical_score = technical.get('overall_score', 0)
|
|
|
|
|
|
- avg_score = (basic_score + technical_score) / 2
|
|
|
+ # 如果RAG被禁用或有错误,忽略它
|
|
|
+ if 'error' in rag:
|
|
|
+ avg_score = (basic_score + technical_score) / 2
|
|
|
+ else:
|
|
|
+ rag_score = rag.get('overall_score', 0)
|
|
|
+ avg_score = (basic_score + technical_score + rag_score) / 3
|
|
|
|
|
|
if avg_score >= 90:
|
|
|
return "low"
|