feat(regulatory): 接入法规核查触发与工作流骨架

This commit is contained in:
2026-06-07 00:34:12 +08:00
parent 26490f7c46
commit 44d31d2a14
9 changed files with 511 additions and 2 deletions

View File

@@ -15,6 +15,7 @@ from .models import Conversation, FileAttachment
logger = logging.getLogger(__name__)
ROUTE_ACTIONS = {"normal_chat", "attachment_reader", "file_summary"}
ROUTE_ACTIONS.add("regulatory_review")
@dataclass(frozen=True)
@@ -34,6 +35,10 @@ class SkillRoute:
def starts_file_summary(self) -> bool:
return self.action == "file_summary"
@property
def starts_regulatory_review(self) -> bool:
return self.action == "regulatory_review"
@property
def is_normal_chat(self) -> bool:
return self.action == "normal_chat"
@@ -100,7 +105,7 @@ def _route_with_llm(
return SkillRoute(
action=action,
skill_name="attachment_reader" if action == "attachment_reader" else "",
workflow_type="file_summary" if action == "file_summary" else "",
workflow_type=action if action in {"file_summary", "regulatory_review"} else "",
confidence=_float_or_zero(payload.get("confidence")),
reason=str(payload.get("reason") or ""),
source="llm",
@@ -108,6 +113,15 @@ def _route_with_llm(
def _route_with_rules(conversation: Conversation, content: str) -> SkillRoute:
if _matches_regulatory_review(content):
return SkillRoute(
action="regulatory_review",
workflow_type="regulatory_review",
confidence=0.7,
reason="命中法规核查关键词。",
source="rule_fallback",
)
file_summary = evaluate_file_summary_trigger(conversation, content)
if file_summary.should_start or file_summary.reason == "missing_attachment":
return SkillRoute(
@@ -148,9 +162,10 @@ def _router_system_prompt() -> str:
return (
"你是审核智能体的工具路由器,只判断是否需要调用工具,不直接回答用户。"
"你必须只输出 JSON 对象,不要输出 Markdown。"
"可选 actionnormal_chat、attachment_reader、file_summary。"
"可选 actionnormal_chat、attachment_reader、file_summary、regulatory_review"
"attachment_reader 用于用户要求阅读、提取、分析、总结、查看上传附件内容。"
"file_summary 用于用户要求自动汇总文件目录、页数、清单或生成目录页数报告。"
"regulatory_review 用于用户要求法规核查、NMPA核查、完整性核查、章节一致性核查、风险预警或整改建议。"
"normal_chat 用于不需要读取附件或执行工作流的一般问答。"
"输出字段action、confidence、reason。"
)
@@ -187,3 +202,18 @@ def _float_or_zero(value) -> float:
return float(value)
except (TypeError, ValueError):
return 0.0
def _matches_regulatory_review(content: str) -> bool:
normalized = content.lower()
keywords = [
"法规核查",
"nmpa核查",
"nmpa 核查",
"完整性核查",
"风险预警",
"整改建议",
"章节核查",
"一致性核查",
]
return any(keyword in normalized for keyword in keywords)