feat: 扩展风险规则体系、审批动态路由与预算中心列表化改造
- 新增 25+ 条风险规则(预算/报销/申请/通用类),完善风险规则模拟与反馈发布机制 - 引入费用审批动态路由、平台风险分级、预审与风险阶段管理 - 预算中心列表化改造,优化票据夹仪表盘与数字员工工作看板 - 新增 Hermes 风险线索收集器、Agent 链路追踪中心 - 扩展数字员工能力库(18 个领域 Skill)与交通费用自动预估 - 完善报销申请快速预览、权限控制与前端测试覆盖
This commit is contained in:
@@ -11,16 +11,126 @@ from app.core.agent_enums import (
|
||||
)
|
||||
from app.models.agent_asset import AgentAsset
|
||||
from app.services.agent_foundation_constants import (
|
||||
DIGITAL_EMPLOYEE_ALGORITHM_REPLAY_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_BUDGET_PRECONTROL_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_DEPARTMENT_BASELINE_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_FALSE_POSITIVE_SAMPLE_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_FEEDBACK_SAMPLE_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_MULTI_EVIDENCE_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_POLICY_ALIGNMENT_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_POLICY_CLAUSE_EXTRACT_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_POLICY_GAP_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_PROFILE_SCAN_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_RISK_GRAPH_SCAN_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_RULE_DISCOVERY_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_RULE_TEMPLATE_ORGANIZE_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_SKILL_CATEGORIES,
|
||||
DIGITAL_EMPLOYEE_SPATIOTEMPORAL_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_SUPPLIER_PROFILE_TASK_CODE,
|
||||
DIGITAL_EMPLOYEE_SUPPLIER_RELATION_TASK_CODE,
|
||||
)
|
||||
|
||||
|
||||
DIGITAL_EMPLOYEE_ANALYSIS_ROLE_BOUNDARY = (
|
||||
"规则由人定义,风险由人确认,主流程由外层智能体执行,"
|
||||
"数字员工只读取事实、规则命中和反馈结果,生成后台分析、报告和待复核材料。"
|
||||
)
|
||||
|
||||
|
||||
class AgentFoundationDigitalEmployeeTaskMixin:
|
||||
def _runtime_digital_employee_task_specs(self) -> tuple[dict[str, object], ...]:
|
||||
return (
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_POLICY_CLAUSE_EXTRACT_TASK_CODE,
|
||||
name="制度条款结构化抽取",
|
||||
description="按计划从财务制度和报销政策中抽取适用范围、限制条件、金额标准、审批要求和证据字段。",
|
||||
scenario_json=["schedule", "knowledge", "policy_clause", "ontology"],
|
||||
owner="财务制度管理组",
|
||||
cron="15 3 * * *",
|
||||
skill_category="整理",
|
||||
skill_name="finance-policy-clause-extractor",
|
||||
output_format="policy_clause_structuring_report",
|
||||
input_sources=["finance_policies", "knowledge_documents", "ontology_parse_logs"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_POLICY_ALIGNMENT_TASK_CODE,
|
||||
name="报销政策口径对齐",
|
||||
description="对齐不同制度、规则中心和知识库中的报销口径,发现同义、冲突、缺失和过期条款。",
|
||||
scenario_json=["schedule", "knowledge", "expense_policy", "rule_center"],
|
||||
owner="财务制度管理组",
|
||||
cron="30 3 * * *",
|
||||
skill_category="整理",
|
||||
skill_name="expense-policy-alignment",
|
||||
output_format="policy_alignment_report",
|
||||
input_sources=["finance_policies", "risk_rules", "knowledge_items"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_RULE_TEMPLATE_ORGANIZE_TASK_CODE,
|
||||
name="规则命中样本整理",
|
||||
description="把外层智能体流程已经产生的规则命中、制度引用和历史样本整理为字段映射与复核材料,不新增、不改写、不发布规则。",
|
||||
scenario_json=["schedule", "rule_hit", "risk_rule", "policy_ref"],
|
||||
owner="风控与审计部",
|
||||
cron="45 3 * * 1",
|
||||
skill_category="整理",
|
||||
skill_name="rule-execution-case-organizer",
|
||||
output_format="rule_hit_sample_pack",
|
||||
input_sources=["approved_risk_rules", "policy_refs", "rule_hits"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_DEPARTMENT_BASELINE_TASK_CODE,
|
||||
name="部门费用基线沉淀",
|
||||
description="按部门、费用类型和时间窗口沉淀费用基线,为预算柔性控制和同类对比提供长期参照。",
|
||||
scenario_json=["schedule", "department", "baseline", "expense"],
|
||||
owner="风控与审计部",
|
||||
cron="45 8 * * 1",
|
||||
skill_category="积累",
|
||||
skill_name="department-expense-baseline-accumulator",
|
||||
output_format="department_expense_baseline_snapshot",
|
||||
input_sources=["expense_claims", "expense_items", "profile_baselines"],
|
||||
execution_strategy="reuse_employee_profile_baseline",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_SUPPLIER_PROFILE_TASK_CODE,
|
||||
name="供应商风险画像沉淀",
|
||||
description="沉淀供应商、商户、酒店和收款方的费用频次、金额分布、异常关系和历史风险反馈。",
|
||||
scenario_json=["schedule", "supplier", "baseline", "risk_graph"],
|
||||
owner="风控与审计部",
|
||||
cron="0 8 * * 2",
|
||||
skill_category="积累",
|
||||
skill_name="supplier-risk-profile-accumulator",
|
||||
output_format="supplier_risk_profile_snapshot",
|
||||
input_sources=["expense_claims", "invoice_entities", "risk_observations"],
|
||||
execution_strategy="reuse_profile_baseline",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_FALSE_POSITIVE_SAMPLE_TASK_CODE,
|
||||
name="历史误报样本沉淀",
|
||||
description="归集被人工标记为误报、忽略或撤销的风险观察,形成算法回放和人工复核校准样本。",
|
||||
scenario_json=["schedule", "false_positive", "feedback", "replay"],
|
||||
owner="风控与审计部",
|
||||
cron="20 10 * * 1",
|
||||
skill_category="积累",
|
||||
skill_name="false-positive-sample-accumulator",
|
||||
output_format="false_positive_sample_pool",
|
||||
input_sources=["risk_observations", "risk_observation_feedback"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_FEEDBACK_SAMPLE_TASK_CODE,
|
||||
name="风险观察反馈样本沉淀",
|
||||
description="归集确认、补件、升级、改写和人工复核反馈,形成风险观察反馈样本池。",
|
||||
scenario_json=["schedule", "feedback", "risk_observation", "sample_pool"],
|
||||
owner="风控与审计部",
|
||||
cron="40 10 * * 1",
|
||||
skill_category="积累",
|
||||
skill_name="risk-feedback-sample-accumulator",
|
||||
output_format="risk_feedback_sample_pool",
|
||||
input_sources=["risk_observations", "risk_observation_feedback", "agent_runs"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
{
|
||||
"code": DIGITAL_EMPLOYEE_RISK_GRAPH_SCAN_TASK_CODE,
|
||||
"name": "财务风险图谱巡检",
|
||||
@@ -43,6 +153,15 @@ class AgentFoundationDigitalEmployeeTaskMixin:
|
||||
],
|
||||
"output_format": "risk_observation_report",
|
||||
"writes_risk_observations": True,
|
||||
"allowed_outputs": [
|
||||
"facts",
|
||||
"rule_hits",
|
||||
"risk_clues",
|
||||
"evidence_refs",
|
||||
"human_review_required",
|
||||
],
|
||||
"role_boundary": DIGITAL_EMPLOYEE_ANALYSIS_ROLE_BOUNDARY,
|
||||
"writes_rules": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -53,7 +172,7 @@ class AgentFoundationDigitalEmployeeTaskMixin:
|
||||
"owner": "风控与审计部",
|
||||
"reviewer": "顾承宇",
|
||||
"cron": "30 8 * * 1",
|
||||
"skill_category": "评估",
|
||||
"skill_category": "积累",
|
||||
"markdown": self._employee_behavior_profile_scan_skill_markdown,
|
||||
"change_note": "初始化员工行为画像巡检能力。",
|
||||
"config": {
|
||||
@@ -66,30 +185,199 @@ class AgentFoundationDigitalEmployeeTaskMixin:
|
||||
],
|
||||
"output_format": "employee_behavior_profile_snapshot",
|
||||
"writes_profile_snapshots": True,
|
||||
"allowed_outputs": [
|
||||
"facts",
|
||||
"profile_snapshots",
|
||||
"baseline_metrics",
|
||||
"evidence_refs",
|
||||
"human_review_required",
|
||||
],
|
||||
"role_boundary": DIGITAL_EMPLOYEE_ANALYSIS_ROLE_BOUNDARY,
|
||||
"writes_rules": False,
|
||||
},
|
||||
},
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_MULTI_EVIDENCE_TASK_CODE,
|
||||
name="单据多凭证一致性评估",
|
||||
description="比对报销单、费用明细、发票、流水、合同和事前申请之间的金额、数量、主体和时间字段。",
|
||||
scenario_json=["schedule", "expense", "multi_evidence", "risk_observation"],
|
||||
owner="风控与审计部",
|
||||
cron="15 9 * * *",
|
||||
skill_category="评估",
|
||||
skill_name="multi-evidence-consistency-evaluator",
|
||||
output_format="multi_evidence_consistency_report",
|
||||
input_sources=["expense_claims", "expense_items", "invoices", "attachments"],
|
||||
execution_strategy="reuse_financial_risk_graph_scan",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_SPATIOTEMPORAL_TASK_CODE,
|
||||
name="差旅时空一致性评估",
|
||||
description="评估差旅发生时间、提交时间、票据地点、消费地点、行程轨迹和开票地点是否一致。",
|
||||
scenario_json=["schedule", "travel", "spatiotemporal", "risk_observation"],
|
||||
owner="风控与审计部",
|
||||
cron="30 9 * * *",
|
||||
skill_category="评估",
|
||||
skill_name="travel-spatiotemporal-consistency-evaluator",
|
||||
output_format="spatiotemporal_consistency_report",
|
||||
input_sources=["expense_claims", "expense_items", "invoice_locations", "travel_routes"],
|
||||
execution_strategy="reuse_financial_risk_graph_scan",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_BUDGET_PRECONTROL_TASK_CODE,
|
||||
name="预算占用与超标预警",
|
||||
description="评估预算占用、费用标准、历史基线和柔性控制边界,输出提交前或审批前预警建议。",
|
||||
scenario_json=["schedule", "budget", "expense", "precontrol"],
|
||||
owner="预算管理组",
|
||||
cron="45 9 * * *",
|
||||
skill_category="评估",
|
||||
skill_name="budget-overrun-precontrol-evaluator",
|
||||
output_format="budget_precontrol_warning_report",
|
||||
input_sources=["expense_claims", "budget_snapshots", "policy_refs", "profile_baselines"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_SUPPLIER_RELATION_TASK_CODE,
|
||||
name="供应商异常关系评估",
|
||||
description="识别员工、部门、供应商、票据和报销单之间的异常聚集、重复关系和跨部门集中风险。",
|
||||
scenario_json=["schedule", "supplier", "risk_graph", "relationship"],
|
||||
owner="风控与审计部",
|
||||
cron="0 9 * * 2",
|
||||
skill_category="评估",
|
||||
skill_name="supplier-abnormal-relation-evaluator",
|
||||
output_format="supplier_abnormal_relation_report",
|
||||
input_sources=["risk_graph", "expense_claims", "invoice_entities", "entity_registry"],
|
||||
execution_strategy="reuse_financial_risk_graph_scan",
|
||||
),
|
||||
{
|
||||
"code": DIGITAL_EMPLOYEE_RULE_DISCOVERY_TASK_CODE,
|
||||
"name": "风险规则候选发现",
|
||||
"description": "按计划复盘风险观察和人工反馈,生成带证据、来源和置信度的候选规则,不直接上线。",
|
||||
"scenario_json": ["schedule", "risk_observation", "feedback", "rule_candidate"],
|
||||
"name": "风险线索归集",
|
||||
"description": "按计划复盘申请、报销、规则命中和人工反馈,归集带事实依据的潜在线索,提交人工复核,不生成规则。",
|
||||
"scenario_json": ["schedule", "application", "reimbursement", "risk_clue"],
|
||||
"owner": "风控与审计部",
|
||||
"reviewer": "顾承宇",
|
||||
"cron": "0 10 * * 1",
|
||||
"skill_category": "升级",
|
||||
"markdown": self._risk_rule_discovery_skill_markdown,
|
||||
"change_note": "初始化风险规则候选发现能力。",
|
||||
"markdown": self._risk_clue_collector_skill_markdown,
|
||||
"change_note": "初始化风险线索归集能力。",
|
||||
"config": {
|
||||
"skill_name": "risk-rule-discovery",
|
||||
"task_type": "risk_clue_collect",
|
||||
"skill_name": "risk-clue-collector",
|
||||
"input_sources": [
|
||||
"risk_observations",
|
||||
"expense_applications",
|
||||
"expense_claims",
|
||||
"rule_hits",
|
||||
"risk_observation_feedback",
|
||||
"algorithm_replay_sets",
|
||||
],
|
||||
"output_format": "candidate_risk_rules",
|
||||
"auto_publish": False,
|
||||
"output_format": "risk_clue_review_packet",
|
||||
"allowed_outputs": [
|
||||
"facts",
|
||||
"rule_hits",
|
||||
"risk_clues",
|
||||
"evidence_refs",
|
||||
"human_review_required",
|
||||
],
|
||||
"role_boundary": DIGITAL_EMPLOYEE_ANALYSIS_ROLE_BOUNDARY,
|
||||
"writes_rules": False,
|
||||
"human_review_required": True,
|
||||
},
|
||||
},
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_ALGORITHM_REPLAY_TASK_CODE,
|
||||
name="风险算法回放评测",
|
||||
description="复跑历史风险观察、反馈标签、本体版本和规则版本,评估算法升级前后的误报率和确认率。",
|
||||
scenario_json=["schedule", "algorithm_replay", "evaluation", "feedback"],
|
||||
owner="风控与审计部",
|
||||
cron="30 10 * * 1",
|
||||
skill_category="升级",
|
||||
skill_name="risk-algorithm-replay-evaluator",
|
||||
output_format="algorithm_replay_evaluation_report",
|
||||
input_sources=["algorithm_replay_sets", "risk_observations", "risk_observation_feedback"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
self._digital_employee_task_spec(
|
||||
code=DIGITAL_EMPLOYEE_POLICY_GAP_TASK_CODE,
|
||||
name="制度引用缺口提示",
|
||||
description="整理申请、报销、规则命中和人工反馈中缺少制度引用的事实位置,提示人工补齐制度依据,不输出规则变更建议。",
|
||||
scenario_json=["schedule", "policy_reference", "evidence_gap", "human_review"],
|
||||
owner="财务制度管理组",
|
||||
cron="0 11 * * 1",
|
||||
skill_category="升级",
|
||||
skill_name="policy-reference-gap-hinter",
|
||||
output_format="policy_reference_gap_hint_report",
|
||||
input_sources=["policy_refs", "rule_hits", "expense_claims", "risk_feedback_samples"],
|
||||
execution_strategy="definition_ready",
|
||||
),
|
||||
)
|
||||
|
||||
def _digital_employee_task_spec(
|
||||
self,
|
||||
*,
|
||||
code: str,
|
||||
name: str,
|
||||
description: str,
|
||||
scenario_json: list[str],
|
||||
owner: str,
|
||||
cron: str,
|
||||
skill_category: str,
|
||||
skill_name: str,
|
||||
output_format: str,
|
||||
input_sources: list[str],
|
||||
execution_strategy: str,
|
||||
) -> dict[str, object]:
|
||||
return {
|
||||
"code": code,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"scenario_json": scenario_json,
|
||||
"owner": owner,
|
||||
"reviewer": "顾承宇",
|
||||
"cron": cron,
|
||||
"skill_category": skill_category,
|
||||
"markdown": lambda: self._generic_digital_employee_skill_markdown(
|
||||
skill_name=skill_name,
|
||||
title=name,
|
||||
description=description,
|
||||
),
|
||||
"change_note": f"初始化{name}能力。",
|
||||
"config": {
|
||||
"skill_name": skill_name,
|
||||
"input_sources": input_sources,
|
||||
"output_format": output_format,
|
||||
"writes_work_record": True,
|
||||
"execution_strategy": execution_strategy,
|
||||
"allowed_outputs": [
|
||||
"facts",
|
||||
"rule_hits",
|
||||
"risk_clues",
|
||||
"evidence_refs",
|
||||
"human_review_required",
|
||||
],
|
||||
"role_boundary": DIGITAL_EMPLOYEE_ANALYSIS_ROLE_BOUNDARY,
|
||||
"writes_rules": False,
|
||||
},
|
||||
}
|
||||
|
||||
def _generic_digital_employee_skill_markdown(
|
||||
self,
|
||||
*,
|
||||
skill_name: str,
|
||||
title: str,
|
||||
description: str,
|
||||
) -> str:
|
||||
return self._read_domain_skill_markdown(
|
||||
skill_name,
|
||||
[
|
||||
"---",
|
||||
f"name: {skill_name}",
|
||||
f"description: {description}",
|
||||
"---",
|
||||
"",
|
||||
f"# {title}",
|
||||
"",
|
||||
"## 功能说明",
|
||||
"",
|
||||
description,
|
||||
],
|
||||
)
|
||||
|
||||
def _upsert_runtime_digital_employee_tasks(self, existing_codes: set[str]) -> None:
|
||||
@@ -146,6 +434,7 @@ class AgentFoundationDigitalEmployeeTaskMixin:
|
||||
cron = str(spec["cron"])
|
||||
base = {
|
||||
**self._digital_employee_task_config(code, cron),
|
||||
"skill_category": str(spec["skill_category"]),
|
||||
"schedule": cron,
|
||||
"cron_expression": cron,
|
||||
**dict(spec["config"]),
|
||||
|
||||
Reference in New Issue
Block a user