|
|
@@ -191,6 +191,8 @@ class AIReviewEngine(BaseReviewer):
|
|
|
Dict[str, Any]: 基础合规性检查结果
|
|
|
"""
|
|
|
review_content = unit_content['content']
|
|
|
+ with open('temp/review_content.txt', 'a', encoding='utf-8') as f:
|
|
|
+ f.write(str(unit_content))
|
|
|
#review_references = unit_content.get('review_references')
|
|
|
|
|
|
logger.info(f"basic开始基础合规性检查, 内容长度: {len(review_content)}")
|
|
|
@@ -213,6 +215,10 @@ class AIReviewEngine(BaseReviewer):
|
|
|
basic_tasks.append(
|
|
|
check_with_semaphore(self.check_sensitive, trace_id_idx=trace_id_idx, review_content=review_content, review_references=None, review_location_label=review_location_label, state=state, stage_name=stage_name),
|
|
|
)
|
|
|
+ if 'completeness_check' in self.task_info.get_review_config_list():
|
|
|
+ basic_tasks.append(
|
|
|
+ check_with_semaphore(self.check_completeness, trace_id_idx=trace_id_idx, review_content=unit_content, review_references=None, review_location_label=review_location_label, state=state, stage_name=stage_name),
|
|
|
+ )
|
|
|
|
|
|
# 一次性执行所有任务,避免重复协程调用
|
|
|
if not basic_tasks:
|
|
|
@@ -229,7 +235,8 @@ class AIReviewEngine(BaseReviewer):
|
|
|
grammar_result = self._process_review_result(None)
|
|
|
semantic_result = self._process_review_result(None)
|
|
|
sensitive_result = self._process_review_result(None)
|
|
|
-
|
|
|
+ completeness_result = self._process_review_result(None)
|
|
|
+ logger.info(f"completeness_result: {completeness_result}")
|
|
|
result_index = 0
|
|
|
|
|
|
if 'sensitive_word_check' in self.task_info.get_review_config_list():
|
|
|
@@ -246,11 +253,16 @@ class AIReviewEngine(BaseReviewer):
|
|
|
if result_index < len(results):
|
|
|
sensitive_result = self._process_review_result(results[result_index])
|
|
|
result_index += 1
|
|
|
+ if 'completeness_check' in self.task_info.get_review_config_list():
|
|
|
+ if result_index < len(results):
|
|
|
+ completeness_result = self._process_review_result(results[result_index])
|
|
|
+ result_index += 1
|
|
|
|
|
|
return {
|
|
|
'grammar_check': grammar_result,
|
|
|
'semantic_check': semantic_result,
|
|
|
'sensitive_check': sensitive_result,
|
|
|
+ 'completeness_check': completeness_result,
|
|
|
}
|
|
|
async def technical_compliance_check(self,trace_id_idx: str, unit_content: Dict[str, Any],
|
|
|
review_location_label: str,state:str,stage_name:str) -> Dict[str, Any]:
|
|
|
@@ -555,27 +567,166 @@ class AIReviewEngine(BaseReviewer):
|
|
|
# return await self.review("semantic_logic_check", trace_id, reviewer_type, prompt_name, review_content, review_references,
|
|
|
# None, review_location_label, state, stage_name)
|
|
|
|
|
|
- async def check_completeness(self, trace_id_idx: str, review_content: str, review_references: str,
|
|
|
+ async def check_completeness(self, trace_id_idx: str, review_content: Dict[str, Any], review_references: str,
|
|
|
review_location_label: str, state: str, stage_name: str) -> Dict[str, Any]:
|
|
|
"""
|
|
|
完整性检查
|
|
|
|
|
|
Args:
|
|
|
trace_id_idx: 追踪ID索引
|
|
|
- review_content: 审查内容
|
|
|
+ review_content: 审查内容,单个文档块(chunk)的字典,格式如文档切分预处理结果.json中的chunks项
|
|
|
review_references: 审查参考信息
|
|
|
stage_name: 阶段名称
|
|
|
state: 状态字典
|
|
|
- current_progress: 当前进度
|
|
|
+ review_location_label: 审查位置标签
|
|
|
|
|
|
Returns:
|
|
|
Dict[str, Any]: 完整性检查结果
|
|
|
"""
|
|
|
- reviewer_type = Stage.BASIC.value['reviewer_type']
|
|
|
- prompt_name = Stage.BASIC.value['completeness']
|
|
|
- trace_id = prompt_name+trace_id_idx
|
|
|
- return await self.review("completeness_check", trace_id, reviewer_type, prompt_name, review_content, review_references,
|
|
|
- None, review_location_label, state, stage_name)
|
|
|
+ from pathlib import Path
|
|
|
+ import sys
|
|
|
+ import json
|
|
|
+
|
|
|
+ # 导入check_completeness组件
|
|
|
+ check_completeness_dir = Path(__file__).parent / "check_completeness"
|
|
|
+ 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
|
|
|
+
|
|
|
+ name = "completeness_check"
|
|
|
+ start_time = time.time()
|
|
|
+
|
|
|
+ try:
|
|
|
+ # 验证review_content格式
|
|
|
+ if not isinstance(review_content, dict):
|
|
|
+ raise ValueError(f"review_content必须是字典类型,当前类型: {type(review_content)}")
|
|
|
+
|
|
|
+ # 获取文档块信息
|
|
|
+ doc = review_content
|
|
|
+ chunk_id = doc.get('chunk_id', 'unknown')
|
|
|
+ chapter_classification = doc.get('chapter_classification', '')
|
|
|
+ content = doc.get('content', '')
|
|
|
+
|
|
|
+ logger.info(f"开始执行 {name} 审查,trace_id: {trace_id_idx}, chunk_id: {chunk_id}, chapter_classification: {chapter_classification}")
|
|
|
+
|
|
|
+ # 检查必要字段
|
|
|
+ if not chapter_classification:
|
|
|
+ raise ValueError(f"文档块 {chunk_id} 缺少chapter_classification字段")
|
|
|
+
|
|
|
+ if not content:
|
|
|
+ raise ValueError(f"文档块 {chunk_id} 缺少content字段")
|
|
|
+
|
|
|
+ # 初始化组件路径
|
|
|
+ base_dir = check_completeness_dir
|
|
|
+ csv_path = base_dir / 'config' / 'Construction_Plan_Content_Specification.csv'
|
|
|
+ prompt_config_path = base_dir / 'config' / 'prompt.yaml'
|
|
|
+ api_config_path = base_dir / 'config' / 'llm_api.yaml'
|
|
|
+
|
|
|
+ # 加载规范文件
|
|
|
+ data_loader = CSVDataLoader()
|
|
|
+ specification = data_loader.load_specification(str(csv_path))
|
|
|
+
|
|
|
+ # 获取对应的规范要求
|
|
|
+ requirements = specification.get(chapter_classification, [])
|
|
|
+ if not requirements:
|
|
|
+ raise ValueError(f"未找到标签 {chapter_classification} 对应的规范要求")
|
|
|
+
|
|
|
+ logger.info(f"找到 {len(requirements)} 个规范要求项")
|
|
|
+
|
|
|
+ # 初始化组件
|
|
|
+ prompt_builder = PromptBuilder(str(prompt_config_path))
|
|
|
+ llm_client = LLMClient(str(api_config_path))
|
|
|
+ result_processor = ResultProcessor()
|
|
|
+
|
|
|
+ # 构建提示词
|
|
|
+ prompt = prompt_builder.build_prompt(content, requirements)
|
|
|
+
|
|
|
+ # 调用LLM
|
|
|
+ logger.info(f"调用LLM进行审查,使用模型: {llm_client.model_type}")
|
|
|
+ llm_response = await llm_client.call_llm(prompt)
|
|
|
+
|
|
|
+ # 处理结果
|
|
|
+ review_result = result_processor.parse_result(llm_response, requirements)
|
|
|
+
|
|
|
+ # 构建details字段,包含审查结果
|
|
|
+ details = {
|
|
|
+ 'chunk_id': chunk_id,
|
|
|
+ 'name': 'completeness_check',
|
|
|
+ 'chapter_classification': chapter_classification,
|
|
|
+ 'section_label': doc.get('section_label', ''),
|
|
|
+ 'requirements_count': len(requirements),
|
|
|
+ 'checked_items': len(review_result),
|
|
|
+ 'response': review_result[0] if review_result else {},
|
|
|
+ }
|
|
|
+
|
|
|
+ execution_time = time.time() - start_time
|
|
|
+
|
|
|
+ # 创建ReviewResult对象
|
|
|
+ from core.construction_review.component.reviewers.base_reviewer import ReviewResult
|
|
|
+ result = ReviewResult(
|
|
|
+ success=True,
|
|
|
+ details=details,
|
|
|
+ error_message=None,
|
|
|
+ execution_time=execution_time
|
|
|
+ )
|
|
|
+ # with open('temp/completeness_check_result.json','w',encoding='utf-8') as f:
|
|
|
+ # json.dump({"details":result.details,"success":result.success,"error_message":result.error_message,"execution_time":result.execution_time},f,ensure_ascii=False,indent=4)
|
|
|
+ # 将审查结果转换为字典格式,添加到issues中
|
|
|
+ review_result_data = {
|
|
|
+ 'name': name,
|
|
|
+ 'success': result.success,
|
|
|
+ 'details': result.details,
|
|
|
+ 'error_message': result.error_message,
|
|
|
+ 'execution_time': result.execution_time,
|
|
|
+ 'timestamp': time.time()
|
|
|
+ }
|
|
|
+
|
|
|
+ # 推送审查完成信息
|
|
|
+ state_dict = None
|
|
|
+ if state:
|
|
|
+ if isinstance(state, dict):
|
|
|
+ state_dict = state
|
|
|
+ elif isinstance(state, str):
|
|
|
+ try:
|
|
|
+ state_dict = json.loads(state)
|
|
|
+ except (json.JSONDecodeError, AttributeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ if state_dict and state_dict.get("progress_manager"):
|
|
|
+ asyncio.create_task(
|
|
|
+ state_dict["progress_manager"].update_stage_progress(
|
|
|
+ callback_task_id=state_dict.get("callback_task_id"),
|
|
|
+ stage_name=stage_name,
|
|
|
+ current=None,
|
|
|
+ status="processing",
|
|
|
+ message=f"{name} 要点审查完成 (chunk_id: {chunk_id}), 耗时: {result.execution_time:.2f}s",
|
|
|
+ issues=[review_result_data],
|
|
|
+ event_type="processing"
|
|
|
+ )
|
|
|
+ )
|
|
|
+ logger.info(f"{name} 审查完成 (chunk_id: {chunk_id}), 耗时: {result.execution_time:.2f}s")
|
|
|
+
|
|
|
+ return result
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ execution_time = time.time() - start_time
|
|
|
+ error_msg = f"{name} 审查失败: {str(e)}"
|
|
|
+ logger.error(error_msg, exc_info=True)
|
|
|
+
|
|
|
+ from core.construction_review.component.reviewers.base_reviewer import ReviewResult
|
|
|
+ return ReviewResult(
|
|
|
+ success=False,
|
|
|
+ details={
|
|
|
+ 'chunk_id': review_content.get('chunk_id', 'unknown') if isinstance(review_content, dict) else 'unknown',
|
|
|
+ 'error': str(e)
|
|
|
+ },
|
|
|
+ error_message=error_msg,
|
|
|
+ execution_time=execution_time
|
|
|
+ )
|
|
|
|
|
|
async def check_sensitive(self, trace_id_idx: str, review_content: str, review_references: str,
|
|
|
review_location_label: str, state: str, stage_name: str) -> Dict[str, Any]:
|