浏览代码

fix: 全链路审查结果过滤,防止解析失败和异常数据泄漏到最终结果

- grammar_check_reviewer: 修正 details["name"] 从 sensitive_word_check 改为 grammar_check
- inter_tool._create_issue_item: 验证 dict 至少含 issue_point/location/suggestion 一个有意义字段
- inter_tool.parse_ai_review_response: 异常处理改为 exist_issue=False
- ai_review_workflow Phase 5: 兜底过滤增加字符串 check_result 检查

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
WangXuMing 19 小时之前
父节点
当前提交
4f2c896abb

+ 2 - 2
core/construction_review/component/reviewers/grammar_check_reviewer.py

@@ -88,7 +88,7 @@ class GrammarCheckReviewer:
             result = ReviewResult(
                 success=True,
                 details={
-                    "name": "sensitive_word_check",
+                    "name": "grammar_check",
                     "response": model_response
                 },
                 error_message=None,
@@ -130,7 +130,7 @@ class GrammarCheckReviewer:
             # 返回失败结果
             result = ReviewResult(
                 success=False,
-                details={"name": "sensitive_word_check"},
+                details={"name": "grammar_check"},
                 error_message=error_msg,
                 execution_time=execution_time
             )

+ 13 - 1
core/construction_review/component/reviewers/utils/inter_tool.py

@@ -613,7 +613,7 @@ class InterTool:
                 "chapter_code": chapter_code,
                 "check_item_code": check_item_code,
                 "check_result": response,
-                "exist_issue": True,
+                "exist_issue": False,
                 "risk_info": {"risk_level": "low"}
             })
 
@@ -711,6 +711,18 @@ class InterTool:
         # 只有当内容不为空,且风险等级不是"无风险"类时,才认为存在问题
         exist_issue = not is_empty and original_risk_level not in ["无风险", "无", "通过", "符合要求"]
 
+        # 额外验证:dict 类型的 issue_data 必须至少包含一个有意义字段
+        # 防止空壳 dict(如 {"risk_level": "中风险"})通过过滤
+        if exist_issue and isinstance(issue_data, dict):
+            meaningful_fields = ["issue_point", "location", "suggestion"]
+            has_meaningful_content = any(
+                bool(issue_data.get(field, "").strip() if isinstance(issue_data.get(field), str) else issue_data.get(field))
+                for field in meaningful_fields
+            )
+            if not has_meaningful_content:
+                exist_issue = False
+                logger.debug(f"检查项 {check_name} 的 issue_data 缺少有意义字段 (issue_point/location/suggestion),设置 exist_issue=False")
+
         # 记录调试信息
         if is_empty:
             logger.debug(f"检查项 {check_name} 的 issue_data 为空,设置 exist_issue=False")

+ 5 - 1
core/construction_review/workflows/ai_review_workflow.py

@@ -408,11 +408,15 @@ class AIReviewWorkflow:
 
             # ===== Phase 5: 结果汇总 =====
             # 最终兜底过滤:移除 exist_issue=false 的审查项,确保无问题项不进入最终结果
+            # 同时过滤 check_result 为字符串的项(解析失败/异常兜底)
             filtered_issues = []
             for issue_wrapper in all_issues:
                 for issue_id, issue_detail in issue_wrapper.items():
                     review_lists = issue_detail.get('review_lists', [])
-                    filtered_lists = [item for item in review_lists if item.get("exist_issue", False)]
+                    filtered_lists = [
+                        item for item in review_lists
+                        if item.get("exist_issue", False) and not isinstance(item.get("check_result"), str)
+                    ]
                     if filtered_lists:
                         issue_detail['review_lists'] = filtered_lists
                         filtered_issues.append(issue_wrapper)