feat: 新增预算中心本体与风险规则评分回填

后端新增预算本体解析模块和风险规则评分回填服务,优化规则
生成本体对齐和提示词构建,增强费用类型关键词和本体验证,
完善报销查询和审计接口,前端预算中心页面增加对话框和本
体工具函数,重构审计页面元数据和视图模型,补充单元测试。
This commit is contained in:
caoxiaozhu
2026-05-26 12:16:20 +08:00
parent 0e861d8fa6
commit e1e515ecae
53 changed files with 4350 additions and 921 deletions

View File

@@ -8,6 +8,8 @@ def build_risk_rule_compiler_messages(
*,
domain: str,
domain_label: str,
business_stage: str,
business_stage_label: str,
expense_category: str | None,
expense_category_label: str,
natural_language: str,
@@ -74,6 +76,9 @@ def build_risk_rule_compiler_messages(
}
guardrails = [
"只能输出 JSON 对象,不能输出 Markdown 或解释。",
"必须区分业务环节:费用申请是事前风控,费用报销是事后核验;不要把二者的字段和流程语义混用。",
"费用申请阶段更关注预算余额、申请金额、申请事由、预计行程、预计费用科目、是否超预算或缺少前置审批。",
"费用报销阶段更关注真实票据、报销明细、发生日期、附件识别结果和申请/行程/票据一致性。",
"字段必须来自 available_fields不能编造字段。",
"多步骤规则要使用 composite_rule_v1先抽取事实变量再写 conditions 和 hit_logic不要压扁成单个关键词判断。",
"城市/地点/路线一致性必须用 field_compare_v1 或 semantic_type=travel_route_city_consistency。",
@@ -88,6 +93,8 @@ def build_risk_rule_compiler_messages(
"keyword_match_v1 只用于品名、摘要、票据全文中出现明确风险词的规则。",
"不要直接指定 risk_level 或 risk_score只输出 risk_scoring_evidence后端会按固定评分模型计算 0-100 分和风险等级。",
"评分证据必须围绕六个指标:业务影响、违规确定性、证据强度、例外/规避空间、处置强度、场景敏感度。",
"若规则语义是可修复的低风险提醒,例如资料要素缺失但归属清晰、仅提醒/提示/补齐且不退回不阻断,则 impact_level 和 control_action 应保持低强度。",
"只有涉及造假、重复报销、金额超标、城市/日期不一致、禁止提交、退回修改、阻断或审计复核时,才应给 high 或 critical 的评分证据。",
]
examples = [
{
@@ -114,6 +121,26 @@ def build_risk_rule_compiler_messages(
"keywords": [],
"exception_keywords": ["绕行", "跨城办事", "临时改签"],
},
},
{
"user_rule": (
"差旅报销时,票据已上传但发票号码或商品服务名称缺失,且报销事由、人员和部门"
"能够说明费用归属,则标记为低风险,仅提醒补齐票据要素。"
),
"expected": {
"template_key": "field_required_v1",
"field_keys": ["attachment.invoice_no", "attachment.goods_name", "claim.reason"],
"condition_summary": "票据要素缺失但费用归属清晰时,仅提示补齐。",
"risk_scoring_evidence": {
"impact_level": "low",
"violation_certainty": "medium",
"evidence_strength": "medium",
"exception_dependence": "low",
"control_action": "remind",
"business_sensitivity": "medium",
"reason": "命中后只做补齐提醒,不阻断、不退回,也不涉及舞弊或金额越权。",
},
},
}
]
return [
@@ -133,11 +160,13 @@ def build_risk_rule_compiler_messages(
"content": json.dumps(
{
"business_domain": domain,
"business_domain_label": domain_label,
"expense_category": expense_category,
"expense_category_label": expense_category_label,
"natural_language": natural_language,
"available_fields": available_fields,
"business_domain_label": domain_label,
"business_stage": business_stage,
"business_stage_label": business_stage_label,
"expense_category": expense_category,
"expense_category_label": expense_category_label,
"natural_language": natural_language,
"available_fields": available_fields,
"required_json_shape": schema,
"examples": examples,
},