feat: 添加可配置场景注册表与规则引擎

- 新增场景基类、配置加载、注册表与原语模块
- 添加 r10_refund_split 规则及场景 JSON Schema
- 扩展 scan 引擎与 scenarios API
- 新增场景注册表/配置/集成测试
- 更新前端 App、api、labels 支持新场景
This commit is contained in:
selfrelease
2026-06-17 09:57:02 +08:00
parent cbaa2156fc
commit 74e35fed96
20 changed files with 998 additions and 2 deletions
+51
View File
@@ -15,6 +15,7 @@ from app.clues import service as clue_svc
from app.clues.models import Clue
from app.scenarios import churn_fraud as cf
from app.scenarios import split_contract as sc
from app.scenarios.base import BaseScenario
MODEL_VERSION = "mock-llm@0.1"
@@ -98,3 +99,53 @@ def run_churn_scan(
data_version_id=data_version_id,
)
return ScanResult("R9", len(retention_curve), clue)
@dataclass
class ScenarioRunResult:
"""通用调度下单个场景的落库结果:扫描覆盖数 + 生成的线索列表。"""
scenario_code: str
scanned_count: int
clues: list[Clue]
def run_scenarios(
session: Session,
scenarios: list[BaseScenario],
*,
data_version_id: uuid.UUID | None = None,
actor: str = "system",
) -> list[ScenarioRunResult]:
"""通用场景调度器:遍历已实例化的场景,检测→按阈值过滤→统一落库。
新增场景无需改动本函数:实现 BaseScenario 子类并经 @register_scenario 注册即可。
每个场景自报扫描覆盖数(证明全量性),超过阈值的草稿由本函数统一调 create_clue 落库。
"""
results: list[ScenarioRunResult] = []
for scenario in scenarios:
outcome = scenario.scan(session, data_version_id=data_version_id)
created: list[Clue] = []
for draft in outcome.drafts:
if draft.score >= scenario.score_threshold:
created.append(
clue_svc.create_clue(
session,
title=draft.title or scenario.title,
risk_domain=scenario.risk_domain,
scenario_code=scenario.code,
score=draft.score,
rationale=draft.rationale,
evidence=draft.evidence,
subjects=draft.subjects,
amount_involved=draft.amount_involved,
model_version=MODEL_VERSION,
rule_version=scenario.rule_version,
data_version_id=data_version_id,
actor=actor,
)
)
results.append(
ScenarioRunResult(scenario.code, outcome.scanned_count, created)
)
return results