|
|
@@ -328,21 +328,20 @@ class LightweightCompletenessChecker:
|
|
|
context = "【问题类型】未知"
|
|
|
reference = ""
|
|
|
|
|
|
- prompt = f"""你是一位资深的工程施工方案审查专家。请根据以下问题上下文和规范参考信息,生成专业的审查建议。
|
|
|
+ prompt = f"""你是一位资深的工程施工方案审查专家。请根据以下问题上下文和规范参考信息,生成专业的补充建议。
|
|
|
|
|
|
{context}
|
|
|
|
|
|
{reference}
|
|
|
|
|
|
-请用JSON格式输出审查建议,包含以下字段:
|
|
|
-- issue_point: 问题摘要(简洁明了,50字以内)
|
|
|
+请用JSON格式输出,只包含以下字段:
|
|
|
- suggestion: 具体补充建议(详细可行,100-200字,包含具体应该补充的内容要点)
|
|
|
-- reason: 规范依据说明(引用具体规范要求,说明为什么需要补充)
|
|
|
|
|
|
注意:
|
|
|
1. suggestion应该具体、可操作,引用规范中的具体内容要求
|
|
|
2. 使用专业的工程术语
|
|
|
3. 语气应该是指导性的,帮助编制人员理解需要补充什么内容
|
|
|
+4. **必须符合现实逻辑**:建议内容应基于实际工程施工的可行性,不能提出不切实际、无法操作或与工程常识相悖的建议
|
|
|
|
|
|
JSON输出:"""
|
|
|
return prompt
|
|
|
@@ -361,8 +360,10 @@ JSON输出:"""
|
|
|
"""
|
|
|
使用大模型生成建议
|
|
|
|
|
|
+ 【修改】只生成 suggestion,issue_point 和 reason 由调用方简单拼接
|
|
|
+
|
|
|
Returns:
|
|
|
- Dict[str, str]: 包含 issue_point, suggestion, reason 的字典
|
|
|
+ Dict[str, str]: 包含 suggestion 的字典,或None使用回退逻辑
|
|
|
"""
|
|
|
if not self.model_client:
|
|
|
return None
|
|
|
@@ -392,14 +393,12 @@ JSON输出:"""
|
|
|
trace_id=trace_id,
|
|
|
task_prompt_info=task_prompt_info,
|
|
|
timeout=timeout,
|
|
|
- model_name="qwen" # 使用默认模型,可根据需要调整
|
|
|
+ model_name="qwen"
|
|
|
)
|
|
|
|
|
|
# 解析模型返回的JSON
|
|
|
try:
|
|
|
- # 尝试从返回文本中提取JSON
|
|
|
response_text = model_response.strip()
|
|
|
- # 查找JSON块
|
|
|
if "```json" in response_text:
|
|
|
json_str = response_text.split("```json")[1].split("```")[0].strip()
|
|
|
elif "```" in response_text:
|
|
|
@@ -408,13 +407,12 @@ JSON输出:"""
|
|
|
json_str = response_text
|
|
|
|
|
|
result = json.loads(json_str)
|
|
|
+ # 只返回 suggestion,issue_point 和 reason 由调用方处理
|
|
|
return {
|
|
|
- "issue_point": result.get("issue_point", ""),
|
|
|
- "suggestion": result.get("suggestion", ""),
|
|
|
- "reason": result.get("reason", "")
|
|
|
+ "suggestion": result.get("suggestion", "")
|
|
|
}
|
|
|
except (json.JSONDecodeError, IndexError) as e:
|
|
|
- logger.warning(f"LLM建议生成结果解析失败: {e},返回: {model_response[:200]}")
|
|
|
+ logger.warning(f"LLM建议生成结果解析失败: {e}")
|
|
|
return None
|
|
|
|
|
|
except Exception as e:
|
|
|
@@ -898,7 +896,11 @@ JSON输出:"""
|
|
|
|
|
|
# ── 一级缺失 ──────────────────────────────────────────────
|
|
|
if first_code not in actual_first:
|
|
|
- # 尝试使用LLM生成建议
|
|
|
+ # issue_point 和 reason 使用简单拼接
|
|
|
+ issue_point = f"【一级章节缺失】'{first_name}'整个章节不存在"
|
|
|
+ reason = f"依据《桥梁公司危险性较大工程管理实施细则(2025版)》规定,文档必须包含'{first_name}'一级章节,当前正文中未发现该章节任何内容"
|
|
|
+
|
|
|
+ # 尝试使用LLM生成 suggestion
|
|
|
llm_result = await self._generate_recommendation_with_llm(
|
|
|
level="一级",
|
|
|
first_code=first_code,
|
|
|
@@ -906,28 +908,20 @@ JSON输出:"""
|
|
|
first_seq=first_seq
|
|
|
)
|
|
|
|
|
|
- if llm_result:
|
|
|
- recommendations.append({
|
|
|
- "level": "一级",
|
|
|
- "issue_point": llm_result.get("issue_point", f"【一级章节缺失】'{first_name}'整个章节不存在"),
|
|
|
- "location": first_name,
|
|
|
- "suggestion": llm_result.get("suggestion", f"请添加'{first_name}'章节及其下全部子章节内容"),
|
|
|
- "reason": llm_result.get("reason", f"根据规范要求,文档必须包含'{first_name}'一级章节,当前正文中未发现该章节任何内容"),
|
|
|
- "first_seq": first_seq,
|
|
|
- })
|
|
|
+ if llm_result and llm_result.get("suggestion"):
|
|
|
+ suggestion = llm_result.get("suggestion")
|
|
|
else:
|
|
|
# 回退到简单拼接
|
|
|
- recommendations.append({
|
|
|
- "level": "一级",
|
|
|
- "issue_point": f"【一级章节缺失】'{first_name}'整个章节不存在",
|
|
|
- "location": first_name,
|
|
|
- "suggestion": f"请添加'{first_name}'章节及其下全部子章节内容",
|
|
|
- "reason": (
|
|
|
- f"根据规范要求,文档必须包含'{first_name}'一级章节,"
|
|
|
- f"当前正文中未发现该章节任何内容"
|
|
|
- ),
|
|
|
- "first_seq": first_seq,
|
|
|
- })
|
|
|
+ suggestion = f"请添加'{first_name}'章节及其下全部子章节内容"
|
|
|
+
|
|
|
+ recommendations.append({
|
|
|
+ "level": "一级",
|
|
|
+ "issue_point": issue_point,
|
|
|
+ "location": first_name,
|
|
|
+ "suggestion": suggestion,
|
|
|
+ "reason": reason,
|
|
|
+ "first_seq": first_seq,
|
|
|
+ })
|
|
|
continue
|
|
|
|
|
|
# ── 一级存在,检查二级 ─────────────────────────────────────
|
|
|
@@ -941,7 +935,11 @@ JSON输出:"""
|
|
|
|
|
|
# ── 二级缺失 ──────────────────────────────────────────
|
|
|
if (cat1, cat2) not in actual_secondary:
|
|
|
- # 尝试使用LLM生成建议
|
|
|
+ # issue_point 和 reason 使用简单拼接
|
|
|
+ issue_point = f"【二级章节缺失】{first_name} > '{second_name}'整个章节不存在"
|
|
|
+ reason = f"依据《桥梁公司危险性较大工程管理实施细则(2025版)》规定,'{first_name}'下应包含'{second_name}'二级章节,当前正文中未发现该章节内容"
|
|
|
+
|
|
|
+ # 尝试使用LLM生成 suggestion
|
|
|
llm_result = await self._generate_recommendation_with_llm(
|
|
|
level="二级",
|
|
|
first_code=cat1,
|
|
|
@@ -950,32 +948,21 @@ JSON输出:"""
|
|
|
second_name=second_name
|
|
|
)
|
|
|
|
|
|
- if llm_result:
|
|
|
- recommendations.append({
|
|
|
- "level": "二级",
|
|
|
- "issue_point": llm_result.get("issue_point", f"【二级章节缺失】{first_name} > '{second_name}'整个章节不存在"),
|
|
|
- "location": f"{first_name} > {second_name}",
|
|
|
- "suggestion": llm_result.get("suggestion", f"请在'{first_name}'下添加'{second_name}'章节内容"),
|
|
|
- "reason": llm_result.get("reason", f"根据规范要求,'{first_name}'下应包含'{second_name}'二级章节,当前正文中未发现该章节内容"),
|
|
|
- "first_seq": first_seq,
|
|
|
- "second_seq": second_seq,
|
|
|
- })
|
|
|
+ if llm_result and llm_result.get("suggestion"):
|
|
|
+ suggestion = llm_result.get("suggestion")
|
|
|
else:
|
|
|
# 回退到简单拼接
|
|
|
- recommendations.append({
|
|
|
- "level": "二级",
|
|
|
- "issue_point": (
|
|
|
- f"【二级章节缺失】{first_name} > '{second_name}'整个章节不存在"
|
|
|
- ),
|
|
|
- "location": f"{first_name} > {second_name}",
|
|
|
- "suggestion": f"请在'{first_name}'下添加'{second_name}'章节内容",
|
|
|
- "reason": (
|
|
|
- f"根据规范要求,'{first_name}'下应包含'{second_name}'二级章节,"
|
|
|
- f"当前正文中未发现该章节内容"
|
|
|
- ),
|
|
|
- "first_seq": first_seq,
|
|
|
- "second_seq": second_seq,
|
|
|
- })
|
|
|
+ suggestion = f"请在'{first_name}'下添加'{second_name}'章节内容"
|
|
|
+
|
|
|
+ recommendations.append({
|
|
|
+ "level": "二级",
|
|
|
+ "issue_point": issue_point,
|
|
|
+ "location": f"{first_name} > {second_name}",
|
|
|
+ "suggestion": suggestion,
|
|
|
+ "reason": reason,
|
|
|
+ "first_seq": first_seq,
|
|
|
+ "second_seq": second_seq,
|
|
|
+ })
|
|
|
continue
|
|
|
|
|
|
# ── 二级存在,检查三级缺失 ────────────────────────────
|
|
|
@@ -993,7 +980,8 @@ JSON输出:"""
|
|
|
if not missing_t_items:
|
|
|
continue
|
|
|
|
|
|
- # 尝试使用LLM批量生成三级缺失建议
|
|
|
+ # issue_point 和 reason 使用简单拼接(三级缺失)
|
|
|
+ # 尝试使用LLM批量生成 suggestion
|
|
|
llm_result = await self._generate_recommendation_with_llm(
|
|
|
level="三级",
|
|
|
first_code=cat1,
|
|
|
@@ -1003,34 +991,26 @@ JSON输出:"""
|
|
|
tertiary_items=missing_t_items
|
|
|
)
|
|
|
|
|
|
- if llm_result:
|
|
|
- # LLM生成了整体建议,为每个缺失项添加相同建议(但位置不同)
|
|
|
- for t_item in missing_t_items:
|
|
|
- recommendations.append({
|
|
|
- "level": "三级",
|
|
|
- "issue_point": f"【三级内容缺失】{first_name} > {second_name} > '{t_item.third_cn}'",
|
|
|
- "location": f"{first_name} > {second_name}",
|
|
|
- "suggestion": llm_result.get("suggestion", f"请补充'{second_name}'下的'{t_item.third_cn}'内容"),
|
|
|
- "reason": llm_result.get("reason", f"'{second_name}'下缺失规范要求的'{t_item.third_cn}'内容要点"),
|
|
|
- "first_seq": first_seq,
|
|
|
- "second_seq": second_seq,
|
|
|
- "third_seq": t_item.third_seq,
|
|
|
- })
|
|
|
+ if llm_result and llm_result.get("suggestion"):
|
|
|
+ suggestion = llm_result.get("suggestion")
|
|
|
else:
|
|
|
- # 回退到简单拼接
|
|
|
- for t_item in missing_t_items:
|
|
|
- recommendations.append({
|
|
|
- "level": "三级",
|
|
|
- "issue_point": (
|
|
|
- f"【三级内容缺失】{first_name} > {second_name} > '{t_item.third_cn}'"
|
|
|
- ),
|
|
|
- "location": f"{first_name} > {second_name}",
|
|
|
- "suggestion": f"请补充'{second_name}'下的'{t_item.third_cn}'内容",
|
|
|
- "reason": f"'{second_name}'下缺失规范要求的'{t_item.third_cn}'内容要点",
|
|
|
- "first_seq": first_seq,
|
|
|
- "second_seq": second_seq,
|
|
|
- "third_seq": t_item.third_seq,
|
|
|
- })
|
|
|
+ # 回退到简单拼接:列出所有缺失项
|
|
|
+ missing_names = "、".join([t.third_cn for t in missing_t_items[:5]])
|
|
|
+ if len(missing_t_items) > 5:
|
|
|
+ missing_names += f"等{len(missing_t_items)}项内容"
|
|
|
+ suggestion = f"请补充'{second_name}'下的{missing_names}"
|
|
|
+
|
|
|
+ for t_item in missing_t_items:
|
|
|
+ recommendations.append({
|
|
|
+ "level": "三级",
|
|
|
+ "issue_point": f"【三级内容缺失】{first_name} > {second_name} > '{t_item.third_cn}'",
|
|
|
+ "location": f"{first_name} > {second_name}",
|
|
|
+ "suggestion": suggestion,
|
|
|
+ "reason": f"依据《桥梁公司危险性较大工程管理实施细则(2025版)》规定,'{second_name}'下应包含'{t_item.third_cn}'内容要点",
|
|
|
+ "first_seq": first_seq,
|
|
|
+ "second_seq": second_seq,
|
|
|
+ "third_seq": t_item.third_seq,
|
|
|
+ })
|
|
|
|
|
|
# ── 一致性审查:目录有列但正文无内容 ─────────────────────────────
|
|
|
if outline_result:
|
|
|
@@ -1039,7 +1019,11 @@ JSON输出:"""
|
|
|
sec_title = e.get("outline_title") or e.get("secondary_name", "")
|
|
|
location = f"{f_name} > {sec_title}" if f_name else sec_title
|
|
|
|
|
|
- # 尝试使用LLM生成建议
|
|
|
+ # issue_point 和 reason 使用简单拼接(一致性审查)
|
|
|
+ issue_point = f"【目录正文不一致】'{location}'目录已列但正文无内容"
|
|
|
+ reason = f"依据《桥梁公司危险性较大工程管理实施细则(2025版)》规定,目录应与正文保持一致。目录页列有'{sec_title}'章节,但正文中未发现对应内容"
|
|
|
+
|
|
|
+ # 尝试使用LLM生成 suggestion
|
|
|
llm_result = await self._generate_recommendation_with_llm(
|
|
|
level="一致性",
|
|
|
first_code="",
|
|
|
@@ -1048,27 +1032,19 @@ JSON输出:"""
|
|
|
outline_title=sec_title
|
|
|
)
|
|
|
|
|
|
- if llm_result:
|
|
|
- recommendations.append({
|
|
|
- "level": "一致性",
|
|
|
- "issue_point": llm_result.get("issue_point", f"【目录正文不一致】'{location}'目录已列但正文无内容"),
|
|
|
- "location": location,
|
|
|
- "suggestion": llm_result.get("suggestion", f"请补充'{sec_title}'章节的正文内容,或从目录中移除该章节"),
|
|
|
- "reason": llm_result.get("reason", f"目录页列有'{sec_title}'章节,但正文中未发现对应内容,存在目录与正文不一致的问题"),
|
|
|
- })
|
|
|
+ if llm_result and llm_result.get("suggestion"):
|
|
|
+ suggestion = llm_result.get("suggestion")
|
|
|
else:
|
|
|
- recommendations.append({
|
|
|
- "level": "一致性",
|
|
|
- "issue_point": f"【目录正文不一致】'{location}'目录已列但正文无内容",
|
|
|
- "location": location,
|
|
|
- "suggestion": (
|
|
|
- f"请补充'{sec_title}'章节的正文内容,或从目录中移除该章节"
|
|
|
- ),
|
|
|
- "reason": (
|
|
|
- f"目录页列有'{sec_title}'章节,但正文中未发现对应内容,"
|
|
|
- f"存在目录与正文不一致的问题"
|
|
|
- ),
|
|
|
- })
|
|
|
+ # 回退到简单拼接
|
|
|
+ suggestion = f"请补充'{sec_title}'章节的正文内容,或从目录中移除该章节"
|
|
|
+
|
|
|
+ recommendations.append({
|
|
|
+ "level": "一致性",
|
|
|
+ "issue_point": issue_point,
|
|
|
+ "location": location,
|
|
|
+ "suggestion": suggestion,
|
|
|
+ "reason": reason,
|
|
|
+ })
|
|
|
|
|
|
if not recommendations:
|
|
|
recommendations.append({
|
|
|
@@ -1076,7 +1052,7 @@ JSON输出:"""
|
|
|
"issue_point": "文档完整性良好",
|
|
|
"location": "",
|
|
|
"suggestion": "无需补充",
|
|
|
- "reason": "文档已覆盖规范要求的所有章节与内容要点",
|
|
|
+ "reason": "依据《桥梁公司危险性较大工程管理实施细则(2025版)》规定,文档已覆盖所有章节与内容要点",
|
|
|
})
|
|
|
|
|
|
return recommendations
|