|
@@ -42,6 +42,7 @@ from langchain_core.messages import AIMessage
|
|
|
from foundation.observability.logger.loggering import server_logger as logger
|
|
from foundation.observability.logger.loggering import server_logger as logger
|
|
|
from foundation.infrastructure.cache.redis_connection import RedisConnectionFactory
|
|
from foundation.infrastructure.cache.redis_connection import RedisConnectionFactory
|
|
|
from core.base.task_models import TaskFileInfo
|
|
from core.base.task_models import TaskFileInfo
|
|
|
|
|
+# from core.construction_review.component.reviewers.base_reviewer import ReviewResult
|
|
|
from ...component.reviewers.utils.inter_tool import InterTool
|
|
from ...component.reviewers.utils.inter_tool import InterTool
|
|
|
from ..types import AIReviewState
|
|
from ..types import AIReviewState
|
|
|
|
|
|
|
@@ -50,8 +51,8 @@ REVIEW_TIMEOUT = 120 # 单个审查任务超时时间(秒)
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
@dataclass
|
|
|
-class ReviewResult:
|
|
|
|
|
- """审查结果"""
|
|
|
|
|
|
|
+class UnitReviewResult():
|
|
|
|
|
+ """Workflow层单元审查结果(包含 basic_compliance 和 technical_compliance)"""
|
|
|
unit_index: int
|
|
unit_index: int
|
|
|
unit_content: Dict[str, Any]
|
|
unit_content: Dict[str, Any]
|
|
|
basic_compliance: Dict[str, Any]
|
|
basic_compliance: Dict[str, Any]
|
|
@@ -141,7 +142,28 @@ class AIReviewCoreFun:
|
|
|
combined_content = "\n\n".join(basis_contents)
|
|
combined_content = "\n\n".join(basis_contents)
|
|
|
logger.info(f"编制依据内容拼接完成,总长度: {len(combined_content)} 字符")
|
|
logger.info(f"编制依据内容拼接完成,总长度: {len(combined_content)} 字符")
|
|
|
|
|
|
|
|
- # 3. 执行需要的审查方法
|
|
|
|
|
|
|
+ # 3. 提取编制依据条目(时效性和规范性审查都需要)
|
|
|
|
|
+ basis_items = None
|
|
|
|
|
+ needs_basis_extraction = any(
|
|
|
|
|
+ fn in ["timeliness_basis_reviewer", "reference_basis_reviewer"]
|
|
|
|
|
+ for fn in func_names
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if needs_basis_extraction:
|
|
|
|
|
+ try:
|
|
|
|
|
+ from core.construction_review.component.reviewers.utils.directory_extraction import (
|
|
|
|
|
+ extract_basis_with_langchain_qwen,
|
|
|
|
|
+ )
|
|
|
|
|
+ basis_items = await extract_basis_with_langchain_qwen(
|
|
|
|
|
+ progress_manager=state.get("progress_manager"),
|
|
|
|
|
+ callback_task_id=state.get("callback_task_id"),
|
|
|
|
|
+ text=combined_content,
|
|
|
|
|
+ )
|
|
|
|
|
+ logger.info(f"编制依据AI提取完成,条数: {len(getattr(basis_items, 'items', []))}")
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ logger.error(f"编制依据AI提取失败: {e}", exc_info=True)
|
|
|
|
|
+
|
|
|
|
|
+ # 4. 执行需要的审查方法
|
|
|
chapter_issues = []
|
|
chapter_issues = []
|
|
|
|
|
|
|
|
for func_name in func_names:
|
|
for func_name in func_names:
|
|
@@ -151,6 +173,7 @@ class AIReviewCoreFun:
|
|
|
try:
|
|
try:
|
|
|
review_data = {
|
|
review_data = {
|
|
|
"content": combined_content,
|
|
"content": combined_content,
|
|
|
|
|
+ "basis_items": basis_items,
|
|
|
"max_concurrent": self.max_concurrent
|
|
"max_concurrent": self.max_concurrent
|
|
|
}
|
|
}
|
|
|
result = await self.ai_review_engine.reference_basis_reviewer(
|
|
result = await self.ai_review_engine.reference_basis_reviewer(
|
|
@@ -173,6 +196,7 @@ class AIReviewCoreFun:
|
|
|
try:
|
|
try:
|
|
|
review_data = {
|
|
review_data = {
|
|
|
"content": combined_content,
|
|
"content": combined_content,
|
|
|
|
|
+ "basis_items": basis_items,
|
|
|
"max_concurrent": self.max_concurrent
|
|
"max_concurrent": self.max_concurrent
|
|
|
}
|
|
}
|
|
|
result = await self.ai_review_engine.timeliness_basis_reviewer(
|
|
result = await self.ai_review_engine.timeliness_basis_reviewer(
|
|
@@ -253,8 +277,8 @@ class AIReviewCoreFun:
|
|
|
chunk_results = await self._execute_chunk_methods(
|
|
chunk_results = await self._execute_chunk_methods(
|
|
|
chapter_code, chunk, chunk_index, func_names, state
|
|
chapter_code, chunk, chunk_index, func_names, state
|
|
|
)
|
|
)
|
|
|
-
|
|
|
|
|
- # 格式化当前块的结果为issues(使用 check_item 模式)
|
|
|
|
|
|
|
+ logger.info(f"🔍 chunk_results: basic_compliance={chunk_results.get('basic_compliance', {})}, technical_compliance={chunk_results.get('technical_compliance', {})}")
|
|
|
|
|
+ # 格式化当前块的结果为issues
|
|
|
chunk_page = chunk.get('page', '')
|
|
chunk_page = chunk.get('page', '')
|
|
|
review_location_label = f"第{chunk_page}页:{chunk_label}"
|
|
review_location_label = f"第{chunk_page}页:{chunk_label}"
|
|
|
issues = self.inter_tool._format_review_results_to_issues(
|
|
issues = self.inter_tool._format_review_results_to_issues(
|
|
@@ -263,14 +287,11 @@ class AIReviewCoreFun:
|
|
|
review_location_label=review_location_label,
|
|
review_location_label=review_location_label,
|
|
|
chapter_code=chapter_code,
|
|
chapter_code=chapter_code,
|
|
|
unit_content=chunk,
|
|
unit_content=chunk,
|
|
|
- basic_result={}, # check_item 模式下不需要
|
|
|
|
|
- technical_result={}, # check_item 模式下不需要
|
|
|
|
|
- merged_results=chunk_results # 直接使用合并结果
|
|
|
|
|
|
|
+ basic_result=chunk_results.get('basic_compliance', {}),
|
|
|
|
|
+ technical_result=chunk_results.get('technical_compliance', {}),
|
|
|
|
|
+ merged_results=None # 不使用 merged_results
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- # 🔍 调试日志:检查issues是否有数据
|
|
|
|
|
- logger.info(f"🔍 块{chunk_index}审查结果: chunk_results键={list(chunk_results.keys()) if chunk_results else 'None'}, issues数量={len(issues) if issues else 0}")
|
|
|
|
|
-
|
|
|
|
|
# 推送当前块的进度
|
|
# 推送当前块的进度
|
|
|
current = int(((chunk_index + 1) / total_chunks) * 100)
|
|
current = int(((chunk_index + 1) / total_chunks) * 100)
|
|
|
await self._send_unit_review_progress(
|
|
await self._send_unit_review_progress(
|
|
@@ -292,7 +313,7 @@ class AIReviewCoreFun:
|
|
|
从审查结果中提取issues列表
|
|
从审查结果中提取issues列表
|
|
|
|
|
|
|
|
Args:
|
|
Args:
|
|
|
- result: 审查结果(可能是ReviewResult、dict、entity_based结果等)
|
|
|
|
|
|
|
+ result: 审查结果(可能是 base_reviewer.ReviewResult、dict、entity_based结果等)
|
|
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
|
List[Dict]: issues列表
|
|
List[Dict]: issues列表
|
|
@@ -302,7 +323,7 @@ class AIReviewCoreFun:
|
|
|
if result is None:
|
|
if result is None:
|
|
|
return issues
|
|
return issues
|
|
|
|
|
|
|
|
- # ReviewResult对象
|
|
|
|
|
|
|
+ # base_reviewer.ReviewResult 对象(Component层)
|
|
|
if hasattr(result, 'details'):
|
|
if hasattr(result, 'details'):
|
|
|
issues.append(result.details)
|
|
issues.append(result.details)
|
|
|
|
|
|
|
@@ -392,14 +413,14 @@ class AIReviewCoreFun:
|
|
|
state: AI审查状态
|
|
state: AI审查状态
|
|
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
|
- Dict[str, Any]: 该块所有方法的执行结果
|
|
|
|
|
|
|
+ Dict[str, Any]: 合并后的 basic_compliance 和 technical_compliance 结果
|
|
|
"""
|
|
"""
|
|
|
- results = {}
|
|
|
|
|
semaphore = asyncio.Semaphore(5) # 单个块内限制并发数为5
|
|
semaphore = asyncio.Semaphore(5) # 单个块内限制并发数为5
|
|
|
rag_enhanced_content = None # 初始化变量,避免作用域错误
|
|
rag_enhanced_content = None # 初始化变量,避免作用域错误
|
|
|
if 'check_parameter_compliance' in func_names or 'check_non_parameter_compliance' in func_names:
|
|
if 'check_parameter_compliance' in func_names or 'check_non_parameter_compliance' in func_names:
|
|
|
logger.debug("开始执行RAG检索增强")
|
|
logger.debug("开始执行RAG检索增强")
|
|
|
rag_enhanced_content = self.ai_review_engine.rag_enhanced_check(chunk.get('content', ''))
|
|
rag_enhanced_content = self.ai_review_engine.rag_enhanced_check(chunk.get('content', ''))
|
|
|
|
|
+
|
|
|
async def execute_with_semaphore(func_name):
|
|
async def execute_with_semaphore(func_name):
|
|
|
async with semaphore:
|
|
async with semaphore:
|
|
|
try:
|
|
try:
|
|
@@ -408,7 +429,14 @@ class AIReviewCoreFun:
|
|
|
return func_name, result
|
|
return func_name, result
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
logger.error(f"审查任务执行失败 [{chapter_code}.chunk{chunk_index}.{func_name}]: {str(e)}")
|
|
logger.error(f"审查任务执行失败 [{chapter_code}.chunk{chunk_index}.{func_name}]: {str(e)}")
|
|
|
- return func_name, {"error": str(e)}
|
|
|
|
|
|
|
+ return func_name, UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={func_name: {"error": str(e)}},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk="error"
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
# 创建并发任务
|
|
# 创建并发任务
|
|
|
async_tasks = [execute_with_semaphore(func_name) for func_name in func_names]
|
|
async_tasks = [execute_with_semaphore(func_name) for func_name in func_names]
|
|
@@ -416,19 +444,33 @@ class AIReviewCoreFun:
|
|
|
# 等待当前块所有方法完成
|
|
# 等待当前块所有方法完成
|
|
|
completed_results = await asyncio.gather(*async_tasks, return_exceptions=True)
|
|
completed_results = await asyncio.gather(*async_tasks, return_exceptions=True)
|
|
|
|
|
|
|
|
- # 整理结果
|
|
|
|
|
|
|
+ # 合并所有 UnitReviewResult 对象的 basic_compliance 和 technical_compliance
|
|
|
|
|
+ merged_basic = {}
|
|
|
|
|
+ merged_technical = {}
|
|
|
|
|
+ merged_rag = {}
|
|
|
|
|
+
|
|
|
for result in completed_results:
|
|
for result in completed_results:
|
|
|
if isinstance(result, Exception):
|
|
if isinstance(result, Exception):
|
|
|
logger.error(f"任务异常: {str(result)}")
|
|
logger.error(f"任务异常: {str(result)}")
|
|
|
continue
|
|
continue
|
|
|
|
|
|
|
|
if result and len(result) == 2:
|
|
if result and len(result) == 2:
|
|
|
- func_name, task_result = result
|
|
|
|
|
- results[func_name] = task_result
|
|
|
|
|
|
|
+ func_name, review_result = result
|
|
|
|
|
+ if isinstance(review_result, UnitReviewResult):
|
|
|
|
|
+ # 合并 basic_compliance
|
|
|
|
|
+ merged_basic.update(review_result.basic_compliance)
|
|
|
|
|
+ # 合并 technical_compliance
|
|
|
|
|
+ merged_technical.update(review_result.technical_compliance)
|
|
|
|
|
+ # 合并 rag_enhanced
|
|
|
|
|
+ merged_rag.update(review_result.rag_enhanced)
|
|
|
|
|
|
|
|
- return results
|
|
|
|
|
|
|
+ return {
|
|
|
|
|
+ 'basic_compliance': merged_basic,
|
|
|
|
|
+ 'technical_compliance': merged_technical,
|
|
|
|
|
+ 'rag_enhanced': merged_rag
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- async def _execute_single_review(self, chapter_code: str, chunk: Dict[str, Any], chunk_index: int, func_name: str, state: AIReviewState,rag_enhanced_content :dict = None) -> Any:
|
|
|
|
|
|
|
+ async def _execute_single_review(self, chapter_code: str, chunk: Dict[str, Any], chunk_index: int, func_name: str, state: AIReviewState,rag_enhanced_content :dict = None) -> UnitReviewResult:
|
|
|
"""
|
|
"""
|
|
|
执行单个块的审查任务
|
|
执行单个块的审查任务
|
|
|
|
|
|
|
@@ -440,12 +482,20 @@ class AIReviewCoreFun:
|
|
|
state: AI审查状态
|
|
state: AI审查状态
|
|
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
|
- Any: 审查结果
|
|
|
|
|
|
|
+ UnitReviewResult: 单个审查方法的UnitReviewResult对象,包含 basic_compliance 或 technical_compliance
|
|
|
"""
|
|
"""
|
|
|
# 从ai_review_engine获取对应的方法
|
|
# 从ai_review_engine获取对应的方法
|
|
|
if not hasattr(self.ai_review_engine, func_name):
|
|
if not hasattr(self.ai_review_engine, func_name):
|
|
|
logger.warning(f"AIReviewEngine中未找到方法: {func_name}")
|
|
logger.warning(f"AIReviewEngine中未找到方法: {func_name}")
|
|
|
- return await self._dummy_review_task(chapter_code, func_name)
|
|
|
|
|
|
|
+ # 返回错误结果的 UnitReviewResult
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={func_name: {"error": f"未找到方法: {func_name}"}},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk="error"
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
method = getattr(self.ai_review_engine, func_name)
|
|
method = getattr(self.ai_review_engine, func_name)
|
|
|
|
|
|
|
@@ -460,44 +510,128 @@ class AIReviewCoreFun:
|
|
|
|
|
|
|
|
# 根据func_name构建对应的参数并调用
|
|
# 根据func_name构建对应的参数并调用
|
|
|
if func_name == "sensitive_word_check":
|
|
if func_name == "sensitive_word_check":
|
|
|
- result = await method(trace_id, review_content, state, stage_name)
|
|
|
|
|
|
|
+ raw_result = await method(trace_id, review_content, state, stage_name)
|
|
|
|
|
+ # 基础审查方法,放入 basic_compliance
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={func_name: raw_result},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk=self._calculate_single_result_risk(raw_result)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
elif func_name == "check_semantic_logic":
|
|
elif func_name == "check_semantic_logic":
|
|
|
- result = await method(trace_id, review_content, state, stage_name)
|
|
|
|
|
|
|
+ raw_result = await method(trace_id, review_content, state, stage_name)
|
|
|
|
|
+ # 基础审查方法,放入 basic_compliance
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={func_name: raw_result},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk=self._calculate_single_result_risk(raw_result)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
elif func_name == "check_sensitive":
|
|
elif func_name == "check_sensitive":
|
|
|
- result = await method(trace_id, review_content, state, stage_name)
|
|
|
|
|
|
|
+ raw_result = await method(trace_id, review_content, state, stage_name)
|
|
|
|
|
+ # 基础审查方法,放入 basic_compliance
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={func_name: raw_result},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk=self._calculate_single_result_risk(raw_result)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
elif func_name == "check_completeness":
|
|
elif func_name == "check_completeness":
|
|
|
- result = await method(trace_id, chunk, state, stage_name)
|
|
|
|
|
|
|
+ raw_result = await method(trace_id, chunk, state, stage_name)
|
|
|
|
|
+ # 基础审查方法,放入 basic_compliance
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={func_name: raw_result},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk=self._calculate_single_result_risk(raw_result)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
elif func_name == "check_non_parameter_compliance":
|
|
elif func_name == "check_non_parameter_compliance":
|
|
|
# 技术审查方法需要从 RAG 检索结果中获取 references
|
|
# 技术审查方法需要从 RAG 检索结果中获取 references
|
|
|
- result = await self._execute_technical_review(
|
|
|
|
|
|
|
+ raw_result = await self._execute_technical_review(
|
|
|
method, trace_id, review_content, chunk, state, stage_name, rag_enhanced_content, func_name
|
|
method, trace_id, review_content, chunk, state, stage_name, rag_enhanced_content, func_name
|
|
|
)
|
|
)
|
|
|
|
|
+ # 技术审查方法,放入 technical_compliance
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={},
|
|
|
|
|
+ technical_compliance={func_name: raw_result},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk=self._calculate_single_result_risk(raw_result)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
elif func_name == "check_parameter_compliance":
|
|
elif func_name == "check_parameter_compliance":
|
|
|
# 技术审查方法需要从 RAG 检索结果中获取 references
|
|
# 技术审查方法需要从 RAG 检索结果中获取 references
|
|
|
- result = await self._execute_technical_review(
|
|
|
|
|
|
|
+ raw_result = await self._execute_technical_review(
|
|
|
method, trace_id, review_content, chunk, state, stage_name, rag_enhanced_content, func_name
|
|
method, trace_id, review_content, chunk, state, stage_name, rag_enhanced_content, func_name
|
|
|
)
|
|
)
|
|
|
|
|
+ # 技术审查方法,放入 technical_compliance
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={},
|
|
|
|
|
+ technical_compliance={func_name: raw_result},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk=self._calculate_single_result_risk(raw_result)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
# ⚠️ 以下三个特殊方法不在块级别处理,由主流程统一管理
|
|
# ⚠️ 以下三个特殊方法不在块级别处理,由主流程统一管理
|
|
|
elif func_name in ["outline_check", "timeliness_basis_reviewer", "reference_basis_reviewer"]:
|
|
elif func_name in ["outline_check", "timeliness_basis_reviewer", "reference_basis_reviewer"]:
|
|
|
logger.warning(f"方法 {func_name} 不应在块级别调用,已在主流程中处理")
|
|
logger.warning(f"方法 {func_name} 不应在块级别调用,已在主流程中处理")
|
|
|
- return None
|
|
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk="low"
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
else:
|
|
else:
|
|
|
logger.warning(f"未知的审查方法: {func_name},使用默认调用方式")
|
|
logger.warning(f"未知的审查方法: {func_name},使用默认调用方式")
|
|
|
- return {
|
|
|
|
|
- "current_stage": "ai_review_check_item",
|
|
|
|
|
- "error_message": f"未知的审查方法: {func_name},使用默认调用方式",
|
|
|
|
|
- "status": "failed",
|
|
|
|
|
- "messages": [AIMessage(content=f"未知的审查方法: {func_name},使用默认调用方式: {state['callback_task_id']}")]
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
|
|
+ unit_index=chunk_index,
|
|
|
|
|
+ unit_content=chunk,
|
|
|
|
|
+ basic_compliance={func_name: {"error": f"未知的审查方法: {func_name}"}},
|
|
|
|
|
+ technical_compliance={},
|
|
|
|
|
+ rag_enhanced={},
|
|
|
|
|
+ overall_risk="error"
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
- return result
|
|
|
|
|
|
|
+ def _calculate_single_result_risk(self, raw_result: Any) -> str:
|
|
|
|
|
+ """计算单个审查结果的风险等级"""
|
|
|
|
|
+ if raw_result is None or isinstance(raw_result, Exception):
|
|
|
|
|
+ return "error"
|
|
|
|
|
+
|
|
|
|
|
+ if isinstance(raw_result, dict):
|
|
|
|
|
+ if "error" in raw_result:
|
|
|
|
|
+ return "error"
|
|
|
|
|
+ # 检查是否有高风险问题
|
|
|
|
|
+ if "details" in raw_result and "response" in raw_result["details"]:
|
|
|
|
|
+ response = raw_result["details"]["response"]
|
|
|
|
|
+ if isinstance(response, str) and ("高风险" in response or "严重" in response):
|
|
|
|
|
+ return "high"
|
|
|
|
|
+ elif hasattr(raw_result, 'success'):
|
|
|
|
|
+ if not raw_result.success:
|
|
|
|
|
+ return "error"
|
|
|
|
|
+ if hasattr(raw_result, 'details') and "response" in raw_result.details:
|
|
|
|
|
+ response = raw_result.details["response"]
|
|
|
|
|
+ if isinstance(response, str) and ("高风险" in response or "严重" in response):
|
|
|
|
|
+ return "high"
|
|
|
|
|
+
|
|
|
|
|
+ return "low"
|
|
|
|
|
|
|
|
async def _execute_technical_review(
|
|
async def _execute_technical_review(
|
|
|
self, method, trace_id: str, review_content: str, chunk: Dict[str, Any],
|
|
self, method, trace_id: str, review_content: str, chunk: Dict[str, Any],
|
|
@@ -801,7 +935,7 @@ class AIReviewCoreFun:
|
|
|
return chunks
|
|
return chunks
|
|
|
|
|
|
|
|
async def _review_single_unit(self, unit_content: Dict[str, Any], unit_index: int,
|
|
async def _review_single_unit(self, unit_content: Dict[str, Any], unit_index: int,
|
|
|
- total_units: int, state: AIReviewState) -> ReviewResult:
|
|
|
|
|
|
|
+ total_units: int, state: AIReviewState) -> UnitReviewResult:
|
|
|
"""
|
|
"""
|
|
|
审查单个单元的核心业务逻辑
|
|
审查单个单元的核心业务逻辑
|
|
|
|
|
|
|
@@ -812,7 +946,7 @@ class AIReviewCoreFun:
|
|
|
state: AI审查状态
|
|
state: AI审查状态
|
|
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
|
- ReviewResult: 单元审查结果
|
|
|
|
|
|
|
+ UnitReviewResult: 单元审查结果
|
|
|
"""
|
|
"""
|
|
|
try:
|
|
try:
|
|
|
|
|
|
|
@@ -859,7 +993,8 @@ class AIReviewCoreFun:
|
|
|
|
|
|
|
|
# 处理异常结果(gather 已经将异常作为结果返回)
|
|
# 处理异常结果(gather 已经将异常作为结果返回)
|
|
|
basic_result = review_results[0] if not isinstance(review_results[0], Exception) else {"error": str(review_results[0])}
|
|
basic_result = review_results[0] if not isinstance(review_results[0], Exception) else {"error": str(review_results[0])}
|
|
|
- technical_result = review_results[1] if not isinstance(review_results[1], Exception) else {"error": str(review_results[1])}
|
|
|
|
|
|
|
+ # technical_result 可能为 None(未提取到实体),需要处理为空字典
|
|
|
|
|
+ technical_result = review_results[1] if not isinstance(review_results[1], Exception) and review_results[1] is not None else {"error": str(review_results[1]) if isinstance(review_results[1], Exception) else "未提取到实体,跳过技术审查"}
|
|
|
|
|
|
|
|
# RAG检查已注释,提供空结果
|
|
# RAG检查已注释,提供空结果
|
|
|
rag_result = {"error": "RAG check disabled"}
|
|
rag_result = {"error": "RAG check disabled"}
|
|
@@ -869,7 +1004,7 @@ class AIReviewCoreFun:
|
|
|
overall_risk = inter_tool._calculate_overall_risk(basic_result, technical_result, rag_result)
|
|
overall_risk = inter_tool._calculate_overall_risk(basic_result, technical_result, rag_result)
|
|
|
|
|
|
|
|
|
|
|
|
|
- return ReviewResult(
|
|
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
unit_index=unit_index,
|
|
unit_index=unit_index,
|
|
|
unit_content=unit_content,
|
|
unit_content=unit_content,
|
|
|
basic_compliance=basic_result,
|
|
basic_compliance=basic_result,
|
|
@@ -880,7 +1015,7 @@ class AIReviewCoreFun:
|
|
|
|
|
|
|
|
except asyncio.TimeoutError:
|
|
except asyncio.TimeoutError:
|
|
|
logger.error(f"审查单元 {unit_index} 超时")
|
|
logger.error(f"审查单元 {unit_index} 超时")
|
|
|
- return ReviewResult(
|
|
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
unit_index=unit_index,
|
|
unit_index=unit_index,
|
|
|
unit_content=unit_content,
|
|
unit_content=unit_content,
|
|
|
basic_compliance={"error": f"审查超时({REVIEW_TIMEOUT}秒)"},
|
|
basic_compliance={"error": f"审查超时({REVIEW_TIMEOUT}秒)"},
|
|
@@ -890,7 +1025,7 @@ class AIReviewCoreFun:
|
|
|
)
|
|
)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
logger.error(f"审查单元 {unit_index} 失败: {str(e)}")
|
|
logger.error(f"审查单元 {unit_index} 失败: {str(e)}")
|
|
|
- return ReviewResult(
|
|
|
|
|
|
|
+ return UnitReviewResult(
|
|
|
unit_index=unit_index,
|
|
unit_index=unit_index,
|
|
|
unit_content=unit_content,
|
|
unit_content=unit_content,
|
|
|
basic_compliance={"error": str(e)},
|
|
basic_compliance={"error": str(e)},
|